From c7a7dd119adfbd036cf3d26b2c9391c8fab4681a Mon Sep 17 00:00:00 2001 From: zengyuan Date: Mon, 24 Oct 2022 16:24:27 +0800 Subject: [PATCH] Fix bug of multiple rest elements in tuple Description: Support to report the error when a rest element follows another rest element in tuple. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I5XJCX Signed-off-by: zengyuan Change-Id: Ic3ca4c4ac049385d5e6d278b8d07c14f809b7f0b --- es2panda/parser/parserImpl.cpp | 18 ++++++++++++++++-- es2panda/parser/parserImpl.h | 3 ++- .../parser/ts/test-tuple-type10-expected.txt | 1 + es2panda/test/parser/ts/test-tuple-type10.ts | 18 ++++++++++++++++++ .../parser/ts/test-tuple-type7-expected.txt | 1 + es2panda/test/parser/ts/test-tuple-type7.ts | 17 +++++++++++++++++ .../parser/ts/test-tuple-type8-expected.txt | 1 + es2panda/test/parser/ts/test-tuple-type8.ts | 17 +++++++++++++++++ .../parser/ts/test-tuple-type9-expected.txt | 1 + es2panda/test/parser/ts/test-tuple-type9.ts | 18 ++++++++++++++++++ 10 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 es2panda/test/parser/ts/test-tuple-type10-expected.txt create mode 100644 es2panda/test/parser/ts/test-tuple-type10.ts create mode 100644 es2panda/test/parser/ts/test-tuple-type7-expected.txt create mode 100644 es2panda/test/parser/ts/test-tuple-type7.ts create mode 100644 es2panda/test/parser/ts/test-tuple-type8-expected.txt create mode 100644 es2panda/test/parser/ts/test-tuple-type8.ts create mode 100644 es2panda/test/parser/ts/test-tuple-type9-expected.txt create mode 100644 es2panda/test/parser/ts/test-tuple-type9.ts diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index c1af0bba70..343841808c 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 fc1663e5e9..aabaef7188 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 0000000000..ba4c86b6c8 --- /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 0000000000..938edf58d0 --- /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 0000000000..01ff5953ca --- /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 0000000000..33417a6b9d --- /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 0000000000..4d9d3bfe29 --- /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 0000000000..1d2c7bd83c --- /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 0000000000..2b1decffb7 --- /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 0000000000..435b8ef0c4 --- /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 -- Gitee