diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index c1af0bba703088d53378784046cc79f9e4a9fd07..343841808c01300a01a19245a5504ca59b7f4fc8 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -804,7 +804,15 @@ bool ParserImpl::IsTSNamedTupleMember() return isNamedMember; } -ir::Expression *ParserImpl::ParseTsTupleElement(ir::TSTupleKind *kind, bool *seenOptional) +void ParserImpl::HandleRestType(ir::AstNodeType elementType, bool *hasRestType) +{ + if (elementType == ir::AstNodeType::TS_ARRAY_TYPE && *hasRestType) { + ThrowSyntaxError("A rest element cannot follow another rest element"); + } + *hasRestType = true; +} + +ir::Expression *ParserImpl::ParseTsTupleElement(ir::TSTupleKind *kind, bool *seenOptional, bool *hasRestType) { lexer::SourcePosition startPos = lexer_->GetToken().Start(); ir::Expression *element = nullptr; @@ -843,6 +851,10 @@ ir::Expression *ParserImpl::ParseTsTupleElement(ir::TSTupleKind *kind, bool *see auto *elementType = ParseTsTypeAnnotation(&options); ASSERT(elementType != nullptr); + if (elementType && isRestType) { + HandleRestType(elementType->Type(), hasRestType); + } + element = AllocNode(elementIdent, elementType, isOptional, isRestType); element->SetRange({startPos, elementType->End()}); } else { @@ -854,6 +866,7 @@ ir::Expression *ParserImpl::ParseTsTupleElement(ir::TSTupleKind *kind, bool *see element = ParseTsTypeAnnotation(&options); ASSERT(element != nullptr); if (element && isRestType) { + HandleRestType(element->Type(), hasRestType); lexer::SourcePosition endPos = element->End(); element = AllocNode(std::move(element)); element->SetRange({startPos, endPos}); @@ -880,11 +893,12 @@ ir::TSTupleType *ParserImpl::ParseTsTupleType() ArenaVector elements(Allocator()->Adapter()); ir::TSTupleKind kind = ir::TSTupleKind::NONE; bool seenOptional = false; + bool hasRestType = false; lexer_->NextToken(); // eat '[' while (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET) { - ir::Expression *element = ParseTsTupleElement(&kind, &seenOptional); + ir::Expression *element = ParseTsTupleElement(&kind, &seenOptional, &hasRestType); elements.push_back(element); diff --git a/es2panda/parser/parserImpl.h b/es2panda/parser/parserImpl.h index fc1663e5e9896e5a37206eb8e04f5d10f6946299..aabaef718848f2d8f5baf3927872bdb7a44bbfd9 100644 --- a/es2panda/parser/parserImpl.h +++ b/es2panda/parser/parserImpl.h @@ -260,7 +260,8 @@ private: ir::Expression *ParseTsQualifiedReference(ir::Expression *typeName); ir::Expression *ParseTsTypeReferenceOrQuery(bool parseQuery = false); bool IsTSNamedTupleMember(); - ir::Expression *ParseTsTupleElement(ir::TSTupleKind *kind, bool *seenOptional); + void HandleRestType(ir::AstNodeType elementType, bool *hasRestType); + ir::Expression *ParseTsTupleElement(ir::TSTupleKind *kind, bool *seenOptional, bool *hasRestType); ir::TSTupleType *ParseTsTupleType(); ir::TSImportType *ParseTsImportType(const lexer::SourcePosition &startLoc, bool isTypeof = false); ir::Expression *ParseTsTypeAnnotation(TypeAnnotationParsingOptions *options); diff --git a/es2panda/test/parser/ts/test-tuple-type10-expected.txt b/es2panda/test/parser/ts/test-tuple-type10-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..ba4c86b6c83b96675cae4151b6c63303c759ea47 --- /dev/null +++ b/es2panda/test/parser/ts/test-tuple-type10-expected.txt @@ -0,0 +1 @@ +SyntaxError: A rest element cannot follow another rest element [test-tuple-type10.ts:18:64] diff --git a/es2panda/test/parser/ts/test-tuple-type10.ts b/es2panda/test/parser/ts/test-tuple-type10.ts new file mode 100644 index 0000000000000000000000000000000000000000..938edf58d082459ca8039c98879b0e107786b705 --- /dev/null +++ b/es2panda/test/parser/ts/test-tuple-type10.ts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +type STRINGS = string[] +type WithMutipleRest4 = [...first: STRINGS, ...second: string[]]; \ No newline at end of file diff --git a/es2panda/test/parser/ts/test-tuple-type7-expected.txt b/es2panda/test/parser/ts/test-tuple-type7-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..01ff5953ca50db5e3ef0fa5b09435589bdce90a1 --- /dev/null +++ b/es2panda/test/parser/ts/test-tuple-type7-expected.txt @@ -0,0 +1 @@ +SyntaxError: A rest element cannot follow another rest element [test-tuple-type7.ts:17:78] diff --git a/es2panda/test/parser/ts/test-tuple-type7.ts b/es2panda/test/parser/ts/test-tuple-type7.ts new file mode 100644 index 0000000000000000000000000000000000000000..33417a6b9d302c89206cf7a91542fa6fdb4546fa --- /dev/null +++ b/es2panda/test/parser/ts/test-tuple-type7.ts @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +type WithMutipleRest = [first: number, ...rest1: string[], ...rest2: string[]]; \ No newline at end of file diff --git a/es2panda/test/parser/ts/test-tuple-type8-expected.txt b/es2panda/test/parser/ts/test-tuple-type8-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..4d9d3bfe297b36d11c0979f2bbe630d6e85b72d1 --- /dev/null +++ b/es2panda/test/parser/ts/test-tuple-type8-expected.txt @@ -0,0 +1 @@ +SyntaxError: A rest element cannot follow another rest element [test-tuple-type8.ts:17:50] diff --git a/es2panda/test/parser/ts/test-tuple-type8.ts b/es2panda/test/parser/ts/test-tuple-type8.ts new file mode 100644 index 0000000000000000000000000000000000000000..1d2c7bd83c8d6df99da7af5ee2836db32c6034d3 --- /dev/null +++ b/es2panda/test/parser/ts/test-tuple-type8.ts @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +type WithMutipleRest2 = [...number[], ...string[]]; \ No newline at end of file diff --git a/es2panda/test/parser/ts/test-tuple-type9-expected.txt b/es2panda/test/parser/ts/test-tuple-type9-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..2b1decffb7a817ad848ece9aa21a19a080028fd7 --- /dev/null +++ b/es2panda/test/parser/ts/test-tuple-type9-expected.txt @@ -0,0 +1 @@ +SyntaxError: A rest element cannot follow another rest element [test-tuple-type9.ts:18:52] diff --git a/es2panda/test/parser/ts/test-tuple-type9.ts b/es2panda/test/parser/ts/test-tuple-type9.ts new file mode 100644 index 0000000000000000000000000000000000000000..435b8ef0c409c5eeb60c23c2346be2c484a3f27d --- /dev/null +++ b/es2panda/test/parser/ts/test-tuple-type9.ts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +type NUMBERSARR = number[] +type WithMutipleRest3 = [...NUMBERSARR, ...string[]]; \ No newline at end of file