1/* 2 * Copyright (c) 2022-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import * as ts from 'typescript'; 17import { FaultID } from './Problems'; 18 19export class TypeScriptLinterConfig { 20 21 /* 22 * The SyntaxKind enum defines additional elements at the end of the enum 23 * that serve as markers (FirstX/LastX). Those elements are initialized 24 * with indices of the previously defined elements. As result, the enum 25 * may return incorrect name for a certain kind index (e.g. 'FirstStatement' 26 * instead of 'VariableStatement'). 27 * The following code creates a map with correct syntax kind names. 28 * It can be used when need to print name of syntax kind of certain 29 * AST node in diagnostic messages. 30 */ 31 static tsSyntaxKindNames: string[] = []; 32 33 static { 34 TypeScriptLinterConfig.initTsSyntaxKindNames(); 35 } 36 37 private static initTsSyntaxKindNames(): void { 38 const keys = Object.keys(ts.SyntaxKind); 39 const values = Object.values(ts.SyntaxKind); 40 41 for (let i = 0; i < values.length; i++) { 42 const val = values[i]; 43 const kindNum = typeof val === 'string' ? parseInt(val) : val; 44 if (kindNum && !TypeScriptLinterConfig.tsSyntaxKindNames[kindNum]) { 45 TypeScriptLinterConfig.tsSyntaxKindNames[kindNum] = keys[i]; 46 } 47 } 48 } 49 50 // must detect terminals during parsing 51 static terminalTokens: Set<ts.SyntaxKind> = new Set([ 52 ts.SyntaxKind.CloseBracketToken, 53 ts.SyntaxKind.OpenBracketToken, 54 ts.SyntaxKind.CloseParenToken, 55 ts.SyntaxKind.OpenParenToken, 56 ts.SyntaxKind.CloseBraceToken, 57 ts.SyntaxKind.OpenBraceToken, 58 ts.SyntaxKind.CommaToken, 59 ts.SyntaxKind.SemicolonToken, 60 ts.SyntaxKind.QuestionDotToken, 61 ts.SyntaxKind.DotDotDotToken, 62 ts.SyntaxKind.DotToken, 63 ts.SyntaxKind.MinusMinusToken, 64 ts.SyntaxKind.PlusPlusToken, 65 ts.SyntaxKind.PercentToken, 66 ts.SyntaxKind.SlashToken, 67 ts.SyntaxKind.AsteriskAsteriskToken, 68 ts.SyntaxKind.AsteriskToken, 69 ts.SyntaxKind.MinusToken, 70 ts.SyntaxKind.PlusToken, 71 ts.SyntaxKind.EqualsGreaterThanToken, 72 ts.SyntaxKind.ExclamationEqualsEqualsToken, 73 ts.SyntaxKind.ExclamationEqualsToken, 74 ts.SyntaxKind.EqualsEqualsToken, 75 ts.SyntaxKind.EqualsEqualsEqualsToken, 76 ts.SyntaxKind.GreaterThanEqualsToken, 77 ts.SyntaxKind.LessThanEqualsToken, 78 ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken, 79 ts.SyntaxKind.GreaterThanGreaterThanToken, 80 ts.SyntaxKind.GreaterThanToken, 81 ts.SyntaxKind.LessThanSlashToken, 82 ts.SyntaxKind.LessThanToken, 83 ts.SyntaxKind.LessThanLessThanToken, 84 ts.SyntaxKind.HashToken, 85 ts.SyntaxKind.BacktickToken, 86 ts.SyntaxKind.AtToken, 87 ts.SyntaxKind.ColonToken, 88 ts.SyntaxKind.QuestionToken, 89 ts.SyntaxKind.QuestionQuestionToken, 90 ts.SyntaxKind.BarBarToken, 91 ts.SyntaxKind.AmpersandAmpersandToken, 92 ts.SyntaxKind.TildeToken, 93 ts.SyntaxKind.ExclamationToken, 94 ts.SyntaxKind.CaretToken, 95 ts.SyntaxKind.BarToken, 96 ts.SyntaxKind.AmpersandToken, 97 ts.SyntaxKind.CaretEqualsToken, 98 ts.SyntaxKind.BarEqualsToken, 99 ts.SyntaxKind.AmpersandEqualsToken, 100 ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken, 101 ts.SyntaxKind.GreaterThanGreaterThanEqualsToken, 102 ts.SyntaxKind.LessThanLessThanEqualsToken, 103 ts.SyntaxKind.PercentEqualsToken, 104 ts.SyntaxKind.SlashEqualsToken, 105 ts.SyntaxKind.AsteriskAsteriskEqualsToken, 106 ts.SyntaxKind.AsteriskEqualsToken, 107 ts.SyntaxKind.MinusEqualsToken, 108 ts.SyntaxKind.PlusEqualsToken, 109 ts.SyntaxKind.EqualsToken, 110 ts.SyntaxKind.MultiLineCommentTrivia, 111 ts.SyntaxKind.SingleLineCommentTrivia, 112 ts.SyntaxKind.WhitespaceTrivia, 113 ts.SyntaxKind.NewLineTrivia, 114 ts.SyntaxKind.EndOfFileToken, 115 ts.SyntaxKind.ConflictMarkerTrivia, 116 ts.SyntaxKind.ShebangTrivia 117 ]); 118 119 // tokens which can be reported without additional parsing 120 static incrementOnlyTokens: Map<ts.SyntaxKind, FaultID> = new Map([ 121 [ts.SyntaxKind.AnyKeyword, FaultID.AnyType], 122 [ts.SyntaxKind.SymbolKeyword, FaultID.SymbolType], 123 [ts.SyntaxKind.ThisType, FaultID.ThisType], 124 [ts.SyntaxKind.TypeQuery, FaultID.TypeQuery], 125 [ts.SyntaxKind.DeleteExpression, FaultID.DeleteOperator], 126 [ts.SyntaxKind.TypePredicate, FaultID.IsOperator], 127 [ts.SyntaxKind.YieldExpression, FaultID.YieldExpression], 128 [ts.SyntaxKind.WithStatement, FaultID.WithStatement], 129 [ts.SyntaxKind.IndexedAccessType, FaultID.IndexedAccessType], 130 [ts.SyntaxKind.UnknownKeyword, FaultID.UnknownType], 131 [ts.SyntaxKind.CallSignature, FaultID.CallSignature], 132 [ts.SyntaxKind.IntersectionType, FaultID.IntersectionType], 133 [ts.SyntaxKind.ConstructorType, FaultID.ConstructorFuncs], 134 [ts.SyntaxKind.ConditionalType, FaultID.ConditionalType], 135 [ts.SyntaxKind.MappedType, FaultID.MappedType], 136 [ts.SyntaxKind.JsxElement, FaultID.JsxElement], 137 [ts.SyntaxKind.JsxSelfClosingElement, FaultID.JsxElement], 138 [ts.SyntaxKind.ImportEqualsDeclaration, FaultID.ImportAssignment], 139 [ts.SyntaxKind.NamespaceExportDeclaration, FaultID.UMDModuleDefinition], 140 [ts.SyntaxKind.ClassExpression, FaultID.ClassExpression] 141 ]); 142} 143