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(toAnalyzerToken(last), |
| 118 unescapeLastStringPart(last.value, quote))); |
| 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 var kernel = toKernel(body, elementStore, library.library, scope); |
| 201 if (member is ProcedureBuilder) { |
| 202 ProcedureBuilder builder = member; |
| 203 builder.body = kernel; |
| 204 } else { |
| 205 internalError("Internal error: expected procedure, but got: $member"); |
| 206 } |
| 207 } |
| 208 |
| 209 void beginCascade(Token token) { |
| 210 debugEvent("beginCascade"); |
| 211 Expression expression = pop(); |
| 212 push(token); |
| 213 if (expression is CascadeExpression) { |
| 214 push(expression); |
| 215 } else { |
| 216 push(ast.cascadeExpression(expression, <Expression>[])); |
| 217 } |
| 218 push(NullValue.CascadeReceiver); |
| 219 } |
| 220 |
| 221 void endCascade() { |
| 222 debugEvent("Cascade"); |
| 223 Expression expression = pop(); |
| 224 CascadeExpression receiver = pop(); |
| 225 pop(); // Token. |
| 226 receiver.cascadeSections.add(expression); |
| 227 push(receiver); |
| 228 } |
| 229 |
| 230 void handleBinaryExpression(Token token) { |
| 231 debugEvent("BinaryExpression"); |
| 232 if (identical(".", token.stringValue) || |
| 233 identical("..", token.stringValue)) { |
| 234 doDotExpression(token); |
| 235 } else { |
| 236 Expression right = pop(); |
| 237 Expression left = pop(); |
| 238 push(ast.binaryExpression(left, toAnalyzerToken(token), right)); |
| 239 } |
| 240 } |
| 241 |
| 242 void doDotExpression(Token token) { |
| 243 Expression identifierOrInvoke = pop(); |
| 244 Expression receiver = pop(); |
| 245 if (identifierOrInvoke is SimpleIdentifier) { |
| 246 push(ast.propertyAccess(receiver, toAnalyzerToken(token), |
| 247 identifierOrInvoke)); |
| 248 } else if (identifierOrInvoke is MethodInvocation) { |
| 249 assert(identifierOrInvoke.target == null); |
| 250 identifierOrInvoke |
| 251 ..target = receiver |
| 252 ..operator = toAnalyzerToken(token); |
| 253 push(identifierOrInvoke); |
| 254 } else { |
| 255 internalError( |
| 256 "Unhandled property access: ${identifierOrInvoke.runtimeType}"); |
| 257 } |
| 258 } |
| 259 |
| 260 void handleLiteralInt(Token token) { |
| 261 debugEvent("LiteralInt"); |
| 262 push(ast.integerLiteral(toAnalyzerToken(token), int.parse(token.value))); |
| 263 } |
| 264 |
| 265 void endReturnStatement( |
| 266 bool hasExpression, Token beginToken, Token endToken) { |
| 267 debugEvent("ReturnStatement"); |
| 268 Expression expression = hasExpression ? pop() : null; |
| 269 push(ast.returnStatement(toAnalyzerToken(beginToken), expression, |
| 270 toAnalyzerToken(endToken))); |
| 271 } |
| 272 |
| 273 void endIfStatement(Token ifToken, Token elseToken) { |
| 274 Statement elsePart = popIfNotNull(elseToken); |
| 275 Statement thenPart = pop(); |
| 276 Expression condition = pop(); |
| 277 BeginGroupToken leftParenthesis = ifToken.next; |
| 278 push(ast.ifStatement( |
| 279 toAnalyzerToken(ifToken), toAnalyzerToken(ifToken.next), condition, |
| 280 toAnalyzerToken(leftParenthesis.endGroup), thenPart, |
| 281 toAnalyzerToken(elseToken), elsePart)); |
| 282 } |
| 283 |
| 284 void prepareInitializers() { |
| 285 debugEvent("prepareInitializers"); |
| 286 } |
| 287 |
| 288 void handleNoInitializers() { |
| 289 debugEvent("NoInitializers"); |
| 290 } |
| 291 |
| 292 void endInitializers(int count, Token beginToken, Token endToken) { |
| 293 debugEvent("Initializers"); |
| 294 popList(count); |
| 295 } |
| 296 |
| 297 void endInitializer(Token assignmentOperator) { |
| 298 debugEvent("Initializer"); |
| 299 assert(assignmentOperator.stringValue == "="); |
| 300 Expression initializer = pop(); |
| 301 Identifier identifier = pop(); |
| 302 // TODO(ahe): Don't push initializers, instead install them. |
| 303 push(ast.variableDeclaration( |
| 304 identifier, toAnalyzerToken(assignmentOperator), initializer)); |
| 305 } |
| 306 |
| 307 void endInitializedIdentifier() { |
| 308 debugEvent("InitializedIdentifier"); |
| 309 AstNode node = pop(); |
| 310 VariableDeclaration variable; |
| 311 if (node is VariableDeclaration) { |
| 312 variable = node; |
| 313 } else if (node is SimpleIdentifier) { |
| 314 variable = ast.variableDeclaration(node, null, null); |
| 315 } else { |
| 316 internalError("unhandled identifier: ${node.runtimeType}"); |
| 317 } |
| 318 push(variable); |
| 319 scope[variable.name.name] = variable.name.staticElement = |
| 320 new AnalyzerLocalVariableElemment(variable); |
| 321 } |
| 322 |
| 323 void endVariablesDeclaration(int count, Token endToken) { |
| 324 debugEvent("VariablesDeclaration"); |
| 325 List<VariableDeclaration> variables = popList(count); |
| 326 TypeName type = pop(); |
| 327 pop(); // Modifiers. |
| 328 push(ast.variableDeclarationStatement( |
| 329 ast.variableDeclarationList(null, null, null, type, variables), |
| 330 toAnalyzerToken(endToken))); |
| 331 } |
| 332 |
| 333 void handleAssignmentExpression(Token token) { |
| 334 debugEvent("AssignmentExpression"); |
| 335 Expression rhs = pop(); |
| 336 Expression lhs = pop(); |
| 337 push(ast.assignmentExpression(lhs, toAnalyzerToken(token), rhs)); |
| 338 } |
| 339 |
| 340 void endBlock(int count, Token beginToken, Token endToken) { |
| 341 debugEvent("Block"); |
| 342 List<Statement> statements = popList(count) ?? <Statement>[]; |
| 343 exitLocalScope(); |
| 344 push(ast.block(toAnalyzerToken(beginToken), statements, |
| 345 toAnalyzerToken(endToken))); |
| 346 } |
| 347 |
| 348 void endForStatement( |
| 349 int updateExpressionCount, Token beginToken, Token endToken) { |
| 350 debugEvent("ForStatement"); |
| 351 Statement body = pop(); |
| 352 List<Expression> updates = popList(updateExpressionCount); |
| 353 ExpressionStatement condition = pop(); |
| 354 VariableDeclarationStatement variables = pop(); |
| 355 exitContinueTarget(); |
| 356 exitBreakTarget(); |
| 357 exitLocalScope(); |
| 358 BeginGroupToken leftParenthesis = beginToken.next; |
| 359 push(ast.forStatement( |
| 360 toAnalyzerToken(beginToken), |
| 361 toAnalyzerToken(leftParenthesis), |
| 362 variables?.variables, |
| 363 null, // initialization. |
| 364 variables?.semicolon, |
| 365 condition.expression, |
| 366 condition.semicolon, |
| 367 updates, |
| 368 toAnalyzerToken(leftParenthesis.endGroup), |
| 369 body)); |
| 370 } |
| 371 |
| 372 void handleLiteralList( |
| 373 int count, Token beginToken, Token constKeyword, Token endToken) { |
| 374 debugEvent("LiteralList"); |
| 375 List<Expression> expressions = popList(count); |
| 376 TypeArgumentList typeArguments = pop(); |
| 377 push(ast.listLiteral( |
| 378 toAnalyzerToken(constKeyword), |
| 379 typeArguments, |
| 380 toAnalyzerToken(beginToken), |
| 381 expressions, |
| 382 toAnalyzerToken(endToken))); |
| 383 } |
| 384 |
| 385 void handleAsyncModifier(Token asyncToken, Token starToken) { |
| 386 debugEvent("AsyncModifier"); |
| 387 push(asyncMarkerFromTokens(asyncToken, starToken)); |
| 388 } |
| 389 |
| 390 void endAwaitExpression(Token beginToken, Token endToken) { |
| 391 debugEvent("AwaitExpression"); |
| 392 push(ast.awaitExpression(toAnalyzerToken(beginToken), pop())); |
| 393 } |
| 394 |
| 395 void beginLiteralSymbol(Token token) { |
| 396 isFirstIdentifier = false; |
| 397 } |
| 398 |
| 399 void handleLiteralBool(Token token) { |
| 400 debugEvent("LiteralBool"); |
| 401 bool value = identical(token.stringValue, "true"); |
| 402 assert(value || identical(token.stringValue, "false")); |
| 403 push(ast.booleanLiteral(toAnalyzerToken(token), value)); |
| 404 } |
| 405 |
| 406 void handleLiteralDouble(Token token) { |
| 407 debugEvent("LiteralDouble"); |
| 408 push(ast.doubleLiteral(toAnalyzerToken(token), double.parse(token.value))); |
| 409 } |
| 410 |
| 411 void handleLiteralNull(Token token) { |
| 412 debugEvent("LiteralNull"); |
| 413 push(ast.nullLiteral(toAnalyzerToken(token))); |
| 414 } |
| 415 |
| 416 void handleLiteralMap( |
| 417 int count, Token beginToken, Token constKeyword, Token endToken) { |
| 418 debugEvent("LiteralMap"); |
| 419 List<MapLiteralEntry> entries = popList(count) ?? <MapLiteralEntry>[]; |
| 420 TypeArgumentList typeArguments = pop(); |
| 421 push(ast.mapLiteral(toAnalyzerToken(constKeyword), typeArguments, |
| 422 toAnalyzerToken(beginToken), entries, toAnalyzerToken(endToken))); |
| 423 } |
| 424 |
| 425 void endLiteralMapEntry(Token colon, Token endToken) { |
| 426 debugEvent("LiteralMapEntry"); |
| 427 Expression value = pop(); |
| 428 Expression key = pop(); |
| 429 push(ast.mapLiteralEntry(key, toAnalyzerToken(colon), value)); |
| 430 } |
| 431 |
| 432 void endLiteralSymbol(Token hashToken, int identifierCount) { |
| 433 debugEvent("LiteralSymbol"); |
| 434 List<analyzer.Token> components = new List<analyzer.Token>(identifierCount); |
| 435 for (int i = identifierCount - 1; i >= 0; i--) { |
| 436 SimpleIdentifier identifier = pop(); |
| 437 components[i] = identifier.token; |
| 438 } |
| 439 push(ast.symbolLiteral(toAnalyzerToken(hashToken), components)); |
| 440 } |
| 441 |
| 442 void endType(Token beginToken, Token endToken) { |
| 443 debugEvent("Type"); |
| 444 TypeArgumentList arguments = pop(); |
| 445 SimpleIdentifier name = pop(); |
| 446 KernelClassElement cls = name.staticElement; |
| 447 if (cls == null) { |
| 448 Builder builder = scope.lookup(name.name); |
| 449 if (builder == null) { |
| 450 internalError("Undefined name: $name"); |
| 451 } |
| 452 cls = elementStore[builder]; |
| 453 assert(cls != null); |
| 454 name.staticElement = cls; |
| 455 } |
| 456 push(ast.typeName(name, arguments)..type = cls.rawType); |
| 457 } |
| 458 |
| 459 void handleAsOperator(Token operator, Token endToken) { |
| 460 debugEvent("AsOperator"); |
| 461 TypeName type = pop(); |
| 462 Expression expression = pop(); |
| 463 push(ast.asExpression(expression, toAnalyzerToken(operator), type)); |
| 464 } |
| 465 |
| 466 void handleIsOperator(Token operator, Token not, Token endToken) { |
| 467 debugEvent("IsOperator"); |
| 468 TypeName type = pop(); |
| 469 Expression expression = pop(); |
| 470 push(ast.isExpression(expression, toAnalyzerToken(operator), |
| 471 toAnalyzerToken(not), type)); |
| 472 } |
| 473 |
| 474 void handleConditionalExpression(Token question, Token colon) { |
| 475 debugEvent("ConditionalExpression"); |
| 476 Expression elseExpression = pop(); |
| 477 Expression thenExpression = pop(); |
| 478 Expression condition = pop(); |
| 479 push(ast.conditionalExpression(condition, toAnalyzerToken(question), |
| 480 thenExpression, toAnalyzerToken(colon), elseExpression)); |
| 481 } |
| 482 |
| 483 void endThrowExpression(Token throwToken, Token endToken) { |
| 484 debugEvent("ThrowExpression"); |
| 485 push(ast.throwExpression(toAnalyzerToken(throwToken), pop())); |
| 486 } |
| 487 |
| 488 void endFormalParameter(Token thisKeyword) { |
| 489 debugEvent("FormalParameter"); |
| 490 if (thisKeyword != null) { |
| 491 internalError("'this' can't be used here."); |
| 492 } |
| 493 SimpleIdentifier name = pop(); |
| 494 TypeName type = pop(); |
| 495 pop(); // Modifiers. |
| 496 pop(); // Metadata. |
| 497 SimpleFormalParameter node = ast.simpleFormalParameter(null, null, |
| 498 toAnalyzerToken(thisKeyword), type, name); |
| 499 scope[name.name] = name.staticElement = new AnalyzerParameterElement(node); |
| 500 push(node); |
| 501 } |
| 502 |
| 503 void endFormalParameters(int count, Token beginToken, Token endToken) { |
| 504 debugEvent("FormalParameters"); |
| 505 List<FormalParameter> parameters = popList(count) ?? <FormalParameter>[]; |
| 506 push(ast.formalParameterList(toAnalyzerToken(beginToken), parameters, |
| 507 null, null, toAnalyzerToken(endToken))); |
| 508 } |
| 509 |
| 510 void handleCatchBlock(Token onKeyword, Token catchKeyword) { |
| 511 debugEvent("CatchBlock"); |
| 512 Block body = pop(); |
| 513 FormalParameterList catchParameters = popIfNotNull(catchKeyword); |
| 514 if (catchKeyword != null) { |
| 515 exitLocalScope(); |
| 516 } |
| 517 TypeName type = popIfNotNull(onKeyword); |
| 518 SimpleIdentifier exception; |
| 519 SimpleIdentifier stackTrace; |
| 520 if (catchParameters != null) { |
| 521 if (catchParameters.length > 0) { |
| 522 exception = catchParameters.parameters[0].identifier; |
| 523 } |
| 524 if (catchParameters.length > 1) { |
| 525 stackTrace = catchParameters.parameters[1].identifier; |
| 526 } |
| 527 } |
| 528 BeginGroupToken leftParenthesis = catchKeyword.next; |
| 529 push(ast.catchClause(toAnalyzerToken(onKeyword), type, |
| 530 toAnalyzerToken(catchKeyword), toAnalyzerToken(leftParenthesis), |
| 531 exception, null, stackTrace, |
| 532 toAnalyzerToken(leftParenthesis.endGroup), body)); |
| 533 } |
| 534 |
| 535 void endTryStatement( |
| 536 int catchCount, Token tryKeyword, Token finallyKeyword) { |
| 537 Block finallyBlock = popIfNotNull(finallyKeyword); |
| 538 List<CatchClause> catchClauses = popList(catchCount); |
| 539 Block body = pop(); |
| 540 push(ast.tryStatement(toAnalyzerToken(tryKeyword), body, catchClauses, |
| 541 toAnalyzerToken(finallyKeyword), finallyBlock)); |
| 542 } |
| 543 |
| 544 void handleNoExpression(Token token) { |
| 545 debugEvent("NoExpression"); |
| 546 push(NullValue.Expression); |
| 547 } |
| 548 |
| 549 void handleIndexedExpression( |
| 550 Token openCurlyBracket, Token closeCurlyBracket) { |
| 551 debugEvent("IndexedExpression"); |
| 552 Expression index = pop(); |
| 553 Expression target = pop(); |
| 554 if (target == null) { |
| 555 CascadeExpression receiver = pop(); |
| 556 Token token = peek(); |
| 557 push(receiver); |
| 558 IndexExpression expression = ast.indexExpressionForCascade( |
| 559 toAnalyzerToken(token), toAnalyzerToken(openCurlyBracket), index, |
| 560 toAnalyzerToken(closeCurlyBracket)); |
| 561 assert(expression.isCascaded); |
| 562 push(expression); |
| 563 } else { |
| 564 push(ast.indexExpressionForTarget(target, |
| 565 toAnalyzerToken(openCurlyBracket), index, |
| 566 toAnalyzerToken(closeCurlyBracket))); |
| 567 } |
| 568 } |
| 569 |
| 570 void handleUnaryPrefixExpression(Token token) { |
| 571 debugEvent("UnaryPrefixExpression"); |
| 572 push(ast.prefixExpression(toAnalyzerToken(token), pop())); |
| 573 } |
| 574 |
| 575 void handleUnaryPrefixAssignmentExpression(Token token) { |
| 576 debugEvent("UnaryPrefixAssignmentExpression"); |
| 577 push(ast.prefixExpression(toAnalyzerToken(token), pop())); |
| 578 } |
| 579 |
| 580 void handleUnaryPostfixAssignmentExpression(Token token) { |
| 581 debugEvent("UnaryPostfixAssignmentExpression"); |
| 582 push(ast.postfixExpression(pop(), toAnalyzerToken(token))); |
| 583 } |
| 584 |
| 585 void handleModifier(Token token) { |
| 586 debugEvent("Modifier"); |
| 587 // TODO(ahe): Don't ignore modifiers. |
| 588 } |
| 589 |
| 590 void handleModifiers(int count) { |
| 591 debugEvent("Modifiers"); |
| 592 // TODO(ahe): Don't ignore modifiers. |
| 593 push(NullValue.Modifiers); |
| 594 } |
| 595 } |
OLD | NEW |