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 2be6cdf701c3d70acb264166cc1715743164a8ee..2d95d204484a031542d4b2ec937e360c53864923 100644 --- a/es2panda/compiler/core/function.cpp +++ b/es2panda/compiler/core/function.cpp @@ -191,11 +191,12 @@ static void CompileClassInitializer(PandaGen *pg, const ir::ScriptFunction *decl if (stmt->IsClassProperty()) { const auto *prop = stmt->AsClassProperty(); - // For compatibility reason, class fields without initial value won't keep in the class for TS files - // before it follow ECMA spec completely. - if (prop->Value() == nullptr && pg->Binder()->Extension() == ScriptExtension::TS) { + + // Do not process public fields when not using define semantic. + if (!prop->IsPrivate() && !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 887b455d1f0f3eff56604568b92be4089d8b6ee9..2e9ec6db2349334b7788b5dcbc443b9335b6f7ec 100644 --- a/es2panda/ir/base/classDefinition.cpp +++ b/es2panda/ir/base/classDefinition.cpp @@ -476,7 +476,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 +499,12 @@ void ClassDefinition::BuildClassEnvironment() ASSERT(stmt->IsClassProperty()); const auto *prop = stmt->AsClassProperty(); + + // Do not process public fields when not using define semantic. + if (!prop->IsPrivate() && !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 4963cc245564941c3aee3f233870c8846a0d1e1c..5bad7122aff772bb32aba738144e5c3a09c9ce36 100644 --- a/es2panda/ir/base/classDefinition.h +++ b/es2panda/ir/base/classDefinition.h @@ -210,7 +210,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 dcf7534b2b155dbde0eabd797d4d94f99bb3a6c4..d84a38c568d6f1a30d1745a4f99881a02b4edb35 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