From 9089a0f23da86226ba7f348de8f286067fcd25ed Mon Sep 17 00:00:00 2001 From: songqi Date: Sun, 8 Oct 2023 12:09:17 +0800 Subject: [PATCH 1/2] Support Symbol and Template String Pattern Index Signatures Issue: I863NM Tests: test_es2abc Signed-off-by: songqi Change-Id: If9666937c1ea85c8b1573bb55286d05aa5475f5f --- es2panda/parser/parserImpl.cpp | 35 +- es2panda/parser/parserImpl.h | 1 + .../ts/test-indexSignature1-expected.txt | 1177 +++++++++++++++++ .../test/parser/ts/test-indexSignature1.ts | 38 + .../ts/test-indexSignature2-expected.txt | 1 + .../test/parser/ts/test-indexSignature2.ts | 19 + 6 files changed, 1261 insertions(+), 10 deletions(-) create mode 100644 es2panda/test/parser/ts/test-indexSignature1-expected.txt create mode 100644 es2panda/test/parser/ts/test-indexSignature1.ts create mode 100644 es2panda/test/parser/ts/test-indexSignature2-expected.txt create mode 100644 es2panda/test/parser/ts/test-indexSignature2.ts diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index 1a8d74c040..5fb0d13cac 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -1320,11 +1320,7 @@ ir::Expression *ParserImpl::ParseTsTypeLiteralOrInterfaceKey(bool *computed, boo TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; ir::Expression *typeAnnotation = ParseTsTypeAnnotation(&options); - if (!typeAnnotation->IsTSNumberKeyword() && !typeAnnotation->IsTSStringKeyword()) { - ThrowSyntaxError( - "An index signature parameter type must be either " - "'string' or 'number'"); - } + ValidateIndexSignatureParameterType(typeAnnotation); key->SetTsTypeAnnotation(typeAnnotation); } else { @@ -1347,6 +1343,29 @@ ir::Expression *ParserImpl::ParseTsTypeLiteralOrInterfaceKey(bool *computed, boo return key; } +void ParserImpl::ValidateIndexSignatureParameterType(ir::Expression *typeAnnotation) +{ + // The verification of TSTypeReference is wide-ranging because the specific type it refers to cannot be determined. + if (!typeAnnotation->IsTSStringKeyword() && !typeAnnotation->IsTSNumberKeyword() && + !typeAnnotation->IsTSSymbolKeyword() && !typeAnnotation->IsTSTemplateLiteralType() && + !typeAnnotation->IsTSUnionType() && !typeAnnotation->IsTSTypeReference()) { + ThrowSyntaxError( + "An index signature parameter type must be 'string', 'number', 'symbol', " + "or a template literal type."); + } + + if (typeAnnotation->IsTSUnionType()) { + for (auto *it : typeAnnotation->AsTSUnionType()->Types()) { + if (!it->IsTSStringKeyword() && !it->IsTSNumberKeyword() && !it->IsTSSymbolKeyword() && + !it->IsTSTemplateLiteralType() && !it->IsTSTypeReference()) { + ThrowSyntaxError( + "An index signature parameter type must be 'string', 'number', 'symbol', " + "or a template literal type."); + } + } + } +} + void ParserImpl::CreateTSVariableForProperty(ir::AstNode *node, const ir::Expression *key, binder::VariableFlags flags) { binder::Variable *propVar = nullptr; @@ -2283,11 +2302,7 @@ ir::Expression *ParserImpl::ParseClassKey(ClassElmentDescriptor *desc, bool isDe TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::THROW_ERROR; ir::Expression *typeAnnotation = ParseTsTypeAnnotation(&options); - if (!typeAnnotation->IsTSNumberKeyword() && !typeAnnotation->IsTSStringKeyword()) { - ThrowSyntaxError( - "An index signature parameter type must be either " - "'string' or 'number'"); - } + ValidateIndexSignatureParameterType(typeAnnotation); propName->SetTsTypeAnnotation(typeAnnotation); diff --git a/es2panda/parser/parserImpl.h b/es2panda/parser/parserImpl.h index 7b026849e8..b0c28c908a 100644 --- a/es2panda/parser/parserImpl.h +++ b/es2panda/parser/parserImpl.h @@ -262,6 +262,7 @@ private: ir::TSMappedType *ParseTsMappedType(); ir::TSTypePredicate *ParseTsTypePredicate(); ir::Expression *ParseTsTypeLiteralOrInterfaceKey(bool *computed, bool *signature, bool *isIndexSignature); + void ValidateIndexSignatureParameterType(ir::Expression *typeAnnotation); ir::Expression *ParseTsConditionalType(ir::Expression *checkType, bool restrictExtends); ir::Expression *ParseTsTypeLiteralOrInterfaceMember(); ArenaVector ParseTsTypeLiteralOrInterface(); diff --git a/es2panda/test/parser/ts/test-indexSignature1-expected.txt b/es2panda/test/parser/ts/test-indexSignature1-expected.txt new file mode 100644 index 0000000000..eb25553b18 --- /dev/null +++ b/es2panda/test/parser/ts/test-indexSignature1-expected.txt @@ -0,0 +1,1177 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 17, + "column": 6 + }, + "end": { + "line": 17, + "column": 7 + } + } + }, + "typeAnnotation": { + "type": "TSSymbolKeyword", + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 17, + "column": 17 + } + } + }, + { + "type": "TSModuleDeclaration", + "id": { + "type": "Identifier", + "name": "ns", + "loc": { + "start": { + "line": 19, + "column": 11 + }, + "end": { + "line": 19, + "column": 13 + } + } + }, + "body": { + "type": "TSModuleBlock", + "body": [ + { + "type": "ExportNamedDeclaration", + "declaration": { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 20, + "column": 18 + } + } + }, + "typeAnnotation": { + "type": "TSStringKeyword", + "loc": { + "start": { + "line": 20, + "column": 21 + }, + "end": { + "line": 20, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 12 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "source": null, + "specifiers": [], + "loc": { + "start": { + "line": 20, + "column": 5 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "declare": false, + "global": false, + "loc": { + "start": { + "line": 19, + "column": 1 + }, + "end": { + "line": 23, + "column": 10 + } + } + }, + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [ + { + "type": "TSIndexSignature", + "parameters": { + "type": "Identifier", + "name": "k1", + "typeAnnotation": { + "type": "TSStringKeyword", + "loc": { + "start": { + "line": 24, + "column": 10 + }, + "end": { + "line": 24, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 6 + }, + "end": { + "line": 24, + "column": 8 + } + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 24, + "column": 19 + }, + "end": { + "line": 24, + "column": 26 + } + } + }, + "readonly": false, + "static": false, + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 27 + } + } + }, + { + "type": "TSIndexSignature", + "parameters": { + "type": "Identifier", + "name": "k2", + "typeAnnotation": { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 25, + "column": 10 + }, + "end": { + "line": 25, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 6 + }, + "end": { + "line": 25, + "column": 8 + } + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 25, + "column": 19 + }, + "end": { + "line": 25, + "column": 26 + } + } + }, + "readonly": false, + "static": false, + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 27 + } + } + }, + { + "type": "TSIndexSignature", + "parameters": { + "type": "Identifier", + "name": "k3", + "typeAnnotation": { + "type": "TSSymbolKeyword", + "loc": { + "start": { + "line": 26, + "column": 10 + }, + "end": { + "line": 26, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 6 + }, + "end": { + "line": 26, + "column": 8 + } + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 26, + "column": 19 + }, + "end": { + "line": 26, + "column": 26 + } + } + }, + "readonly": false, + "static": false, + "loc": { + "start": { + "line": 26, + "column": 5 + }, + "end": { + "line": 26, + "column": 27 + } + } + }, + { + "type": "TSIndexSignature", + "parameters": { + "type": "Identifier", + "name": "k4", + "typeAnnotation": { + "type": "TSTemplateLiteralType", + "references": [ + { + "type": "TSStringKeyword", + "loc": { + "start": { + "line": 27, + "column": 29 + }, + "end": { + "line": 27, + "column": 35 + } + } + } + ], + "quasis": [ + { + "type": "TemplateElement", + "value": { + "raw": "templateLiteral-", + "cooked": "templateLiteral-" + }, + "loc": { + "start": { + "line": 27, + "column": 11 + }, + "end": { + "line": 27, + "column": 27 + } + } + }, + { + "type": "TemplateElement", + "value": { + "raw": "", + "cooked": "" + }, + "loc": { + "start": { + "line": 27, + "column": 36 + }, + "end": { + "line": 27, + "column": 36 + } + } + } + ], + "loc": { + "start": { + "line": 27, + "column": 10 + }, + "end": { + "line": 27, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 6 + }, + "end": { + "line": 27, + "column": 8 + } + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 27, + "column": 40 + }, + "end": { + "line": 27, + "column": 47 + } + } + }, + "readonly": false, + "static": false, + "loc": { + "start": { + "line": 27, + "column": 5 + }, + "end": { + "line": 27, + "column": 48 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 14 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + "id": { + "type": "Identifier", + "name": "I1", + "loc": { + "start": { + "line": 23, + "column": 11 + }, + "end": { + "line": 23, + "column": 13 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 23, + "column": 1 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [ + { + "type": "TSIndexSignature", + "parameters": { + "type": "Identifier", + "name": "k1", + "typeAnnotation": { + "type": "TSUnionType", + "types": [ + { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 31, + "column": 10 + }, + "end": { + "line": 31, + "column": 16 + } + } + }, + { + "type": "TSTypeReference", + "typeName": { + "type": "TSQualifiedName", + "left": { + "type": "Identifier", + "name": "ns", + "loc": { + "start": { + "line": 31, + "column": 19 + }, + "end": { + "line": 31, + "column": 21 + } + } + }, + "right": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 31, + "column": 22 + }, + "end": { + "line": 31, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 19 + }, + "end": { + "line": 31, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 19 + }, + "end": { + "line": 31, + "column": 25 + } + } + }, + { + "type": "TSTypeReference", + "typeName": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 31, + "column": 26 + }, + "end": { + "line": 31, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 26 + }, + "end": { + "line": 31, + "column": 27 + } + } + } + ], + "loc": { + "start": { + "line": 31, + "column": 10 + }, + "end": { + "line": 31, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 31, + "column": 6 + }, + "end": { + "line": 31, + "column": 8 + } + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 31, + "column": 30 + }, + "end": { + "line": 31, + "column": 37 + } + } + }, + "readonly": false, + "static": false, + "loc": { + "start": { + "line": 31, + "column": 5 + }, + "end": { + "line": 31, + "column": 38 + } + } + } + ], + "loc": { + "start": { + "line": 30, + "column": 14 + }, + "end": { + "line": 32, + "column": 2 + } + } + }, + "id": { + "type": "Identifier", + "name": "I2", + "loc": { + "start": { + "line": 30, + "column": 11 + }, + "end": { + "line": 30, + "column": 13 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 30, + "column": 1 + }, + "end": { + "line": 32, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "loc": { + "start": { + "line": 34, + "column": 7 + }, + "end": { + "line": 34, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "constructor": { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": null, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 34, + "column": 1 + }, + "end": { + "line": 36, + "column": 2 + } + } + }, + "body": [], + "indexSignatures": [ + { + "type": "TSIndexSignature", + "parameters": { + "type": "Identifier", + "name": "k1", + "typeAnnotation": { + "type": "TSUnionType", + "types": [ + { + "type": "TSStringKeyword", + "loc": { + "start": { + "line": 35, + "column": 10 + }, + "end": { + "line": 35, + "column": 16 + } + } + }, + { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 35, + "column": 19 + }, + "end": { + "line": 35, + "column": 25 + } + } + }, + { + "type": "TSSymbolKeyword", + "loc": { + "start": { + "line": 35, + "column": 28 + }, + "end": { + "line": 35, + "column": 34 + } + } + }, + { + "type": "TSTemplateLiteralType", + "references": [ + { + "type": "TSStringKeyword", + "loc": { + "start": { + "line": 35, + "column": 56 + }, + "end": { + "line": 35, + "column": 62 + } + } + } + ], + "quasis": [ + { + "type": "TemplateElement", + "value": { + "raw": "templateLiteral-", + "cooked": "templateLiteral-" + }, + "loc": { + "start": { + "line": 35, + "column": 38 + }, + "end": { + "line": 35, + "column": 54 + } + } + }, + { + "type": "TemplateElement", + "value": { + "raw": "", + "cooked": "" + }, + "loc": { + "start": { + "line": 35, + "column": 63 + }, + "end": { + "line": 35, + "column": 63 + } + } + } + ], + "loc": { + "start": { + "line": 35, + "column": 37 + }, + "end": { + "line": 35, + "column": 64 + } + } + } + ], + "loc": { + "start": { + "line": 35, + "column": 10 + }, + "end": { + "line": 35, + "column": 64 + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 6 + }, + "end": { + "line": 35, + "column": 8 + } + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 35, + "column": 67 + }, + "end": { + "line": 35, + "column": 74 + } + } + }, + "readonly": false, + "static": false, + "loc": { + "start": { + "line": 35, + "column": 5 + }, + "end": { + "line": 35, + "column": 74 + } + } + } + ], + "loc": { + "start": { + "line": 34, + "column": 9 + }, + "end": { + "line": 36, + "column": 2 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 34, + "column": 1 + }, + "end": { + "line": 36, + "column": 2 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": { + "type": "TSTypeLiteral", + "members": [ + { + "type": "TSIndexSignature", + "parameters": { + "type": "Identifier", + "name": "k", + "typeAnnotation": { + "type": "TSUnionType", + "types": [ + { + "type": "TSStringKeyword", + "loc": { + "start": { + "line": 38, + "column": 16 + }, + "end": { + "line": 38, + "column": 22 + } + } + }, + { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 38, + "column": 25 + }, + "end": { + "line": 38, + "column": 31 + } + } + }, + { + "type": "TSSymbolKeyword", + "loc": { + "start": { + "line": 38, + "column": 34 + }, + "end": { + "line": 38, + "column": 40 + } + } + }, + { + "type": "TSTemplateLiteralType", + "references": [ + { + "type": "TSStringKeyword", + "loc": { + "start": { + "line": 38, + "column": 62 + }, + "end": { + "line": 38, + "column": 68 + } + } + } + ], + "quasis": [ + { + "type": "TemplateElement", + "value": { + "raw": "templateLiteral-", + "cooked": "templateLiteral-" + }, + "loc": { + "start": { + "line": 38, + "column": 44 + }, + "end": { + "line": 38, + "column": 60 + } + } + }, + { + "type": "TemplateElement", + "value": { + "raw": "", + "cooked": "" + }, + "loc": { + "start": { + "line": 38, + "column": 69 + }, + "end": { + "line": 38, + "column": 69 + } + } + } + ], + "loc": { + "start": { + "line": 38, + "column": 43 + }, + "end": { + "line": 38, + "column": 70 + } + } + } + ], + "loc": { + "start": { + "line": 38, + "column": 16 + }, + "end": { + "line": 38, + "column": 70 + } + } + }, + "loc": { + "start": { + "line": 38, + "column": 13 + }, + "end": { + "line": 38, + "column": 14 + } + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 38, + "column": 73 + }, + "end": { + "line": 38, + "column": 80 + } + } + }, + "readonly": false, + "static": false, + "loc": { + "start": { + "line": 38, + "column": 12 + }, + "end": { + "line": 38, + "column": 82 + } + } + } + ], + "loc": { + "start": { + "line": 38, + "column": 10 + }, + "end": { + "line": 38, + "column": 82 + } + } + }, + "loc": { + "start": { + "line": 38, + "column": 7 + }, + "end": { + "line": 38, + "column": 8 + } + } + }, + "init": { + "type": "ObjectExpression", + "properties": [], + "loc": { + "start": { + "line": 38, + "column": 85 + }, + "end": { + "line": 38, + "column": 87 + } + } + }, + "loc": { + "start": { + "line": 38, + "column": 7 + }, + "end": { + "line": 38, + "column": 87 + } + } + } + ], + "kind": "const", + "loc": { + "start": { + "line": 38, + "column": 1 + }, + "end": { + "line": 38, + "column": 88 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 39, + "column": 1 + } + } +} diff --git a/es2panda/test/parser/ts/test-indexSignature1.ts b/es2panda/test/parser/ts/test-indexSignature1.ts new file mode 100644 index 0000000000..825967df3e --- /dev/null +++ b/es2panda/test/parser/ts/test-indexSignature1.ts @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 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 a = symbol; + +namespace ns { + export type a = string +} + +interface I1 { + [k1: string]: boolean; + [k2: number]: boolean; + [k3: symbol]: boolean; + [k4: `templateLiteral-${string}`]: boolean; +} + +interface I2 { + [k1: number | ns.a | a]: boolean; +} + +class A { + [k1: string | number | symbol | `templateLiteral-${string}`]: boolean; +} + +const x: { [k: string | number | symbol | `templateLiteral-${string}`]: boolean } = {}; diff --git a/es2panda/test/parser/ts/test-indexSignature2-expected.txt b/es2panda/test/parser/ts/test-indexSignature2-expected.txt new file mode 100644 index 0000000000..07446b518c --- /dev/null +++ b/es2panda/test/parser/ts/test-indexSignature2-expected.txt @@ -0,0 +1 @@ +SyntaxError: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. [test-indexSignature2.ts:18:25] diff --git a/es2panda/test/parser/ts/test-indexSignature2.ts b/es2panda/test/parser/ts/test-indexSignature2.ts new file mode 100644 index 0000000000..efae066c9f --- /dev/null +++ b/es2panda/test/parser/ts/test-indexSignature2.ts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 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 I1 { + [k: string | boolean]: boolean; +} -- Gitee From 9372ac3329091c8d8fe196b415503d2ef962fe58 Mon Sep 17 00:00:00 2001 From: songqi Date: Wed, 18 Oct 2023 15:50:28 +0800 Subject: [PATCH 2/2] Fix comments-1 Signed-off-by: songqi Change-Id: I742c6a7bec7b70d7560d08c34a320d1f4c2a87fe --- es2panda/parser/parserImpl.cpp | 17 +- .../ts/test-indexSignature2-expected.txt | 2 +- .../test/parser/ts/test-indexSignature2.ts | 2 +- .../ts/test-indexSignature3-expected.txt | 877 ++++++++++++++++++ .../test/parser/ts/test-indexSignature3.ts | 37 + 5 files changed, 920 insertions(+), 15 deletions(-) create mode 100644 es2panda/test/parser/ts/test-indexSignature3-expected.txt create mode 100644 es2panda/test/parser/ts/test-indexSignature3.ts diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index 5fb0d13cac..4b12806e31 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -1345,25 +1345,16 @@ ir::Expression *ParserImpl::ParseTsTypeLiteralOrInterfaceKey(bool *computed, boo void ParserImpl::ValidateIndexSignatureParameterType(ir::Expression *typeAnnotation) { - // The verification of TSTypeReference is wide-ranging because the specific type it refers to cannot be determined. + // Validation of IndexSignatureParameterType is coarse-grained. if (!typeAnnotation->IsTSStringKeyword() && !typeAnnotation->IsTSNumberKeyword() && !typeAnnotation->IsTSSymbolKeyword() && !typeAnnotation->IsTSTemplateLiteralType() && - !typeAnnotation->IsTSUnionType() && !typeAnnotation->IsTSTypeReference()) { + !typeAnnotation->IsTSUnionType() && !typeAnnotation->IsTSTypeReference() && + !typeAnnotation->IsTSParenthesizedType() && !typeAnnotation->IsTSConditionalType() && + !typeAnnotation->IsTSIndexedAccessType() && !typeAnnotation->IsTSIntersectionType()) { ThrowSyntaxError( "An index signature parameter type must be 'string', 'number', 'symbol', " "or a template literal type."); } - - if (typeAnnotation->IsTSUnionType()) { - for (auto *it : typeAnnotation->AsTSUnionType()->Types()) { - if (!it->IsTSStringKeyword() && !it->IsTSNumberKeyword() && !it->IsTSSymbolKeyword() && - !it->IsTSTemplateLiteralType() && !it->IsTSTypeReference()) { - ThrowSyntaxError( - "An index signature parameter type must be 'string', 'number', 'symbol', " - "or a template literal type."); - } - } - } } void ParserImpl::CreateTSVariableForProperty(ir::AstNode *node, const ir::Expression *key, binder::VariableFlags flags) diff --git a/es2panda/test/parser/ts/test-indexSignature2-expected.txt b/es2panda/test/parser/ts/test-indexSignature2-expected.txt index 07446b518c..414f832a0c 100644 --- a/es2panda/test/parser/ts/test-indexSignature2-expected.txt +++ b/es2panda/test/parser/ts/test-indexSignature2-expected.txt @@ -1 +1 @@ -SyntaxError: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. [test-indexSignature2.ts:18:25] +SyntaxError: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. [test-indexSignature2.ts:18:16] diff --git a/es2panda/test/parser/ts/test-indexSignature2.ts b/es2panda/test/parser/ts/test-indexSignature2.ts index efae066c9f..0bb7759283 100644 --- a/es2panda/test/parser/ts/test-indexSignature2.ts +++ b/es2panda/test/parser/ts/test-indexSignature2.ts @@ -15,5 +15,5 @@ interface I1 { - [k: string | boolean]: boolean; + [k: boolean]: boolean; } diff --git a/es2panda/test/parser/ts/test-indexSignature3-expected.txt b/es2panda/test/parser/ts/test-indexSignature3-expected.txt new file mode 100644 index 0000000000..a8535dec21 --- /dev/null +++ b/es2panda/test/parser/ts/test-indexSignature3-expected.txt @@ -0,0 +1,877 @@ +{ + "type": "Program", + "statements": [ + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [ + { + "type": "TSIndexSignature", + "parameters": { + "type": "Identifier", + "name": "key", + "typeAnnotation": { + "type": "TSParenthesizedType", + "typeAnnotation": { + "type": "TSUnionType", + "types": [ + { + "type": "TSStringKeyword", + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 18 + } + } + }, + { + "type": "TSParenthesizedType", + "typeAnnotation": { + "type": "TSUnionType", + "types": [ + { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 18, + "column": 22 + }, + "end": { + "line": 18, + "column": 28 + } + } + }, + { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 18, + "column": 31 + }, + "end": { + "line": 18, + "column": 37 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 22 + }, + "end": { + "line": 18, + "column": 37 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 21 + }, + "end": { + "line": 18, + "column": 38 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 18, + "column": 38 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 11 + }, + "end": { + "line": 18, + "column": 39 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 6 + }, + "end": { + "line": 18, + "column": 9 + } + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 18, + "column": 42 + }, + "end": { + "line": 18, + "column": 49 + } + } + }, + "readonly": false, + "static": false, + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 19, + "column": 4 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 19, + "column": 4 + } + } + }, + "id": { + "type": "Identifier", + "name": "I1", + "loc": { + "start": { + "line": 17, + "column": 11 + }, + "end": { + "line": 17, + "column": 13 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 17, + "column": 1 + }, + "end": { + "line": 19, + "column": 4 + } + } + }, + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [ + { + "type": "TSIndexSignature", + "parameters": { + "type": "Identifier", + "name": "key", + "typeAnnotation": { + "type": "TSConditionalType", + "checkType": { + "type": "TSIntersectionType", + "types": [ + { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 22, + "column": 11 + }, + "end": { + "line": 22, + "column": 18 + } + } + }, + { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 22, + "column": 21 + }, + "end": { + "line": 22, + "column": 27 + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 11 + }, + "end": { + "line": 22, + "column": 27 + } + } + }, + "extendsType": { + "type": "TSStringKeyword", + "loc": { + "start": { + "line": 22, + "column": 36 + }, + "end": { + "line": 22, + "column": 42 + } + } + }, + "trueType": { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 22, + "column": 45 + }, + "end": { + "line": 22, + "column": 51 + } + } + }, + "falseType": { + "type": "TSSymbolKeyword", + "loc": { + "start": { + "line": 22, + "column": 54 + }, + "end": { + "line": 22, + "column": 60 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 11 + }, + "end": { + "line": 22, + "column": 60 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 6 + }, + "end": { + "line": 22, + "column": 9 + } + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 22, + "column": 63 + }, + "end": { + "line": 22, + "column": 70 + } + } + }, + "readonly": false, + "static": false, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 23, + "column": 4 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 16 + }, + "end": { + "line": 23, + "column": 4 + } + } + }, + "id": { + "type": "Identifier", + "name": "I2", + "loc": { + "start": { + "line": 21, + "column": 13 + }, + "end": { + "line": 21, + "column": 15 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 21, + "column": 3 + }, + "end": { + "line": 23, + "column": 4 + } + } + }, + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "A", + "loc": { + "start": { + "line": 25, + "column": 8 + }, + "end": { + "line": 25, + "column": 9 + } + } + }, + "typeAnnotation": { + "type": "TSTypeLiteral", + "members": [ + { + "type": "TSPropertySignature", + "computed": false, + "optional": false, + "readonly": false, + "key": { + "type": "Identifier", + "name": "a", + "loc": { + "start": { + "line": 25, + "column": 14 + }, + "end": { + "line": 25, + "column": 15 + } + } + }, + "typeAnnotation": { + "type": "TSNumberKeyword", + "loc": { + "start": { + "line": 25, + "column": 17 + }, + "end": { + "line": 25, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 14 + }, + "end": { + "line": 25, + "column": 25 + } + } + } + ], + "loc": { + "start": { + "line": 25, + "column": 12 + }, + "end": { + "line": 25, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 3 + }, + "end": { + "line": 27, + "column": 12 + } + } + }, + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [ + { + "type": "TSIndexSignature", + "parameters": { + "type": "Identifier", + "name": "key", + "typeAnnotation": { + "type": "TSIndexedAccessType", + "objectType": { + "type": "TSTypeReference", + "typeName": { + "type": "Identifier", + "name": "A", + "loc": { + "start": { + "line": 28, + "column": 11 + }, + "end": { + "line": 28, + "column": 12 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 11 + }, + "end": { + "line": 28, + "column": 13 + } + } + }, + "indexType": { + "type": "TSLiteralType", + "literal": { + "type": "StringLiteral", + "value": "a", + "loc": { + "start": { + "line": 28, + "column": 13 + }, + "end": { + "line": 28, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 13 + }, + "end": { + "line": 28, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 11 + }, + "end": { + "line": 28, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 6 + }, + "end": { + "line": 28, + "column": 9 + } + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 28, + "column": 20 + }, + "end": { + "line": 28, + "column": 27 + } + } + }, + "readonly": false, + "static": false, + "loc": { + "start": { + "line": 28, + "column": 5 + }, + "end": { + "line": 29, + "column": 4 + } + } + } + ], + "loc": { + "start": { + "line": 27, + "column": 16 + }, + "end": { + "line": 29, + "column": 4 + } + } + }, + "id": { + "type": "Identifier", + "name": "I3", + "loc": { + "start": { + "line": 27, + "column": 13 + }, + "end": { + "line": 27, + "column": 15 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 27, + "column": 3 + }, + "end": { + "line": 29, + "column": 4 + } + } + }, + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [ + { + "type": "TSIndexSignature", + "parameters": { + "type": "Identifier", + "name": "key", + "typeAnnotation": { + "type": "TSIntersectionType", + "types": [ + { + "type": "TSStringKeyword", + "loc": { + "start": { + "line": 32, + "column": 11 + }, + "end": { + "line": 32, + "column": 17 + } + } + }, + { + "type": "TSStringKeyword", + "loc": { + "start": { + "line": 32, + "column": 20 + }, + "end": { + "line": 32, + "column": 26 + } + } + } + ], + "loc": { + "start": { + "line": 32, + "column": 11 + }, + "end": { + "line": 32, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 32, + "column": 6 + }, + "end": { + "line": 32, + "column": 9 + } + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 32, + "column": 29 + }, + "end": { + "line": 32, + "column": 36 + } + } + }, + "readonly": false, + "static": false, + "loc": { + "start": { + "line": 32, + "column": 5 + }, + "end": { + "line": 33, + "column": 4 + } + } + } + ], + "loc": { + "start": { + "line": 31, + "column": 16 + }, + "end": { + "line": 33, + "column": 4 + } + } + }, + "id": { + "type": "Identifier", + "name": "I4", + "loc": { + "start": { + "line": 31, + "column": 13 + }, + "end": { + "line": 31, + "column": 15 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 31, + "column": 3 + }, + "end": { + "line": 33, + "column": 4 + } + } + }, + { + "type": "TSInterfaceDeclaration", + "body": { + "type": "TSInterfaceBody", + "body": [ + { + "type": "TSIndexSignature", + "parameters": { + "type": "Identifier", + "name": "key", + "typeAnnotation": { + "type": "TSUnionType", + "types": [ + { + "type": "TSStringKeyword", + "loc": { + "start": { + "line": 36, + "column": 11 + }, + "end": { + "line": 36, + "column": 17 + } + } + }, + { + "type": "TSIntersectionType", + "types": [ + { + "type": "TSStringKeyword", + "loc": { + "start": { + "line": 36, + "column": 22 + }, + "end": { + "line": 36, + "column": 28 + } + } + } + ], + "loc": { + "start": { + "line": 36, + "column": 20 + }, + "end": { + "line": 36, + "column": 28 + } + } + } + ], + "loc": { + "start": { + "line": 36, + "column": 11 + }, + "end": { + "line": 36, + "column": 28 + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 6 + }, + "end": { + "line": 36, + "column": 9 + } + } + }, + "typeAnnotation": { + "type": "TSBooleanKeyword", + "loc": { + "start": { + "line": 36, + "column": 31 + }, + "end": { + "line": 36, + "column": 38 + } + } + }, + "readonly": false, + "static": false, + "loc": { + "start": { + "line": 36, + "column": 5 + }, + "end": { + "line": 37, + "column": 4 + } + } + } + ], + "loc": { + "start": { + "line": 35, + "column": 16 + }, + "end": { + "line": 37, + "column": 4 + } + } + }, + "id": { + "type": "Identifier", + "name": "I5", + "loc": { + "start": { + "line": 35, + "column": 13 + }, + "end": { + "line": 35, + "column": 15 + } + } + }, + "extends": [], + "loc": { + "start": { + "line": 35, + "column": 3 + }, + "end": { + "line": 37, + "column": 4 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 38, + "column": 1 + } + } +} diff --git a/es2panda/test/parser/ts/test-indexSignature3.ts b/es2panda/test/parser/ts/test-indexSignature3.ts new file mode 100644 index 0000000000..ac4fdcbef9 --- /dev/null +++ b/es2panda/test/parser/ts/test-indexSignature3.ts @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 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 I1 { + [key: (string | (number | number))]: boolean + } + + interface I2 { + [key: boolean & number extends string ? number : symbol]: boolean + } + + type A = { a: number } + + interface I3 { + [key: A["a"]]: boolean + } + + interface I4 { + [key: string & string]: boolean + } + + interface I5 { + [key: string | & string]: boolean + } -- Gitee