From 3026e2df6265249757c27b5760166e373e965b29 Mon Sep 17 00:00:00 2001 From: shawn_hu_ls Date: Fri, 7 Apr 2023 22:25:23 +0800 Subject: [PATCH] Fix some aot and benchmark test cases cannot passed on es2abc 1. Fix the ClassDefinition identify is not binded to the ClassDecl 2. Fix the methods list in classType is not saved like AST 3. Add more function modifiers in functionType to make sure the AOT compiler can calculate the correct offset for class methods which has implementation Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I6TRTU?from=project-issue Test: Test262 & Parser & TSC & Compiler & TypeExtractor Signed-off-by: shawn_hu_ls --- es2panda/parser/parserImpl.cpp | 10 +- es2panda/parser/parserImpl.h | 2 +- es2panda/test/runner.py | 59 +- .../test-interface-type-test-1-expected.txt | 2 +- .../test-type-summary-order-1-expected.txt | 4 +- .../testcases/test-class-1-expected.txt | 573 +++++++++++ .../type_extractor/testcases/test-class-1.ts | 23 + ...st-class-with-abstract-method-expected.txt | 653 +++++++++++++ .../test-class-with-abstract-method.ts | 24 + ...st-class-with-overload-method-expected.txt | 889 ++++++++++++++++++ .../test-class-with-overload-method.ts | 26 + .../test-class-expected.txt | 1 + .../testcases_with_running/test-class.ts | 24 + es2panda/typescript/extractor/typeSystem.h | 83 +- 14 files changed, 2308 insertions(+), 65 deletions(-) mode change 100644 => 100755 es2panda/test/type_extractor/dts-testcases/test-interface-type-test-1-expected.txt mode change 100644 => 100755 es2panda/test/type_extractor/dts-testcases/test-type-summary-order-1-expected.txt create mode 100644 es2panda/test/type_extractor/testcases/test-class-1-expected.txt create mode 100644 es2panda/test/type_extractor/testcases/test-class-1.ts create mode 100644 es2panda/test/type_extractor/testcases/test-class-with-abstract-method-expected.txt create mode 100644 es2panda/test/type_extractor/testcases/test-class-with-abstract-method.ts create mode 100644 es2panda/test/type_extractor/testcases/test-class-with-overload-method-expected.txt create mode 100644 es2panda/test/type_extractor/testcases/test-class-with-overload-method.ts create mode 100644 es2panda/test/type_extractor/testcases_with_running/test-class-expected.txt create mode 100644 es2panda/test/type_extractor/testcases_with_running/test-class.ts diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index 4092e21fb4..c15df07510 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -2769,7 +2769,7 @@ bool ParserImpl::IsMethodDefinitionsAreSame(const ir::MethodDefinition *property return IsPropertyKeysAreSame(property->Key(), overload->Key()); } -ir::Identifier *ParserImpl::SetIdentNodeInClassDefinition(bool isDeclare) +ir::Identifier *ParserImpl::SetIdentNodeInClassDefinition(bool isDeclare, binder::ConstDecl **decl) { lexer::TokenType keywType = lexer_->GetToken().KeywordType(); CheckStrictReservedWord(); @@ -2780,7 +2780,7 @@ ir::Identifier *ParserImpl::SetIdentNodeInClassDefinition(bool isDeclare) const util::StringView &identStr = lexer_->GetToken().Ident(); - Binder()->AddDecl(lexer_->GetToken().Start(), isDeclare, identStr); + *decl = Binder()->AddDecl(lexer_->GetToken().Start(), isDeclare, identStr); auto *identNode = AllocNode(identStr); identNode->SetRange(lexer_->GetToken().Loc()); @@ -2797,13 +2797,14 @@ ir::ClassDefinition *ParserImpl::ParseClassDefinition(bool isDeclaration, bool i lexer::SourcePosition startLoc = lexer_->GetToken().Start(); lexer_->NextToken(); + binder::ConstDecl *decl = nullptr; ir::Identifier *identNode = nullptr; auto classCtx = binder::LexicalScope(Binder()); if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && (Extension() != ScriptExtension::TS || lexer_->GetToken().KeywordType() != lexer::TokenType::KEYW_IMPLEMENTS)) { - identNode = SetIdentNodeInClassDefinition(isDeclare); + identNode = SetIdentNodeInClassDefinition(isDeclare, &decl); } else if (isDeclaration && idRequired) { ThrowSyntaxError("Unexpected token, expected an identifier."); } @@ -2947,6 +2948,9 @@ ir::ClassDefinition *ParserImpl::ParseClassDefinition(bool isDeclaration, bool i std::move(properties), std::move(indexSignatures), isDeclare, isAbstract); classDefinition->SetRange({classBodyStartLoc, classBodyEndLoc}); + if (decl != nullptr) { + decl->BindNode(classDefinition); + } return classDefinition; } diff --git a/es2panda/parser/parserImpl.h b/es2panda/parser/parserImpl.h index 626be76fa2..cf4e71e6c6 100644 --- a/es2panda/parser/parserImpl.h +++ b/es2panda/parser/parserImpl.h @@ -309,7 +309,7 @@ private: ir::MethodDefinition *CheckClassMethodOverload(ir::Statement *property, ir::MethodDefinition **ctor, bool isDeclare, lexer::SourcePosition errorInfo, ir::MethodDefinition *lastOverload, bool implExists, bool isAbstract = false); - ir::Identifier *SetIdentNodeInClassDefinition(bool isDeclare); + ir::Identifier *SetIdentNodeInClassDefinition(bool isDeclare, binder::ConstDecl **decl); ir::ClassDefinition *ParseClassDefinition(bool isDeclaration, bool idRequired = true, bool isDeclare = false, bool isAbstract = false); diff --git a/es2panda/test/runner.py b/es2panda/test/runner.py index 46cc5e739d..342d97ddf5 100755 --- a/es2panda/test/runner.py +++ b/es2panda/test/runner.py @@ -1218,6 +1218,7 @@ class TypeExtractorRunner(Runner): self.add_directory("testcases", []) self.add_directory("dts-testcases", [], True) self.add_directory("testcases_with_assert", []) + self.add_directory("testcases_with_running", []) def add_tsc_directory(self, directory, flags): ts_suite_dir = path.join(self.tsc_path, 'tests/cases') @@ -1245,8 +1246,10 @@ class TypeExtractorRunner(Runner): files = fnmatch.filter(files, ts_suite_dir + '**' + self.args.filter) for f in files: - if directory.endswith("testcases_with_assert"): - test = TypeExtractorWithAssertTest(f, flags) + if directory.endswith("testcases_with_assert") or directory.endswith("testcases_with_running"): + if (self.ld_library_path == "" or self.ark_aot_compiler == ""): + break + test = TypeExtractorWithAOTTest(f, flags, directory.endswith("testcases_with_running")) self.tests.append(test) else: test = TypeExtractorTest(f, flags, is_dts_test) @@ -1306,12 +1309,40 @@ class TypeExtractorTest(Test): return self -class TypeExtractorWithAssertTest(Test): - def __init__(self, test_path, flags): +class TypeExtractorWithAOTTest(Test): + def __init__(self, test_path, flags, with_running=False): Test.__init__(self, test_path, flags) + self.with_running = with_running + + def run_js_vm(self, runner, file_name, test_abc_name): + expected_path = "%s-expected.txt" % (file_name) + run_aot_cmd = [runner.ark_js_vm] + run_aot_cmd.extend(["--aot-file=%s" % file_name]) + run_aot_cmd.extend(["--entry-point=%s" % path.basename(file_name)]) + run_aot_cmd.extend([test_abc_name]) + self.log_cmd(run_aot_cmd) + + process = subprocess.Popen(run_aot_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = process.communicate(timeout=runner.args.timeout) + self.output = out.decode("utf-8", errors="ignore") + err.decode("utf-8", errors="ignore") + try: + with open(expected_path, 'r') as fp: + expected = fp.read() + self.passed = expected == self.output and process.returncode in [0, 1] + except Exception: + self.passed = False + + if not self.passed: + self.error = err.decode("utf-8", errors="ignore") + + if os.path.isfile("%s.an" % (file_name)): + os.remove("%s.an" % (file_name)) + if os.path.isfile("%s.ai" % (file_name)): + os.remove("%s.ai" % (file_name)) def run(self, runner): - test_abc_name = ("%s.abc" % (path.splitext(self.path)[0])).replace("/", "_") + file_name = path.splitext(self.path)[0] + test_abc_name = ("%s.abc" % path.basename(file_name)) cmd = runner.cmd_prefix + [runner.es2panda, '--module', '--merge-abc', '--opt-level=2', '--type-extractor'] cmd.extend(self.flags) @@ -1327,17 +1358,14 @@ class TypeExtractorWithAssertTest(Test): self.error = err.decode("utf-8", errors="ignore") return self - if (runner.ld_library_path == "" or runner.ld_library_path == ""): - if os.path.isfile(test_abc_name): - os.remove(test_abc_name) - self.passed = True - return self - ld_library_path = runner.ld_library_path os.environ.setdefault("LD_LIBRARY_PATH", ld_library_path) aot_abc_cmd = [runner.ark_aot_compiler] - aot_abc_cmd.extend(["--assert-types=true"]) - aot_abc_cmd.extend(["--enable-type-lowering=false"]) + if self.with_running: + aot_abc_cmd.extend(["--aot-file=%s" % file_name]) + else: + aot_abc_cmd.extend(["--assert-types=true"]) + aot_abc_cmd.extend(["--enable-type-lowering=false"]) aot_abc_cmd.extend([test_abc_name]) self.log_cmd(aot_abc_cmd) @@ -1347,7 +1375,10 @@ class TypeExtractorWithAssertTest(Test): self.passed = False self.error = err.decode("utf-8", errors="ignore") else: - self.passed = True + if self.with_running: + self.run_js_vm(runner, file_name, test_abc_name) + else: + self.passed = True if os.path.isfile(test_abc_name): os.remove(test_abc_name) diff --git a/es2panda/test/type_extractor/dts-testcases/test-interface-type-test-1-expected.txt b/es2panda/test/type_extractor/dts-testcases/test-interface-type-test-1-expected.txt old mode 100644 new mode 100755 index 13ee8e936f..054fb9bd6b --- a/es2panda/test/type_extractor/dts-testcases/test-interface-type-test-1-expected.txt +++ b/es2panda/test/type_extractor/dts-testcases/test-interface-type-test-1-expected.txt @@ -1223,7 +1223,7 @@ slot _83 { index: 3 tag: 2 - val: 0 + val: 128 }, { index: 4 diff --git a/es2panda/test/type_extractor/dts-testcases/test-type-summary-order-1-expected.txt b/es2panda/test/type_extractor/dts-testcases/test-type-summary-order-1-expected.txt old mode 100644 new mode 100755 index 23a0045288..5654431ff5 --- a/es2panda/test/type_extractor/dts-testcases/test-type-summary-order-1-expected.txt +++ b/es2panda/test/type_extractor/dts-testcases/test-type-summary-order-1-expected.txt @@ -1189,7 +1189,7 @@ slot _81 { index: 3 tag: 2 - val: 0 + val: 128 }, { index: 4 @@ -1283,7 +1283,7 @@ slot _83 { index: 3 tag: 2 - val: 0 + val: 128 }, { index: 4 diff --git a/es2panda/test/type_extractor/testcases/test-class-1-expected.txt b/es2panda/test/type_extractor/testcases/test-class-1-expected.txt new file mode 100644 index 0000000000..b43b179cf1 --- /dev/null +++ b/es2panda/test/type_extractor/testcases/test-class-1-expected.txt @@ -0,0 +1,573 @@ +======> literal array buffer <====== +------------------------------------ +slot _-1 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: -1 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _4 +}, +{ + index: 4 + tag: 0 + val: 2 +}, +{ + index: 5 + tag: 2 + val: -2 +}, +{ + index: 6 + tag: 0 + val: 24 +}, +{ + index: 7 + tag: 24 + val: _3 +}, +------------------------------------ +slot _-2 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: -1 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _2 +}, +{ + index: 4 + tag: 0 + val: 2 +}, +{ + index: 5 + tag: 2 + val: -2 +}, +{ + index: 6 + tag: 0 + val: 24 +}, +{ + index: 7 + tag: 24 + val: _3 +}, +------------------------------------ +slot _-3 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: -2 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _3 +}, +------------------------------------ +slot _-4 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 4 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _1 +}, +------------------------------------ +slot _0 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 4 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _1 +}, +{ + index: 4 + tag: 0 + val: 24 +}, +{ + index: 5 + tag: 24 + val: _2 +}, +{ + index: 6 + tag: 0 + val: 24 +}, +{ + index: 7 + tag: 24 + val: _3 +}, +{ + index: 8 + tag: 0 + val: 24 +}, +{ + index: 9 + tag: 24 + val: _4 +}, +{ + index: 10 + tag: 0 + val: 2 +}, +{ + index: 11 + tag: 2 + val: 0 +}, +------------------------------------ +slot _1 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 1 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 0 +}, +{ + index: 4 + tag: 0 + val: 25 +}, +{ + index: 5 + tag: 25 + val: 0 +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 0 +}, +{ + index: 10 + tag: 0 + val: 2 +}, +{ + index: 11 + tag: 2 + val: 2 +}, +{ + index: 12 + tag: 0 + val: 5 +}, +{ + index: 13 + tag: 5 + val: cur +}, +{ + index: 14 + tag: 0 + val: 24 +}, +{ + index: 15 + tag: 24 + val: _2 +}, +{ + index: 16 + tag: 0 + val: 5 +}, +{ + index: 17 + tag: 5 + val: dump +}, +{ + index: 18 + tag: 0 + val: 24 +}, +{ + index: 19 + tag: 24 + val: _4 +}, +{ + index: 20 + tag: 0 + val: 2 +}, +{ + index: 21 + tag: 2 + val: 0 +}, +{ + index: 22 + tag: 0 + val: 2 +}, +{ + index: 23 + tag: 2 + val: 0 +}, +------------------------------------ +slot _2 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 3 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 0 +}, +{ + index: 4 + tag: 0 + val: 5 +}, +{ + index: 5 + tag: 5 + val: cur +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 0 +}, +{ + index: 10 + tag: 0 + val: 24 +}, +{ + index: 11 + tag: 24 + val: _3 +}, +------------------------------------ +slot _3 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 2 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _1 +}, +------------------------------------ +slot _4 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 3 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 0 +}, +{ + index: 4 + tag: 0 + val: 5 +}, +{ + index: 5 + tag: 5 + val: dump +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 1 +}, +{ + index: 10 + tag: 0 + val: 24 +}, +{ + index: 11 + tag: 24 + val: _3 +}, +{ + index: 12 + tag: 0 + val: 25 +}, +{ + index: 13 + tag: 25 + val: 3 +}, +------------------------------------ +slot _5 +{ + 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 _6 +{ + index: 0 + tag: 0 + val: 5 +}, +{ + index: 1 + tag: 5 + val: cur +}, +{ + index: 2 + tag: 0 + val: 6 +}, +{ + index: 3 + tag: 6 + val: .cur +}, +{ + index: 4 + tag: 0 + val: 9 +}, +{ + index: 5 + tag: 9 + val: 0 +}, +{ + index: 6 + tag: 0 + val: 5 +}, +{ + index: 7 + tag: 5 + val: dump +}, +{ + index: 8 + tag: 0 + val: 6 +}, +{ + index: 9 + tag: 6 + val: .dump +}, +{ + index: 10 + tag: 0 + val: 9 +}, +{ + index: 11 + tag: 9 + val: 1 +}, +{ + index: 12 + tag: 0 + val: 2 +}, +{ + index: 13 + tag: 2 + val: 2 +}, diff --git a/es2panda/test/type_extractor/testcases/test-class-1.ts b/es2panda/test/type_extractor/testcases/test-class-1.ts new file mode 100644 index 0000000000..5ccc60685d --- /dev/null +++ b/es2panda/test/type_extractor/testcases/test-class-1.ts @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +class Student { + cur() : Student { + return new Student(); + } + dump(s : Student) : void { + } +} diff --git a/es2panda/test/type_extractor/testcases/test-class-with-abstract-method-expected.txt b/es2panda/test/type_extractor/testcases/test-class-with-abstract-method-expected.txt new file mode 100644 index 0000000000..ba8c3081b7 --- /dev/null +++ b/es2panda/test/type_extractor/testcases/test-class-with-abstract-method-expected.txt @@ -0,0 +1,653 @@ +======> literal array buffer <====== +------------------------------------ +slot _-1 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: -1 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _5 +}, +------------------------------------ +slot _-2 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: -1 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _3 +}, +------------------------------------ +slot _-3 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 2 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _1 +}, +------------------------------------ +slot _0 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 5 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _1 +}, +{ + index: 4 + tag: 0 + val: 24 +}, +{ + index: 5 + tag: 24 + val: _2 +}, +{ + index: 6 + tag: 0 + val: 24 +}, +{ + index: 7 + tag: 24 + val: _3 +}, +{ + index: 8 + tag: 0 + val: 24 +}, +{ + index: 9 + tag: 24 + val: _4 +}, +{ + index: 10 + tag: 0 + val: 24 +}, +{ + index: 11 + tag: 24 + val: _5 +}, +{ + index: 12 + tag: 0 + val: 2 +}, +{ + index: 13 + tag: 2 + val: 0 +}, +------------------------------------ +slot _1 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 1 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 1 +}, +{ + index: 4 + tag: 0 + val: 25 +}, +{ + index: 5 + tag: 25 + val: 0 +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 0 +}, +{ + index: 10 + tag: 0 + val: 2 +}, +{ + index: 11 + tag: 2 + val: 4 +}, +{ + index: 12 + tag: 0 + val: 5 +}, +{ + index: 13 + tag: 5 + val: z +}, +{ + index: 14 + tag: 0 + val: 24 +}, +{ + index: 15 + tag: 24 + val: _2 +}, +{ + index: 16 + tag: 0 + val: 5 +}, +{ + index: 17 + tag: 5 + val: y +}, +{ + index: 18 + tag: 0 + val: 24 +}, +{ + index: 19 + tag: 24 + val: _3 +}, +{ + index: 20 + tag: 0 + val: 5 +}, +{ + index: 21 + tag: 5 + val: x +}, +{ + index: 22 + tag: 0 + val: 24 +}, +{ + index: 23 + tag: 24 + val: _4 +}, +{ + index: 24 + tag: 0 + val: 5 +}, +{ + index: 25 + tag: 5 + val: w +}, +{ + index: 26 + tag: 0 + val: 24 +}, +{ + index: 27 + tag: 24 + val: _5 +}, +{ + index: 28 + tag: 0 + val: 2 +}, +{ + index: 29 + tag: 2 + val: 0 +}, +{ + index: 30 + tag: 0 + val: 2 +}, +{ + index: 31 + tag: 2 + val: 0 +}, +------------------------------------ +slot _2 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 3 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 192 +}, +{ + index: 4 + tag: 0 + val: 5 +}, +{ + index: 5 + tag: 5 + val: z +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 0 +}, +{ + index: 10 + tag: 0 + val: 25 +}, +{ + index: 11 + tag: 25 + val: 3 +}, +------------------------------------ +slot _3 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 3 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 0 +}, +{ + index: 4 + tag: 0 + val: 5 +}, +{ + index: 5 + tag: 5 + val: y +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 0 +}, +{ + index: 10 + tag: 0 + val: 25 +}, +{ + index: 11 + tag: 25 + val: 3 +}, +------------------------------------ +slot _4 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 3 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 192 +}, +{ + index: 4 + tag: 0 + val: 5 +}, +{ + index: 5 + tag: 5 + val: x +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 0 +}, +{ + index: 10 + tag: 0 + val: 25 +}, +{ + index: 11 + tag: 25 + val: 3 +}, +------------------------------------ +slot _5 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 3 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 0 +}, +{ + index: 4 + tag: 0 + val: 5 +}, +{ + index: 5 + tag: 5 + val: w +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 0 +}, +{ + index: 10 + tag: 0 + val: 25 +}, +{ + index: 11 + tag: 25 + val: 1 +}, +------------------------------------ +slot _6 +{ + 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 _7 +{ + index: 0 + tag: 0 + val: 5 +}, +{ + index: 1 + tag: 5 + val: y +}, +{ + index: 2 + tag: 0 + val: 6 +}, +{ + index: 3 + tag: 6 + val: .y +}, +{ + index: 4 + tag: 0 + val: 9 +}, +{ + index: 5 + tag: 9 + val: 0 +}, +{ + index: 6 + tag: 0 + val: 5 +}, +{ + index: 7 + tag: 5 + val: w +}, +{ + index: 8 + tag: 0 + val: 6 +}, +{ + index: 9 + tag: 6 + val: .w +}, +{ + index: 10 + tag: 0 + val: 9 +}, +{ + index: 11 + tag: 9 + val: 0 +}, +{ + index: 12 + tag: 0 + val: 2 +}, +{ + index: 13 + tag: 2 + val: 2 +}, diff --git a/es2panda/test/type_extractor/testcases/test-class-with-abstract-method.ts b/es2panda/test/type_extractor/testcases/test-class-with-abstract-method.ts new file mode 100644 index 0000000000..00e423ac13 --- /dev/null +++ b/es2panda/test/type_extractor/testcases/test-class-with-abstract-method.ts @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +abstract class Student { + abstract z() : void; + y() : void {} + abstract x() : void; + w() : number { + return 1; + } +} diff --git a/es2panda/test/type_extractor/testcases/test-class-with-overload-method-expected.txt b/es2panda/test/type_extractor/testcases/test-class-with-overload-method-expected.txt new file mode 100644 index 0000000000..941c35f6d7 --- /dev/null +++ b/es2panda/test/type_extractor/testcases/test-class-with-overload-method-expected.txt @@ -0,0 +1,889 @@ +======> literal array buffer <====== +------------------------------------ +slot _-1 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: -1 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _5 +}, +{ + index: 4 + tag: 0 + val: 2 +}, +{ + index: 5 + tag: 2 + val: -2 +}, +{ + index: 6 + tag: 0 + val: 24 +}, +{ + index: 7 + tag: 24 + val: _7 +}, +------------------------------------ +slot _-2 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: -1 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _2 +}, +{ + index: 4 + tag: 0 + val: 2 +}, +{ + index: 5 + tag: 2 + val: -2 +}, +{ + index: 6 + tag: 0 + val: 24 +}, +{ + index: 7 + tag: 24 + val: _7 +}, +------------------------------------ +slot _-3 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: -2 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _7 +}, +------------------------------------ +slot _-4 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 2 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _1 +}, +------------------------------------ +slot _0 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 7 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _1 +}, +{ + index: 4 + tag: 0 + val: 24 +}, +{ + index: 5 + tag: 24 + val: _2 +}, +{ + index: 6 + tag: 0 + val: 24 +}, +{ + index: 7 + tag: 24 + val: _3 +}, +{ + index: 8 + tag: 0 + val: 24 +}, +{ + index: 9 + tag: 24 + val: _4 +}, +{ + index: 10 + tag: 0 + val: 24 +}, +{ + index: 11 + tag: 24 + val: _5 +}, +{ + index: 12 + tag: 0 + val: 24 +}, +{ + index: 13 + tag: 24 + val: _6 +}, +{ + index: 14 + tag: 0 + val: 24 +}, +{ + index: 15 + tag: 24 + val: _7 +}, +{ + index: 16 + tag: 0 + val: 2 +}, +{ + index: 17 + tag: 2 + val: 0 +}, +------------------------------------ +slot _1 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 1 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 0 +}, +{ + index: 4 + tag: 0 + val: 25 +}, +{ + index: 5 + tag: 25 + val: 0 +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 0 +}, +{ + index: 10 + tag: 0 + val: 2 +}, +{ + index: 11 + tag: 2 + val: 5 +}, +{ + index: 12 + tag: 0 + val: 5 +}, +{ + index: 13 + tag: 5 + val: foo +}, +{ + index: 14 + tag: 0 + val: 24 +}, +{ + index: 15 + tag: 24 + val: _2 +}, +{ + index: 16 + tag: 0 + val: 5 +}, +{ + index: 17 + tag: 5 + val: foo +}, +{ + index: 18 + tag: 0 + val: 24 +}, +{ + index: 19 + tag: 24 + val: _3 +}, +{ + index: 20 + tag: 0 + val: 5 +}, +{ + index: 21 + tag: 5 + val: foo +}, +{ + index: 22 + tag: 0 + val: 24 +}, +{ + index: 23 + tag: 24 + val: _4 +}, +{ + index: 24 + tag: 0 + val: 5 +}, +{ + index: 25 + tag: 5 + val: bar +}, +{ + index: 26 + tag: 0 + val: 24 +}, +{ + index: 27 + tag: 24 + val: _5 +}, +{ + index: 28 + tag: 0 + val: 5 +}, +{ + index: 29 + tag: 5 + val: baz +}, +{ + index: 30 + tag: 0 + val: 24 +}, +{ + index: 31 + tag: 24 + val: _6 +}, +{ + index: 32 + tag: 0 + val: 2 +}, +{ + index: 33 + tag: 2 + val: 0 +}, +{ + index: 34 + tag: 0 + val: 2 +}, +{ + index: 35 + tag: 2 + val: 0 +}, +------------------------------------ +slot _2 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 3 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 0 +}, +{ + index: 4 + tag: 0 + val: 5 +}, +{ + index: 5 + tag: 5 + val: foo +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 1 +}, +{ + index: 10 + tag: 0 + val: 25 +}, +{ + index: 11 + tag: 25 + val: 1 +}, +{ + index: 12 + tag: 0 + val: 25 +}, +{ + index: 13 + tag: 25 + val: 1 +}, +------------------------------------ +slot _3 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 3 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 128 +}, +{ + index: 4 + tag: 0 + val: 5 +}, +{ + index: 5 + tag: 5 + val: foo +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 2 +}, +{ + index: 10 + tag: 0 + val: 25 +}, +{ + index: 11 + tag: 25 + val: 1 +}, +{ + index: 12 + tag: 0 + val: 25 +}, +{ + index: 13 + tag: 25 + val: 4 +}, +{ + index: 14 + tag: 0 + val: 25 +}, +{ + index: 15 + tag: 25 + val: 1 +}, +------------------------------------ +slot _4 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 3 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 128 +}, +{ + index: 4 + tag: 0 + val: 5 +}, +{ + index: 5 + tag: 5 + val: foo +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 2 +}, +{ + index: 10 + tag: 0 + val: 25 +}, +{ + index: 11 + tag: 25 + val: 1 +}, +{ + index: 12 + tag: 0 + val: 25 +}, +{ + index: 13 + tag: 25 + val: 1 +}, +{ + index: 14 + tag: 0 + val: 25 +}, +{ + index: 15 + tag: 25 + val: 1 +}, +------------------------------------ +slot _5 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 3 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 0 +}, +{ + index: 4 + tag: 0 + val: 5 +}, +{ + index: 5 + tag: 5 + val: bar +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 0 +}, +{ + index: 10 + tag: 0 + val: 25 +}, +{ + index: 11 + tag: 25 + val: 0 +}, +------------------------------------ +slot _6 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 3 +}, +{ + index: 2 + tag: 0 + val: 2 +}, +{ + index: 3 + tag: 2 + val: 128 +}, +{ + index: 4 + tag: 0 + val: 5 +}, +{ + index: 5 + tag: 5 + val: baz +}, +{ + index: 6 + tag: 0 + val: 2 +}, +{ + index: 7 + tag: 2 + val: 0 +}, +{ + index: 8 + tag: 0 + val: 2 +}, +{ + index: 9 + tag: 2 + val: 0 +}, +{ + index: 10 + tag: 0 + val: 25 +}, +{ + index: 11 + tag: 25 + val: 3 +}, +------------------------------------ +slot _7 +{ + index: 0 + tag: 0 + val: 2 +}, +{ + index: 1 + tag: 2 + val: 2 +}, +{ + index: 2 + tag: 0 + val: 24 +}, +{ + index: 3 + tag: 24 + val: _1 +}, +------------------------------------ +slot _8 +{ + 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 _9 +{ + index: 0 + tag: 0 + val: 5 +}, +{ + index: 1 + tag: 5 + val: foo +}, +{ + index: 2 + tag: 0 + val: 6 +}, +{ + index: 3 + tag: 6 + val: .foo +}, +{ + index: 4 + tag: 0 + val: 9 +}, +{ + index: 5 + tag: 9 + val: 1 +}, +{ + index: 6 + tag: 0 + val: 5 +}, +{ + index: 7 + tag: 5 + val: bar +}, +{ + index: 8 + tag: 0 + val: 6 +}, +{ + index: 9 + tag: 6 + val: .bar +}, +{ + index: 10 + tag: 0 + val: 9 +}, +{ + index: 11 + tag: 9 + val: 0 +}, +{ + index: 12 + tag: 0 + val: 2 +}, +{ + index: 13 + tag: 2 + val: 2 +}, diff --git a/es2panda/test/type_extractor/testcases/test-class-with-overload-method.ts b/es2panda/test/type_extractor/testcases/test-class-with-overload-method.ts new file mode 100644 index 0000000000..942270e0bd --- /dev/null +++ b/es2panda/test/type_extractor/testcases/test-class-with-overload-method.ts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +class Student { + foo?(a:number): number { + console.log(a); + return a; + } + foo?(a:number, b:string):number; + foo?(a:number, b:number):number; + bar(){}; + baz?(): void; +} diff --git a/es2panda/test/type_extractor/testcases_with_running/test-class-expected.txt b/es2panda/test/type_extractor/testcases_with_running/test-class-expected.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/es2panda/test/type_extractor/testcases_with_running/test-class-expected.txt @@ -0,0 +1 @@ +1 diff --git a/es2panda/test/type_extractor/testcases_with_running/test-class.ts b/es2panda/test/type_extractor/testcases_with_running/test-class.ts new file mode 100644 index 0000000000..9d322e0c41 --- /dev/null +++ b/es2panda/test/type_extractor/testcases_with_running/test-class.ts @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +abstract class Student { + constructor() {} + abstract foo() : void; + bar() : number { + return 1; + } +} +print(Student.prototype.bar()); diff --git a/es2panda/typescript/extractor/typeSystem.h b/es2panda/typescript/extractor/typeSystem.h index 275e43528a..1420492ac3 100644 --- a/es2panda/typescript/extractor/typeSystem.h +++ b/es2panda/typescript/extractor/typeSystem.h @@ -222,22 +222,14 @@ enum UserType : uint8_t { INDEXSIG }; -enum Modifier : uint8_t { - NONSTATIC = 0, +enum FuncModifier : uint8_t { + NOMODIFIER = 0, STATIC = 1 << 2, ASYNC = 1 << 3, GENERATOR = 1 << 4, - ACCESSOR = 1 << 5 -}; - -enum ModifierAB : uint8_t { - NONABSTRACT, - ABSTRACT -}; - -enum ModifierRO : uint8_t { - NONREADONLY, - READONLY + ACCESSOR = 1 << 5, + ABSTRACT = 1 << 6, + OVERLOAD = 1 << 7 }; enum AccessFlag : uint8_t { @@ -470,12 +462,7 @@ public: if (modifiers & ir::ModifierFlags::PROTECTED) { accessFlag_ = AccessFlag::PROTECTED; } - if (methodDef->IsStatic()) { - modifier_ += Modifier::STATIC; - } - if (methodDef->IsAccessor()) { - modifier_ += Modifier::ACCESSOR; - } + FillMethodModifier(methodDef); fn(methodDef->Function()); } else if (node->IsFunctionDeclaration()) { fn(node->AsFunctionDeclaration()->Function()); @@ -506,7 +493,7 @@ public: private: util::StringView name_ {}; AccessFlag accessFlag_ = AccessFlag::PUBLIC; - uint8_t modifier_ = Modifier::NONSTATIC; + uint8_t modifier_ = FuncModifier::NOMODIFIER; bool containThis_ = false; ArenaVector paramsTypeIndex_; int64_t typeIndexReturn_ = PrimitiveType::ANY; @@ -540,13 +527,29 @@ private: FillLiteralBuffer(); } + void FillMethodModifier(const ir::MethodDefinition *methodDef) + { + if (methodDef->IsStatic()) { + modifier_ += FuncModifier::STATIC; + } + if (methodDef->IsAccessor()) { + modifier_ += FuncModifier::ACCESSOR; + } + if (methodDef->IsAbstract()) { + modifier_ += FuncModifier::ABSTRACT; + } + } + void FillModifier(const ir::ScriptFunction *scriptFunc) { if (scriptFunc->IsAsync()) { - modifier_ += Modifier::ASYNC; + modifier_ += FuncModifier::ASYNC; } if (scriptFunc->IsGenerator()) { - modifier_ += Modifier::GENERATOR; + modifier_ += FuncModifier::GENERATOR; + } + if (scriptFunc->IsOverload()) { + modifier_ += FuncModifier::OVERLOAD; } } @@ -649,16 +652,16 @@ public: } private: - ModifierAB modifierAB_ = ModifierAB::NONABSTRACT; + bool modifierAB_ = false; int64_t extendsHeritage_ = PrimitiveType::ANY; ArenaVector implementsHeritages_; ArenaMap paramTypes_; // 3 field infos, typeIndex / accessFlag / modifier ArenaMap> staticFields_; - ArenaMap staticMethods_; + ArenaMap staticMethods_; // 3 field infos, typeIndex / accessFlag / modifier ArenaMap> fields_; - ArenaMap methods_; + ArenaMap methods_; ArenaMap indexSignatures_; int64_t typeIndex_ = PrimitiveType::ANY; int64_t typeIndexShift_ = PrimitiveType::ANY; @@ -668,9 +671,7 @@ private: void FillModifier(const ir::ClassDefinition *classDef) { - if (classDef->Abstract()) { - modifierAB_ = ModifierAB::ABSTRACT; - } + modifierAB_ = classDef->Abstract(); } void FillHeritages(const ir::ClassDefinition *classDef) @@ -698,14 +699,11 @@ private: if (modifiers & ir::ModifierFlags::PROTECTED) { flag = AccessFlag::PROTECTED; } - ModifierRO modifier = ModifierRO::NONREADONLY; - if (modifiers & ir::ModifierFlags::READONLY) { - modifier = ModifierRO::READONLY; - } + auto isReadonly = (modifiers & ir::ModifierFlags::READONLY); int64_t typeIndex = extractor_->GetTypeIndexFromAnnotation(field->TypeAnnotation()); // 3 field infos, typeIndex / accessFlag / modifier - std::array fieldInfo = {typeIndex, flag, modifier}; + std::array fieldInfo = {typeIndex, flag, static_cast(isReadonly)}; auto fn = [&fieldInfo, &isStatic, this](const util::StringView &name) { if (isStatic) { staticFields_[name] = fieldInfo; @@ -739,10 +737,10 @@ private: void FillMethod(const ir::MethodDefinition *method) { auto fn = [&method, this](const FunctionType &functionType, const util::StringView &name) { - if ((functionType.GetModifier() & Modifier::STATIC) == 0) { - methods_[name] = recorder_->GetNodeTypeIndex(method->Function()); + if ((functionType.GetModifier() & FuncModifier::STATIC) == 0) { + methods_[recorder_->GetNodeTypeIndex(method->Function())] = name; } else { - staticMethods_[name] = recorder_->GetNodeTypeIndex(method->Function()); + staticMethods_ [recorder_->GetNodeTypeIndex(method->Function())] = name; } }; @@ -828,11 +826,11 @@ private: void FillMethodsLiteralBuffer(bool isStatic) { - auto fn = [this](const ArenaMap &map) { + auto fn = [this](const ArenaMap &map) { buffer_->Add(recorder_->Allocator()->New(map.size())); std::for_each(map.begin(), map.end(), [this](const auto &t) { - buffer_->Add(recorder_->Allocator()->New(t.first)); - FillTypeIndexLiteralBuffer(t.second); + buffer_->Add(recorder_->Allocator()->New(t.second)); + FillTypeIndexLiteralBuffer(t.first); }); }; @@ -955,14 +953,11 @@ private: void FillField(const ir::TSPropertySignature *field) { AccessFlag flag = AccessFlag::PUBLIC; - ModifierRO modifier = ModifierRO::NONREADONLY; - if (field->Readonly()) { - modifier = ModifierRO::READONLY; - } + auto isReadonly = field->Readonly(); int64_t typeIndex = extractor_->GetTypeIndexFromAnnotation(field->TypeAnnotation()); // 3 field infos, typeIndex / accessFlag / modifier - std::array fieldInfo = {typeIndex, flag, modifier}; + std::array fieldInfo = {typeIndex, flag, static_cast(isReadonly)}; auto res = CalculateName(field->Key()); if (std::holds_alternative(res)) { -- Gitee