diff --git a/ets2panda/compiler/lowering/ets/ambientLowering.cpp b/ets2panda/compiler/lowering/ets/ambientLowering.cpp index 99f86069d8f2a86b243bb2c57191bfe0c25a787a..9609e91605fdf3c17e7490f11d3246f749883e0b 100644 --- a/ets2panda/compiler/lowering/ets/ambientLowering.cpp +++ b/ets2panda/compiler/lowering/ets/ambientLowering.cpp @@ -56,6 +56,7 @@ ir::MethodDefinition *CreateMethodFunctionDefinition(ir::DummyNode *node, public ir::MethodDefinitionKind funcKind) { auto parser = ctx->parser->AsETSParser(); + auto allocator = ctx->allocator; auto indexName = node->GetIndexName(); if (node->IsBrokenStatement()) { @@ -65,17 +66,18 @@ ir::MethodDefinition *CreateMethodFunctionDefinition(ir::DummyNode *node, public indexName = "_"; } std::string sourceCode; + if (funcKind == ir::MethodDefinitionKind::GET) { - sourceCode = "$_get(" + std::string(indexName) + - " : number) : " + std::string(node->GetReturnTypeLiteral()->DumpEtsSrc()); + sourceCode = "$_get (" + std::string(indexName) + " : @@T1) : @@T2 "; } else if (funcKind == ir::MethodDefinitionKind::SET) { - sourceCode = "$_set(" + std::string(indexName) + " : number, " + - "value : " + std::string(node->GetReturnTypeLiteral()->DumpEtsSrc()) + " ) : void"; + sourceCode = "$_set (" + std::string(indexName) + " : @@T1, value : @@T2) : void"; } else { ES2PANDA_UNREACHABLE(); } - auto methodDefinition = parser->CreateFormattedClassMethodDefinition(sourceCode); + auto methodDefinition = + parser->CreateFormattedClassMethodDefinition(sourceCode, node->IndexTypeAnno()->Clone(allocator, nullptr), + node->GetReturnTypeLiteral()->Clone(allocator, nullptr)); // NOTE(kaskov): #23399 It is temporary solution, we set default SourcePosition in all nodes in generated code compiler::SetSourceRangesRecursively(methodDefinition, node->Range()); diff --git a/ets2panda/ir/expressions/dummyNode.h b/ets2panda/ir/expressions/dummyNode.h index 2cc26c2559a46761941f557d77ae2f9415499220..5f6bf1037892fac28dd6e0279b4e6a574d09a9c8 100644 --- a/ets2panda/ir/expressions/dummyNode.h +++ b/ets2panda/ir/expressions/dummyNode.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -44,8 +44,13 @@ public: public: explicit DummyNode(util::StringView const name, util::StringView indexName, TypeNode *returnType, - DummyNodeFlag flag) - : AstNode(AstNodeType::DUMMYNODE), name_(name), indexName_(indexName), returnType_(returnType), flag_(flag) + DummyNodeFlag flag, TypeNode *indexTypeAnno = nullptr) + : AstNode(AstNodeType::DUMMYNODE), + name_(name), + indexName_(indexName), + returnType_(returnType), + indexTypeAnno_(indexTypeAnno), + flag_(flag) { } @@ -88,6 +93,11 @@ public: return name_; } + TypeNode *IndexTypeAnno() const + { + return indexTypeAnno_; + } + bool operator==(const DummyNode &node) const { return name_.Is(std::string(node.Name().Bytes())); @@ -111,6 +121,7 @@ private: util::StringView name_; util::StringView indexName_; TypeNode *returnType_; + TypeNode *indexTypeAnno_; DummyNodeFlag flag_ {DummyNodeFlag::NONE}; }; } // namespace ark::es2panda::ir diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 4fa885b8b2de7be6ef356dcc6767ee0c3e3eb953..bd6f5de076ca33d2e190e7cd7548eb1954f6e22d 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -2080,8 +2080,11 @@ ir::AstNode *ETSParser::ParseAmbientSignature(const lexer::SourcePosition &start Lexer()->GetToken().SetTokenType(lexer::TokenType::KEYW_NUMBER); } + TypeAnnotationParsingOptions typAnotationOptions = TypeAnnotationParsingOptions::NO_OPTS; + auto typeAnno = ParseTypeAnnotation(&typAnotationOptions); + // eat indexType - if (Lexer()->NextToken(); Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { + if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { // ambient_indexer_7.ets LogError(diagnostic::EXPECTED_BRACKETS_IN_INDEX); @@ -2107,7 +2110,7 @@ ir::AstNode *ETSParser::ParseAmbientSignature(const lexer::SourcePosition &start } auto dummyNode = AllocNode(compiler::Signatures::AMBIENT_INDEXER, indexName, returnType, - ir::DummyNodeFlag::INDEXER); + ir::DummyNodeFlag::INDEXER, typeAnno); ES2PANDA_ASSERT(dummyNode != nullptr); dummyNode->SetRange({startPos, Lexer()->GetToken().End()}); return dummyNode; diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_3.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_3.ets index c4f60ba8db373a47fe65087577a1826b8f7b66b1..efd4f356c643e8cf69cad05f4cdb27638295dc55 100644 --- a/ets2panda/test/ast/parser/ets/ambient_indexer_3.ets +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_3.ets @@ -14,11 +14,19 @@ */ declare class A { - [index : /* @@ label */string] : string + [index : string] : string } function main() { let a : A = new A(); } -/* @@@ label Error SyntaxError: Index type must be number in index signature. */ +/* @@? 17:14 Error SyntaxError: Index type must be number in index signature. */ +/* @@? 17:14 Error SyntaxError: ] expected in index signature. */ +/* @@? 17:20 Error SyntaxError: An index signature must have a type annotation. */ +/* @@? 17:20 Error SyntaxError: Expected ':', got ']'. */ +/* @@? 17:20 Error SyntaxError: Invalid Type. */ +/* @@? 17:20 Error SyntaxError: Return type of index signature from exported class or interface need to be identifier. */ +/* @@? 17:20 Error SyntaxError: Unexpected token ']'. */ +/* @@? 17:22 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:30 Error SyntaxError: Field type annotation expected. */ diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_8.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_8.ets index 6b4158eb99594372d193ca6a89fc47c71e1abb3a..62e5623e90ffa388b98664a0f462b1a359771abe 100644 --- a/ets2panda/test/ast/parser/ets/ambient_indexer_8.ets +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_8.ets @@ -15,16 +15,14 @@ declare class A { [index/* @@ label */] /* @@ label1 */: /* @@ label2 */string -/* @@ label3 */} +} function main() { let a : A = new A(); } -/* @@@ label Error SyntaxError: Index type expected in index signature. */ -/* @@@ label1 Error SyntaxError: Index type must be number in index signature. */ -/* @@@ label2 Error SyntaxError: ] expected in index signature. */ -/* @@@ label3 Error SyntaxError: An index signature must have a type annotation. */ -/* @@@ label3 Error SyntaxError: Expected ':', got '}'. */ -/* @@@ label3 Error SyntaxError: Invalid Type. */ -/* @@@ label3 Error SyntaxError: Return type of index signature from exported class or interface need to be identifier. */ +/* @@@ label Error SyntaxError: Index type expected in index signature. */ +/* @@@ label1 Error SyntaxError: Index type must be number in index signature. */ +/* @@@ label1 Error SyntaxError: ] expected in index signature. */ +/* @@@ label2 Error SyntaxError: An index signature must have a type annotation. */ +/* @@@ label2 Error SyntaxError: Expected ':', got 'identification literal'. */ diff --git a/ets2panda/test/ast/parser/ets/interface_ambient_indexer_2.ets b/ets2panda/test/ast/parser/ets/interface_ambient_indexer_2.ets index b8e57b5856ace9265904051f4df6c40303349890..6789f5f0985c114f39be7b3b0aaff4afdb74a515 100644 --- a/ets2panda/test/ast/parser/ets/interface_ambient_indexer_2.ets +++ b/ets2panda/test/ast/parser/ets/interface_ambient_indexer_2.ets @@ -17,4 +17,15 @@ declare interface A { [index : string]: string } -/* @@? 17:14 Error SyntaxError: Index type must be number in index signature. */ \ No newline at end of file +/* @@? 17:14 Error SyntaxError: Index type must be number in index signature. */ +/* @@? 17:14 Error SyntaxError: ] expected in index signature. */ +/* @@? 17:20 Error SyntaxError: An index signature must have a type annotation. */ +/* @@? 17:20 Error SyntaxError: Expected ':', got ']'. */ +/* @@? 17:20 Error SyntaxError: Invalid Type. */ +/* @@? 17:20 Error SyntaxError: Return type of index signature from exported class or interface need to be identifier. */ +/* @@? 17:20 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:20 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 17:21 Error SyntaxError: Identifier expected. */ +/* @@? 17:21 Error SyntaxError: Unexpected token, expected ','. */ +/* @@? 17:21 Error SyntaxError: Unexpected token, expected 'private' or identifier. */ +/* @@? 18:1 Error SyntaxError: Invalid Type. */