|
6 | 6 | * found in the LICENSE file at https://angular.io/license
|
7 | 7 | */
|
8 | 8 | import * as ts from 'typescript';
|
9 |
| -import { drilldownNodes } from '../helpers/ast-utils'; |
10 |
| - |
11 |
| - |
12 |
| -export function testWrapEnums(content: string) { |
13 |
| - // TODO: remove this method, it's not doing anything anymore. |
14 |
| - return true; |
15 |
| -} |
16 | 9 |
|
17 | 10 | function isBlockLike(node: ts.Node): node is ts.BlockLike {
|
18 | 11 | return node.kind === ts.SyntaxKind.Block
|
@@ -166,73 +159,96 @@ function visitBlockStatements(
|
166 | 159 |
|
167 | 160 | // TS 2.3 enums have statements that are inside a IIFE.
|
168 | 161 | function findTs2_3EnumIife(name: string, statement: ts.Statement): ts.CallExpression | null {
|
169 |
| - if (!ts.isExpressionStatement(statement) || !ts.isCallExpression(statement.expression)) { |
| 162 | + if (!ts.isExpressionStatement(statement)) { |
| 163 | + return null; |
| 164 | + } |
| 165 | + |
| 166 | + let expression = statement.expression; |
| 167 | + while (ts.isParenthesizedExpression(expression)) { |
| 168 | + expression = expression.expression; |
| 169 | + } |
| 170 | + |
| 171 | + if (!expression || !ts.isCallExpression(expression) || expression.arguments.length !== 1) { |
| 172 | + return null; |
| 173 | + } |
| 174 | + |
| 175 | + const callExpression = expression; |
| 176 | + |
| 177 | + const argument = expression.arguments[0]; |
| 178 | + if (!ts.isBinaryExpression(argument) |
| 179 | + || argument.operatorToken.kind !== ts.SyntaxKind.BarBarToken) { |
| 180 | + return null; |
| 181 | + } |
| 182 | + |
| 183 | + if (!ts.isIdentifier(argument.left) || argument.left.text !== name) { |
| 184 | + return null; |
| 185 | + } |
| 186 | + |
| 187 | + expression = expression.expression; |
| 188 | + while (ts.isParenthesizedExpression(expression)) { |
| 189 | + expression = expression.expression; |
| 190 | + } |
| 191 | + |
| 192 | + if (!expression || !ts.isFunctionExpression(expression) || expression.parameters.length !== 1) { |
170 | 193 | return null;
|
171 | 194 | }
|
172 | 195 |
|
173 |
| - const funcExpr = drilldownNodes<ts.FunctionExpression>(statement, |
174 |
| - [ |
175 |
| - { prop: null, kind: ts.SyntaxKind.ExpressionStatement }, |
176 |
| - { prop: 'expression', kind: ts.SyntaxKind.CallExpression }, |
177 |
| - { prop: 'expression', kind: ts.SyntaxKind.ParenthesizedExpression }, |
178 |
| - { prop: 'expression', kind: ts.SyntaxKind.FunctionExpression }, |
179 |
| - ]); |
180 |
| - |
181 |
| - if (funcExpr === null) { return null; } |
182 |
| - |
183 |
| - if (!( |
184 |
| - funcExpr.parameters.length === 1 |
185 |
| - && funcExpr.parameters[0].name.kind === ts.SyntaxKind.Identifier |
186 |
| - && (funcExpr.parameters[0].name as ts.Identifier).text === name |
187 |
| - )) { |
| 196 | + const parameter = expression.parameters[0]; |
| 197 | + if (!ts.isIdentifier(parameter.name) || parameter.name.text !== name) { |
188 | 198 | return null;
|
189 | 199 | }
|
190 | 200 |
|
191 | 201 | // In TS 2.3 enums, the IIFE contains only expressions with a certain format.
|
192 | 202 | // If we find any that is different, we ignore the whole thing.
|
193 |
| - for (const innerStmt of funcExpr.body.statements) { |
| 203 | + for (let bodyIndex = 0; bodyIndex < expression.body.statements.length; ++bodyIndex) { |
| 204 | + const bodyStatement = expression.body.statements[bodyIndex]; |
194 | 205 |
|
195 |
| - const innerBinExpr = drilldownNodes<ts.BinaryExpression>(innerStmt, |
196 |
| - [ |
197 |
| - { prop: null, kind: ts.SyntaxKind.ExpressionStatement }, |
198 |
| - { prop: 'expression', kind: ts.SyntaxKind.BinaryExpression }, |
199 |
| - ]); |
| 206 | + if (!ts.isExpressionStatement(bodyStatement) || !bodyStatement.expression) { |
| 207 | + return null; |
| 208 | + } |
200 | 209 |
|
201 |
| - if (innerBinExpr === null) { return null; } |
| 210 | + if (!ts.isBinaryExpression(bodyStatement.expression) |
| 211 | + || bodyStatement.expression.operatorToken.kind !== ts.SyntaxKind.FirstAssignment) { |
| 212 | + return null; |
| 213 | + } |
202 | 214 |
|
203 |
| - if (!(innerBinExpr.operatorToken.kind === ts.SyntaxKind.FirstAssignment |
204 |
| - && innerBinExpr.left.kind === ts.SyntaxKind.ElementAccessExpression)) { |
| 215 | + const assignment = bodyStatement.expression.left; |
| 216 | + const value = bodyStatement.expression.right; |
| 217 | + if (!ts.isElementAccessExpression(assignment) || !ts.isStringLiteral(value)) { |
205 | 218 | return null;
|
206 | 219 | }
|
207 | 220 |
|
208 |
| - const innerElemAcc = innerBinExpr.left as ts.ElementAccessExpression; |
| 221 | + if (!ts.isIdentifier(assignment.expression) || assignment.expression.text !== name) { |
| 222 | + return null; |
| 223 | + } |
209 | 224 |
|
210 |
| - if (!( |
211 |
| - innerElemAcc.expression.kind === ts.SyntaxKind.Identifier |
212 |
| - && (innerElemAcc.expression as ts.Identifier).text === name |
213 |
| - && innerElemAcc.argumentExpression |
214 |
| - && innerElemAcc.argumentExpression.kind === ts.SyntaxKind.BinaryExpression |
215 |
| - )) { |
| 225 | + const memberArgument = assignment.argumentExpression; |
| 226 | + if (!memberArgument || !ts.isBinaryExpression(memberArgument) |
| 227 | + || memberArgument.operatorToken.kind !== ts.SyntaxKind.FirstAssignment) { |
216 | 228 | return null;
|
217 | 229 | }
|
218 | 230 |
|
219 |
| - const innerArgBinExpr = innerElemAcc.argumentExpression as ts.BinaryExpression; |
220 | 231 |
|
221 |
| - if (innerArgBinExpr.left.kind !== ts.SyntaxKind.ElementAccessExpression) { |
| 232 | + if (!ts.isElementAccessExpression(memberArgument.left)) { |
| 233 | + return null; |
| 234 | + } |
| 235 | + |
| 236 | + if (!ts.isIdentifier(memberArgument.left.expression) |
| 237 | + || memberArgument.left.expression.text !== name) { |
222 | 238 | return null;
|
223 | 239 | }
|
224 | 240 |
|
225 |
| - const innerArgElemAcc = innerArgBinExpr.left as ts.ElementAccessExpression; |
| 241 | + if (!memberArgument.left.argumentExpression |
| 242 | + || !ts.isStringLiteral(memberArgument.left.argumentExpression)) { |
| 243 | + return null; |
| 244 | + } |
226 | 245 |
|
227 |
| - if (!( |
228 |
| - innerArgElemAcc.expression.kind === ts.SyntaxKind.Identifier |
229 |
| - && (innerArgElemAcc.expression as ts.Identifier).text === name |
230 |
| - )) { |
| 246 | + if (memberArgument.left.argumentExpression.text !== value.text) { |
231 | 247 | return null;
|
232 | 248 | }
|
233 | 249 | }
|
234 | 250 |
|
235 |
| - return statement.expression; |
| 251 | + return callExpression; |
236 | 252 | }
|
237 | 253 |
|
238 | 254 | // TS 2.2 enums have statements after the variable declaration, with index statements followed
|
|
0 commit comments