diff --git a/es2panda/BUILD.gn b/es2panda/BUILD.gn index 55bc5123584c1d864e617b111dceb02dcba8c200..935925f844d7876d684762f3c53167d9afaf134c 100644 --- a/es2panda/BUILD.gn +++ b/es2panda/BUILD.gn @@ -96,6 +96,8 @@ es2panda_src = [ "ir/expressions/unaryExpression.cpp", "ir/expressions/updateExpression.cpp", "ir/expressions/yieldExpression.cpp", + "ir/module/assertClause.cpp", + "ir/module/assertEntry.cpp", "ir/module/exportAllDeclaration.cpp", "ir/module/exportDefaultDeclaration.cpp", "ir/module/exportNamedDeclaration.cpp", diff --git a/es2panda/ir/astNodeMapping.h b/es2panda/ir/astNodeMapping.h index 8b3f02bf59d32115863b2f4e7103067e10fbca4d..f39185ab91e0589a5901c28a2e602a7f14c305b0 100644 --- a/es2panda/ir/astNodeMapping.h +++ b/es2panda/ir/astNodeMapping.h @@ -18,6 +18,8 @@ #define AST_NODE_MAPPING(_) \ _(ARROW_FUNCTION_EXPRESSION, ArrowFunctionExpression) \ + _(ASSERT_CLAUSE, AssertClause) \ + _(ASSERT_ENTRY, AssertEntry) \ _(AWAIT_EXPRESSION, AwaitExpression) \ _(BIGINT_LITERAL, BigIntLiteral) \ _(BINARY_EXPRESSION, BinaryExpression) \ diff --git a/es2panda/ir/expressions/importExpression.cpp b/es2panda/ir/expressions/importExpression.cpp index fbd4020a3b1aa6be24fb171259c9e8b5cf68c17d..b600452b29b39506ae6e259af69740631988af18 100644 --- a/es2panda/ir/expressions/importExpression.cpp +++ b/es2panda/ir/expressions/importExpression.cpp @@ -23,11 +23,17 @@ namespace panda::es2panda::ir { void ImportExpression::Iterate(const NodeTraverser &cb) const { cb(source_); + + if (importAssertion_) { + cb(importAssertion_); + } } void ImportExpression::Dump(ir::AstDumper *dumper) const { - dumper->Add({{"type", "ImportExpression"}, {"source", source_}}); + dumper->Add({{"type", "ImportExpression"}, + {"source", source_}, + {"importAssertion", AstDumper::Optional(importAssertion_)}}); } void ImportExpression::Compile(compiler::PandaGen *pg) const @@ -44,6 +50,10 @@ checker::Type *ImportExpression::Check([[maybe_unused]] checker::Checker *checke void ImportExpression::UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] binder::Binder *binder) { source_ = std::get(cb(source_))->AsExpression(); + + if (importAssertion_) { + importAssertion_ = std::get(cb(importAssertion_))->AsObjectExpression(); + } } } // namespace panda::es2panda::ir diff --git a/es2panda/ir/expressions/importExpression.h b/es2panda/ir/expressions/importExpression.h index d3affc819a61ac39fef09a2e8fc4ea9915dd8066..5393fc4ebb504492c99ed3b013863dbc49844c47 100644 --- a/es2panda/ir/expressions/importExpression.h +++ b/es2panda/ir/expressions/importExpression.h @@ -17,6 +17,7 @@ #define ES2PANDA_IR_EXPRESSION_IMPORT_EXPRESSION_H #include +#include namespace panda::es2panda::compiler { class PandaGen; @@ -31,7 +32,9 @@ namespace panda::es2panda::ir { class ImportExpression : public Expression { public: - explicit ImportExpression(Expression *source) : Expression(AstNodeType::IMPORT_EXPRESSION), source_(source) {} + explicit ImportExpression(Expression *source, ObjectExpression *importAssertion) + : Expression(AstNodeType::IMPORT_EXPRESSION), + source_(source), importAssertion_(importAssertion) {} void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; @@ -41,6 +44,7 @@ public: private: Expression *source_; + ObjectExpression *importAssertion_; }; } // namespace panda::es2panda::ir diff --git a/es2panda/ir/module/assertClause.cpp b/es2panda/ir/module/assertClause.cpp new file mode 100644 index 0000000000000000000000000000000000000000..92128ecdcc68f63554e106fe64146eb98ae53fd2 --- /dev/null +++ b/es2panda/ir/module/assertClause.cpp @@ -0,0 +1,49 @@ +/** + * 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. + */ + +#include "assertClause.h" + +#include + +namespace panda::es2panda::ir { + +void AssertClause::Iterate(const NodeTraverser &cb) const +{ + for (auto *it : elements_) { + cb(it); + } +} + +void AssertClause::Dump(ir::AstDumper *dumper) const +{ + dumper->Add({{"type", "AssertClause"}, + {"elements", elements_}}); +} + +void AssertClause::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} + +checker::Type *AssertClause::Check([[maybe_unused]] checker::Checker *checker) const +{ + return nullptr; +} + +void AssertClause::UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] binder::Binder *binder) +{ + for (auto iter = elements_.begin(); iter != elements_.end(); iter++) { + *iter = std::get(cb(*iter))->AsAssertEntry(); + } +} + +} // namespace panda::es2panda::ir diff --git a/es2panda/ir/module/assertClause.h b/es2panda/ir/module/assertClause.h new file mode 100644 index 0000000000000000000000000000000000000000..6614f7e20c3be27a09b5cb0ea47db3d09ce204ee --- /dev/null +++ b/es2panda/ir/module/assertClause.h @@ -0,0 +1,57 @@ +/** + * 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. + */ + +#ifndef ES2PANDA_IR_MODULE_ASSERT_CLAUSE_H +#define ES2PANDA_IR_MODULE_ASSERT_CLAUSE_H + +#include +#include + +namespace panda::es2panda::compiler { +class PandaGen; +} // namespace panda::es2panda::compiler + +namespace panda::es2panda::checker { +class Checker; +class Type; +} // namespace panda::es2panda::checker + +namespace panda::es2panda::ir { + +class AssertClause : public AstNode { +public: + explicit AssertClause(ArenaVector &&elements) + : AstNode(AstNodeType::ASSERT_CLAUSE), elements_(std::move(elements)) + { + } + + const ArenaVector &Elements() const + { + return elements_; + } + + void Iterate(const NodeTraverser &cb) const override; + void Dump(ir::AstDumper *dumper) const override; + void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; + checker::Type *Check([[maybe_unused]] checker::Checker *checker) const override; + void UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] binder::Binder *binder) override; + +private: + ArenaVector elements_; +}; + +} // namespace panda::es2panda::ir + +#endif diff --git a/es2panda/ir/module/assertEntry.cpp b/es2panda/ir/module/assertEntry.cpp new file mode 100644 index 0000000000000000000000000000000000000000..448832acd20e495f8bdf1bd1e598cef7911a6428 --- /dev/null +++ b/es2panda/ir/module/assertEntry.cpp @@ -0,0 +1,50 @@ +/** + * 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. + */ + +#include "assertEntry.h" + +#include +#include +#include + +namespace panda::es2panda::ir { + +void AssertEntry::Iterate(const NodeTraverser &cb) const +{ + cb(key_); + cb(value_); +} + +void AssertEntry::Dump(ir::AstDumper *dumper) const +{ + dumper->Add({{"type", "AssertEntry"}, + {"key", key_}, + {"value", value_}}); +} + +void AssertEntry::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} + +checker::Type *AssertEntry::Check([[maybe_unused]] checker::Checker *checker) const +{ + return nullptr; +} + +void AssertEntry::UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] binder::Binder *binder) +{ + key_ = std::get(cb(key_))->AsExpression(); + value_ = std::get(cb(value_))->AsStringLiteral(); +} + +} // namespace panda::es2panda::ir diff --git a/es2panda/ir/module/assertEntry.h b/es2panda/ir/module/assertEntry.h new file mode 100644 index 0000000000000000000000000000000000000000..c7f35dcb30121aa6067513ad8b3bacbe97d46f48 --- /dev/null +++ b/es2panda/ir/module/assertEntry.h @@ -0,0 +1,65 @@ +/** + * 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. + */ + +#ifndef ES2PANDA_IR_MODULE_ASSERTENTRY_H +#define ES2PANDA_IR_MODULE_ASSERTENTRY_H + +#include + +namespace panda::es2panda::compiler { +class PandaGen; +} // namespace panda::es2panda::compiler + +namespace panda::es2panda::checker { +class Checker; +class Type; +} // namespace panda::es2panda::checker + +namespace panda::es2panda::ir { + +class Expression; +class StringLiteral; + +class AssertEntry : public AstNode { +public: + explicit AssertEntry(Expression *key, StringLiteral *value) + : AstNode(AstNodeType::ASSERT_ENTRY), key_(key), value_(value) + { + } + + const Expression *Key() const + { + return key_; + } + + const StringLiteral *Value() const + { + return value_; + } + + void Iterate(const NodeTraverser &cb) const override; + void Dump(ir::AstDumper *dumper) const override; + void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; + checker::Type *Check([[maybe_unused]] checker::Checker *checker) const override; + void UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] binder::Binder *binder) override; + +private: + Expression *key_; + StringLiteral *value_; +}; + +} // namespace panda::es2panda::ir + +#endif diff --git a/es2panda/ir/module/exportAllDeclaration.cpp b/es2panda/ir/module/exportAllDeclaration.cpp index a9562694e4154e131f78462c7241c67b7884dd86..1b6ad67188712b01afd762318d5cadce2de3308f 100644 --- a/es2panda/ir/module/exportAllDeclaration.cpp +++ b/es2panda/ir/module/exportAllDeclaration.cpp @@ -28,11 +28,18 @@ void ExportAllDeclaration::Iterate(const NodeTraverser &cb) const if (exported_) { cb(exported_); } + + if (assertClause_) { + cb(assertClause_); + } } void ExportAllDeclaration::Dump(ir::AstDumper *dumper) const { - dumper->Add({{"type", "ExportAllDeclaration"}, {"source", source_}, {"exported", AstDumper::Nullable(exported_)}}); + dumper->Add({{"type", "ExportAllDeclaration"}, + {"source", source_}, + {"exported", AstDumper::Nullable(exported_)}, + {"assertClause", AstDumper::Optional(assertClause_)}}); } void ExportAllDeclaration::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} @@ -49,6 +56,10 @@ void ExportAllDeclaration::UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] bi if (exported_) { exported_ = std::get(cb(exported_))->AsIdentifier(); } + + if (assertClause_) { + assertClause_ = std::get(cb(assertClause_))->AsAssertClause(); + } } } // namespace panda::es2panda::ir diff --git a/es2panda/ir/module/exportAllDeclaration.h b/es2panda/ir/module/exportAllDeclaration.h index 149dae0196767175cddd5d27259685e111df2371..f3aa0a82ec1bc2e634aa8b479548dbbe3ddda6be 100644 --- a/es2panda/ir/module/exportAllDeclaration.h +++ b/es2panda/ir/module/exportAllDeclaration.h @@ -16,6 +16,7 @@ #ifndef ES2PANDA_IR_MODULE_EXPORT_ALL_DECLARATION_H #define ES2PANDA_IR_MODULE_EXPORT_ALL_DECLARATION_H +#include #include namespace panda::es2panda::compiler { @@ -34,8 +35,9 @@ class StringLiteral; class ExportAllDeclaration : public Statement { public: - explicit ExportAllDeclaration(StringLiteral *source, Identifier *exported) - : Statement(AstNodeType::EXPORT_ALL_DECLARATION), source_(source), exported_(exported) + explicit ExportAllDeclaration(StringLiteral *source, Identifier *exported, AssertClause *assertClause) + : Statement(AstNodeType::EXPORT_ALL_DECLARATION), + source_(source), exported_(exported), assertClause_(assertClause) { } @@ -58,6 +60,7 @@ public: private: StringLiteral *source_; Identifier *exported_; + AssertClause *assertClause_; }; } // namespace panda::es2panda::ir diff --git a/es2panda/ir/module/exportNamedDeclaration.cpp b/es2panda/ir/module/exportNamedDeclaration.cpp index b379ed7a273df8b4452aefd0ac70b16ea6d80a2c..4f6b9e75132042d7bf70bccf4c32508b63fee4bf 100644 --- a/es2panda/ir/module/exportNamedDeclaration.cpp +++ b/es2panda/ir/module/exportNamedDeclaration.cpp @@ -34,6 +34,10 @@ void ExportNamedDeclaration::Iterate(const NodeTraverser &cb) const for (auto *it : specifiers_) { cb(it); } + + if (assertClause_) { + cb(assertClause_); + } } } @@ -43,6 +47,7 @@ void ExportNamedDeclaration::Dump(ir::AstDumper *dumper) const {"declaration", AstDumper::Nullable(decl_)}, {"source", AstDumper::Nullable(source_)}, {"specifiers", specifiers_}, + {"assertClause", AstDumper::Optional(assertClause_)}, {"isType", AstDumper::Optional(IsType())}}); } @@ -68,10 +73,14 @@ void ExportNamedDeclaration::UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] if (source_) { source_ = std::get(cb(source_))->AsStringLiteral(); } - + for (auto iter = specifiers_.begin(); iter != specifiers_.end(); iter++) { *iter = std::get(cb(*iter))->AsExportSpecifier(); } + + if (assertClause_) { + assertClause_ = std::get(cb(assertClause_))->AsAssertClause(); + } } } diff --git a/es2panda/ir/module/exportNamedDeclaration.h b/es2panda/ir/module/exportNamedDeclaration.h index 51730b538e579f6193b51e5b6a148d4228afad16..fb53fd8068b1bc0c187d6a6be63d57e36a602c76 100644 --- a/es2panda/ir/module/exportNamedDeclaration.h +++ b/es2panda/ir/module/exportNamedDeclaration.h @@ -16,6 +16,7 @@ #ifndef ES2PANDA_IR_MODULE_EXPORT_DECLARATION_H #define ES2PANDA_IR_MODULE_EXPORT_DECLARATION_H +#include #include namespace panda::es2panda::compiler { @@ -34,11 +35,13 @@ class ExportSpecifier; class ExportNamedDeclaration : public Statement { public: - explicit ExportNamedDeclaration(StringLiteral *source, ArenaVector &&specifiers, bool isType) + explicit ExportNamedDeclaration(StringLiteral *source, ArenaVector &&specifiers, + AssertClause *assertClause, bool isType) : Statement(AstNodeType::EXPORT_NAMED_DECLARATION), source_(source), decl_(nullptr), specifiers_(std::move(specifiers)), + assertClause_(assertClause), isType_(isType) { } @@ -48,6 +51,7 @@ public: source_(nullptr), decl_(decl), specifiers_(std::move(specifiers)), + assertClause_(nullptr), isType_(false) { } @@ -92,6 +96,7 @@ private: StringLiteral *source_; Statement *decl_; ArenaVector specifiers_; + AssertClause *assertClause_; bool isType_; }; diff --git a/es2panda/ir/module/importDeclaration.cpp b/es2panda/ir/module/importDeclaration.cpp index 8c6a8afda7393dd5c38c5d8953836cd6d84805ab..fa41d32f52163feb265ad197f4b529d6c380f09b 100644 --- a/es2panda/ir/module/importDeclaration.cpp +++ b/es2panda/ir/module/importDeclaration.cpp @@ -27,6 +27,10 @@ void ImportDeclaration::Iterate(const NodeTraverser &cb) const for (auto *it : specifiers_) { cb(it); } + + if (assertClause_) { + cb(assertClause_); + } } void ImportDeclaration::Dump(ir::AstDumper *dumper) const @@ -34,6 +38,7 @@ void ImportDeclaration::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ImportDeclaration"}, {"source", source_}, {"specifiers", specifiers_}, + {"assertClause", AstDumper::Optional(assertClause_)}, {"isType", AstDumper::Optional(IsType())}}); } @@ -51,6 +56,10 @@ void ImportDeclaration::UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] binde for (auto iter = specifiers_.begin(); iter != specifiers_.end(); iter++) { *iter = std::get(cb(*iter)); } + + if (assertClause_) { + assertClause_ = std::get(cb(assertClause_))->AsAssertClause(); + } } } // namespace panda::es2panda::ir diff --git a/es2panda/ir/module/importDeclaration.h b/es2panda/ir/module/importDeclaration.h index a51e4fa5d5b8de492f2d4f61cc79479a3073ef9c..b1d298390e5aae406881b0762114b68c44261784 100644 --- a/es2panda/ir/module/importDeclaration.h +++ b/es2panda/ir/module/importDeclaration.h @@ -16,6 +16,7 @@ #ifndef ES2PANDA_IR_MODULE_IMPORT_DECLARATION_H #define ES2PANDA_IR_MODULE_IMPORT_DECLARATION_H +#include #include #include @@ -34,10 +35,12 @@ class StringLiteral; class ImportDeclaration : public Statement { public: - explicit ImportDeclaration(StringLiteral *source, ArenaVector &&specifiers, bool isType) + explicit ImportDeclaration(StringLiteral *source, ArenaVector &&specifiers, + AssertClause *assertClause, bool isType) : Statement(AstNodeType::IMPORT_DECLARATION), source_(source), specifiers_(std::move(specifiers)), + assertClause_(assertClause), isType_(isType) { } @@ -66,6 +69,7 @@ public: private: StringLiteral *source_; ArenaVector specifiers_; + AssertClause *assertClause_; bool isType_; }; diff --git a/es2panda/parser/expressionParser.cpp b/es2panda/parser/expressionParser.cpp index 1e9377ffdcb0deeac767b4d3a03f326afabd28d6..263640e52a0c02d42a4ce507f28b7e57af9c651c 100644 --- a/es2panda/parser/expressionParser.cpp +++ b/es2panda/parser/expressionParser.cpp @@ -2371,22 +2371,57 @@ ir::Expression *ParserImpl::ParseImportExpression() ir::Expression *source = ParseExpression(); + ir::ObjectExpression *importAssertion = nullptr; if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { - ThrowSyntaxError( - "Dynamic imports can only accept a module specifier, optional assertion is not supported yet."); + importAssertion = ParseImportAssertionForDynamicImport(); } if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { ThrowSyntaxError("Unexpected token"); } - auto *importExpression = AllocNode(source); + auto *importExpression = AllocNode(source, importAssertion); importExpression->SetRange({startLoc, lexer_->GetToken().End()}); lexer_->NextToken(); // eat right paren return importExpression; } +ir::ObjectExpression *ParserImpl::ParseImportAssertionForDynamicImport() +{ + if (Extension() != ScriptExtension::TS) { + ThrowSyntaxError( + "Dynamic imports can only accept a module specifier, optional assertion is not supported yet."); + } + + lexer_->NextToken(); + if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { + ThrowSyntaxError("expected '{'."); + } + + ir::ObjectExpression *importAssertion = ParseObjectExpression(); + + ValidateImportAssertionForDynamicImport(importAssertion); + + return importAssertion; +} + +void ParserImpl::ValidateImportAssertionForDynamicImport(ir::ObjectExpression *importAssertion) +{ + ArenaVector properties = importAssertion->Properties(); + if (properties.size() != 1) { + ThrowSyntaxError("There should be only one Import assertion in dynamic import."); + } + + auto *property = properties.front(); + if (!property->IsProperty() || + !property->AsProperty()->Key()->IsIdentifier() || + !property->AsProperty()->Key()->AsIdentifier()->Name().Is("assert") || + !property->AsProperty()->Value()->IsObjectExpression()) { + ThrowSyntaxError("Incorrect format of Import assertion in dynamic import."); + } +} + ir::FunctionExpression *ParserImpl::ParseFunctionExpression(ParserStatus newStatus) { lexer::SourcePosition startLoc = lexer_->GetToken().Start(); diff --git a/es2panda/parser/parserImpl.h b/es2panda/parser/parserImpl.h index af7cd5a23e8c534498a4e17f512efe718bf2fc13..aec42d5dcdf03bb9ce956649e2430ace28a2d839 100644 --- a/es2panda/parser/parserImpl.h +++ b/es2panda/parser/parserImpl.h @@ -414,6 +414,10 @@ private: bool allowDefault = true, bool isDeclare = false); ir::TemplateLiteral *ParseTemplateLiteral(); ir::Expression *ParseImportExpression(); + ir::ObjectExpression *ParseImportAssertionForDynamicImport(); + void ValidateImportAssertionForDynamicImport(ir::ObjectExpression *importAssertion); + ir::AssertClause *ParseAssertClause(); + ir::AssertEntry *ParseAssertEntry(); ir::FunctionExpression *ParseFunctionExpression(ParserStatus newStatus = ParserStatus::NO_OPTS); ir::Expression *ParseOptionalChain(ir::Expression *leftSideExpr); void ParseNameSpaceImport(ArenaVector *specifiers, bool isType); diff --git a/es2panda/parser/statementParser.cpp b/es2panda/parser/statementParser.cpp index b47cf9e724579517857fc0b0aa3a1aafee481c5d..63a6f6a20b3503a231c6d8480181aa5049bf664f 100644 --- a/es2panda/parser/statementParser.cpp +++ b/es2panda/parser/statementParser.cpp @@ -2483,7 +2483,14 @@ ir::ExportAllDeclaration *ParserImpl::ParseExportAllDeclaration(const lexer::Sou // record export star entry AddExportStarEntryItem(startLoc, source, exported); - auto *exportDeclaration = AllocNode(source, exported); + ir::AssertClause *assertClause = nullptr; + if (Extension() == ScriptExtension::TS && !lexer_->GetToken().NewLine() && + lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && + lexer_->GetToken().Ident().Is("assert")) { + assertClause = ParseAssertClause(); + } + + auto *exportDeclaration = AllocNode(source, exported, assertClause); exportDeclaration->SetRange({startLoc, endLoc}); ConsumeSemicolon(exportDeclaration); @@ -2566,7 +2573,21 @@ ir::ExportNamedDeclaration *ParserImpl::ParseExportNamedSpecifiers(const lexer:: // record ExportEntry AddExportNamedEntryItem(specifiers, source, isType); - auto *exportDeclaration = AllocNode(source, std::move(specifiers), isType); + ir::AssertClause *assertClause = nullptr; + if (Extension() == ScriptExtension::TS && !lexer_->GetToken().NewLine() && + lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && + lexer_->GetToken().Ident().Is("assert")) { + if (source == nullptr) { + ThrowSyntaxError("';' expected."); + } + if (isType) { + ThrowSyntaxError("Import assertions cannot be used with type-only imports or exports."); + } + assertClause = ParseAssertClause(); + } + + auto *exportDeclaration = AllocNode(source, std::move(specifiers), + assertClause, isType); exportDeclaration->SetRange({startLoc, endPos}); ConsumeSemicolon(exportDeclaration); @@ -3072,8 +3093,18 @@ ir::Statement *ParserImpl::ParseImportDeclaration(StatementParsingFlags flags) AddImportEntryItem(source, nullptr, isType); } + ir::AssertClause *assertClause = nullptr; + if (Extension() == ScriptExtension::TS && !lexer_->GetToken().NewLine() && + lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && + lexer_->GetToken().Ident().Is("assert")) { + if (isType) { + ThrowSyntaxError("Import assertions cannot be used with type-only imports or exports."); + } + assertClause = ParseAssertClause(); + } + lexer::SourcePosition endLoc = source->End(); - auto *importDeclaration = AllocNode(source, std::move(specifiers), isType); + auto *importDeclaration = AllocNode(source, std::move(specifiers), assertClause, isType); importDeclaration->SetRange({startLoc, endLoc}); ConsumeSemicolon(importDeclaration); @@ -3081,4 +3112,68 @@ ir::Statement *ParserImpl::ParseImportDeclaration(StatementParsingFlags flags) return importDeclaration; } +ir::AssertClause *ParserImpl::ParseAssertClause() +{ + lexer::SourcePosition startLoc = lexer_->GetToken().Start(); + lexer_->NextToken(); // eat assert + + if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { + ThrowSyntaxError("expected left brace."); + } + lexer_->NextToken(); // eat '{' + + ArenaVector elements(Allocator()->Adapter()); + while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { + elements.push_back(ParseAssertEntry()); + } + + lexer_->NextToken(); // eat '}' + + auto *assertClause = AllocNode(std::move(elements)); + assertClause->SetRange({startLoc, lexer_->GetToken().End()}); + + return assertClause; +} + +ir::AssertEntry *ParserImpl::ParseAssertEntry() +{ + ir::Expression *key = nullptr; + if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { + key = AllocNode(lexer_->GetToken().Ident()); + key->SetRange(lexer_->GetToken().Loc()); + } else if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING) { + key = AllocNode(lexer_->GetToken().String()); + key->SetRange(lexer_->GetToken().Loc()); + } else { + ThrowSyntaxError("Identifier or string literal expected."); + } + + lexer_->NextToken(); + + if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { + ThrowSyntaxError("':' expected."); + } + lexer_->NextToken(); // eat : + + if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_STRING) { + ThrowSyntaxError("Import assertion values must be string literal expressions."); + } + + ir::StringLiteral *value = AllocNode(lexer_->GetToken().String()); + value->SetRange(lexer_->GetToken().Loc()); + lexer_->NextToken(); + + ASSERT(key); + ASSERT(value); + + auto *assertEntry = AllocNode(key, value); + assertEntry->SetRange({key->Start(), value->End()}); + + if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { + lexer_->NextToken(); // eat comma + } + + return assertEntry; +} + } // namespace panda::es2panda::parser diff --git a/es2panda/test/parser/ts/test_export_AssertClause1-expected.txt b/es2panda/test/parser/ts/test_export_AssertClause1-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..197b7ea89009e0ec828e9c3f6e0228fce1e2bdd8 --- /dev/null +++ b/es2panda/test/parser/ts/test_export_AssertClause1-expected.txt @@ -0,0 +1,225 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ExportNamedDeclaration", + "declaration": null, + "source": { + "type": "StringLiteral", + "value": "test", + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 25 + } + } + }, + "specifiers": [ + { + "type": "ExportSpecifier", + "local": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + "exported": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + "isType": false, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 11 + } + } + } + ], + "assertClause": { + "type": "AssertClause", + "elements": [ + { + "type": "AssertEntry", + "key": { + "type": "Identifier", + "name": "key1", + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 9 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "value1", + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + { + "type": "AssertEntry", + "key": { + "type": "Identifier", + "name": "key2", + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 9 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "value2", + "loc": { + "start": { + "line": 21, + "column": 11 + }, + "end": { + "line": 21, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 19 + } + } + }, + { + "type": "AssertEntry", + "key": { + "type": "Identifier", + "name": "key3", + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 9 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "value3", + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 23, + "column": 13 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 26 + }, + "end": { + "line": 23, + "column": 17 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 23, + "column": 17 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 24, + "column": 1 + } + } +} diff --git a/es2panda/test/parser/ts/test_export_AssertClause1.ts b/es2panda/test/parser/ts/test_export_AssertClause1.ts new file mode 100644 index 0000000000000000000000000000000000000000..e0ee14d594274862ea92e7a8044e5b06522bfa06 --- /dev/null +++ b/es2panda/test/parser/ts/test_export_AssertClause1.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. + */ + + +export { a } from "test" assert { + key1 + : + "value1", + key2: "value2", + key3: + "value3", }; diff --git a/es2panda/test/parser/ts/test_export_AssertClause2-expected.txt b/es2panda/test/parser/ts/test_export_AssertClause2-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..771713df0629ec63993f5d64a5e03551d42dd46b --- /dev/null +++ b/es2panda/test/parser/ts/test_export_AssertClause2-expected.txt @@ -0,0 +1,112 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ExportAllDeclaration", + "source": { + "type": "StringLiteral", + "value": "test", + "loc": { + "start": { + "line": 17, + "column": 21 + }, + "end": { + "line": 17, + "column": 27 + } + } + }, + "exported": { + "type": "Identifier", + "name": "ns", + "loc": { + "start": { + "line": 17, + "column": 13 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "assertClause": { + "type": "AssertClause", + "elements": [ + { + "type": "AssertEntry", + "key": { + "type": "Identifier", + "name": "key", + "loc": { + "start": { + "line": 18, + "column": 2 + }, + "end": { + "line": 18, + "column": 5 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "value", + "loc": { + "start": { + "line": 18, + "column": 7 + }, + "end": { + "line": 18, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 2 + }, + "end": { + "line": 18, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 18, + "column": 16 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 19, + "column": 1 + } + } +} diff --git a/es2panda/test/parser/ts/test_export_AssertClause2.ts b/es2panda/test/parser/ts/test_export_AssertClause2.ts new file mode 100644 index 0000000000000000000000000000000000000000..af1ef7f218938eddbfafe99785fb03c633563f11 --- /dev/null +++ b/es2panda/test/parser/ts/test_export_AssertClause2.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + + +export * as ns from "test" assert +{key: "value"}; diff --git a/es2panda/test/parser/ts/test_import_AssertClause1-expected.txt b/es2panda/test/parser/ts/test_import_AssertClause1-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..a23d2c26e00d7a7096b853cb4e4dcd6c18a35dcf --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause1-expected.txt @@ -0,0 +1,450 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ImportExpression", + "source": { + "type": "StringLiteral", + "value": "test", + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 14 + } + } + }, + "importAssertion": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "name": "assert", + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 17, + "column": 24 + } + } + }, + "value": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "name": "k1", + "loc": { + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 17, + "column": 30 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "json", + "loc": { + "start": { + "line": 17, + "column": 32 + }, + "end": { + "line": 17, + "column": 38 + } + } + }, + "kind": "init", + "loc": { + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 17, + "column": 38 + } + } + }, + { + "type": "Property", + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "StringLiteral", + "value": "k2", + "loc": { + "start": { + "line": 17, + "column": 40 + }, + "end": { + "line": 17, + "column": 44 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "v1", + "loc": { + "start": { + "line": 17, + "column": 46 + }, + "end": { + "line": 17, + "column": 50 + } + } + }, + "kind": "init", + "loc": { + "start": { + "line": 17, + "column": 40 + }, + "end": { + "line": 17, + "column": 50 + } + } + }, + { + "type": "Property", + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "NumberLiteral", + "value": 3, + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 29 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "k3", + "loc": { + "start": { + "line": 18, + "column": 31 + }, + "end": { + "line": 18, + "column": 35 + } + } + }, + "kind": "init", + "loc": { + "start": { + "line": 18, + "column": 28 + }, + "end": { + "line": 18, + "column": 35 + } + } + }, + { + "type": "Property", + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "name": "k4", + "loc": { + "start": { + "line": 19, + "column": 28 + }, + "end": { + "line": 19, + "column": 30 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "xxx", + "loc": { + "start": { + "line": 19, + "column": 32 + }, + "end": { + "line": 19, + "column": 37 + } + } + }, + "kind": "init", + "loc": { + "start": { + "line": 19, + "column": 28 + }, + "end": { + "line": 19, + "column": 37 + } + } + }, + { + "type": "Property", + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "name": "type", + "loc": { + "start": { + "line": 20, + "column": 28 + }, + "end": { + "line": 20, + "column": 32 + } + } + }, + "value": { + "type": "TemplateLiteral", + "expressions": [], + "quasis": [ + { + "type": "TemplateElement", + "value": { + "raw": "xx", + "cooked": "xx" + }, + "loc": { + "start": { + "line": 20, + "column": 35 + }, + "end": { + "line": 20, + "column": 37 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 34 + }, + "end": { + "line": 20, + "column": 38 + } + } + }, + "kind": "init", + "loc": { + "start": { + "line": 20, + "column": 28 + }, + "end": { + "line": 20, + "column": 38 + } + } + }, + { + "type": "Property", + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "name": "k6", + "loc": { + "start": { + "line": 20, + "column": 40 + }, + "end": { + "line": 20, + "column": 42 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "", + "loc": { + "start": { + "line": 20, + "column": 44 + }, + "end": { + "line": 20, + "column": 46 + } + } + }, + "kind": "init", + "loc": { + "start": { + "line": 20, + "column": 40 + }, + "end": { + "line": 20, + "column": 46 + } + } + }, + { + "type": "Property", + "method": false, + "shorthand": false, + "computed": true, + "key": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 20, + "column": 49 + }, + "end": { + "line": 20, + "column": 50 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "xxx", + "loc": { + "start": { + "line": 20, + "column": 53 + }, + "end": { + "line": 20, + "column": 58 + } + } + }, + "kind": "init", + "loc": { + "start": { + "line": 20, + "column": 48 + }, + "end": { + "line": 20, + "column": 58 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 26 + }, + "end": { + "line": 20, + "column": 60 + } + } + }, + "kind": "init", + "loc": { + "start": { + "line": 17, + "column": 18 + }, + "end": { + "line": 20, + "column": 60 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 16 + }, + "end": { + "line": 20, + "column": 61 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 20, + "column": 62 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 20, + "column": 63 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 21, + "column": 1 + } + } +} diff --git a/es2panda/test/parser/ts/test_import_AssertClause1.ts b/es2panda/test/parser/ts/test_import_AssertClause1.ts new file mode 100644 index 0000000000000000000000000000000000000000..2c88ab64db561ea0e0fdc520196b9f7156b17507 --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause1.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ + + +import("test", { assert: { k1: "json", "k2": "v1", + 3: "k3", + k4: "xxx", + type: `xx`, k6: "", [1]: "xxx" }}); diff --git a/es2panda/test/parser/ts/test_import_AssertClause2-expected.txt b/es2panda/test/parser/ts/test_import_AssertClause2-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..e17ed57d08f99f73e568678941f65ce8e89c2acf --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause2-expected.txt @@ -0,0 +1,222 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "a", + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + "specifiers": [], + "assertClause": { + "type": "AssertClause", + "elements": [ + { + "type": "AssertEntry", + "key": { + "type": "Identifier", + "name": "key1", + "loc": { + "start": { + "line": 17, + "column": 21 + }, + "end": { + "line": 17, + "column": 25 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "value1", + "loc": { + "start": { + "line": 17, + "column": 27 + }, + "end": { + "line": 17, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 21 + }, + "end": { + "line": 17, + "column": 35 + } + } + }, + { + "type": "AssertEntry", + "key": { + "type": "StringLiteral", + "value": "key2", + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 11 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "value2", + "loc": { + "start": { + "line": 18, + "column": 13 + }, + "end": { + "line": 18, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 21 + } + } + }, + { + "type": "AssertEntry", + "key": { + "type": "Identifier", + "name": "key3", + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 19, + "column": 9 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "value3", + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 5 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + { + "type": "AssertEntry", + "key": { + "type": "Identifier", + "name": "key4", + "loc": { + "start": { + "line": 21, + "column": 7 + }, + "end": { + "line": 21, + "column": 11 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "value4", + "loc": { + "start": { + "line": 21, + "column": 13 + }, + "end": { + "line": 21, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 7 + }, + "end": { + "line": 21, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 12 + }, + "end": { + "line": 22, + "column": 3 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 22, + "column": 3 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 23, + "column": 1 + } + } +} diff --git a/es2panda/test/parser/ts/test_import_AssertClause2.ts b/es2panda/test/parser/ts/test_import_AssertClause2.ts new file mode 100644 index 0000000000000000000000000000000000000000..880153d45cdd63b3e246e3996fcbe9b562d98fc7 --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause2.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. + */ + + +import "a" assert { key1: "value1", + "key2": "value2", + key3: + "value3" + , key4: "value4" +}; diff --git a/es2panda/test/parser/ts/test_import_AssertClause3-expected.txt b/es2panda/test/parser/ts/test_import_AssertClause3-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..1b386d5d56c19d098080fdb01894a21f5c3dcf35 --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause3-expected.txt @@ -0,0 +1 @@ +SyntaxError: Import assertions cannot be used with type-only imports or exports. [test_import_AssertClause3.ts:17:31] diff --git a/es2panda/test/parser/ts/test_import_AssertClause3.ts b/es2panda/test/parser/ts/test_import_AssertClause3.ts new file mode 100644 index 0000000000000000000000000000000000000000..adc4dc2ec9a5027f73f060b8a8d1fd9228ebbbde --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause3.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + + +import type { a } from "test" assert { key1: "value1"}; diff --git a/es2panda/test/parser/ts/test_import_AssertClause4-expected.txt b/es2panda/test/parser/ts/test_import_AssertClause4-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..f2064af3b62dc37da649a8518e764ba064b4f19e --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause4-expected.txt @@ -0,0 +1 @@ +SyntaxError: Identifier or string literal expected. [test_import_AssertClause4.ts:17:51] diff --git a/es2panda/test/parser/ts/test_import_AssertClause4.ts b/es2panda/test/parser/ts/test_import_AssertClause4.ts new file mode 100644 index 0000000000000000000000000000000000000000..472062ac9701ca84dff6757a02f25b7e56b23691 --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause4.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + + +import { a } from "test" assert { key1: "value1", 2: "value2"}; diff --git a/es2panda/test/parser/ts/test_import_AssertClause5-expected.txt b/es2panda/test/parser/ts/test_import_AssertClause5-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..9efa49b499aaefc0cce2e84d16e65ae3482e778d --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause5-expected.txt @@ -0,0 +1 @@ +SyntaxError: Import assertion values must be string literal expressions. [test_import_AssertClause5.ts:17:59] diff --git a/es2panda/test/parser/ts/test_import_AssertClause5.ts b/es2panda/test/parser/ts/test_import_AssertClause5.ts new file mode 100644 index 0000000000000000000000000000000000000000..a753faaa796023ebdcb4e4bfeae500967430278a --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause5.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + + +import { a } from "test" assert { key1: "value1", "key2": 2}; diff --git a/es2panda/test/parser/ts/test_import_AssertClause6-expected.txt b/es2panda/test/parser/ts/test_import_AssertClause6-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..8d676607f53e010b6423bc2031628cc69e20522c --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause6-expected.txt @@ -0,0 +1,477 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "test", + "loc": { + "start": { + "line": 17, + "column": 20 + }, + "end": { + "line": 17, + "column": 26 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "a0", + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 12 + } + } + }, + "imported": { + "type": "Identifier", + "name": "a0", + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 12 + } + } + }, + "isType": false, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 12 + } + } + } + ], + "assertClause": { + "type": "AssertClause", + "elements": [], + "loc": { + "start": { + "line": 17, + "column": 27 + }, + "end": { + "line": 17, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 37 + } + } + }, + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "test", + "loc": { + "start": { + "line": 19, + "column": 20 + }, + "end": { + "line": 19, + "column": 26 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "a1", + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 12 + } + } + }, + "imported": { + "type": "Identifier", + "name": "a1", + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 12 + } + } + }, + "isType": false, + "loc": { + "start": { + "line": 19, + "column": 10 + }, + "end": { + "line": 19, + "column": 12 + } + } + } + ], + "assertClause": { + "type": "AssertClause", + "elements": [ + { + "type": "AssertEntry", + "key": { + "type": "Identifier", + "name": "key1", + "loc": { + "start": { + "line": 19, + "column": 35 + }, + "end": { + "line": 19, + "column": 39 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "value1", + "loc": { + "start": { + "line": 19, + "column": 41 + }, + "end": { + "line": 19, + "column": 49 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 35 + }, + "end": { + "line": 19, + "column": 49 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 26 + }, + "end": { + "line": 19, + "column": 51 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 51 + } + } + }, + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "test", + "loc": { + "start": { + "line": 21, + "column": 20 + }, + "end": { + "line": 21, + "column": 26 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "a2", + "loc": { + "start": { + "line": 21, + "column": 10 + }, + "end": { + "line": 21, + "column": 12 + } + } + }, + "imported": { + "type": "Identifier", + "name": "a2", + "loc": { + "start": { + "line": 21, + "column": 10 + }, + "end": { + "line": 21, + "column": 12 + } + } + }, + "isType": false, + "loc": { + "start": { + "line": 21, + "column": 10 + }, + "end": { + "line": 21, + "column": 12 + } + } + } + ], + "assertClause": { + "type": "AssertClause", + "elements": [ + { + "type": "AssertEntry", + "key": { + "type": "Identifier", + "name": "key1", + "loc": { + "start": { + "line": 21, + "column": 36 + }, + "end": { + "line": 21, + "column": 40 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "value1", + "loc": { + "start": { + "line": 21, + "column": 42 + }, + "end": { + "line": 21, + "column": 50 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 36 + }, + "end": { + "line": 21, + "column": 50 + } + } + }, + { + "type": "AssertEntry", + "key": { + "type": "StringLiteral", + "value": "key2", + "loc": { + "start": { + "line": 22, + "column": 7 + }, + "end": { + "line": 22, + "column": 13 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "value2", + "loc": { + "start": { + "line": 23, + "column": 7 + }, + "end": { + "line": 23, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 7 + }, + "end": { + "line": 23, + "column": 15 + } + } + }, + { + "type": "AssertEntry", + "key": { + "type": "Identifier", + "name": "key3", + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 9 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "value3", + "loc": { + "start": { + "line": 24, + "column": 11 + }, + "end": { + "line": 24, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 19 + } + } + }, + { + "type": "AssertEntry", + "key": { + "type": "Identifier", + "name": "key4", + "loc": { + "start": { + "line": 24, + "column": 21 + }, + "end": { + "line": 24, + "column": 25 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "value4", + "loc": { + "start": { + "line": 24, + "column": 27 + }, + "end": { + "line": 24, + "column": 35 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 21 + }, + "end": { + "line": 24, + "column": 35 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 27 + }, + "end": { + "line": 24, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 24, + "column": 37 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 25, + "column": 1 + } + } +} diff --git a/es2panda/test/parser/ts/test_import_AssertClause6.ts b/es2panda/test/parser/ts/test_import_AssertClause6.ts new file mode 100644 index 0000000000000000000000000000000000000000..dd5953d4277f9b94bcc28fbbf961ce4ec808b2e4 --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause6.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. + */ + + +import { a0 } from "test" assert {}; + +import { a1 } from "test"assert { key1: "value1"}; + +import { a2 } from "test" assert { key1: "value1" + , "key2" + : "value2", + key3: "value3", key4: "value4"}; diff --git a/es2panda/test/parser/ts/test_import_AssertClause7-expected.txt b/es2panda/test/parser/ts/test_import_AssertClause7-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..3e098cd1cd14a8715e891fb3594243d472b00a6c --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause7-expected.txt @@ -0,0 +1,170 @@ +{ + "type": "Program", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "assert", + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 11 + } + } + }, + "init": { + "type": "NumberLiteral", + "value": 1, + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 17, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 15 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + { + "type": "ImportDeclaration", + "source": { + "type": "StringLiteral", + "value": "./test", + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 27 + } + } + }, + "specifiers": [ + { + "type": "ImportSpecifier", + "local": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 11 + } + } + }, + "imported": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 11 + } + } + }, + "isType": false, + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 11 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 1 + }, + "end": { + "line": 18, + "column": 27 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "Identifier", + "name": "assert", + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 7 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 19, + "column": 8 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 20, + "column": 1 + } + } +} diff --git a/es2panda/test/parser/ts/test_import_AssertClause7.ts b/es2panda/test/parser/ts/test_import_AssertClause7.ts new file mode 100644 index 0000000000000000000000000000000000000000..15fdf707d7e928ffe48a009d5a9a500fa77205b7 --- /dev/null +++ b/es2panda/test/parser/ts/test_import_AssertClause7.ts @@ -0,0 +1,19 @@ +/* + * 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. + */ + + +let assert = 1; +import { a } from "./test" +assert; diff --git a/es2panda/test/parser/ts/test_satisfies2-expected.txt b/es2panda/test/parser/ts/test_satisfies2-expected.txt index ab385b8874bef5773f8c65e97c7e181a73118fa8..153cac03cf117ca0c88350ae9ea0898c95222ea1 100644 --- a/es2panda/test/parser/ts/test_satisfies2-expected.txt +++ b/es2panda/test/parser/ts/test_satisfies2-expected.txt @@ -105,6 +105,7 @@ } }, "readonly": false, + "static": false, "loc": { "start": { "line": 17, diff --git a/es2panda/test/parser/ts/test_satisfies8-expected.txt b/es2panda/test/parser/ts/test_satisfies8-expected.txt index 6f047e8bdb3f87d0cdd89ea6c1572890963b20a9..0d4c1b8556d0341db66936a8bc41e4528bc68a1b 100644 --- a/es2panda/test/parser/ts/test_satisfies8-expected.txt +++ b/es2panda/test/parser/ts/test_satisfies8-expected.txt @@ -63,6 +63,7 @@ } }, "readonly": false, + "static": false, "loc": { "start": { "line": 17,