diff --git a/es2panda/aot/options.cpp b/es2panda/aot/options.cpp index b08e45d67c5fb68b91fc6c931b6bd14dae855321..16c16f09c700cec792dcf9ccac3d263e34799bd0 100644 --- a/es2panda/aot/options.cpp +++ b/es2panda/aot/options.cpp @@ -229,6 +229,8 @@ bool Options::Parse(int argc, const char **argv) panda::PandArg opCacheFile("cache-file", "", "cache file for incremental compile"); panda::PandArg opNpmModuleEntryList("npm-module-entry-list", "", "entry list file for module compile"); panda::PandArg opMergeAbc("merge-abc", false, "Compile as merge abc"); + panda::PandArg opuseDefineSemantic("use-define-semantic", false, "Compile ts class fields "\ + "in accordance with ECMAScript2022"); // patchfix && hotreload panda::PandArg opDumpSymbolTable("dump-symbol-table", "", "dump symbol table to file"); @@ -279,6 +281,7 @@ bool Options::Parse(int argc, const char **argv) argparser_->Add(&opCacheFile); argparser_->Add(&opNpmModuleEntryList); argparser_->Add(&opMergeAbc); + argparser_->Add(&opuseDefineSemantic); argparser_->Add(&opDumpSymbolTable); argparser_->Add(&opInputSymbolTable); @@ -387,6 +390,10 @@ bool Options::Parse(int argc, const char **argv) compilerOptions_.mergeAbc = opMergeAbc.GetValue(); } + if (opuseDefineSemantic.GetValue()) { + compilerOptions_.useDefineSemantic = opuseDefineSemantic.GetValue(); + } + if (!inputIsEmpty) { // common mode auto inputAbs = panda::os::file::File::GetAbsolutePath(sourceFile_); diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index 7b42acbbdbde9f9dd939107f3895ba4e5da35954..e20ffe5248e7514ec97bc2f316814be9754d0568 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -575,7 +575,7 @@ void Binder::BuildClassDefinition(ir::ClassDefinition *classDef) // new class features in ecma2022 are only supported for api11 and above if (Program()->TargetApiVersion() > 10 && !(bindingFlags_ & ResolveBindingFlags::TS_BEFORE_TRANSFORM)) { - classDef->BuildClassEnvironment(); + classDef->BuildClassEnvironment(program_->UseDefineSemantic()); } if (classDef->Ident()) { diff --git a/es2panda/compiler/core/emitter/emitter.cpp b/es2panda/compiler/core/emitter/emitter.cpp index 26510572e6f1ff1a39bfab3563697f98c4905e53..2336bcd16a5519f943b74fd1a47b31ebbf611339 100644 --- a/es2panda/compiler/core/emitter/emitter.cpp +++ b/es2panda/compiler/core/emitter/emitter.cpp @@ -251,7 +251,6 @@ void FunctionEmitter::GenFunctionSource() if (pg_->Context()->IsRecordSource() || (static_cast(pg_->RootNode()))->ShowSource()) { func_->source_code = SourceCode().Mutf8(); } - } void FunctionEmitter::GenScopeVariableInfo(const binder::Scope *scope) diff --git a/es2panda/compiler/core/function.cpp b/es2panda/compiler/core/function.cpp index 57676ef6233872ae4ebccd027f7b95a0f478d04d..8700de95af33e40b60b9131282e3fbdadddb5360 100644 --- a/es2panda/compiler/core/function.cpp +++ b/es2panda/compiler/core/function.cpp @@ -191,6 +191,12 @@ static void CompileClassInitializer(PandaGen *pg, const ir::ScriptFunction *decl if (stmt->IsClassProperty()) { const auto *prop = stmt->AsClassProperty(); + + // Do not process non-static public fields when not using define semantic. + if (!prop->IsPrivate() && !prop->IsStatic() && !pg->Binder()->Program()->UseDefineSemantic()) { + continue; + } + if (prop->IsStatic() == isStatic) { CompileField(pg, prop, thisReg, level); } diff --git a/es2panda/es2panda.h b/es2panda/es2panda.h index 85ea26ff268d742a9ec71b194e52f7ca2e99ddea..b8136bcb392b88be542b564e92ad6e2a67432d54 100644 --- a/es2panda/es2panda.h +++ b/es2panda/es2panda.h @@ -82,6 +82,7 @@ struct CompilerOptions { bool dumpLiteralBuffer {false}; bool isDebuggerEvaluateExpressionMode {false}; bool mergeAbc {false}; + bool useDefineSemantic {false}; bool typeExtractor {false}; bool typeDtsBuiltin {false}; bool recordSource {false}; diff --git a/es2panda/ir/base/classDefinition.cpp b/es2panda/ir/base/classDefinition.cpp index e68031d4a49641042df70805b75e2398376ccd45..d1b4a4b3070c3fa20c5814f608aa405401c42e15 100644 --- a/es2panda/ir/base/classDefinition.cpp +++ b/es2panda/ir/base/classDefinition.cpp @@ -374,6 +374,12 @@ void ClassDefinition::CompileComputedKeys(compiler::PandaGen *pg) const for (const auto &stmt : body_) { if (stmt->IsClassProperty()) { const ir::ClassProperty *prop = stmt->AsClassProperty(); + + // Do not process non-static public fields when not using define semantic. + if (!prop->IsStatic() && !pg->Binder()->Program()->UseDefineSemantic()) { + continue; + } + if (prop->IsComputed() && prop->NeedCompileKey()) { prop->Key()->Compile(pg); pg->ToComputedPropertyKey(prop->Key()); @@ -476,7 +482,7 @@ void ClassDefinition::UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) } -void ClassDefinition::BuildClassEnvironment() +void ClassDefinition::BuildClassEnvironment(bool useDefineSemantic) { int instancePrivateMethodCnt = 0; int staticPrivateMethodCnt = 0; @@ -499,6 +505,12 @@ void ClassDefinition::BuildClassEnvironment() ASSERT(stmt->IsClassProperty()); const auto *prop = stmt->AsClassProperty(); + + // Do not process non-static public fields when not using define semantic. + if (!prop->IsPrivate() && !prop->IsStatic() && !useDefineSemantic) { + continue; + } + if (prop->IsComputed() && prop->NeedCompileKey()) { hasComputedKey_ = true; scope_->AddClassVariable(prop->Key()); diff --git a/es2panda/ir/base/classDefinition.h b/es2panda/ir/base/classDefinition.h index 6f05d7a53fc83eadab492d9f291e0952c1a269be..86a584cbb580e40fc28f43cd71d9aa98daa6df70 100644 --- a/es2panda/ir/base/classDefinition.h +++ b/es2panda/ir/base/classDefinition.h @@ -229,7 +229,7 @@ public: util::StringView GetName() const; - void BuildClassEnvironment(); + void BuildClassEnvironment(bool useDefineSemantic); void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index e0c82a5ff587d4cb4e5768da385ec14408d0134c..c601d57d6b72ba9f2a9aced7c1539febf1213e5e 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -134,6 +134,9 @@ Program ParserImpl::Parse(const std::string &fileName, const std::string &source program_.SetRecordName(recordName); program_.SetDebug(options.isDebug); program_.SetTargetApiVersion(options.targetApiVersion); + if (Extension() == ScriptExtension::TS) { + program_.SetDefineSemantic(options.useDefineSemantic); + } /* * In order to make the lexer's memory alive, the return value 'lexer' can not be omitted. diff --git a/es2panda/parser/program/program.cpp b/es2panda/parser/program/program.cpp index d203aa86df3d5e9a88598c63e6f09a14b3ab5bf5..6398552a6b421e000e614c6b6ed1519a4e5acd64 100644 --- a/es2panda/parser/program/program.cpp +++ b/es2panda/parser/program/program.cpp @@ -46,7 +46,8 @@ Program::Program(Program &&other) isDtsFile_(other.isDtsFile_), hasTLA_(other.hasTLA_), isDebug_(other.isDebug_), - targetApiVersion_(other.targetApiVersion_) + targetApiVersion_(other.targetApiVersion_), + useDefineSemantic_(other.useDefineSemantic_) { other.binder_ = nullptr; other.ast_ = nullptr; diff --git a/es2panda/parser/program/program.h b/es2panda/parser/program/program.h index 2430b89eedc872865d1e35f7c60ebcae20b49923..a158fe77eb773bf8244325f4908093f68a1dafb0 100644 --- a/es2panda/parser/program/program.h +++ b/es2panda/parser/program/program.h @@ -185,6 +185,16 @@ public: targetApiVersion_ = targetApiVersion; } + bool UseDefineSemantic() const + { + return useDefineSemantic_; + } + + void SetDefineSemantic(bool useDefineSemantic) + { + useDefineSemantic_ = useDefineSemantic; + } + std::string Dump() const; void SetKind(ScriptKind kind); @@ -206,6 +216,7 @@ private: bool hasTLA_ {false}; bool isDebug_ {false}; int targetApiVersion_ {0}; + bool useDefineSemantic_ {true}; }; } // namespace panda::es2panda::parser diff --git a/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-1-expected.txt b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-1-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..c508d5366f70bba37fcc09d128b6537c4adb2c79 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-1-expected.txt @@ -0,0 +1 @@ +false diff --git a/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-1.ts b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-1.ts new file mode 100644 index 0000000000000000000000000000000000000000..db253a5c15c2e4d80dca70c77597180873cdc158 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-1.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +class A1 { + prop; +} + +let a1 = new A1(); +print("prop" in a1); diff --git a/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-2-expected.txt b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-2-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..27ba77ddaf61532f217964734769a42cdabc17dc --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-2-expected.txt @@ -0,0 +1 @@ +true diff --git a/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-2.ts b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-2.ts new file mode 100644 index 0000000000000000000000000000000000000000..a395dde961a3748e6cba4dd845e73169120c759d --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-2.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +class A2 { + prop = 1; +} + +let a2 = new A2(); +print("prop" in a2); diff --git a/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-3-expected.txt b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-3-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..27ba77ddaf61532f217964734769a42cdabc17dc --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-3-expected.txt @@ -0,0 +1 @@ +true diff --git a/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-3.ts b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-3.ts new file mode 100644 index 0000000000000000000000000000000000000000..f5bc7ed99c90952d4d059abca32648439f66c0c6 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-3.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +class B1 { + static prop; +} + +let b1 = new B1(); +print("prop" in B1); diff --git a/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-4-expected.txt b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-4-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..27ba77ddaf61532f217964734769a42cdabc17dc --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-4-expected.txt @@ -0,0 +1 @@ +true diff --git a/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-4.ts b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-4.ts new file mode 100644 index 0000000000000000000000000000000000000000..b2c356ed02ecdbb4337193f0e7f357ecd4475546 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-4.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +class B2 { + static prop = 1; +} + +let b2 = new B2(); +print("prop" in B2); diff --git a/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-5-expected.txt b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-5-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..321522ce446b4de78c4ed073b63569e1e051798a --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-5-expected.txt @@ -0,0 +1,4 @@ +false +false +false +false diff --git a/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-5.ts b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-5.ts new file mode 100644 index 0000000000000000000000000000000000000000..3636a2cd5f4b380245a8cb6b33c5f1e68a983fe0 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-5.ts @@ -0,0 +1,51 @@ +/* + * 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 A3 { + public b; + #c = 2; + constructor() { + print("b" in this); + } +} +let a3 = new A3(); + +class B3 { + private b; + #c = 2; + constructor() { + print("b" in this); + } +} +let b3 = new B3(); + +class C3 { + protected b; + #c = 2; + constructor() { + print("b" in this); + } +} +let c3 = new C3(); + +class D3 { + b; + #c = 2; + constructor() { + print("b" in this); + } +} +let d3 = new D3(); diff --git a/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-6-expected.txt b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-6-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..1140ff52e2ba1f46b1315269500c551a9bd48768 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-6-expected.txt @@ -0,0 +1,4 @@ +true +true +true +true diff --git a/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-6.ts b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-6.ts new file mode 100644 index 0000000000000000000000000000000000000000..4bb8955e05097e5dbfb6828c6a613e3c2fd3f3b2 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/compiler/test-ts-class-element-6.ts @@ -0,0 +1,51 @@ +/* + * 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 A4 { + public b = 1; + #c = 2; + constructor() { + print("b" in this); + } +} +let a4 = new A4(); + +class B4 { + private b = 1; + #c = 2; + constructor() { + print("b" in this); + } +} +let b4 = new B4(); + +class C4 { + protected b = 1; + #c = 2; + constructor() { + print("b" in this); + } +} +let c4 = new C4(); + +class D4 { + b = 1; + #c = 2; + constructor() { + print("b" in this); + } +} +let d4 = new D4(); diff --git a/es2panda/test/runner.py b/es2panda/test/runner.py index a6b63c7f94629ea7225cd75d7ce14536b001de1a..df0683a03e779cccd7ffa570f23a000598cf4419 100755 --- a/es2panda/test/runner.py +++ b/es2panda/test/runner.py @@ -1520,7 +1520,8 @@ def main(): runner.add_directory("parser/binder", "js", ["--dump-assembly"]) runner.add_directory("parser/js/emptySource", "js", ["--dump-assembly"]) runner.add_directory("parser/js/language/arguments-object", "js", ["--parse-only"]) - runner.add_directory("parser/sendable_class", "ts", ["--dump-assembly", "--dump-literal-buffer"]) + runner.add_directory("parser/sendable_class", "ts", ["--dump-assembly", "--dump-literal-buffer", + "--use-define-semantic"]) runners.append(runner) diff --git a/es2panda/test/type_extractor/testcases/test-class-generic-type-expected.txt b/es2panda/test/type_extractor/testcases/test-class-generic-type-expected.txt index db1832984f80304df05c7b92b2517abf20740a24..d82e2115d153edd598305f1c0170de949d8fcfbc 100644 --- a/es2panda/test/type_extractor/testcases/test-class-generic-type-expected.txt +++ b/es2panda/test/type_extractor/testcases/test-class-generic-type-expected.txt @@ -93,7 +93,7 @@ slot _.func_main_0_-1 { index: 1 tag: 2 - val: 4 + val: 3 }, { index: 2 @@ -113,7 +113,7 @@ slot _.func_main_0_-1 { index: 5 tag: 2 - val: 13 + val: 9 }, { index: 6 @@ -133,7 +133,7 @@ slot _.func_main_0_-1 { index: 9 tag: 2 - val: 18 + val: 14 }, { index: 10 @@ -146,28 +146,6 @@ slot _.func_main_0_-1 val: _8 }, ------------------------------------ -slot _.instance_initializer_-1 -{ - index: 0 - tag: 0 - val: 2 -}, -{ - index: 1 - tag: 2 - val: -2 -}, -{ - index: 2 - tag: 0 - val: 24 -}, -{ - index: 3 - tag: 24 - val: _4 -}, ------------------------------------- slot _0 { index: 0 diff --git a/es2panda/test/type_extractor/testcases/test-class-with-static-field-expected.txt b/es2panda/test/type_extractor/testcases/test-class-with-static-field-expected.txt index e1772d34c6d765bc83071efd4bf6dc149c9176fd..a36449ba783fbd1202d3d0f922fce526d346b75f 100644 --- a/es2panda/test/type_extractor/testcases/test-class-with-static-field-expected.txt +++ b/es2panda/test/type_extractor/testcases/test-class-with-static-field-expected.txt @@ -31,7 +31,7 @@ slot _.func_main_0_-1 { index: 1 tag: 2 - val: 4 + val: 3 }, { index: 2 @@ -44,28 +44,6 @@ slot _.func_main_0_-1 val: _1 }, ------------------------------------ -slot _.instance_initializer_-1 -{ - index: 0 - tag: 0 - val: 2 -}, -{ - index: 1 - tag: 2 - val: -2 -}, -{ - index: 2 - tag: 0 - val: 24 -}, -{ - index: 3 - tag: 24 - val: _2 -}, ------------------------------------- slot _.static_initializer_-1 { index: 0