diff --git a/ets2panda/ir/module/importDeclaration.h b/ets2panda/ir/module/importDeclaration.h index 2da6374989c9541c10731ccc600647b9fbf5dcf1..c22360ba7bd893bf5f3c09ea0c5ad536e9a5f806 100644 --- a/ets2panda/ir/module/importDeclaration.h +++ b/ets2panda/ir/module/importDeclaration.h @@ -22,6 +22,7 @@ namespace ark::es2panda::ir { class StringLiteral; enum class ImportKinds { ALL, TYPES }; +using ExportKinds = ImportKinds; class ImportDeclaration : public Statement { public: diff --git a/ets2panda/lexer/scripts/keywords.yaml b/ets2panda/lexer/scripts/keywords.yaml index 5e53a6b6ef51d5511d0d4eb3d47ce1f87028ee18..8317df906f616d888d21e5de6da67dd784437fa1 100644 --- a/ets2panda/lexer/scripts/keywords.yaml +++ b/ets2panda/lexer/scripts/keywords.yaml @@ -531,7 +531,6 @@ keywords: - name: 'type' token: KEYW_TYPE keyword_like: [ets, js, ts] - flags: [definable_type_name] - name: 'typeof' token: KEYW_TYPEOF diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index e4b25915ea843bfd0b9febf3a5945ebebd39ad08..c7c7cc73b8d68208c4c5c825ec07befc55015f6a 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -1173,9 +1173,36 @@ ir::Statement *ETSParser::ParseDefaultIfSingleExport(ir::ModifierFlags modifiers return !isSelectiveExport ? ParseSingleExport(modifiers) : nullptr; } -ir::Statement *ETSParser::ParseExport(lexer::SourcePosition startLoc, ir::ModifierFlags modifiers) +ir::ExportNamedDeclaration *ETSParser::CreateExportNamedDeclaration(const SpecifiersInfo &specs, + const ir::ModifierFlags &modifiers, + const lexer::SourcePosition &startLoc) { const size_t exportDefaultMaxSize = 1; + ArenaVector exports(Allocator()->Adapter()); + auto endLoc = startLoc; + for (auto spec : specs.result) { + exports.emplace_back(AllocNode(spec->Local(), spec->Imported())); + endLoc = endLoc.index < spec->End().index ? spec->End() : endLoc; + } + + if (specs.resultExportDefault.size() > exportDefaultMaxSize) { + LogError(diagnostic::EXPORT_DEFAULT_WITH_MUPLTIPLE_SPECIFIER); + } + for (auto spec : specs.resultExportDefault) { + exports.emplace_back(spec); + endLoc = endLoc.index < spec->End().index ? spec->End() : endLoc; + } + + auto result = AllocNode(Allocator(), static_cast(nullptr), + std::move(exports)); + ES2PANDA_ASSERT(result != nullptr); + result->AddModifier(modifiers); + result->SetRange({startLoc, endLoc}); + return result; +} + +ir::Statement *ETSParser::ParseExport(lexer::SourcePosition startLoc, ir::ModifierFlags modifiers) +{ if (!InAmbientContext() && (GetContext().Status() & ParserStatus::IN_NAMESPACE) != 0) { LogError(diagnostic::EXPORT_IN_NAMESPACE); } @@ -1196,32 +1223,14 @@ ir::Statement *ETSParser::ParseExport(lexer::SourcePosition startLoc, ir::Modifi // export * as xxx from yyy, the xxx should have export flag to pass the following check. specifiers[0]->AddModifier(ir::ModifierFlags::EXPORT); } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { - auto specs = ParseNamedSpecifiers(); + ir::ExportKinds exportKind = + (modifiers & ir::ModifierFlags::EXPORT_TYPE) != 0U ? ir::ExportKinds::TYPES : ir::ExportKinds::ALL; + auto specs = ParseNamedSpecifiers(exportKind); if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_FROM) { specifiers = util::Helpers::ConvertVector(specs.result); } else { - ArenaVector exports(Allocator()->Adapter()); - auto endLoc = startLoc; - for (auto spec : specs.result) { - exports.emplace_back(AllocNode(spec->Local(), spec->Imported())); - endLoc = endLoc.index < spec->End().index ? spec->End() : endLoc; - } - - if (specs.resultExportDefault.size() > exportDefaultMaxSize) { - LogError(diagnostic::EXPORT_DEFAULT_WITH_MUPLTIPLE_SPECIFIER); - } - for (auto spec : specs.resultExportDefault) { - exports.emplace_back(spec); - endLoc = endLoc.index < spec->End().index ? spec->End() : endLoc; - } - - auto result = AllocNode(Allocator(), static_cast(nullptr), - std::move(exports)); - ES2PANDA_ASSERT(result != nullptr); - result->AddModifier(modifiers); - result->SetRange({startLoc, endLoc}); - return result; + return CreateExportNamedDeclaration(specs, modifiers, startLoc); } } else { return ParseSingleExport(modifiers); @@ -1334,8 +1343,7 @@ ArenaVector ETSParser::ParseImportDeclarations() auto startLoc = Lexer()->GetToken().Start(); Lexer()->NextToken(); // eat import - ir::ImportKinds importKind = - Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_TYPE) ? ir::ImportKinds::TYPES : ir::ImportKinds::ALL; + ir::ImportKinds importKind = NextIsTypeKeyword(true) ? ir::ImportKinds::TYPES : ir::ImportKinds::ALL; ArenaVector specifiers(Allocator()->Adapter()); ArenaVector defaultSpecifiers(Allocator()->Adapter()); @@ -1343,7 +1351,7 @@ ArenaVector ETSParser::ParseImportDeclarations() if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) { ParseNameSpaceSpecifier(&specifiers); } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { - auto specs = ParseNamedSpecifiers(); + auto specs = ParseNamedSpecifiers(importKind); specifiers = util::Helpers::ConvertVector(specs.result); defaultSpecifiers = util::Helpers::ConvertVector(specs.resultDefault); } else { @@ -1526,7 +1534,7 @@ bool ETSParser::ParseNamedSpecifiesImport(ArenaVector *re return true; } -SpecifiersInfo ETSParser::ParseNamedSpecifiers() +SpecifiersInfo ETSParser::ParseNamedSpecifiers(const ir::ImportKinds importKind) { // NOTE(user): handle qualifiedName in file bindings: qualifiedName '.' '*' if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_LEFT_BRACE)) { @@ -1551,18 +1559,23 @@ SpecifiersInfo ETSParser::ParseNamedSpecifiers() ParseList( lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::KEYWORD_TO_IDENT, - [this, &result, &resultDefault, &resultExportDefault, &fileName]() { + [this, &result, &resultDefault, &resultExportDefault, &fileName, &importKind](bool &typeKeywordOnSpecifier) { + if (typeKeywordOnSpecifier && importKind == ir::ImportKinds::TYPES) { + LogError(diagnostic::REPEATED_TYPE_KEYWORD); + } if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) { LogError(diagnostic::ASTERIKS_NOT_ALLOWED_IN_SELECTIVE_BINDING); } if (!IsDefaultImport()) { + typeKeywordOnSpecifier = false; return ParseNamedSpecifiesImport(&result, &resultExportDefault, fileName); } ParseNamedSpecifiesDefaultImport(&resultDefault, fileName); + typeKeywordOnSpecifier = false; return true; }, - nullptr, true); + nullptr, ParseListOptions::ALLOW_TRAILING_SEP | ParseListOptions::ALLOW_TYPE_KEYWORD); return {result, resultDefault, resultExportDefault}; } @@ -1623,7 +1636,10 @@ ir::AstNode *ETSParser::ParseImportDefaultSpecifier(ArenaVector * if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_MULTIPLY) { ParseNameSpaceSpecifier(specifiers); } else if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { - auto specs = ParseNamedSpecifiers(); + const ir::ImportKinds importKind = Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_TYPE) + ? ir::ImportKinds::TYPES + : ir::ImportKinds::ALL; + auto specs = ParseNamedSpecifiers(importKind); auto importSpecifiers = util::Helpers::ConvertVector(specs.result); specifiers->insert(specifiers->end(), importSpecifiers.begin(), importSpecifiers.end()); } @@ -2328,7 +2344,8 @@ ir::OverloadDeclaration *ETSParser::ParseOverloadDeclaration(ir::ModifierFlags m ParseList( lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::NONE, - [this, &overloads, overloadDef]() { return ParseOverloadListElement(overloads, overloadDef); }, &endLoc, true); + [this, &overloads, overloadDef](bool &) { return ParseOverloadListElement(overloads, overloadDef); }, &endLoc, + ParseListOptions::ALLOW_TRAILING_SEP); overloadDef->SetOverloadedList(std::move(overloads)); overloadDef->SetRange({startLoc, endLoc}); for (ir::Expression *overloadedName : overloadDef->OverloadedList()) { diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 66ddcc044e8e2c478bf790a9923d043e37cef6ec..e4fc7f93f23adfe3843b22622d90eb3faccb01ec 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -202,7 +202,7 @@ private: bool ParseNamedSpecifiesImport(ArenaVector *result, ArenaVector *resultExportDefault, const std::string &fileName); - SpecifiersInfo ParseNamedSpecifiers(); + SpecifiersInfo ParseNamedSpecifiers(const ir::ImportKinds importKind); ir::ExportNamedDeclaration *ParseSingleExport(ir::ModifierFlags modifiers); ir::ExportNamedDeclaration *ParseSingleExportForAnonymousConst(ir::ModifierFlags modifiers); ArenaVector ParseImportDeclarations(); @@ -301,6 +301,9 @@ private: ir::Statement *ParseTryStatement() override; ir::Statement *ParseDebuggerStatement() override; ir::Statement *ParseDefaultIfSingleExport(ir::ModifierFlags modifiers); + ir::ExportNamedDeclaration *CreateExportNamedDeclaration(const SpecifiersInfo &specs, + const ir::ModifierFlags &modifiers, + const lexer::SourcePosition &startLoc); 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/parser/ETSparserClasses.cpp b/ets2panda/parser/ETSparserClasses.cpp index f9d858dbc79b249ffe63e527ea2fae7a0c9e30e8..ca48d702b3083831abd56f9894880eb78f05f2af 100644 --- a/ets2panda/parser/ETSparserClasses.cpp +++ b/ets2panda/parser/ETSparserClasses.cpp @@ -565,7 +565,8 @@ ir::OverloadDeclaration *ETSParser::ParseClassOverloadDeclaration(ir::ModifierFl ParseList( lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::NONE, - [this, &overloads, overloadDef]() { return ParseOverloadListElement(overloads, overloadDef); }, &endLoc, true); + [this, &overloads, overloadDef](bool &) { return ParseOverloadListElement(overloads, overloadDef); }, &endLoc, + ParseListOptions::ALLOW_TRAILING_SEP); overloadDef->SetOverloadedList(std::move(overloads)); overloadDef->SetRange({startLoc, endLoc}); ValidateOverloadList(overloadDef->OverloadedList()); @@ -1122,7 +1123,8 @@ ir::OverloadDeclaration *ETSParser::ParseInterfaceOverload(ir::ModifierFlags mod ParseList( lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::NONE, - [this, &overloads, overloadDef]() { return ParseOverloadListElement(overloads, overloadDef); }, &endLoc, true); + [this, &overloads, overloadDef](bool &) { return ParseOverloadListElement(overloads, overloadDef); }, &endLoc, + ParseListOptions::ALLOW_TRAILING_SEP); overloadDef->SetOverloadedList(std::move(overloads)); overloadDef->SetRange({startLoc, endLoc}); diff --git a/ets2panda/parser/ETSparserEnums.cpp b/ets2panda/parser/ETSparserEnums.cpp index 44434862cb24624894067944521b420157710561..b2eadae5ea74a1391395c47c4ce0ee26e6367c2c 100644 --- a/ets2panda/parser/ETSparserEnums.cpp +++ b/ets2panda/parser/ETSparserEnums.cpp @@ -246,7 +246,7 @@ lexer::SourcePosition ETSParser::ParseEnumMember(ArenaVector &mem ir::Expression *currentNumberExpr = AllocNode(lexer::Number(0)); // Lambda to parse enum member (maybe with initializer) - auto const parseMember = [this, &members, ¤tNumberExpr]() { + auto const parseMember = [this, &members, ¤tNumberExpr](bool &) { auto *const ident = ExpectIdentifier(false, true); ir::Expression *ordinal; @@ -285,7 +285,7 @@ lexer::SourcePosition ETSParser::ParseEnumMember(ArenaVector &mem lexer::SourcePosition enumEnd; ParseList(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::KEYWORD_TO_IDENT, parseMember, &enumEnd, - true); + ParseListOptions::ALLOW_TRAILING_SEP); return enumEnd; } diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index f1cd269a67a4657c5c4fdef72b7a06fd81b8256c..8733d9fc98c63f7cb69b4f35b1d4797a02cf8e7f 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -683,7 +683,7 @@ void ETSParser::ParseArgumentsNewExpression(ArenaVector &argum ParseList( lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS, lexer::NextTokenFlags::NONE, - [this, &arguments]() { + [this, &arguments](bool &) { ir::Expression *argument = Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD ? ParseSpreadElement(ExpressionParseFlags::POTENTIALLY_IN_PATTERN) @@ -695,7 +695,7 @@ void ETSParser::ParseArgumentsNewExpression(ArenaVector &argum arguments.push_back(argument); return true; }, - &endLoc, true); + &endLoc, ParseListOptions::ALLOW_TRAILING_SEP); } } diff --git a/ets2panda/parser/ETSparserStatements.cpp b/ets2panda/parser/ETSparserStatements.cpp index bb7d3f6db0e6f009aa5414a9d115b164e3732e4d..7d665ac913b45d709d97a0d72da4ff6d64655024 100644 --- a/ets2panda/parser/ETSparserStatements.cpp +++ b/ets2panda/parser/ETSparserStatements.cpp @@ -189,8 +189,7 @@ ir::Statement *ETSParser::ParseTopLevelDeclStatement(StatementParsingFlags flags } ir::Statement *result = nullptr; - auto token = Lexer()->GetToken(); - switch (token.Type()) { + switch (Lexer()->GetToken().Type()) { case lexer::TokenType::KEYW_FUNCTION: { result = ParseFunctionDeclaration(false, memberModifiers); ES2PANDA_ASSERT(result != nullptr); diff --git a/ets2panda/parser/ETSparserTypes.cpp b/ets2panda/parser/ETSparserTypes.cpp index b2da373d7fed73c1471bb15fa7fcc69bf92e8057..fc82ce37bf3bcfdf7657c325f745f9a730f5357d 100644 --- a/ets2panda/parser/ETSparserTypes.cpp +++ b/ets2panda/parser/ETSparserTypes.cpp @@ -250,7 +250,7 @@ ir::TypeNode *ETSParser::ParseETSTupleType(TypeAnnotationParsingOptions *const o ArenaVector tupleTypeList(Allocator()->Adapter()); auto *const tupleType = AllocNode(Allocator()); - auto parseElem = [this, options, &tupleTypeList, &tupleType]() { + auto parseElem = [this, options, &tupleTypeList, &tupleType](bool &) { auto *const currentTypeAnnotation = ParseTypeAnnotation(options); if (currentTypeAnnotation == nullptr) { // Error processing. Lexer()->NextToken(); @@ -264,7 +264,8 @@ ir::TypeNode *ETSParser::ParseETSTupleType(TypeAnnotationParsingOptions *const o }; lexer::SourcePosition endLoc; - ParseList(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET, lexer::NextTokenFlags::NONE, parseElem, &endLoc, true); + ParseList(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET, lexer::NextTokenFlags::NONE, parseElem, &endLoc, + ParseListOptions::ALLOW_TRAILING_SEP); ES2PANDA_ASSERT(tupleType != nullptr); tupleType->SetTypeAnnotationsList(std::move(tupleTypeList)); diff --git a/ets2panda/parser/TypedParser.cpp b/ets2panda/parser/TypedParser.cpp index 64dc2383bc7e5e12726cc4b7c49469ab91c1a4be..d7a1834407264781a3745bca70895a5f129c55bb 100644 --- a/ets2panda/parser/TypedParser.cpp +++ b/ets2panda/parser/TypedParser.cpp @@ -669,7 +669,7 @@ ir::TSEnumDeclaration *TypedParser::ParseEnumMembers(ir::Identifier *key, const lexer::SourcePosition endLoc; ParseList( lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::KEYWORD_TO_IDENT, - [this, &members]() { + [this, &members](bool &) { ir::Expression *memberKey = nullptr; if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { @@ -700,7 +700,7 @@ ir::TSEnumDeclaration *TypedParser::ParseEnumMembers(ir::Identifier *key, const members.push_back(member); return true; }, - &endLoc, true); + &endLoc, ParseListOptions::ALLOW_TRAILING_SEP); auto *enumDeclaration = AllocNode(Allocator(), key, std::move(members), diff --git a/ets2panda/parser/expressionParser.cpp b/ets2panda/parser/expressionParser.cpp index 6d111ce34ace4c3348ba058e12bf2ad0e88774d0..57fae67e1eb1a3e9cd2a9076f48d6119f975f43f 100644 --- a/ets2panda/parser/expressionParser.cpp +++ b/ets2panda/parser/expressionParser.cpp @@ -182,7 +182,7 @@ ir::ArrayExpression *ParserImpl::ParseArrayExpression(ExpressionParseFlags flags lexer::SourcePosition endLoc; ParseList( lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET, lexer::NextTokenFlags::NONE, - [this, inPattern, startLoc, allowOmitted, &elements, &trailingComma]() { + [this, inPattern, startLoc, allowOmitted, &elements, &trailingComma](bool &) { if (allowOmitted && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA) { auto *omitted = AllocNode(); omitted->SetRange(lexer_->GetToken().Loc()); @@ -204,7 +204,7 @@ ir::ArrayExpression *ParserImpl::ParseArrayExpression(ExpressionParseFlags flags trailingComma = ParseArrayExpressionRightBracketHelper(containsRest, startLoc); return true; }, - &endLoc, true); + &endLoc, ParseListOptions::ALLOW_TRAILING_SEP); auto nodeType = inPattern ? ir::AstNodeType::ARRAY_PATTERN : ir::AstNodeType::ARRAY_EXPRESSION; auto *arrayExpressionNode = @@ -806,7 +806,7 @@ ir::Expression *ParserImpl::ParseNewExpression() // parse argument part of NewExpression ParseList( lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS, lexer::NextTokenFlags::NONE, - [this, &arguments]() { + [this, &arguments](bool &) { ir::Expression *argument = nullptr; if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { @@ -817,7 +817,7 @@ ir::Expression *ParserImpl::ParseNewExpression() arguments.push_back(argument); return true; }, - &endLoc, true); + &endLoc, ParseListOptions::ALLOW_TRAILING_SEP); auto *newExprNode = AllocNode(callee, std::move(arguments)); ES2PANDA_ASSERT(newExprNode != nullptr); @@ -1381,7 +1381,7 @@ ArenaVector ParserImpl::ParseCallExpressionArguments(bool &tra } else { ParseList( lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS, lexer::NextTokenFlags::NONE, - [this, &trailingComma, &arguments]() { + [this, &trailingComma, &arguments](bool &) { trailingComma = false; ir::Expression *argument {}; if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { @@ -1396,7 +1396,7 @@ ArenaVector ParserImpl::ParseCallExpressionArguments(bool &tra } return true; }, - &endLoc, true); + &endLoc, ParseListOptions::ALLOW_TRAILING_SEP); } return arguments; diff --git a/ets2panda/parser/parserImpl.cpp b/ets2panda/parser/parserImpl.cpp index a96e0eabc0c24a277eca86cb4321ee72c33375be..58fa03fa549c94a2b4abafbda6a3fcef9851c2ce 100644 --- a/ets2panda/parser/parserImpl.cpp +++ b/ets2panda/parser/parserImpl.cpp @@ -898,7 +898,7 @@ ArenaVector ParserImpl::ParseFunctionParams() ArenaVector params(Allocator()->Adapter()); - auto parseFunc = [this, ¶ms]() { + auto parseFunc = [this, ¶ms](bool &) { ir::Expression *parameter = ParseFunctionParameter(); if (parameter == nullptr) { return false; @@ -933,7 +933,7 @@ ArenaVector ParserImpl::ParseFunctionParams() params = std::move(ParseExpressionsArrayFormatPlaceholder()); } else { ParseList(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS, lexer::NextTokenFlags::NONE, parseFunc, nullptr, - true); + ParseListOptions::ALLOW_TRAILING_SEP); } return params; @@ -1496,16 +1496,45 @@ bool ParserImpl::CheckModuleAsModifier() return true; } +bool ParserImpl::NextIsTypeKeyword(bool eatTypeKeyword) +{ + bool res = false; + auto posBeforeTypeKw = Lexer()->Save(); + lexer::LexerPosition posAfterTypeKw = posBeforeTypeKw; + if (Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_TYPE)) { + posAfterTypeKw = Lexer()->Save(); + res = !(Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_AS) || + Lexer()->TryEatTokenKeyword(lexer::TokenType::KEYW_FROM) || + Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COMMA) || + Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE)); + } else { + res = false; + } + + if (res && eatTypeKeyword) { + Lexer()->Rewind(posAfterTypeKw); + } else { + Lexer()->Rewind(posBeforeTypeKw); + } + return res; +} + bool ParserImpl::ParseList(std::optional termToken, lexer::NextTokenFlags flags, - const std::function &parseElement, lexer::SourcePosition *sourceEnd, - bool allowTrailingSep) + const std::function &parseElement, + lexer::SourcePosition *sourceEnd, ParseListOptions parseListOptions) { bool success = true; + bool allowTypeKeyword = (parseListOptions & ParseListOptions::ALLOW_TYPE_KEYWORD) != 0U; auto sep = lexer::TokenType::PUNCTUATOR_COMMA; + bool typeKeywordOnSpecifier = false; while (Lexer()->GetToken().Type() != termToken && Lexer()->GetToken().Type() != lexer::TokenType::EOS) { // ErrorRecursionGuard is not feasible because we can break without consuming any tokens + if (allowTypeKeyword && NextIsTypeKeyword(true)) { + typeKeywordOnSpecifier = true; + continue; + } auto savedPos = lexer_->Save(); - auto elemSuccess = parseElement(); + auto elemSuccess = parseElement(typeKeywordOnSpecifier); bool hasSep = false; if (Lexer()->GetToken().Type() == sep) { Lexer()->NextToken(flags); @@ -1520,7 +1549,7 @@ bool ParserImpl::ParseList(std::optional termToken, lexer::Nex continue; } if (termToken == Lexer()->GetToken().Type() || (!termToken.has_value() && !hasSep)) { - if (hasSep && !allowTrailingSep) { + if (hasSep && (parseListOptions & ParseListOptions::ALLOW_TRAILING_SEP) == 0U) { LogError(diagnostic::TRAILING_COMMA_NOT_ALLOWED); } break; diff --git a/ets2panda/parser/parserImpl.h b/ets2panda/parser/parserImpl.h index cd39352b1d1015be72c794a3ccb5842142086e0e..3cdaf18a3a476a0ca6a33e3315af01f2a09cd256 100644 --- a/ets2panda/parser/parserImpl.h +++ b/ets2panda/parser/parserImpl.h @@ -69,6 +69,12 @@ enum class TypeAnnotationParsingOptions : uint32_t { TYPE_ALIAS_CONTEXT = 1U << 19U }; +enum class ParseListOptions : uint32_t { + NO_OPT = 0U, + ALLOW_TRAILING_SEP = 1U << 0U, + ALLOW_TYPE_KEYWORD = 1U << 1U, +}; + class ParserImpl { public: explicit ParserImpl(Program *program, const util::Options *options, util::DiagnosticEngine &diagnosticEngine, @@ -581,9 +587,11 @@ protected: return classId_; } + bool NextIsTypeKeyword(bool eatTypeKeyword = false); bool ParseList(std::optional termToken, lexer::NextTokenFlags flags, - const std::function &parseElement, lexer::SourcePosition *sourceEnd = nullptr, - bool allowTrailingSep = false); + const std::function &parseElement, + lexer::SourcePosition *sourceEnd = nullptr, + ParseListOptions parseListOptions = ParseListOptions::NO_OPT); RecursiveContext &RecursiveCtx() { @@ -608,4 +616,8 @@ template <> struct enumbitops::IsAllowedType : std::true_type { }; +template <> +struct enumbitops::IsAllowedType : std::true_type { +}; + #endif diff --git a/ets2panda/parser/statementParser.cpp b/ets2panda/parser/statementParser.cpp index 1a490f379b30ea32b4d6bada6c36e8077bb00f5b..915bc7bcba82c29ced2cc04a2542176818ed00be 100644 --- a/ets2panda/parser/statementParser.cpp +++ b/ets2panda/parser/statementParser.cpp @@ -1749,7 +1749,7 @@ ir::ExportNamedDeclaration *ParserImpl::ParseExportNamedSpecifiers(const lexer:: ParseList( lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::KEYWORD_TO_IDENT, - [this, &specifiers]() { + [this, &specifiers](bool &) { if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { // test exists for ts extension only LogExpectedToken(lexer::TokenType::LITERAL_IDENT); @@ -1778,7 +1778,7 @@ ir::ExportNamedDeclaration *ParserImpl::ParseExportNamedSpecifiers(const lexer:: } return true; }, - &endPos, true); + &endPos, ParseListOptions::ALLOW_TRAILING_SEP); ir::StringLiteral *source = nullptr; @@ -1921,7 +1921,7 @@ void ParserImpl::ParseNamedImportSpecifiers(ArenaVector *specifie ParseList( lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::KEYWORD_TO_IDENT, - [this, specifiers]() { + [this, specifiers](bool &) { if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { // test exists for ts extension only LogExpectedToken(lexer::TokenType::LITERAL_IDENT); @@ -1947,7 +1947,7 @@ void ParserImpl::ParseNamedImportSpecifiers(ArenaVector *specifie specifiers->push_back(specifier); return true; }, - nullptr, true); + nullptr, ParseListOptions::ALLOW_TRAILING_SEP); } ir::AstNode *ParserImpl::ParseImportDefaultSpecifier(ArenaVector *specifiers) diff --git a/ets2panda/test/ast/parser/ets/type_export_import/type_kw_on_identifiers/export.ets b/ets2panda/test/ast/parser/ets/type_export_import/type_kw_on_identifiers/export.ets new file mode 100644 index 0000000000000000000000000000000000000000..c9e6a3d14b282d27e55a8ac0681c6fdfa9d74997 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/type_export_import/type_kw_on_identifiers/export.ets @@ -0,0 +1,53 @@ +/* + * 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. + */ + +export { A, B } +export type { C, D } +export { type E } +export { F, type G } +export { type H, type I } +export { J, K, type L } + +export {type a as default}; +export type { type /* @@ first */M, N } // expect: CTE +export type { O, type /* @@ second */P } // expect: CTE +export type { type /* @@ third */Q, type /* @@ fourth */R } // expect: CTE + +class A {} +class B {} +class C {} +class D {} +class E {} +class F {} +class G {} +class H {} +class I {} +class J {} +class K {} +class L {} +class M {} +class N {} +class O {} +class P {} +class Q {} +class R {} + +let a = 0; + + +/* @@@ first Error SyntaxError: Type keyword set on both the specifier list and on the specifier itself. */ +/* @@@ second Error SyntaxError: Type keyword set on both the specifier list and on the specifier itself. */ +/* @@@ third Error SyntaxError: Type keyword set on both the specifier list and on the specifier itself. */ +/* @@@ fourth Error SyntaxError: Type keyword set on both the specifier list and on the specifier itself. */ diff --git a/ets2panda/test/ast/parser/ets/type_export_import/type_kw_on_identifiers/import.ets b/ets2panda/test/ast/parser/ets/type_export_import/type_kw_on_identifiers/import.ets new file mode 100644 index 0000000000000000000000000000000000000000..a902fe01f1f5b6f6f04dba6cc0c500f08e7b7d40 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/type_export_import/type_kw_on_identifiers/import.ets @@ -0,0 +1,39 @@ +/* + * 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. + */ + + +import { A, B } from "./source" +import type { C, D } from "./source" +import { type E } from "./source" +import { F, type G } from "./source" +import { type H, type I } from "./source" +import { J, K, type L } from "./source" + +import d from "./source" +import type dd from "./source" +import {type default as ddd} from "./source" +import {type default as type} from "./source"; + +import type { type /* @@ first */M, N } from "./source" // expect: CTE +import type { O, type /* @@ second */P } from "./source" // expect: CTE +import type { type /* @@ third */Q, type /* @@ fourth */R } from "./source" // expect: CTE + +import type {type /* @@ fifth */default as DD} from "./source" + +/* @@@ first Error SyntaxError: Type keyword set on both the specifier list and on the specifier itself. */ +/* @@@ second Error SyntaxError: Type keyword set on both the specifier list and on the specifier itself. */ +/* @@@ third Error SyntaxError: Type keyword set on both the specifier list and on the specifier itself. */ +/* @@@ fourth Error SyntaxError: Type keyword set on both the specifier list and on the specifier itself. */ +/* @@@ fifth Error SyntaxError: Type keyword set on both the specifier list and on the specifier itself. */ diff --git a/ets2panda/test/ast/parser/ets/type_export_import/type_kw_on_identifiers/source.ets b/ets2panda/test/ast/parser/ets/type_export_import/type_kw_on_identifiers/source.ets new file mode 100644 index 0000000000000000000000000000000000000000..205045ba8fa4ae75c02f37cc888bc3de13220748 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/type_export_import/type_kw_on_identifiers/source.ets @@ -0,0 +1,37 @@ +/* + * 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. + */ + +export class A {} +export class B {} +export class C {} +export class D {} +export class E {} +export class F {} +export class G {} +export class H {} +export class I {} +export class J {} +export class K {} +export class L {} +export class M {} +export class N {} +export class O {} +export class P {} +export class Q {} +export class R {} + +export default d; + +let d = 0; \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/user_defined_23.ets b/ets2panda/test/ast/parser/ets/user_defined_23.ets index efb6979bc61e44de27990bbd37e84816bf8ad7ad..b52d29ebb8eecb3149136958b5169cb897b273bb 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_23.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_23.ets @@ -16,5 +16,3 @@ class /* @@ label */type { type: number = 0 } - -/* @@@ label Error SyntaxError: Cannot be used as user-defined type. */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_24.ets b/ets2panda/test/ast/parser/ets/user_defined_24.ets index fb94fe840a90385d19360ff6623d2612fba52c2e..27b9a6925034178688d8673577af707325f49530 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_24.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_24.ets @@ -17,5 +17,4 @@ struct type { type: number = 0 } -/* @@? 16:8 Error SyntaxError: Cannot be used as user-defined type. */ /* @@? 16:1 Error TypeError: Structs are only used to define UI components, it should be translated at 'plugin after parser' phase. */ diff --git a/ets2panda/test/ast/parser/ets/user_defined_25.ets b/ets2panda/test/ast/parser/ets/user_defined_25.ets index a51079cba2b300ed2602e782961485091f370491..d4257332494074368391191102c05c55b1216402 100644 --- a/ets2panda/test/ast/parser/ets/user_defined_25.ets +++ b/ets2panda/test/ast/parser/ets/user_defined_25.ets @@ -17,7 +17,6 @@ interface /* @@ label1 */type { type: number /* @@ label2 */= /* @@ label3 */0 /* @@ label4 */} -/* @@@ label1 Error SyntaxError: Cannot be used as user-defined type. */ /* @@@ label2 Error SyntaxError: Interface member initialization is prohibited. */ /* @@@ label3 Error SyntaxError: Unexpected token, expected ','. */ /* @@? 17:48 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_0/main.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_0/main.ets new file mode 100644 index 0000000000000000000000000000000000000000..7beb2573b41560c77a21fa7fea8c19c0e0b0a880 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_0/main.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ + +/*--- +files: ['./source.ets'] +---*/ + +import type type from "./source" + +function main() { + let t = new type() + arktest.assertEQ(t.a, 0) +} diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_0/source.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_0/source.ets new file mode 100644 index 0000000000000000000000000000000000000000..e1c604f363424c2acd08bb14c77269215d900dec --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_0/source.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ + + +/*--- +tags: [not-a-test] +---*/ + +export default type + +class type { + a = 0 +} diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_1/main.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_1/main.ets new file mode 100644 index 0000000000000000000000000000000000000000..a32f495fa91557695f3dd9051c029b2776076143 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_1/main.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ + +/*--- +files: ['./source.ets'] +---*/ + +import type from "./source" + +function main() { + let t = new type() + arktest.assertEQ(t.a, 0) +} diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_1/source.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_1/source.ets new file mode 100644 index 0000000000000000000000000000000000000000..b57d7f2111802dc2991d27705a392a6f92ae0f72 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_1/source.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + +/*--- +tags: [not-a-test] +---*/ + +export default A + +class A { + a = 0 +} diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_2/main.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_2/main.ets new file mode 100644 index 0000000000000000000000000000000000000000..650cf2b77c029d0f6e3d51228823c957e43c7d72 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_2/main.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ + +/*--- +files: ['./source.ets'] +---*/ + +import {type} from "./source" + +function main() { + let b = type + arktest.assertEQ(b, 0) +} diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_2/source.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_2/source.ets new file mode 100644 index 0000000000000000000000000000000000000000..b4185ca92acdeb8a7500cb04ce30a00a5fcc473e --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_2/source.ets @@ -0,0 +1,23 @@ +/* + * 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. + */ + +/*--- +tags: [not-a-test] +---*/ + +export {a as type} + +let a = 0 +let type = 1 diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_3/main.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_3/main.ets new file mode 100644 index 0000000000000000000000000000000000000000..786813dd01ddfc822ca663ca678a83db4056036e --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_3/main.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ + +/*--- +files: ['./source.ets'] +---*/ + +import {a as type} from "./source" + +function main() { + let b = type + arktest.assertEQ(b, 0) +} diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_3/source.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_3/source.ets new file mode 100644 index 0000000000000000000000000000000000000000..149401f2353fe799b20041040f5780ff59c02279 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_3/source.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +/*--- +tags: [not-a-test] +---*/ + +export {type as a} + +let type = 0 diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_4/main.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_4/main.ets new file mode 100644 index 0000000000000000000000000000000000000000..cb8a5719f9a5e97c6c9a076c3b1609074834de3c --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_4/main.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ + +/*--- +files: ['./source.ets'] +---*/ + +import * as type from "./source" + +function main() { + let b = type.type + arktest.assertEQ(b, 0) +} diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_4/source.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_4/source.ets new file mode 100644 index 0000000000000000000000000000000000000000..02a0223239144e2d35fa6cdff49c5aa9ef36dc05 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_4/source.ets @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/*--- +tags: [not-a-test] +---*/ + +export let type = 0 diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_5/main.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_5/main.ets new file mode 100644 index 0000000000000000000000000000000000000000..12f5a63e702d3299bea6b0ae0c804f6eff951c33 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_5/main.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + +/*--- +files: ['./source.ets'] +---*/ + +import {default as a} from "./source" + +function main() { + arktest.assertEQ(a, "type") +} diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_5/source.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_5/source.ets new file mode 100644 index 0000000000000000000000000000000000000000..61785226f00b92484a89d9bdebc3eb12d27def88 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_5/source.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +/*--- +tags: [not-a-test] +---*/ + +export default type + +let type = "type" diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_6/main.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_6/main.ets new file mode 100644 index 0000000000000000000000000000000000000000..c8020ac7b3b401645c51a8dc99d8bfc892d0e48b --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_6/main.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + +/*--- +files: ['./source.ets'] +---*/ + +import {a, b, type, c } from "./source" + +function main() { + arktest.assertEQ(a + b + type + c, 6) +} diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_6/source.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_6/source.ets new file mode 100644 index 0000000000000000000000000000000000000000..f1e147e348f4a65f246f14b249beb2b5b046a109 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_6/source.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ + +/*--- +tags: [not-a-test] +---*/ + +export {a, b, type, c } + +let type = 0 +let a = 1 +let b = 2 +let c = 3 diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_7/main.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_7/main.ets new file mode 100644 index 0000000000000000000000000000000000000000..62634ba23d6e601e7814ffe04783f178b2522860 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_7/main.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + +/*--- +files: ['./source.ets'] +---*/ + +import * as type from "./source" + +function main() { + arktest.assertEQ(type.type.type, 1234) +} diff --git a/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_7/source.ets b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_7/source.ets new file mode 100644 index 0000000000000000000000000000000000000000..ce77db6e54b44e6da61392f2951d991f201ce836 --- /dev/null +++ b/ets2panda/test/runtime/ets/type_soft_keyword/in_import_export/test_7/source.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + + /*--- +tags: [not-a-test] +---*/ + +export namespace type { + export const type = 1234 +} diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index 6ceffd61d75754163aecf4eeb1110c15ddf32d46..0b38f11c500387a9e1c800058e5a2e454d4eb69b 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -1031,6 +1031,10 @@ syntax: id: 237 message: "Readonly utility type expected but readonly found." +- name: REPEATED_TYPE_KEYWORD + id: 135857 + message: "Type keyword set on both the specifier list and on the specifier itself." + - name: REQUIRED_PARAM_AFTER_DEFAULT id: 14 message: "Required parameter follows default parameter(s)."