diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index f7dd8b5d568c34e585e8d7b820d76083cd50e2c1..bf5e640345826327c72c8b0802399a46c70ad598 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -119,6 +119,10 @@ void Binder::IdentifierAnalysis(ResolveBindingFlags flags) ResolveReferences(program_->Ast()); AddMandatoryParams(); if (topScope_->IsModuleScope()) { + if (Program()->Extension() == ScriptExtension::TS) { + auto *moduleRecord = Program()->ModuleRecord(); + moduleRecord->RemoveImportEntry(); + } AssignIndexToModuleVariable(); } } @@ -241,6 +245,13 @@ void Binder::LookupIdentReference(ir::Identifier *ident) ident->SetTdz(); } + if (topScope_->IsModuleScope() && Program()->Extension() == ScriptExtension::TS && + decl->HasFlag(DeclarationFlags::IMPORT) && !ident->IsType()) { + auto name = ident->Name(); + auto *moduleRecord = Program()->ModuleRecord(); + moduleRecord->RemoveImportEntryTypeFlag(name); + } + ident->SetVariable(res.variable); } diff --git a/es2panda/ir/expressions/identifier.h b/es2panda/ir/expressions/identifier.h index 8bf87b5d86b21a5feda989d25136a21123854548..b1e43937c6f3e5e2dff336f3c35347241cd3160e 100644 --- a/es2panda/ir/expressions/identifier.h +++ b/es2panda/ir/expressions/identifier.h @@ -39,6 +39,7 @@ enum class IdentifierFlags { OPTIONAL = 1 << 0, REFERENCE = 1 << 1, TDZ = 1 << 2, + TYPE = 1 << 3, }; DEFINE_BITOPS(IdentifierFlags) @@ -101,6 +102,16 @@ public: flags_ |= IdentifierFlags::REFERENCE; } + bool IsType() const + { + return (flags_ & IdentifierFlags::TYPE) != 0; + } + + void SetType() + { + flags_ |= IdentifierFlags::TYPE; + } + const std::vector &TSVariables() const { return tsVariables_; diff --git a/es2panda/parser/module/sourceTextModuleRecord.cpp b/es2panda/parser/module/sourceTextModuleRecord.cpp index a6b213ed4a6bfe714aefb19d142f467c7e6de022..e5e0ab85fb378c0d44dd13a419d8ebfc0b5721be 100644 --- a/es2panda/parser/module/sourceTextModuleRecord.cpp +++ b/es2panda/parser/module/sourceTextModuleRecord.cpp @@ -187,4 +187,25 @@ namespace panda::es2panda::parser { (*index)++; } } + + void SourceTextModuleRecord::RemoveImportEntryTypeFlag(const util::StringView name) + { + ASSERT(!name.Empty()); + auto regularImport = regularImportEntries_.find(name); + if (regularImport != regularImportEntries_.end()) { + regularImport->second->typeFlag_ = false; + } + } + + void SourceTextModuleRecord::RemoveImportEntry() + { + for (auto iter = regularImportEntries_.begin(); iter != regularImportEntries_.end();) + { + if (iter->second->typeFlag_) { + iter = regularImportEntries_.erase(iter); + } else { + iter++; + } + } + } } // namespace panda::es2panda::parser diff --git a/es2panda/parser/module/sourceTextModuleRecord.h b/es2panda/parser/module/sourceTextModuleRecord.h index 7e08fbe0f40fbcf700b0a646c6cdaebe3fa93c1b..826508676b384d067329668ac38cc36e9518b7fc 100644 --- a/es2panda/parser/module/sourceTextModuleRecord.h +++ b/es2panda/parser/module/sourceTextModuleRecord.h @@ -52,13 +52,14 @@ public: util::StringView importName_; const ir::Identifier *localId_; const ir::Identifier *importId_; + bool typeFlag_; ImportEntry(const util::StringView localName, const util::StringView importName, int moduleRequestIdx, const ir::Identifier *localId, const ir::Identifier *importId) : moduleRequestIdx_(moduleRequestIdx), localName_(localName), importName_(importName), - localId_(localId), importId_(importId) {} + localId_(localId), importId_(importId), typeFlag_(true) {} ImportEntry(const util::StringView localName, int moduleRequestIdx, const ir::Identifier *localId) - : moduleRequestIdx_(moduleRequestIdx), localName_(localName), localId_(localId) {} + : moduleRequestIdx_(moduleRequestIdx), localName_(localName), localId_(localId), typeFlag_(true) {} }; struct ExportEntry { @@ -99,6 +100,9 @@ public: void AssignIndexToModuleVariable(binder::ModuleScope *moduleScope); + void RemoveImportEntryTypeFlag(const util::StringView source); + void RemoveImportEntry(); + using ModuleRequestList = ArenaVector; using ModuleRequestMap = ArenaMap; using ModuleRequestIdxMap = ArenaMap; diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index a245d55f623237c7552bbaa1efe1f2d3e0ac0393..e89c9ccdf476a0f777ed093014419d6f3eed1520 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -302,6 +302,7 @@ ir::TSTypeReference *ParserImpl::ParseTsConstExpression() { auto *identRef = AllocNode(lexer_->GetToken().Ident()); identRef->SetReference(); + identRef->SetType(); identRef->SetRange(lexer_->GetToken().Loc()); auto *typeReference = AllocNode(identRef, nullptr); @@ -1054,6 +1055,7 @@ ir::Expression *ParserImpl::ParseTsTypeReferenceOrQuery(bool parseQuery) ir::Expression *typeName = AllocNode(lexer_->GetToken().Ident()); typeName->SetRange(lexer_->GetToken().Loc()); typeName->AsIdentifier()->SetReference(); + typeName->AsIdentifier()->SetType(); if (lexer_->Lookahead() == LEX_CHAR_LESS_THAN) { lexer_->ForwardToken(lexer::TokenType::PUNCTUATOR_LESS_THAN, 1); @@ -2826,6 +2828,7 @@ ir::ClassDefinition *ParserImpl::ParseClassDefinition(bool isDeclaration, bool i ir::Expression *expr = AllocNode(lexer_->GetToken().Ident()); expr->SetRange(lexer_->GetToken().Loc()); expr->AsIdentifier()->SetReference(); + expr->AsIdentifier()->SetType(); lexer_->NextToken(); diff --git a/es2panda/parser/statementParser.cpp b/es2panda/parser/statementParser.cpp index e8f67909e36dec0a196f52e9ea5f1b01461ae326..fd56131f24e45ca1ad3341370de3fc451b9842d9 100644 --- a/es2panda/parser/statementParser.cpp +++ b/es2panda/parser/statementParser.cpp @@ -777,6 +777,7 @@ ir::TSInterfaceDeclaration *ParserImpl::ParseTsInterfaceDeclaration() lexer::SourcePosition heritageEnd = lexer_->GetToken().End(); ir::Expression *expr = AllocNode(lexer_->GetToken().Ident()); expr->AsIdentifier()->SetReference(); + expr->AsIdentifier()->SetType(); expr->SetRange(lexer_->GetToken().Loc()); if (lexer_->Lookahead() == LEX_CHAR_LESS_THAN) { diff --git a/es2panda/test/compiler/ts/projects/ts_import_type_project_3/test-ts-export-type.ts b/es2panda/test/compiler/ts/projects/ts_import_type_project_3/test-ts-export-type.ts new file mode 100644 index 0000000000000000000000000000000000000000..a663fe914bedb39f229efee9f3306fa2a79869c4 --- /dev/null +++ b/es2panda/test/compiler/ts/projects/ts_import_type_project_3/test-ts-export-type.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 { + a : string; +} +var b : A = {a : "b"}; +export type {A}; +export {b}; diff --git a/es2panda/test/compiler/ts/projects/ts_import_type_project_3/test-ts-import-type-exec-expected.txt b/es2panda/test/compiler/ts/projects/ts_import_type_project_3/test-ts-import-type-exec-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..de980441c3ab03a8c07dda1ad27b8a11f39deb1e --- /dev/null +++ b/es2panda/test/compiler/ts/projects/ts_import_type_project_3/test-ts-import-type-exec-expected.txt @@ -0,0 +1,3 @@ +a +b +c diff --git a/es2panda/test/compiler/ts/projects/ts_import_type_project_3/test-ts-import-type-exec.ts b/es2panda/test/compiler/ts/projects/ts_import_type_project_3/test-ts-import-type-exec.ts new file mode 100644 index 0000000000000000000000000000000000000000..c4e1271eafdc44cbd50f59e1a81469425024e3bc --- /dev/null +++ b/es2panda/test/compiler/ts/projects/ts_import_type_project_3/test-ts-import-type-exec.ts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "./test-ts-export-type"; + +var a : A = {a : "a"}; +print(a.a); +print(b.a); + +class C implements A { + a = "c"; +} +var c = new C(); +print(c.a) + \ No newline at end of file