diff --git a/es2panda/ir/base/classDefinition.cpp b/es2panda/ir/base/classDefinition.cpp index 1537fcd926cbcb7ea06d00c8a9daf1e70db75af3..65296203876092c06f45d119e5bbed7d410a2fbb 100644 --- a/es2panda/ir/base/classDefinition.cpp +++ b/es2panda/ir/base/classDefinition.cpp @@ -564,15 +564,55 @@ void ClassDefinition::AddFieldTypeForTypeReference(const TSTypeReference *typeRe if (typeName->IsIdentifier()) { util::StringView propertyName = typeName->AsIdentifier()->Name(); - - if (IsTypeParam(propertyName)) { - fieldType |= FieldType::TYPE_PARAMETER; + binder::ScopeFindResult result = scope_->Find(propertyName); + + if (IsTypeParam(propertyName) || (result.variable != nullptr && result.variable->IsModuleVariable())) { + fieldType |= FieldType::GENERIC; return; } + + const ir::Identifier *identifier = nullptr; + const ir::AstNode *declNode = GetDeclNodeFromIdentifier(typeName->AsIdentifier(), &identifier); + + if (declNode != nullptr) { + auto originalNode = declNode->Original(); + if (originalNode && originalNode->Type() == ir::AstNodeType::TS_ENUM_DECLARATION) { + fieldType |= FieldType::STRING | FieldType::NUMBER; + return; + } + } } + // sendable class / sendable interface will be TS_TYPE_REF + // other types that are not sendable type will be restricted in the linter fieldType |= FieldType::TS_TYPE_REF; } +const ir::AstNode *ClassDefinition::GetDeclNodeFromIdentifier(const ir::Identifier *identifier, + const ir::Identifier **variable) const +{ + if (identifier == nullptr) { + return nullptr; + } + + std::vector variables; + variables.reserve(identifier->TSVariables().size() + 1U); + variables.emplace_back(identifier->Variable()); + for (const auto &v : identifier->TSVariables()) { + variables.emplace_back(v); + } + + for (const auto &v : variables) { + if (v == nullptr || v->Declaration() == nullptr || v->Declaration()->Node() == nullptr) { + continue; + } + + auto res = v->Declaration()->Node(); + *variable = identifier; + return res; + } + return nullptr; +} + bool ClassDefinition::IsTypeParam(const util::StringView &propertyName) const { if (typeParams_ == nullptr) { diff --git a/es2panda/ir/base/classDefinition.h b/es2panda/ir/base/classDefinition.h index dcd8bc06d5c51b17dfda185aaf9d35c297a5e4c3..5b1f3b6254f05469d4c23aa9207a5d279b281c94 100644 --- a/es2panda/ir/base/classDefinition.h +++ b/es2panda/ir/base/classDefinition.h @@ -45,7 +45,7 @@ enum class FieldType { BOOLEAN = (1 << 2), TS_TYPE_REF = (1 << 3), BIGINT = (1 << 4), - TYPE_PARAMETER = (1 << 5), + GENERIC = (1 << 5), // import type / type parameter TS_NULL = (1 << 6), TS_UNDEFINED = (1 << 7), }; @@ -241,6 +241,8 @@ public: void Compile(compiler::PandaGen *pg) const override; checker::Type *Check(checker::Checker *checker) const override; void UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) override; + const ir::AstNode *GetDeclNodeFromIdentifier(const ir::Identifier *identifier, + const ir::Identifier **variable) const; private: compiler::VReg CompileHeritageClause(compiler::PandaGen *pg) const; diff --git a/es2panda/test/parser/sendable_class/sendable-class-field-type-expected.txt b/es2panda/test/parser/sendable_class/sendable-class-field-type-expected.txt index e93cb2ef3d59f62b090d056a4c645356b3492f27..2eaeea3c88eeca299b7ed96ad6bb98443a0e4ea0 100644 --- a/es2panda/test/parser/sendable_class/sendable-class-field-type-expected.txt +++ b/es2panda/test/parser/sendable_class/sendable-class-field-type-expected.txt @@ -1,5 +1,21 @@ .language ECMAScript +.function any .#14695981039346656037#(any a0, any a1, any a2, any a3) { +label_1: +label_0: + lda.str BEIJING + sta v0 + lda.str beijing + stobjbyvalue 0x0, a3, v0 + lda.str SHANGHAI + sta v0 + lda.str shanghai + stobjbyvalue 0x2, a3, v0 + ldundefined + returnundefined +label_2: +} + .function any .Person(any a0, any a1, any a2) { label_1: label_0: @@ -28,15 +44,28 @@ label_2: } .function any .func_main_0(any a0, any a1, any a2) { -label_1: +label_4: label_0: + ldundefined + sta v0 definefunc 0x0, .Test, 0x0 + definefunc 0x1, .#14695981039346656037#, 0x1 + sta v1 + lda v0 + istrue + jnez label_3 +label_2: + createemptyobject + sta v0 +label_3: + lda v1 + callarg1 0x2, v0 ldhole sta v0 - callruntime.definesendableclass 0x1, .Person, _4, 0x0, v0 + callruntime.definesendableclass 0x4, .Person, _4, 0x0, v0 ldundefined returnundefined -label_2: +label_5: } @@ -46,30 +75,50 @@ slot _0 { index: 0 tag: 2 - val: 0 + val: 1 }, { index: 1 + tag: 5 + val: ./test +}, +{ + index: 2 tag: 2 + val: 1 +}, +{ + index: 3 + tag: 5 + val: Country +}, +{ + index: 4 + tag: 5 + val: Country +}, +{ + index: 5 + tag: 9 val: 0 }, { - index: 2 + index: 6 tag: 2 val: 0 }, { - index: 3 + index: 7 tag: 2 val: 0 }, { - index: 4 + index: 8 tag: 2 val: 0 }, { - index: 5 + index: 9 tag: 2 val: 0 }, @@ -292,12 +341,92 @@ slot _3 { index: 24 tag: 0 - val: 2 + val: 5 }, { index: 25 + tag: 5 + val: country +}, +{ + index: 26 + tag: 0 + val: 2 +}, +{ + index: 27 + tag: 2 + val: 32 +}, +{ + index: 28 + tag: 0 + val: 5 +}, +{ + index: 29 + tag: 5 + val: city +}, +{ + index: 30 + tag: 0 + val: 2 +}, +{ + index: 31 + tag: 2 + val: 3 +}, +{ + index: 32 + tag: 0 + val: 5 +}, +{ + index: 33 + tag: 5 + val: pos +}, +{ + index: 34 + tag: 0 + val: 2 +}, +{ + index: 35 + tag: 2 + val: 8 +}, +{ + index: 36 + tag: 0 + val: 5 +}, +{ + index: 37 + tag: 5 + val: mix +}, +{ + index: 38 + tag: 0 + val: 2 +}, +{ + index: 39 + tag: 2 + val: 43 +}, +{ + index: 40 + tag: 0 + val: 2 +}, +{ + index: 41 tag: 2 - val: 6 + val: 10 }, ------------------------------------ slot _4 diff --git a/es2panda/test/parser/sendable_class/sendable-class-field-type.ts b/es2panda/test/parser/sendable_class/sendable-class-field-type.ts index 38534b23cf69c48f21b0afdf19ba445612bb8e4d..c58ef4ac3656b272180db3c905338642e3584ad3 100644 --- a/es2panda/test/parser/sendable_class/sendable-class-field-type.ts +++ b/es2panda/test/parser/sendable_class/sendable-class-field-type.ts @@ -13,6 +13,15 @@ * limitations under the License. */ +import { Country } from './test' + +const enum City { + BEIJING = 'beijing', + SHANGHAI = 'shanghai', +}; + +interface Position {}; + class Person { name: string; private age: number; @@ -20,6 +29,10 @@ class Person { father: Person; num: bigint; child: Person | null; + country: Country; + city: City; + pos: Position; + mix: Country | City | Position; constructor() { "use sendable"; }