Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library fasta.analyzer.ast_builder; | |
| 6 | |
| 7 import 'package:dart_scanner/src/token.dart' show | |
| 8 BeginGroupToken, | |
| 9 Token; | |
| 10 | |
| 11 import 'package:analyzer/analyzer.dart'; | |
| 12 | |
| 13 import 'package:analyzer/dart/ast/token.dart' as analyzer show | |
| 14 Token; | |
| 15 | |
| 16 import 'package:analyzer/dart/element/element.dart' show | |
| 17 Element; | |
| 18 | |
| 19 import 'package:analyzer/dart/ast/ast_factory.dart' show | |
| 20 AstFactory; | |
| 21 | |
| 22 import 'package:analyzer/dart/ast/standard_ast_factory.dart' as standard; | |
| 23 | |
| 24 import '../errors.dart' show | |
| 25 internalError; | |
| 26 | |
| 27 import '../source/scope_listener.dart' show | |
| 28 JumpTargetKind, | |
| 29 NullValue, | |
| 30 Scope, | |
| 31 ScopeListener; | |
| 32 | |
| 33 import '../kernel/kernel_builder.dart' show | |
| 34 Builder, | |
| 35 KernelLibraryBuilder, | |
| 36 ProcedureBuilder; | |
| 37 | |
| 38 import '../quote.dart'; | |
| 39 | |
| 40 import '../source/outline_builder.dart' show | |
| 41 asyncMarkerFromTokens; | |
| 42 | |
| 43 import 'element_store.dart' show | |
| 44 AnalyzerLocalVariableElemment, | |
| 45 AnalyzerParameterElement, | |
| 46 ElementStore, | |
| 47 KernelClassElement; | |
| 48 | |
| 49 import 'token_utils.dart' show | |
| 50 toAnalyzerToken; | |
| 51 | |
| 52 import 'analyzer.dart' show | |
| 53 toKernel; | |
| 54 | |
| 55 class AstBuilder extends ScopeListener { | |
| 56 final AstFactory ast = standard.astFactory; | |
| 57 | |
| 58 final KernelLibraryBuilder library; | |
| 59 | |
| 60 final Builder member; | |
| 61 | |
| 62 final ElementStore elementStore; | |
| 63 | |
| 64 bool isFirstIdentifier = false; | |
| 65 | |
| 66 AstBuilder(this.library, this.member, this.elementStore, Scope scope) | |
| 67 : super(scope); | |
| 68 | |
| 69 Uri get uri => library.uri; | |
| 70 | |
| 71 createJumpTarget(JumpTargetKind kind) { | |
| 72 // TODO(ahe): Implement jump targets. | |
| 73 return null; | |
| 74 } | |
| 75 | |
| 76 void beginLiteralString(Token token) { | |
| 77 debugEvent("beginLiteralString"); | |
| 78 push(token); | |
| 79 } | |
| 80 | |
| 81 void handleStringPart(Token token) { | |
| 82 debugEvent("StringPart"); | |
| 83 push(token); | |
| 84 } | |
| 85 | |
| 86 void doStringPart(Token token) { | |
| 87 push(ast.simpleStringLiteral(toAnalyzerToken(token), token.value)); | |
| 88 } | |
| 89 | |
| 90 void endLiteralString(int interpolationCount) { | |
| 91 debugEvent("endLiteralString"); | |
| 92 if (interpolationCount == 0) { | |
| 93 Token token = pop(); | |
| 94 String value = unescapeString(token.value); | |
| 95 push(ast.simpleStringLiteral(toAnalyzerToken(token), value)); | |
| 96 } else { | |
| 97 List parts = popList(1 + interpolationCount * 2); | |
| 98 Token first = parts.first; | |
| 99 Token last = parts.last; | |
| 100 Quote quote = analyzeQuote(first.value); | |
| 101 List<InterpolationElement> elements = <InterpolationElement>[]; | |
| 102 elements.add(ast.interpolationString( | |
| 103 toAnalyzerToken(first), | |
| 104 unescapeFirstStringPart(first.value, quote))); | |
| 105 for (int i = 1; i < parts.length - 1; i++) { | |
| 106 var part = parts[i]; | |
| 107 if (part is Token) { | |
| 108 elements.add(ast.interpolationString( | |
| 109 toAnalyzerToken(part), part.value)); | |
| 110 } else if (part is Expression) { | |
| 111 elements.add(ast.interpolationExpression(null, part, null)); | |
| 112 } else { | |
| 113 internalError( | |
| 114 "Unexpected part in string interpolation: ${part.runtimeType}"); | |
| 115 } | |
| 116 } | |
| 117 elements.add(ast.interpolationString( | |
| 118 toAnalyzerToken(last), unescapeLastStringPart(last.value, quote))) ; | |
|
asgerf
2017/01/19 10:13:26
Long line
ahe
2017/01/19 10:59:45
Done.
| |
| 119 push(ast.stringInterpolation(elements)); | |
| 120 } | |
| 121 } | |
| 122 | |
| 123 void handleStringJuxtaposition(int literalCount) { | |
| 124 debugEvent("StringJuxtaposition"); | |
| 125 push(ast.adjacentStrings(popList(literalCount))); | |
| 126 } | |
| 127 | |
| 128 void endArguments(int count, Token beginToken, Token endToken) { | |
| 129 debugEvent("Arguments"); | |
| 130 List expressions = popList(count); | |
| 131 ArgumentList arguments = ast.argumentList(toAnalyzerToken(beginToken), | |
| 132 expressions, toAnalyzerToken(endToken)); | |
| 133 push(ast.methodInvocation(null, null, null, null, arguments)); | |
| 134 } | |
| 135 | |
| 136 void beginExpression(Token token) { | |
| 137 isFirstIdentifier = true; | |
| 138 } | |
| 139 | |
| 140 void handleIdentifier(Token token) { | |
| 141 debugEvent("handleIdentifier"); | |
| 142 String name = token.value; | |
| 143 SimpleIdentifier identifier = ast.simpleIdentifier(toAnalyzerToken(token)); | |
| 144 if (isFirstIdentifier) { | |
| 145 Builder builder = scope.lookup(name); | |
| 146 if (builder != null) { | |
| 147 Element element = elementStore[builder]; | |
| 148 assert(element != null); | |
| 149 identifier.staticElement = element; | |
| 150 } | |
| 151 } | |
| 152 push(identifier); | |
| 153 isFirstIdentifier = false; | |
| 154 } | |
| 155 | |
| 156 void endSend(Token token) { | |
| 157 debugEvent("Send"); | |
| 158 MethodInvocation arguments = pop(); | |
| 159 TypeArgumentList typeArguments = pop(); | |
| 160 if (arguments != null) { | |
| 161 if (typeArguments != null) { | |
| 162 arguments.typeArguments = typeArguments; | |
| 163 } | |
| 164 doInvocation(token, arguments); | |
| 165 } else { | |
| 166 doPropertyGet(token); | |
| 167 } | |
| 168 } | |
| 169 | |
| 170 void doInvocation(Token token, MethodInvocation arguments) { | |
| 171 Expression receiver = pop(); | |
| 172 if (receiver is SimpleIdentifier) { | |
| 173 arguments.methodName = receiver; | |
| 174 push(arguments); | |
| 175 } else { | |
| 176 internalError("Unhandled receiver in send: ${receiver.runtimeType}"); | |
| 177 } | |
| 178 } | |
| 179 | |
| 180 void doPropertyGet(Token token) { | |
| 181 } | |
| 182 | |
| 183 void endExpressionStatement(Token token) { | |
| 184 debugEvent("ExpressionStatement"); | |
| 185 push(ast.expressionStatement(pop(), toAnalyzerToken(token))); | |
| 186 } | |
| 187 | |
| 188 void endFunctionBody(int count, Token beginToken, Token endToken) { | |
| 189 debugEvent("FunctionBody"); | |
| 190 List statements = popList(count); | |
| 191 if (beginToken != null) { | |
| 192 exitLocalScope(); | |
| 193 } | |
| 194 push(ast.block(toAnalyzerToken(beginToken), statements, | |
| 195 toAnalyzerToken(endToken))); | |
| 196 } | |
| 197 | |
| 198 void finishFunction(formals, asyncModifier, Statement body) { | |
| 199 debugEvent("finishFunction"); | |
| 200 print(""" | |
| 201 Analyzer AST: | |
| 202 $body | |
|
asgerf
2017/01/19 10:13:26
Please remove these prints.
ahe
2017/01/19 10:59:45
Done.
| |
| 203 """); | |
| 204 var kernel = toKernel(body, elementStore, library.library, scope); | |
| 205 print(""" | |
| 206 Kernel from analyzer AST: | |
| 207 $kernel"""); | |
| 208 if (member is ProcedureBuilder) { | |
| 209 ProcedureBuilder builder = member; | |
| 210 builder.body = kernel; | |
| 211 } else { | |
| 212 internalError("Internal error: expected procedure, but got: $member"); | |
| 213 } | |
| 214 } | |
| 215 | |
| 216 void beginCascade(Token token) { | |
| 217 debugEvent("beginCascade"); | |
| 218 Expression expression = pop(); | |
| 219 push(token); | |
| 220 if (expression is CascadeExpression) { | |
| 221 push(expression); | |
| 222 } else { | |
| 223 push(ast.cascadeExpression(expression, <Expression>[])); | |
| 224 } | |
| 225 push(NullValue.CascadeReceiver); | |
| 226 } | |
| 227 | |
| 228 void endCascade() { | |
| 229 debugEvent("Cascade"); | |
| 230 Expression expression = pop(); | |
| 231 CascadeExpression receiver = pop(); | |
| 232 pop(); // Token. | |
| 233 receiver.cascadeSections.add(expression); | |
| 234 push(receiver); | |
| 235 } | |
| 236 | |
| 237 void handleBinaryExpression(Token token) { | |
| 238 debugEvent("BinaryExpression"); | |
| 239 if (identical(".", token.stringValue) || | |
| 240 identical("..", token.stringValue)) { | |
| 241 doDotExpression(token); | |
| 242 } else { | |
| 243 Expression right = pop(); | |
| 244 Expression left = pop(); | |
| 245 push(ast.binaryExpression(left, toAnalyzerToken(token), right)); | |
| 246 } | |
| 247 } | |
| 248 | |
| 249 void doDotExpression(Token token) { | |
| 250 Expression identifierOrInvoke = pop(); | |
| 251 Expression receiver = pop(); | |
| 252 if (identifierOrInvoke is SimpleIdentifier) { | |
| 253 push(ast.propertyAccess(receiver, toAnalyzerToken(token), | |
| 254 identifierOrInvoke)); | |
| 255 } else if (identifierOrInvoke is MethodInvocation) { | |
| 256 assert(identifierOrInvoke.target == null); | |
| 257 identifierOrInvoke | |
| 258 ..target = receiver | |
| 259 ..operator = toAnalyzerToken(token); | |
| 260 push(identifierOrInvoke); | |
| 261 } else { | |
| 262 internalError("Unhandled property access: ${identifierOrInvoke.runtimeType }"); | |
|
asgerf
2017/01/19 10:13:26
Long Lineâ„¢
ahe
2017/01/19 10:59:45
Done.
| |
| 263 } | |
| 264 } | |
| 265 | |
| 266 void handleLiteralInt(Token token) { | |
| 267 debugEvent("LiteralInt"); | |
| 268 push(ast.integerLiteral(toAnalyzerToken(token), int.parse(token.value))); | |
| 269 } | |
| 270 | |
| 271 void endReturnStatement( | |
| 272 bool hasExpression, Token beginToken, Token endToken) { | |
| 273 debugEvent("ReturnStatement"); | |
| 274 Expression expression = hasExpression ? pop() : null; | |
| 275 push(ast.returnStatement(toAnalyzerToken(beginToken), expression, | |
| 276 toAnalyzerToken(endToken))); | |
| 277 } | |
| 278 | |
| 279 void endIfStatement(Token ifToken, Token elseToken) { | |
| 280 Statement elsePart = popIfNotNull(elseToken); | |
| 281 Statement thenPart = pop(); | |
| 282 Expression condition = pop(); | |
| 283 BeginGroupToken leftParenthesis = ifToken.next; | |
| 284 push(ast.ifStatement( | |
| 285 toAnalyzerToken(ifToken), toAnalyzerToken(ifToken.next), condition, | |
| 286 toAnalyzerToken(leftParenthesis.endGroup), thenPart, | |
| 287 toAnalyzerToken(elseToken), elsePart)); | |
| 288 } | |
| 289 | |
| 290 void prepareInitializers() { | |
| 291 debugEvent("prepareInitializers"); | |
| 292 } | |
| 293 | |
| 294 void handleNoInitializers() { | |
| 295 debugEvent("NoInitializers"); | |
| 296 } | |
| 297 | |
| 298 void endInitializers(int count, Token beginToken, Token endToken) { | |
| 299 debugEvent("Initializers"); | |
| 300 popList(count); | |
| 301 } | |
| 302 | |
| 303 void endInitializer(Token assignmentOperator) { | |
| 304 debugEvent("Initializer"); | |
| 305 assert(assignmentOperator.stringValue == "="); | |
| 306 Expression initializer = pop(); | |
| 307 Identifier identifier = pop(); | |
| 308 // TODO(ahe): Don't push initializers, instead install them. | |
| 309 push(ast.variableDeclaration( | |
| 310 identifier, toAnalyzerToken(assignmentOperator), initializer)); | |
| 311 } | |
| 312 | |
| 313 void endInitializedIdentifier() { | |
| 314 debugEvent("InitializedIdentifier"); | |
| 315 AstNode node = pop(); | |
| 316 VariableDeclaration variable; | |
| 317 if (node is VariableDeclaration) { | |
| 318 variable = node; | |
| 319 } else if (node is SimpleIdentifier) { | |
| 320 variable = ast.variableDeclaration(node, null, null); | |
| 321 } else { | |
| 322 internalError("unhandled identifier: ${node.runtimeType}"); | |
| 323 } | |
| 324 push(variable); | |
| 325 scope[variable.name.name] = variable.name.staticElement = | |
| 326 new AnalyzerLocalVariableElemment(variable); | |
| 327 } | |
| 328 | |
| 329 void endVariablesDeclaration(int count, Token endToken) { | |
| 330 debugEvent("VariablesDeclaration"); | |
| 331 List<VariableDeclaration> variables = popList(count); | |
| 332 TypeName type = pop(); | |
| 333 pop(); // Modifiers. | |
| 334 push(ast.variableDeclarationStatement( | |
| 335 ast.variableDeclarationList(null, null, null, type, variables), | |
| 336 toAnalyzerToken(endToken))); | |
| 337 } | |
| 338 | |
| 339 void handleAssignmentExpression(Token token) { | |
| 340 debugEvent("AssignmentExpression"); | |
| 341 Expression rhs = pop(); | |
| 342 Expression lhs = pop(); | |
| 343 push(ast.assignmentExpression(lhs, toAnalyzerToken(token), rhs)); | |
| 344 } | |
| 345 | |
| 346 void endBlock(int count, Token beginToken, Token endToken) { | |
| 347 debugEvent("Block"); | |
| 348 List<Statement> statements = popList(count) ?? <Statement>[]; | |
| 349 exitLocalScope(); | |
| 350 push(ast.block(toAnalyzerToken(beginToken), statements, | |
| 351 toAnalyzerToken(endToken))); | |
| 352 } | |
| 353 | |
| 354 void endForStatement( | |
| 355 int updateExpressionCount, Token beginToken, Token endToken) { | |
| 356 debugEvent("ForStatement"); | |
| 357 Statement body = pop(); | |
| 358 List<Expression> updates = popList(updateExpressionCount); | |
| 359 ExpressionStatement condition = pop(); | |
| 360 VariableDeclarationStatement variables = pop(); | |
| 361 exitContinueTarget(); | |
| 362 exitBreakTarget(); | |
| 363 exitLocalScope(); | |
| 364 BeginGroupToken leftParenthesis = beginToken.next; | |
| 365 push(ast.forStatement( | |
| 366 toAnalyzerToken(beginToken), | |
| 367 toAnalyzerToken(leftParenthesis), | |
| 368 variables?.variables, | |
| 369 null, // initialization. | |
| 370 variables?.semicolon, | |
| 371 condition.expression, | |
| 372 condition.semicolon, | |
| 373 updates, | |
| 374 toAnalyzerToken(leftParenthesis.endGroup), | |
| 375 body)); | |
| 376 } | |
| 377 | |
| 378 void handleLiteralList( | |
| 379 int count, Token beginToken, Token constKeyword, Token endToken) { | |
| 380 debugEvent("LiteralList"); | |
| 381 List<Expression> expressions = popList(count); | |
| 382 TypeArgumentList typeArguments = pop(); | |
| 383 push(ast.listLiteral( | |
| 384 toAnalyzerToken(constKeyword), | |
| 385 typeArguments, | |
| 386 toAnalyzerToken(beginToken), | |
| 387 expressions, | |
| 388 toAnalyzerToken(endToken))); | |
| 389 } | |
| 390 | |
| 391 void handleAsyncModifier(Token asyncToken, Token starToken) { | |
| 392 debugEvent("AsyncModifier"); | |
| 393 push(asyncMarkerFromTokens(asyncToken, starToken)); | |
| 394 } | |
| 395 | |
| 396 void endAwaitExpression(Token beginToken, Token endToken) { | |
| 397 debugEvent("AwaitExpression"); | |
| 398 push(ast.awaitExpression(toAnalyzerToken(beginToken), pop())); | |
| 399 } | |
| 400 | |
| 401 void beginLiteralSymbol(Token token) { | |
| 402 isFirstIdentifier = false; | |
| 403 } | |
| 404 | |
| 405 void handleLiteralBool(Token token) { | |
| 406 debugEvent("LiteralBool"); | |
| 407 bool value = identical(token.stringValue, "true"); | |
| 408 assert(value || identical(token.stringValue, "false")); | |
| 409 push(ast.booleanLiteral(toAnalyzerToken(token), value)); | |
| 410 } | |
| 411 | |
| 412 void handleLiteralDouble(Token token) { | |
| 413 debugEvent("LiteralDouble"); | |
| 414 push(ast.doubleLiteral(toAnalyzerToken(token), double.parse(token.value))); | |
| 415 } | |
| 416 | |
| 417 void handleLiteralNull(Token token) { | |
| 418 debugEvent("LiteralNull"); | |
| 419 push(ast.nullLiteral(toAnalyzerToken(token))); | |
| 420 } | |
| 421 | |
| 422 void handleLiteralMap( | |
| 423 int count, Token beginToken, Token constKeyword, Token endToken) { | |
| 424 debugEvent("LiteralMap"); | |
| 425 List<MapLiteralEntry> entries = popList(count) ?? <MapLiteralEntry>[]; | |
| 426 TypeArgumentList typeArguments = pop(); | |
| 427 push(ast.mapLiteral(toAnalyzerToken(constKeyword), typeArguments, | |
| 428 toAnalyzerToken(beginToken), entries, toAnalyzerToken(endToken))); | |
| 429 } | |
| 430 | |
| 431 void endLiteralMapEntry(Token colon, Token endToken) { | |
| 432 debugEvent("LiteralMapEntry"); | |
| 433 Expression value = pop(); | |
| 434 Expression key = pop(); | |
| 435 push(ast.mapLiteralEntry(key, toAnalyzerToken(colon), value)); | |
| 436 } | |
| 437 | |
| 438 void endLiteralSymbol(Token hashToken, int identifierCount) { | |
| 439 debugEvent("LiteralSymbol"); | |
| 440 List<analyzer.Token> components = new List<analyzer.Token>(identifierCount); | |
| 441 for (int i = identifierCount - 1; i >= 0; i--) { | |
| 442 SimpleIdentifier identifier = pop(); | |
| 443 components[i] = identifier.token; | |
| 444 } | |
| 445 push(ast.symbolLiteral(toAnalyzerToken(hashToken), components)); | |
| 446 } | |
| 447 | |
| 448 void endType(Token beginToken, Token endToken) { | |
| 449 debugEvent("Type"); | |
| 450 TypeArgumentList arguments = pop(); | |
| 451 SimpleIdentifier name = pop(); | |
| 452 KernelClassElement cls = name.staticElement; | |
| 453 if (cls == null) { | |
| 454 Builder builder = scope.lookup(name.name); | |
| 455 if (builder == null) { | |
| 456 internalError("Undefined name: $name"); | |
| 457 } | |
| 458 cls = elementStore[builder]; | |
| 459 assert(cls != null); | |
| 460 name.staticElement = cls; | |
| 461 } | |
| 462 push(ast.typeName(name, arguments)..type = cls.rawType); | |
| 463 } | |
| 464 | |
| 465 void handleAsOperator(Token operator, Token endToken) { | |
| 466 debugEvent("AsOperator"); | |
| 467 TypeName type = pop(); | |
| 468 Expression expression = pop(); | |
| 469 push(ast.asExpression(expression, toAnalyzerToken(operator), type)); | |
| 470 } | |
| 471 | |
| 472 void handleIsOperator(Token operator, Token not, Token endToken) { | |
| 473 debugEvent("IsOperator"); | |
| 474 TypeName type = pop(); | |
| 475 Expression expression = pop(); | |
| 476 push(ast.isExpression(expression, toAnalyzerToken(operator), | |
| 477 toAnalyzerToken(not), type)); | |
| 478 } | |
| 479 | |
| 480 void handleConditionalExpression(Token question, Token colon) { | |
| 481 debugEvent("ConditionalExpression"); | |
| 482 Expression elseExpression = pop(); | |
| 483 Expression thenExpression = pop(); | |
| 484 Expression condition = pop(); | |
| 485 push(ast.conditionalExpression(condition, toAnalyzerToken(question), | |
| 486 thenExpression, toAnalyzerToken(colon), elseExpression)); | |
| 487 } | |
| 488 | |
| 489 void endThrowExpression(Token throwToken, Token endToken) { | |
| 490 debugEvent("ThrowExpression"); | |
| 491 push(ast.throwExpression(toAnalyzerToken(throwToken), pop())); | |
| 492 } | |
| 493 | |
| 494 void endFormalParameter(Token thisKeyword) { | |
| 495 debugEvent("FormalParameter"); | |
| 496 if (thisKeyword != null) { | |
| 497 internalError("'this' can't be used here."); | |
| 498 } | |
| 499 SimpleIdentifier name = pop(); | |
| 500 TypeName type = pop(); | |
| 501 pop(); // Modifiers. | |
| 502 pop(); // Metadata. | |
| 503 SimpleFormalParameter node = ast.simpleFormalParameter(null, null, | |
| 504 toAnalyzerToken(thisKeyword), type, name); | |
| 505 scope[name.name] = name.staticElement = new AnalyzerParameterElement(node); | |
| 506 push(node); | |
| 507 } | |
| 508 | |
| 509 void endFormalParameters(int count, Token beginToken, Token endToken) { | |
| 510 debugEvent("FormalParameters"); | |
| 511 List<FormalParameter> parameters = popList(count) ?? <FormalParameter>[]; | |
| 512 push(ast.formalParameterList(toAnalyzerToken(beginToken), parameters, | |
| 513 null, null, toAnalyzerToken(endToken))); | |
| 514 } | |
| 515 | |
| 516 void handleCatchBlock(Token onKeyword, Token catchKeyword) { | |
| 517 debugEvent("CatchBlock"); | |
| 518 Block body = pop(); | |
| 519 FormalParameterList catchParameters = popIfNotNull(catchKeyword); | |
| 520 if (catchKeyword != null) { | |
| 521 exitLocalScope(); | |
| 522 } | |
| 523 TypeName type = popIfNotNull(onKeyword); | |
| 524 SimpleIdentifier exception; | |
| 525 SimpleIdentifier stackTrace; | |
| 526 if (catchParameters != null) { | |
| 527 if (catchParameters.length > 0) { | |
| 528 exception = catchParameters.parameters[0].identifier; | |
| 529 } | |
| 530 if (catchParameters.length > 1) { | |
| 531 stackTrace = catchParameters.parameters[1].identifier; | |
| 532 } | |
| 533 } | |
| 534 BeginGroupToken leftParenthesis = catchKeyword.next; | |
| 535 push(ast.catchClause(toAnalyzerToken(onKeyword), type, | |
| 536 toAnalyzerToken(catchKeyword), toAnalyzerToken(leftParenthesis), | |
| 537 exception, null, stackTrace, | |
| 538 toAnalyzerToken(leftParenthesis.endGroup), body)); | |
| 539 } | |
| 540 | |
| 541 void endTryStatement( | |
| 542 int catchCount, Token tryKeyword, Token finallyKeyword) { | |
| 543 Block finallyBlock = popIfNotNull(finallyKeyword); | |
| 544 List<CatchClause> catchClauses = popList(catchCount); | |
| 545 Block body = pop(); | |
| 546 push(ast.tryStatement(toAnalyzerToken(tryKeyword), body, catchClauses, | |
| 547 toAnalyzerToken(finallyKeyword), finallyBlock)); | |
| 548 } | |
| 549 | |
| 550 void handleNoExpression(Token token) { | |
| 551 debugEvent("NoExpression"); | |
| 552 push(NullValue.Expression); | |
| 553 } | |
| 554 | |
| 555 void handleIndexedExpression( | |
| 556 Token openCurlyBracket, Token closeCurlyBracket) { | |
| 557 debugEvent("IndexedExpression"); | |
| 558 Expression index = pop(); | |
| 559 Expression target = pop(); | |
| 560 if (target == null) { | |
| 561 CascadeExpression receiver = pop(); | |
| 562 Token token = peek(); | |
| 563 push(receiver); | |
| 564 IndexExpression expression = ast.indexExpressionForCascade( | |
| 565 toAnalyzerToken(token), toAnalyzerToken(openCurlyBracket), index, | |
| 566 toAnalyzerToken(closeCurlyBracket)); | |
| 567 assert(expression.isCascaded); | |
| 568 push(expression); | |
| 569 } else { | |
| 570 push(ast.indexExpressionForTarget(target, | |
| 571 toAnalyzerToken(openCurlyBracket), index, | |
| 572 toAnalyzerToken(closeCurlyBracket))); | |
| 573 } | |
| 574 } | |
| 575 | |
| 576 void handleUnaryPrefixExpression(Token token) { | |
| 577 debugEvent("UnaryPrefixExpression"); | |
| 578 push(ast.prefixExpression(toAnalyzerToken(token), pop())); | |
| 579 } | |
| 580 | |
| 581 void handleUnaryPrefixAssignmentExpression(Token token) { | |
| 582 debugEvent("UnaryPrefixAssignmentExpression"); | |
| 583 push(ast.prefixExpression(toAnalyzerToken(token), pop())); | |
| 584 } | |
| 585 | |
| 586 void handleUnaryPostfixAssignmentExpression(Token token) { | |
| 587 debugEvent("UnaryPostfixAssignmentExpression"); | |
| 588 push(ast.postfixExpression(pop(), toAnalyzerToken(token))); | |
| 589 } | |
| 590 | |
| 591 void handleModifier(Token token) { | |
| 592 debugEvent("Modifier"); | |
| 593 // TODO(ahe): Don't ignore modifiers. | |
| 594 } | |
| 595 | |
| 596 void handleModifiers(int count) { | |
| 597 debugEvent("Modifiers"); | |
| 598 // TODO(ahe): Don't ignore modifiers. | |
| 599 push(NullValue.Modifiers); | |
| 600 } | |
| 601 } | |
| OLD | NEW |