From 4044b57e01fd507d3d0c905d5d206d751af1a105 Mon Sep 17 00:00:00 2001 From: Gabor Aron Takacs Date: Sun, 22 Jun 2025 20:12:55 +0200 Subject: [PATCH] Export parser should work on object literal Reason: Default export from specification 13.5.1 Exported Declarations doesn't work correctly on object literals Description: Adding parser implementation for specific cornercase Fixes #26901 internal issue. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJTPP Signed-off-by: Gabor Aron Takacs Signed-off-by: Torok Gergo --- ets2panda/ir/module/exportSpecifier.cpp | 8 +++++- ets2panda/parser/ETSparser.cpp | 27 ++++++++++++++++--- ets2panda/parser/ETSparser.h | 1 + .../ets/defaultExportObjectLiteral_exp.ets | 26 ++++++++++++++++++ 4 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 ets2panda/test/runtime/ets/defaultExportObjectLiteral_exp.ets diff --git a/ets2panda/ir/module/exportSpecifier.cpp b/ets2panda/ir/module/exportSpecifier.cpp index 1133414d19..1c28d57fe5 100644 --- a/ets2panda/ir/module/exportSpecifier.cpp +++ b/ets2panda/ir/module/exportSpecifier.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 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 @@ -48,6 +48,12 @@ void ExportSpecifier::Dump(ir::AstDumper *dumper) const void ExportSpecifier::Dump(ir::SrcDumper *dumper) const { + if (GetConstantExpression() != nullptr) { + GetConstantExpression()->Dump(dumper); + dumper->Add("as default"); + return; + } + exported_->Dump(dumper); if (local_ != nullptr) { diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 9788c8d7af..2847966a88 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -1121,17 +1121,36 @@ ir::Statement *ETSParser::CreateReExportDeclarationNode(ir::ETSImportDeclaration return reExport; } +ir::Statement *ETSParser::ParseDefaultIfSingleExport(ir::ModifierFlags modifiers) +{ + auto tokenType = Lexer()->GetToken().Type(); + if (tokenType != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { + return ParseSingleExport(modifiers); + } + auto savePos = Lexer()->Save(); + Lexer()->NextToken(); + auto isSelectiveExport = Lexer()->TryEatTokenType(lexer::TokenType::LITERAL_IDENT) && + (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA || + Lexer()->GetToken().Type() == lexer::TokenType::KEYW_AS || + Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE); + Lexer()->Rewind(savePos); + return !isSelectiveExport ? ParseSingleExport(modifiers) : nullptr; +} + ir::Statement *ETSParser::ParseExport(lexer::SourcePosition startLoc, ir::ModifierFlags modifiers) { const size_t exportDefaultMaxSize = 1; if (!InAmbientContext() && (GetContext().Status() & ParserStatus::IN_NAMESPACE) != 0) { LogError(diagnostic::EXPORT_IN_NAMESPACE); } - [[maybe_unused]] auto tokenType = Lexer()->GetToken().Type(); // export a constant variable anonymously, as export default new A() - if ((modifiers & ir::ModifierFlags::DEFAULT_EXPORT) != 0U && tokenType != lexer::TokenType::PUNCTUATOR_MULTIPLY && - tokenType != lexer::TokenType::PUNCTUATOR_LEFT_BRACE && tokenType != lexer::TokenType::LITERAL_IDENT) { - return ParseSingleExport(modifiers); + if ((modifiers & ir::ModifierFlags::DEFAULT_EXPORT) != 0U && + Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_MULTIPLY && + Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + auto exportedExpression = ParseDefaultIfSingleExport(modifiers); + if (exportedExpression != nullptr) { + return exportedExpression; + } } ArenaVector specifiers(Allocator()->Adapter()); diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 8dddff53b5..c92657f139 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -302,6 +302,7 @@ private: ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS) override; ir::Statement *ParseTryStatement() override; ir::Statement *ParseDebuggerStatement() override; + ir::Statement *ParseDefaultIfSingleExport(ir::ModifierFlags modifiers); ir::Statement *ParseExport(lexer::SourcePosition startLoc, ir::ModifierFlags modifiers); ir::Statement *ParseImportDeclaration(StatementParsingFlags flags) override; ir::Statement *ParseExportDeclaration(StatementParsingFlags flags) override; diff --git a/ets2panda/test/runtime/ets/defaultExportObjectLiteral_exp.ets b/ets2panda/test/runtime/ets/defaultExportObjectLiteral_exp.ets new file mode 100644 index 0000000000..885d31856d --- /dev/null +++ b/ets2panda/test/runtime/ets/defaultExportObjectLiteral_exp.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 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 User { + name: string; + age: number; + email: string; +}; + +export default { + name: 'John Doe', + age: 30, + email: 'johndoe@example.com' +} as User; -- Gitee