| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of resolution; | 5 part of resolution; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Core implementation of resolution. | 8 * Core implementation of resolution. |
| 9 * | 9 * |
| 10 * Do not subclass or instantiate this class outside this library | 10 * Do not subclass or instantiate this class outside this library |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 ? Scope.buildEnclosingScope(element) : element.buildScope(), | 95 ? Scope.buildEnclosingScope(element) : element.buildScope(), |
| 96 // The type annotations on a typedef do not imply type checks. | 96 // The type annotations on a typedef do not imply type checks. |
| 97 // TODO(karlklose): clean this up (dartbug.com/8870). | 97 // TODO(karlklose): clean this up (dartbug.com/8870). |
| 98 inCheckContext = compiler.enableTypeAssertions && | 98 inCheckContext = compiler.enableTypeAssertions && |
| 99 !element.isLibrary && | 99 !element.isLibrary && |
| 100 !element.isTypedef && | 100 !element.isTypedef && |
| 101 !element.enclosingElement.isTypedef, | 101 !element.enclosingElement.isTypedef, |
| 102 inCatchBlock = false, | 102 inCatchBlock = false, |
| 103 super(compiler, registry); | 103 super(compiler, registry); |
| 104 | 104 |
| 105 CoreTypes get coreTypes => compiler.coreTypes; |
| 106 |
| 105 AsyncMarker get currentAsyncMarker { | 107 AsyncMarker get currentAsyncMarker { |
| 106 if (enclosingElement is FunctionElement) { | 108 if (enclosingElement is FunctionElement) { |
| 107 FunctionElement function = enclosingElement; | 109 FunctionElement function = enclosingElement; |
| 108 return function.asyncMarker; | 110 return function.asyncMarker; |
| 109 } | 111 } |
| 110 return AsyncMarker.SYNC; | 112 return AsyncMarker.SYNC; |
| 111 } | 113 } |
| 112 | 114 |
| 113 Element reportLookupErrorIfAny(Element result, Node node, String name) { | 115 Element reportLookupErrorIfAny(Element result, Node node, String name) { |
| 114 if (!Elements.isUnresolved(result)) { | 116 if (!Elements.isUnresolved(result)) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 return result; | 161 return result; |
| 160 } | 162 } |
| 161 | 163 |
| 162 doInPromotionScope(Node node, action()) { | 164 doInPromotionScope(Node node, action()) { |
| 163 promotionScope = promotionScope.prepend(node); | 165 promotionScope = promotionScope.prepend(node); |
| 164 var result = action(); | 166 var result = action(); |
| 165 promotionScope = promotionScope.tail; | 167 promotionScope = promotionScope.tail; |
| 166 return result; | 168 return result; |
| 167 } | 169 } |
| 168 | 170 |
| 169 visitInStaticContext(Node node) { | 171 ResolutionResult visitInStaticContext(Node node) { |
| 170 inStaticContext(() => visit(node)); | 172 return inStaticContext(() => visit(node)); |
| 171 } | 173 } |
| 172 | 174 |
| 173 ErroneousElement reportAndCreateErroneousElement( | 175 ErroneousElement reportAndCreateErroneousElement( |
| 174 Node node, | 176 Node node, |
| 175 String name, | 177 String name, |
| 176 MessageKind kind, | 178 MessageKind kind, |
| 177 Map arguments, | 179 Map arguments, |
| 178 {bool isError: false}) { | 180 {bool isError: false}) { |
| 179 if (isError) { | 181 if (isError) { |
| 180 compiler.reportError(node, kind, arguments); | 182 compiler.reportError(node, kind, arguments); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 registry.registerThrowNoSuchMethod(); | 225 registry.registerThrowNoSuchMethod(); |
| 224 return reportAndCreateErroneousElement( | 226 return reportAndCreateErroneousElement( |
| 225 node, name, kind, arguments, isError: inInitializer); | 227 node, name, kind, arguments, isError: inInitializer); |
| 226 } | 228 } |
| 227 | 229 |
| 228 ResolutionResult visitIdentifier(Identifier node) { | 230 ResolutionResult visitIdentifier(Identifier node) { |
| 229 if (node.isThis()) { | 231 if (node.isThis()) { |
| 230 if (!inInstanceContext) { | 232 if (!inInstanceContext) { |
| 231 error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); | 233 error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); |
| 232 } | 234 } |
| 233 return null; | 235 return const NoneResult(); |
| 234 } else if (node.isSuper()) { | 236 } else if (node.isSuper()) { |
| 235 if (!inInstanceContext) { | 237 if (!inInstanceContext) { |
| 236 error(node, MessageKind.NO_SUPER_IN_STATIC); | 238 error(node, MessageKind.NO_SUPER_IN_STATIC); |
| 237 } | 239 } |
| 238 if ((ElementCategory.SUPER & allowedCategory) == 0) { | 240 if ((ElementCategory.SUPER & allowedCategory) == 0) { |
| 239 error(node, MessageKind.INVALID_USE_OF_SUPER); | 241 error(node, MessageKind.INVALID_USE_OF_SUPER); |
| 240 } | 242 } |
| 241 return null; | 243 return const NoneResult(); |
| 242 } else { | 244 } else { |
| 243 String name = node.source; | 245 String name = node.source; |
| 244 Element element = lookupInScope(compiler, node, scope, name); | 246 Element element = lookupInScope(compiler, node, scope, name); |
| 245 if (Elements.isUnresolved(element) && name == 'dynamic') { | 247 if (Elements.isUnresolved(element) && name == 'dynamic') { |
| 246 // TODO(johnniwinther): Remove this hack when we can return more complex | 248 // TODO(johnniwinther): Remove this hack when we can return more complex |
| 247 // objects than [Element] from this method. | 249 // objects than [Element] from this method. |
| 248 element = compiler.typeClass; | 250 element = compiler.typeClass; |
| 249 // Set the type to be `dynamic` to mark that this is a type literal. | 251 // Set the type to be `dynamic` to mark that this is a type literal. |
| 250 registry.setType(node, const DynamicType()); | 252 registry.setType(node, const DynamicType()); |
| 251 } | 253 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 265 } | 267 } |
| 266 } | 268 } |
| 267 if (!Elements.isUnresolved(element) && element.isClass) { | 269 if (!Elements.isUnresolved(element) && element.isClass) { |
| 268 ClassElement classElement = element; | 270 ClassElement classElement = element; |
| 269 classElement.ensureResolved(compiler); | 271 classElement.ensureResolved(compiler); |
| 270 } | 272 } |
| 271 return new ElementResult(registry.useElement(node, element)); | 273 return new ElementResult(registry.useElement(node, element)); |
| 272 } | 274 } |
| 273 } | 275 } |
| 274 | 276 |
| 275 ResolutionResult visitTypeAnnotation(TypeAnnotation node) { | 277 TypeResult visitTypeAnnotation(TypeAnnotation node) { |
| 276 DartType type = resolveTypeAnnotation(node); | 278 DartType type = resolveTypeAnnotation(node); |
| 277 if (inCheckContext) { | 279 if (inCheckContext) { |
| 278 registry.registerIsCheck(type); | 280 registry.registerIsCheck(type); |
| 279 } | 281 } |
| 280 return new TypeResult(type); | 282 return new TypeResult(type); |
| 281 } | 283 } |
| 282 | 284 |
| 283 bool isNamedConstructor(Send node) => node.receiver != null; | 285 bool isNamedConstructor(Send node) => node.receiver != null; |
| 284 | 286 |
| 285 Selector getRedirectingThisOrSuperConstructorSelector(Send node) { | 287 Selector getRedirectingThisOrSuperConstructorSelector(Send node) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 compiler.resolver.constantCompiler.compileConstant(parameter); | 353 compiler.resolver.constantCompiler.compileConstant(parameter); |
| 352 }); | 354 }); |
| 353 }); | 355 }); |
| 354 if (inCheckContext) { | 356 if (inCheckContext) { |
| 355 functionParameters.forEachParameter((ParameterElement element) { | 357 functionParameters.forEachParameter((ParameterElement element) { |
| 356 registry.registerIsCheck(element.type); | 358 registry.registerIsCheck(element.type); |
| 357 }); | 359 }); |
| 358 } | 360 } |
| 359 } | 361 } |
| 360 | 362 |
| 361 visitCascade(Cascade node) { | 363 ResolutionResult visitCascade(Cascade node) { |
| 362 visit(node.expression); | 364 visit(node.expression); |
| 365 return const NoneResult(); |
| 363 } | 366 } |
| 364 | 367 |
| 365 visitCascadeReceiver(CascadeReceiver node) { | 368 ResolutionResult visitCascadeReceiver(CascadeReceiver node) { |
| 366 visit(node.expression); | 369 visit(node.expression); |
| 370 return const NoneResult(); |
| 367 } | 371 } |
| 368 | 372 |
| 369 visitClassNode(ClassNode node) { | 373 ResolutionResult visitIn(Node node, Scope nestedScope) { |
| 370 internalError(node, "shouldn't be called"); | |
| 371 } | |
| 372 | |
| 373 visitIn(Node node, Scope nestedScope) { | |
| 374 Scope oldScope = scope; | 374 Scope oldScope = scope; |
| 375 scope = nestedScope; | 375 scope = nestedScope; |
| 376 ResolutionResult result = visit(node); | 376 ResolutionResult result = visit(node); |
| 377 scope = oldScope; | 377 scope = oldScope; |
| 378 return result; | 378 return result; |
| 379 } | 379 } |
| 380 | 380 |
| 381 /** | 381 /** |
| 382 * Introduces new default targets for break and continue | 382 * Introduces new default targets for break and continue |
| 383 * before visiting the body of the loop | 383 * before visiting the body of the loop |
| 384 */ | 384 */ |
| 385 visitLoopBodyIn(Loop loop, Node body, Scope bodyScope) { | 385 void visitLoopBodyIn(Loop loop, Node body, Scope bodyScope) { |
| 386 JumpTarget element = getOrDefineTarget(loop); | 386 JumpTarget element = getOrDefineTarget(loop); |
| 387 statementScope.enterLoop(element); | 387 statementScope.enterLoop(element); |
| 388 visitIn(body, bodyScope); | 388 visitIn(body, bodyScope); |
| 389 statementScope.exitLoop(); | 389 statementScope.exitLoop(); |
| 390 if (!element.isTarget) { | 390 if (!element.isTarget) { |
| 391 registry.undefineTarget(loop); | 391 registry.undefineTarget(loop); |
| 392 } | 392 } |
| 393 } | 393 } |
| 394 | 394 |
| 395 visitBlock(Block node) { | 395 ResolutionResult visitBlock(Block node) { |
| 396 visitIn(node.statements, new BlockScope(scope)); | 396 visitIn(node.statements, new BlockScope(scope)); |
| 397 return const NoneResult(); |
| 397 } | 398 } |
| 398 | 399 |
| 399 visitDoWhile(DoWhile node) { | 400 ResolutionResult visitDoWhile(DoWhile node) { |
| 400 visitLoopBodyIn(node, node.body, new BlockScope(scope)); | 401 visitLoopBodyIn(node, node.body, new BlockScope(scope)); |
| 401 visit(node.condition); | 402 visit(node.condition); |
| 403 return const NoneResult(); |
| 402 } | 404 } |
| 403 | 405 |
| 404 visitEmptyStatement(EmptyStatement node) { } | 406 ResolutionResult visitEmptyStatement(EmptyStatement node) { |
| 407 return const NoneResult(); |
| 408 } |
| 405 | 409 |
| 406 visitExpressionStatement(ExpressionStatement node) { | 410 ResolutionResult visitExpressionStatement(ExpressionStatement node) { |
| 407 ExpressionStatement oldExpressionStatement = currentExpressionStatement; | 411 ExpressionStatement oldExpressionStatement = currentExpressionStatement; |
| 408 currentExpressionStatement = node; | 412 currentExpressionStatement = node; |
| 409 visit(node.expression); | 413 visit(node.expression); |
| 410 currentExpressionStatement = oldExpressionStatement; | 414 currentExpressionStatement = oldExpressionStatement; |
| 415 return const NoneResult(); |
| 411 } | 416 } |
| 412 | 417 |
| 413 visitFor(For node) { | 418 ResolutionResult visitFor(For node) { |
| 414 Scope blockScope = new BlockScope(scope); | 419 Scope blockScope = new BlockScope(scope); |
| 415 visitIn(node.initializer, blockScope); | 420 visitIn(node.initializer, blockScope); |
| 416 visitIn(node.condition, blockScope); | 421 visitIn(node.condition, blockScope); |
| 417 visitIn(node.update, blockScope); | 422 visitIn(node.update, blockScope); |
| 418 visitLoopBodyIn(node, node.body, blockScope); | 423 visitLoopBodyIn(node, node.body, blockScope); |
| 424 return const NoneResult(); |
| 419 } | 425 } |
| 420 | 426 |
| 421 visitFunctionDeclaration(FunctionDeclaration node) { | 427 ResolutionResult visitFunctionDeclaration(FunctionDeclaration node) { |
| 422 assert(node.function.name != null); | 428 assert(node.function.name != null); |
| 423 visitFunctionExpression(node.function, inFunctionDeclaration: true); | 429 visitFunctionExpression(node.function, inFunctionDeclaration: true); |
| 430 return const NoneResult(); |
| 424 } | 431 } |
| 425 | 432 |
| 426 | 433 |
| 427 /// Process a local function declaration or an anonymous function expression. | 434 /// Process a local function declaration or an anonymous function expression. |
| 428 /// | 435 /// |
| 429 /// [inFunctionDeclaration] is `true` when the current node is the immediate | 436 /// [inFunctionDeclaration] is `true` when the current node is the immediate |
| 430 /// child of a function declaration. | 437 /// child of a function declaration. |
| 431 /// | 438 /// |
| 432 /// This is used to distinguish local function declarations from anonymous | 439 /// This is used to distinguish local function declarations from anonymous |
| 433 /// function expressions. | 440 /// function expressions. |
| 434 visitFunctionExpression(FunctionExpression node, | 441 ResolutionResult visitFunctionExpression( |
| 435 {bool inFunctionDeclaration: false}) { | 442 FunctionExpression node, |
| 443 {bool inFunctionDeclaration: false}) { |
| 436 bool doAddToScope = inFunctionDeclaration; | 444 bool doAddToScope = inFunctionDeclaration; |
| 437 if (!inFunctionDeclaration && node.name != null) { | 445 if (!inFunctionDeclaration && node.name != null) { |
| 438 compiler.reportError( | 446 compiler.reportError( |
| 439 node.name, | 447 node.name, |
| 440 MessageKind.NAMED_FUNCTION_EXPRESSION, | 448 MessageKind.NAMED_FUNCTION_EXPRESSION, |
| 441 {'name': node.name}); | 449 {'name': node.name}); |
| 442 } | 450 } |
| 443 visit(node.returnType); | 451 visit(node.returnType); |
| 444 String name; | 452 String name; |
| 445 if (node.name == null) { | 453 if (node.name == null) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 473 StatementScope oldStatementScope = statementScope; | 481 StatementScope oldStatementScope = statementScope; |
| 474 statementScope = new StatementScope(); | 482 statementScope = new StatementScope(); |
| 475 visit(node.body); | 483 visit(node.body); |
| 476 statementScope = oldStatementScope; | 484 statementScope = oldStatementScope; |
| 477 | 485 |
| 478 scope = oldScope; | 486 scope = oldScope; |
| 479 enclosingElement = previousEnclosingElement; | 487 enclosingElement = previousEnclosingElement; |
| 480 | 488 |
| 481 registry.registerClosure(function); | 489 registry.registerClosure(function); |
| 482 registry.registerInstantiatedClass(compiler.functionClass); | 490 registry.registerInstantiatedClass(compiler.functionClass); |
| 491 return const NoneResult(); |
| 483 } | 492 } |
| 484 | 493 |
| 485 visitIf(If node) { | 494 ResolutionResult visitIf(If node) { |
| 486 doInPromotionScope(node.condition.expression, () => visit(node.condition)); | 495 doInPromotionScope(node.condition.expression, () => visit(node.condition)); |
| 487 doInPromotionScope(node.thenPart, | 496 doInPromotionScope(node.thenPart, |
| 488 () => visitIn(node.thenPart, new BlockScope(scope))); | 497 () => visitIn(node.thenPart, new BlockScope(scope))); |
| 489 visitIn(node.elsePart, new BlockScope(scope)); | 498 visitIn(node.elsePart, new BlockScope(scope)); |
| 499 return const NoneResult(); |
| 490 } | 500 } |
| 491 | 501 |
| 492 ResolutionResult resolveSend(Send node) { | 502 ResolutionResult resolveSend(Send node) { |
| 493 Selector selector = resolveSelector(node, null); | 503 Selector selector = resolveSelector(node, null); |
| 494 if (node.isSuperCall) registry.registerSuperUse(node); | 504 if (node.isSuperCall) registry.registerSuperUse(node); |
| 495 | 505 |
| 496 if (node.receiver == null) { | 506 if (node.receiver == null) { |
| 497 // If this send is of the form "assert(expr);", then | 507 // If this send is of the form "assert(expr);", then |
| 498 // this is an assertion. | 508 // this is an assertion. |
| 499 if (selector.isAssert) { | 509 if (selector.isAssert) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 526 } | 536 } |
| 527 | 537 |
| 528 allowedCategory = oldCategory; | 538 allowedCategory = oldCategory; |
| 529 | 539 |
| 530 Element target; | 540 Element target; |
| 531 String name = node.selector.asIdentifier().source; | 541 String name = node.selector.asIdentifier().source; |
| 532 if (identical(name, 'this')) { | 542 if (identical(name, 'this')) { |
| 533 // TODO(ahe): Why is this using GENERIC? | 543 // TODO(ahe): Why is this using GENERIC? |
| 534 error(node.selector, MessageKind.GENERIC, | 544 error(node.selector, MessageKind.GENERIC, |
| 535 {'text': "expected an identifier"}); | 545 {'text': "expected an identifier"}); |
| 536 return null; | 546 return const NoneResult(); |
| 537 } else if (node.isSuperCall) { | 547 } else if (node.isSuperCall) { |
| 538 if (node.isOperator) { | 548 if (node.isOperator) { |
| 539 if (isUserDefinableOperator(name)) { | 549 if (isUserDefinableOperator(name)) { |
| 540 name = selector.name; | 550 name = selector.name; |
| 541 } else { | 551 } else { |
| 542 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name}); | 552 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name}); |
| 543 return null; | 553 return const NoneResult(); |
| 544 } | 554 } |
| 545 } | 555 } |
| 546 if (!inInstanceContext) { | 556 if (!inInstanceContext) { |
| 547 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); | 557 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); |
| 548 return null; | 558 return const NoneResult(); |
| 549 } | 559 } |
| 550 if (currentClass.supertype == null) { | 560 if (currentClass.supertype == null) { |
| 551 // This is just to guard against internal errors, so no need | 561 // This is just to guard against internal errors, so no need |
| 552 // for a real error message. | 562 // for a real error message. |
| 553 error(node.receiver, MessageKind.GENERIC, | 563 error(node.receiver, MessageKind.GENERIC, |
| 554 {'text': "Object has no superclass"}); | 564 {'text': "Object has no superclass"}); |
| 555 return null; | 565 return const NoneResult(); |
| 556 } | 566 } |
| 557 // TODO(johnniwinther): Ensure correct behavior if currentClass is a | 567 // TODO(johnniwinther): Ensure correct behavior if currentClass is a |
| 558 // patch. | 568 // patch. |
| 559 target = currentClass.lookupSuperByName(selector.memberName); | 569 target = currentClass.lookupSuperByName(selector.memberName); |
| 560 // [target] may be null which means invoking noSuchMethod on | 570 // [target] may be null which means invoking noSuchMethod on |
| 561 // super. | 571 // super. |
| 562 if (target == null) { | 572 if (target == null) { |
| 563 target = reportAndCreateErroneousElement( | 573 target = reportAndCreateErroneousElement( |
| 564 node, name, MessageKind.NO_SUCH_SUPER_MEMBER, | 574 node, name, MessageKind.NO_SUCH_SUPER_MEMBER, |
| 565 {'className': currentClass.name, 'memberName': name}); | 575 {'className': currentClass.name, 'memberName': name}); |
| 566 // We still need to register the invocation, because we might | 576 // We still need to register the invocation, because we might |
| 567 // call [:super.noSuchMethod:] which calls | 577 // call [:super.noSuchMethod:] which calls |
| 568 // [JSInvocationMirror._invokeOn]. | 578 // [JSInvocationMirror._invokeOn]. |
| 569 registry.registerDynamicInvocation(selector); | 579 registry.registerDynamicInvocation(selector); |
| 570 registry.registerSuperNoSuchMethod(); | 580 registry.registerSuperNoSuchMethod(); |
| 571 } | 581 } |
| 572 } else if (resolvedReceiver == null || | 582 } else if (Elements.isUnresolved(resolvedReceiver.element)) { |
| 573 Elements.isUnresolved(resolvedReceiver.element)) { | 583 return const NoneResult(); |
| 574 return null; | |
| 575 } else if (resolvedReceiver.element.isClass) { | 584 } else if (resolvedReceiver.element.isClass) { |
| 576 ClassElement receiverClass = resolvedReceiver.element; | 585 ClassElement receiverClass = resolvedReceiver.element; |
| 577 receiverClass.ensureResolved(compiler); | 586 receiverClass.ensureResolved(compiler); |
| 578 if (node.isOperator) { | 587 if (node.isOperator) { |
| 579 // When the resolved receiver is a class, we can have two cases: | 588 // When the resolved receiver is a class, we can have two cases: |
| 580 // 1) a static send: C.foo, or | 589 // 1) a static send: C.foo, or |
| 581 // 2) an operator send, where the receiver is a class literal: 'C + 1'. | 590 // 2) an operator send, where the receiver is a class literal: 'C + 1'. |
| 582 // The following code that looks up the selector on the resolved | 591 // The following code that looks up the selector on the resolved |
| 583 // receiver will treat the second as the invocation of a static operator | 592 // receiver will treat the second as the invocation of a static operator |
| 584 // if the resolved receiver is not null. | 593 // if the resolved receiver is not null. |
| 585 return null; | 594 return const NoneResult(); |
| 586 } | 595 } |
| 587 MembersCreator.computeClassMembersByName( | 596 MembersCreator.computeClassMembersByName( |
| 588 compiler, receiverClass.declaration, name); | 597 compiler, receiverClass.declaration, name); |
| 589 target = receiverClass.lookupLocalMember(name); | 598 target = receiverClass.lookupLocalMember(name); |
| 590 if (target == null || target.isInstanceMember) { | 599 if (target == null || target.isInstanceMember) { |
| 591 registry.registerThrowNoSuchMethod(); | 600 registry.registerThrowNoSuchMethod(); |
| 592 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 601 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
| 593 // try to resolve injected elements if [currentClass] is in the patch | 602 // try to resolve injected elements if [currentClass] is in the patch |
| 594 // library of [receiverClass]. | 603 // library of [receiverClass]. |
| 595 | 604 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 623 AmbiguousElement ambiguous = target; | 632 AmbiguousElement ambiguous = target; |
| 624 target = reportAndCreateErroneousElement( | 633 target = reportAndCreateErroneousElement( |
| 625 node, name, ambiguous.messageKind, ambiguous.messageArguments); | 634 node, name, ambiguous.messageKind, ambiguous.messageArguments); |
| 626 ambiguous.diagnose(enclosingElement, compiler); | 635 ambiguous.diagnose(enclosingElement, compiler); |
| 627 return new ElementResult(target); | 636 return new ElementResult(target); |
| 628 } else if (target.kind == ElementKind.CLASS) { | 637 } else if (target.kind == ElementKind.CLASS) { |
| 629 ClassElement classElement = target; | 638 ClassElement classElement = target; |
| 630 classElement.ensureResolved(compiler); | 639 classElement.ensureResolved(compiler); |
| 631 } | 640 } |
| 632 } | 641 } |
| 633 return new ElementResult(target); | 642 return new ResolutionResult.forElement(target); |
| 634 } | 643 } |
| 635 | 644 |
| 636 static Selector computeSendSelector(Send node, | 645 static Selector computeSendSelector(Send node, |
| 637 LibraryElement library, | 646 LibraryElement library, |
| 638 Element element) { | 647 Element element) { |
| 639 // First determine if this is part of an assignment. | 648 // First determine if this is part of an assignment. |
| 640 bool isSet = node.asSendSet() != null; | 649 bool isSet = node.asSendSet() != null; |
| 641 | 650 |
| 642 if (node.isIndex) { | 651 if (node.isIndex) { |
| 643 return isSet ? new Selector.indexSet() : new Selector.index(); | 652 return isSet ? new Selector.indexSet() : new Selector.index(); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 type = resolveTypeAnnotation(typeNode); | 899 type = resolveTypeAnnotation(typeNode); |
| 891 sendStructure = new IsNotStructure(type); | 900 sendStructure = new IsNotStructure(type); |
| 892 } else { | 901 } else { |
| 893 // `e is T`. | 902 // `e is T`. |
| 894 Node typeNode = node.arguments.head; | 903 Node typeNode = node.arguments.head; |
| 895 type = resolveTypeAnnotation(typeNode); | 904 type = resolveTypeAnnotation(typeNode); |
| 896 sendStructure = new IsStructure(type); | 905 sendStructure = new IsStructure(type); |
| 897 } | 906 } |
| 898 registry.registerIsCheck(type); | 907 registry.registerIsCheck(type); |
| 899 registry.registerSendStructure(node, sendStructure); | 908 registry.registerSendStructure(node, sendStructure); |
| 900 return null; | 909 return const NoneResult(); |
| 901 } | 910 } |
| 902 | 911 |
| 903 /// Handle a type cast expression, like `a as T`. | 912 /// Handle a type cast expression, like `a as T`. |
| 904 ResolutionResult handleAs(Send node) { | 913 ResolutionResult handleAs(Send node) { |
| 905 Node expression = node.receiver; | 914 Node expression = node.receiver; |
| 906 visitExpression(expression); | 915 visitExpression(expression); |
| 907 | 916 |
| 908 Node typeNode = node.arguments.head; | 917 Node typeNode = node.arguments.head; |
| 909 DartType type = resolveTypeAnnotation(typeNode); | 918 DartType type = resolveTypeAnnotation(typeNode); |
| 910 registry.registerAsCheck(type); | 919 registry.registerAsCheck(type); |
| 911 registry.registerSendStructure(node, new AsStructure(type)); | 920 registry.registerSendStructure(node, new AsStructure(type)); |
| 912 return null; | 921 return const NoneResult(); |
| 913 } | 922 } |
| 914 | 923 |
| 915 /// Handle the unary expression of an unresolved unary operator [text], like | 924 /// Handle the unary expression of an unresolved unary operator [text], like |
| 916 /// the no longer supported `+a`. | 925 /// the no longer supported `+a`. |
| 917 ResolutionResult handleUnresolvedUnary(Send node, String text) { | 926 ResolutionResult handleUnresolvedUnary(Send node, String text) { |
| 918 Node expression = node.receiver; | 927 Node expression = node.receiver; |
| 919 if (node.isSuperCall) { | 928 if (node.isSuperCall) { |
| 920 checkSuperAccess(node); | 929 checkSuperAccess(node); |
| 921 } else { | 930 } else { |
| 922 visitExpression(expression); | 931 visitExpression(expression); |
| 923 } | 932 } |
| 924 | 933 |
| 925 registry.registerSendStructure(node, const InvalidUnaryStructure()); | 934 registry.registerSendStructure(node, const InvalidUnaryStructure()); |
| 926 return null; | 935 return const NoneResult(); |
| 927 } | 936 } |
| 928 | 937 |
| 929 /// Handle the unary expression of a user definable unary [operator], like | 938 /// Handle the unary expression of a user definable unary [operator], like |
| 930 /// `-a`, and `-super`. | 939 /// `-a`, and `-super`. |
| 931 ResolutionResult handleUserDefinableUnary(Send node, UnaryOperator operator) { | 940 ResolutionResult handleUserDefinableUnary(Send node, UnaryOperator operator) { |
| 941 ResolutionResult result = const NoneResult(); |
| 932 Node expression = node.receiver; | 942 Node expression = node.receiver; |
| 933 Selector selector = operator.selector; | 943 Selector selector = operator.selector; |
| 934 // TODO(johnniwinther): Remove this when all information goes through the | 944 // TODO(johnniwinther): Remove this when all information goes through the |
| 935 // [SendStructure]. | 945 // [SendStructure]. |
| 936 registry.setSelector(node, selector); | 946 registry.setSelector(node, selector); |
| 937 | 947 |
| 938 AccessSemantics semantics; | 948 AccessSemantics semantics; |
| 939 if (node.isSuperCall) { | 949 if (node.isSuperCall) { |
| 940 if (checkSuperAccess(node)) { | 950 if (checkSuperAccess(node)) { |
| 941 semantics = computeSuperSemantics(node, selector); | 951 semantics = computeSuperSemantics(node, selector); |
| 942 // TODO(johnniwinther): Add information to [AccessSemantics] about | 952 // TODO(johnniwinther): Add information to [AccessSemantics] about |
| 943 // whether it is erroneous. | 953 // whether it is erroneous. |
| 944 if (semantics.kind == AccessKind.SUPER_METHOD) { | 954 if (semantics.kind == AccessKind.SUPER_METHOD) { |
| 945 registry.registerStaticUse(semantics.element.declaration); | 955 registry.registerStaticUse(semantics.element.declaration); |
| 946 } | 956 } |
| 947 // TODO(johnniwinther): Remove this when all information goes through | 957 // TODO(johnniwinther): Remove this when all information goes through |
| 948 // the [SendStructure]. | 958 // the [SendStructure]. |
| 949 registry.useElement(node, semantics.element); | 959 registry.useElement(node, semantics.element); |
| 950 } | 960 } |
| 951 } else { | 961 } else { |
| 952 visitExpression(expression); | 962 ResolutionResult expressionResult = visitExpression(expression); |
| 953 semantics = new DynamicAccess.dynamicProperty(expression); | 963 semantics = new DynamicAccess.dynamicProperty(expression); |
| 954 registry.registerDynamicInvocation(selector); | 964 registry.registerDynamicInvocation(selector); |
| 965 |
| 966 if (expressionResult.isConstant) { |
| 967 bool isValidConstant; |
| 968 ConstantExpression expressionConstant = expressionResult.constant; |
| 969 DartType knownExpressionType = |
| 970 expressionConstant.getKnownType(coreTypes); |
| 971 switch (operator.kind) { |
| 972 case UnaryOperatorKind.COMPLEMENT: |
| 973 isValidConstant = |
| 974 knownExpressionType == coreTypes.intType; |
| 975 break; |
| 976 case UnaryOperatorKind.NEGATE: |
| 977 isValidConstant = |
| 978 knownExpressionType == coreTypes.intType || |
| 979 knownExpressionType == coreTypes.doubleType; |
| 980 break; |
| 981 case UnaryOperatorKind.NOT: |
| 982 internalError(node, |
| 983 "Unexpected user definable unary operator: $operator"); |
| 984 } |
| 985 if (isValidConstant) { |
| 986 // TODO(johnniwinther): Handle potentially invalid constant |
| 987 // expressions. |
| 988 ConstantExpression constant = |
| 989 new UnaryConstantExpression(operator, expressionConstant); |
| 990 registry.setConstant(node, constant); |
| 991 result = new ConstantResult(node, constant); |
| 992 } |
| 993 } |
| 955 } | 994 } |
| 956 if (semantics != null) { | 995 if (semantics != null) { |
| 957 // TODO(johnniwinther): Support invalid super access as an | 996 // TODO(johnniwinther): Support invalid super access as an |
| 958 // [AccessSemantics]. | 997 // [AccessSemantics]. |
| 959 registry.registerSendStructure(node, | 998 registry.registerSendStructure(node, |
| 960 new UnaryStructure(semantics, operator)); | 999 new UnaryStructure(semantics, operator)); |
| 961 } | 1000 } |
| 962 return null; | 1001 return result; |
| 963 } | 1002 } |
| 964 | 1003 |
| 965 /// Handle a not expression, like `!a`. | 1004 /// Handle a not expression, like `!a`. |
| 966 ResolutionResult handleNot(Send node, UnaryOperator operator) { | 1005 ResolutionResult handleNot(Send node, UnaryOperator operator) { |
| 967 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT)); | 1006 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT)); |
| 968 | 1007 |
| 969 Node expression = node.receiver; | 1008 Node expression = node.receiver; |
| 970 visitExpression(expression); | 1009 ResolutionResult result = visitExpression(expression); |
| 971 registry.registerSendStructure(node, | 1010 registry.registerSendStructure(node, |
| 972 new NotStructure(new DynamicAccess.dynamicProperty(expression))); | 1011 new NotStructure(new DynamicAccess.dynamicProperty(expression))); |
| 973 return null; | 1012 |
| 1013 if (result.isConstant) { |
| 1014 ConstantExpression expressionConstant = result.constant; |
| 1015 if (expressionConstant.getKnownType(coreTypes) == coreTypes.boolType) { |
| 1016 // TODO(johnniwinther): Handle potentially invalid constant expressions. |
| 1017 ConstantExpression constant = |
| 1018 new UnaryConstantExpression(operator, expressionConstant); |
| 1019 registry.setConstant(node, constant); |
| 1020 return new ConstantResult(node, constant); |
| 1021 } |
| 1022 } |
| 1023 |
| 1024 return const NoneResult(); |
| 974 } | 1025 } |
| 975 | 1026 |
| 976 /// Handle a logical and expression, like `a && b`. | 1027 /// Handle a logical and expression, like `a && b`. |
| 977 ResolutionResult handleLogicalAnd(Send node) { | 1028 ResolutionResult handleLogicalAnd(Send node) { |
| 978 Node left = node.receiver; | 1029 Node left = node.receiver; |
| 979 Node right = node.arguments.head; | 1030 Node right = node.arguments.head; |
| 980 doInPromotionScope(left, () => visitExpression(left)); | 1031 ResolutionResult leftResult = |
| 981 doInPromotionScope(right, () => visitExpression(right)); | 1032 doInPromotionScope(left, () => visitExpression(left)); |
| 1033 ResolutionResult rightResult = |
| 1034 doInPromotionScope(right, () => visitExpression(right)); |
| 982 registry.registerSendStructure(node, const LogicalAndStructure()); | 1035 registry.registerSendStructure(node, const LogicalAndStructure()); |
| 983 return null; | 1036 |
| 1037 if (leftResult.isConstant && rightResult.isConstant) { |
| 1038 ConstantExpression leftConstant = leftResult.constant; |
| 1039 ConstantExpression rightConstant = rightResult.constant; |
| 1040 if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && |
| 1041 rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { |
| 1042 // TODO(johnniwinther): Handle potentially invalid constant expressions. |
| 1043 ConstantExpression constant = new BinaryConstantExpression( |
| 1044 leftConstant, |
| 1045 BinaryOperator.LOGICAL_AND, |
| 1046 rightConstant); |
| 1047 registry.setConstant(node, constant); |
| 1048 return new ConstantResult(node, constant); |
| 1049 } |
| 1050 } |
| 1051 |
| 1052 return const NoneResult(); |
| 984 } | 1053 } |
| 985 | 1054 |
| 986 /// Handle a logical or expression, like `a || b`. | 1055 /// Handle a logical or expression, like `a || b`. |
| 987 ResolutionResult handleLogicalOr(Send node) { | 1056 ResolutionResult handleLogicalOr(Send node) { |
| 988 Node left = node.receiver; | 1057 Node left = node.receiver; |
| 989 Node right = node.arguments.head; | 1058 Node right = node.arguments.head; |
| 990 visitExpression(left); | 1059 ResolutionResult leftResult = visitExpression(left); |
| 991 visitExpression(right); | 1060 ResolutionResult rightResult = visitExpression(right); |
| 992 registry.registerSendStructure(node, const LogicalOrStructure()); | 1061 registry.registerSendStructure(node, const LogicalOrStructure()); |
| 993 return null; | 1062 |
| 1063 if (leftResult.isConstant && rightResult.isConstant) { |
| 1064 ConstantExpression leftConstant = leftResult.constant; |
| 1065 ConstantExpression rightConstant = rightResult.constant; |
| 1066 if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && |
| 1067 rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { |
| 1068 // TODO(johnniwinther): Handle potentially invalid constant expressions. |
| 1069 ConstantExpression constant = new BinaryConstantExpression( |
| 1070 leftConstant, |
| 1071 BinaryOperator.LOGICAL_OR, |
| 1072 rightConstant); |
| 1073 registry.setConstant(node, constant); |
| 1074 return new ConstantResult(node, constant); |
| 1075 } |
| 1076 } |
| 1077 return const NoneResult(); |
| 994 } | 1078 } |
| 995 | 1079 |
| 996 /// Handle an if-null expression, like `a ?? b`. | 1080 /// Handle an if-null expression, like `a ?? b`. |
| 997 ResolutionResult handleIfNull(Send node) { | 1081 ResolutionResult handleIfNull(Send node) { |
| 998 Node left = node.receiver; | 1082 Node left = node.receiver; |
| 999 Node right = node.arguments.head; | 1083 Node right = node.arguments.head; |
| 1000 visitExpression(left); | 1084 visitExpression(left); |
| 1001 visitExpression(right); | 1085 visitExpression(right); |
| 1002 registry.registerSendStructure(node, const IfNullStructure()); | 1086 registry.registerSendStructure(node, const IfNullStructure()); |
| 1003 return null; | 1087 return const NoneResult(); |
| 1004 } | 1088 } |
| 1005 | 1089 |
| 1006 /// Handle the binary expression of an unresolved binary operator [text], like | 1090 /// Handle the binary expression of an unresolved binary operator [text], like |
| 1007 /// the no longer supported `a === b`. | 1091 /// the no longer supported `a === b`. |
| 1008 ResolutionResult handleUnresolvedBinary(Send node, String text) { | 1092 ResolutionResult handleUnresolvedBinary(Send node, String text) { |
| 1009 Node left = node.receiver; | 1093 Node left = node.receiver; |
| 1010 Node right = node.arguments.head; | 1094 Node right = node.arguments.head; |
| 1011 if (node.isSuperCall) { | 1095 if (node.isSuperCall) { |
| 1012 checkSuperAccess(node); | 1096 checkSuperAccess(node); |
| 1013 } else { | 1097 } else { |
| 1014 visitExpression(left); | 1098 visitExpression(left); |
| 1015 } | 1099 } |
| 1016 visitExpression(right); | 1100 visitExpression(right); |
| 1017 registry.registerSendStructure(node, const InvalidBinaryStructure()); | 1101 registry.registerSendStructure(node, const InvalidBinaryStructure()); |
| 1018 return null; | 1102 return const NoneResult(); |
| 1019 } | 1103 } |
| 1020 | 1104 |
| 1021 /// Handle the binary expression of a user definable binary [operator], like | 1105 /// Handle the binary expression of a user definable binary [operator], like |
| 1022 /// `a + b`, `super + b`, `a == b` and `a != b`. | 1106 /// `a + b`, `super + b`, `a == b` and `a != b`. |
| 1023 ResolutionResult handleUserDefinableBinary(Send node, | 1107 ResolutionResult handleUserDefinableBinary(Send node, |
| 1024 BinaryOperator operator) { | 1108 BinaryOperator operator) { |
| 1109 ResolutionResult result = const NoneResult(); |
| 1025 Node left = node.receiver; | 1110 Node left = node.receiver; |
| 1026 Node right = node.arguments.head; | 1111 Node right = node.arguments.head; |
| 1027 AccessSemantics semantics; | 1112 AccessSemantics semantics; |
| 1028 Selector selector; | 1113 Selector selector; |
| 1029 if (operator.kind == BinaryOperatorKind.INDEX) { | 1114 if (operator.kind == BinaryOperatorKind.INDEX) { |
| 1030 selector = new Selector.index(); | 1115 selector = new Selector.index(); |
| 1031 } else { | 1116 } else { |
| 1032 selector = new Selector.binaryOperator(operator.selectorName); | 1117 selector = new Selector.binaryOperator(operator.selectorName); |
| 1033 } | 1118 } |
| 1034 // TODO(johnniwinther): Remove this when all information goes through the | 1119 // TODO(johnniwinther): Remove this when all information goes through the |
| 1035 // [SendStructure]. | 1120 // [SendStructure]. |
| 1036 registry.setSelector(node, selector); | 1121 registry.setSelector(node, selector); |
| 1037 | 1122 |
| 1038 if (node.isSuperCall) { | 1123 if (node.isSuperCall) { |
| 1039 if (checkSuperAccess(node)) { | 1124 if (checkSuperAccess(node)) { |
| 1040 semantics = computeSuperSemantics(node, selector); | 1125 semantics = computeSuperSemantics(node, selector); |
| 1041 // TODO(johnniwinther): Add information to [AccessSemantics] about | 1126 // TODO(johnniwinther): Add information to [AccessSemantics] about |
| 1042 // whether it is erroneous. | 1127 // whether it is erroneous. |
| 1043 if (semantics.kind == AccessKind.SUPER_METHOD) { | 1128 if (semantics.kind == AccessKind.SUPER_METHOD) { |
| 1044 registry.registerStaticUse(semantics.element.declaration); | 1129 registry.registerStaticUse(semantics.element.declaration); |
| 1045 } | 1130 } |
| 1046 // TODO(johnniwinther): Remove this when all information goes through | 1131 // TODO(johnniwinther): Remove this when all information goes through |
| 1047 // the [SendStructure]. | 1132 // the [SendStructure]. |
| 1048 registry.useElement(node, semantics.element); | 1133 registry.useElement(node, semantics.element); |
| 1049 } | 1134 } |
| 1135 visitExpression(right); |
| 1050 } else { | 1136 } else { |
| 1051 visitExpression(left); | 1137 ResolutionResult leftResult = visitExpression(left); |
| 1138 ResolutionResult rightResult = visitExpression(right); |
| 1052 registry.registerDynamicInvocation(selector); | 1139 registry.registerDynamicInvocation(selector); |
| 1053 semantics = new DynamicAccess.dynamicProperty(left); | 1140 semantics = new DynamicAccess.dynamicProperty(left); |
| 1141 |
| 1142 if (leftResult.isConstant && rightResult.isConstant) { |
| 1143 bool isValidConstant; |
| 1144 ConstantExpression leftConstant = leftResult.constant; |
| 1145 ConstantExpression rightConstant = leftResult.constant; |
| 1146 DartType knownLeftType = leftConstant.getKnownType(coreTypes); |
| 1147 DartType knownRightType = rightConstant.getKnownType(coreTypes); |
| 1148 switch (operator.kind) { |
| 1149 case BinaryOperatorKind.EQ: |
| 1150 case BinaryOperatorKind.NOT_EQ: |
| 1151 isValidConstant = |
| 1152 (knownLeftType == coreTypes.intType || |
| 1153 knownLeftType == coreTypes.doubleType || |
| 1154 knownLeftType == coreTypes.stringType || |
| 1155 knownLeftType == coreTypes.boolType || |
| 1156 knownLeftType == coreTypes.nullType) && |
| 1157 (knownRightType == coreTypes.intType || |
| 1158 knownRightType == coreTypes.doubleType || |
| 1159 knownRightType == coreTypes.stringType || |
| 1160 knownRightType == coreTypes.boolType || |
| 1161 knownRightType == coreTypes.nullType); |
| 1162 break; |
| 1163 case BinaryOperatorKind.ADD: |
| 1164 isValidConstant = |
| 1165 (knownLeftType == coreTypes.intType || |
| 1166 knownLeftType == coreTypes.doubleType || |
| 1167 knownLeftType == coreTypes.stringType) && |
| 1168 (knownRightType == coreTypes.intType || |
| 1169 knownRightType == coreTypes.doubleType || |
| 1170 knownRightType == coreTypes.stringType); |
| 1171 break; |
| 1172 case BinaryOperatorKind.SUB: |
| 1173 case BinaryOperatorKind.MUL: |
| 1174 case BinaryOperatorKind.DIV: |
| 1175 case BinaryOperatorKind.IDIV: |
| 1176 case BinaryOperatorKind.MOD: |
| 1177 case BinaryOperatorKind.GTEQ: |
| 1178 case BinaryOperatorKind.GT: |
| 1179 case BinaryOperatorKind.LTEQ: |
| 1180 case BinaryOperatorKind.LT: |
| 1181 isValidConstant = |
| 1182 (knownLeftType == coreTypes.intType || |
| 1183 knownLeftType == coreTypes.doubleType) && |
| 1184 (knownRightType == coreTypes.intType || |
| 1185 knownRightType == coreTypes.doubleType); |
| 1186 break; |
| 1187 case BinaryOperatorKind.SHL: |
| 1188 case BinaryOperatorKind.SHR: |
| 1189 case BinaryOperatorKind.AND: |
| 1190 case BinaryOperatorKind.OR: |
| 1191 case BinaryOperatorKind.XOR: |
| 1192 isValidConstant = |
| 1193 knownLeftType == coreTypes.intType && |
| 1194 knownRightType == coreTypes.intType; |
| 1195 break; |
| 1196 case BinaryOperatorKind.INDEX: |
| 1197 isValidConstant = false; |
| 1198 break; |
| 1199 case BinaryOperatorKind.LOGICAL_AND: |
| 1200 case BinaryOperatorKind.LOGICAL_OR: |
| 1201 case BinaryOperatorKind.IF_NULL: |
| 1202 internalError(node, "Unexpected binary operator '${operator}'."); |
| 1203 break; |
| 1204 } |
| 1205 if (isValidConstant) { |
| 1206 // TODO(johnniwinther): Handle potentially invalid constant |
| 1207 // expressions. |
| 1208 ConstantExpression constant = new BinaryConstantExpression( |
| 1209 leftResult.constant, |
| 1210 operator, |
| 1211 rightResult.constant); |
| 1212 registry.setConstant(node, constant); |
| 1213 result = new ConstantResult(node, constant); |
| 1214 } |
| 1215 } |
| 1054 } | 1216 } |
| 1055 visitExpression(right); | |
| 1056 | 1217 |
| 1057 if (semantics != null) { | 1218 if (semantics != null) { |
| 1058 // TODO(johnniwinther): Support invalid super access as an | 1219 // TODO(johnniwinther): Support invalid super access as an |
| 1059 // [AccessSemantics]. | 1220 // [AccessSemantics]. |
| 1060 SendStructure sendStructure; | 1221 SendStructure sendStructure; |
| 1061 switch (operator.kind) { | 1222 switch (operator.kind) { |
| 1062 case BinaryOperatorKind.EQ: | 1223 case BinaryOperatorKind.EQ: |
| 1063 sendStructure = new EqualsStructure(semantics); | 1224 sendStructure = new EqualsStructure(semantics); |
| 1064 break; | 1225 break; |
| 1065 case BinaryOperatorKind.NOT_EQ: | 1226 case BinaryOperatorKind.NOT_EQ: |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1086 sendStructure = new BinaryStructure(semantics, operator); | 1247 sendStructure = new BinaryStructure(semantics, operator); |
| 1087 break; | 1248 break; |
| 1088 case BinaryOperatorKind.LOGICAL_AND: | 1249 case BinaryOperatorKind.LOGICAL_AND: |
| 1089 case BinaryOperatorKind.LOGICAL_OR: | 1250 case BinaryOperatorKind.LOGICAL_OR: |
| 1090 case BinaryOperatorKind.IF_NULL: | 1251 case BinaryOperatorKind.IF_NULL: |
| 1091 internalError(node, "Unexpected binary operator '${operator}'."); | 1252 internalError(node, "Unexpected binary operator '${operator}'."); |
| 1092 break; | 1253 break; |
| 1093 } | 1254 } |
| 1094 registry.registerSendStructure(node, sendStructure); | 1255 registry.registerSendStructure(node, sendStructure); |
| 1095 } | 1256 } |
| 1096 return null; | 1257 return result; |
| 1097 } | 1258 } |
| 1098 | 1259 |
| 1099 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. | 1260 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. |
| 1100 ResolutionResult handleExpressionInvoke(Send node) { | 1261 ResolutionResult handleExpressionInvoke(Send node) { |
| 1101 assert(invariant(node, node.isCall, | 1262 assert(invariant(node, node.isCall, |
| 1102 message: "Unexpected expression: $node")); | 1263 message: "Unexpected expression: $node")); |
| 1103 Node expression = node.selector; | 1264 Node expression = node.selector; |
| 1104 visitExpression(expression); | 1265 visitExpression(expression); |
| 1105 CallStructure callStructure = resolveArguments(node.argumentsNode); | 1266 CallStructure callStructure = resolveArguments(node.argumentsNode); |
| 1106 Selector selector = callStructure.callSelector; | 1267 Selector selector = callStructure.callSelector; |
| 1107 // TODO(johnniwinther): Remove this when all information goes through the | 1268 // TODO(johnniwinther): Remove this when all information goes through the |
| 1108 // [SendStructure]. | 1269 // [SendStructure]. |
| 1109 registry.setSelector(node, selector); | 1270 registry.setSelector(node, selector); |
| 1110 registry.registerDynamicInvocation(selector); | 1271 registry.registerDynamicInvocation(selector); |
| 1111 registry.registerSendStructure(node, | 1272 registry.registerSendStructure(node, |
| 1112 new InvokeStructure(new AccessSemantics.expression(), selector)); | 1273 new InvokeStructure(new AccessSemantics.expression(), selector)); |
| 1113 return null; | 1274 return const NoneResult(); |
| 1114 } | 1275 } |
| 1115 | 1276 |
| 1116 /// Handle a, possibly invalid, assertion, like `assert(cond)` or `assert()`. | 1277 /// Handle a, possibly invalid, assertion, like `assert(cond)` or `assert()`. |
| 1117 ResolutionResult handleAssert(Send node) { | 1278 ResolutionResult handleAssert(Send node) { |
| 1118 assert(invariant(node, node.isCall, | 1279 assert(invariant(node, node.isCall, |
| 1119 message: "Unexpected assert: $node")); | 1280 message: "Unexpected assert: $node")); |
| 1120 // If this send is of the form "assert(expr);", then | 1281 // If this send is of the form "assert(expr);", then |
| 1121 // this is an assertion. | 1282 // this is an assertion. |
| 1122 | 1283 |
| 1123 CallStructure callStructure = resolveArguments(node.argumentsNode); | 1284 CallStructure callStructure = resolveArguments(node.argumentsNode); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1155 assert(invariant(node, node.isPropertyAccess)); | 1316 assert(invariant(node, node.isPropertyAccess)); |
| 1156 selector = new Selector( | 1317 selector = new Selector( |
| 1157 SelectorKind.GETTER, name, CallStructure.NO_ARGS); | 1318 SelectorKind.GETTER, name, CallStructure.NO_ARGS); |
| 1158 registry.registerDynamicGetter(selector); | 1319 registry.registerDynamicGetter(selector); |
| 1159 sendStructure = new GetStructure(accessSemantics, selector); | 1320 sendStructure = new GetStructure(accessSemantics, selector); |
| 1160 } | 1321 } |
| 1161 registry.registerSendStructure(node, sendStructure); | 1322 registry.registerSendStructure(node, sendStructure); |
| 1162 // TODO(johnniwinther): Remove this when all information goes through | 1323 // TODO(johnniwinther): Remove this when all information goes through |
| 1163 // the [SendStructure]. | 1324 // the [SendStructure]. |
| 1164 registry.setSelector(node, selector); | 1325 registry.setSelector(node, selector); |
| 1165 return null; | 1326 return const NoneResult(); |
| 1166 } | 1327 } |
| 1167 | 1328 |
| 1168 /// Handle access on `this`, like `this()` and `this` when it is parsed as a | 1329 /// Handle access on `this`, like `this()` and `this` when it is parsed as a |
| 1169 /// [Send] node. | 1330 /// [Send] node. |
| 1170 ResolutionResult handleThisAccess(Send node) { | 1331 ResolutionResult handleThisAccess(Send node) { |
| 1171 AccessSemantics accessSemantics = new AccessSemantics.thisAccess(); | 1332 AccessSemantics accessSemantics = new AccessSemantics.thisAccess(); |
| 1172 if (node.isCall) { | 1333 if (node.isCall) { |
| 1173 CallStructure callStructure = resolveArguments(node.argumentsNode); | 1334 CallStructure callStructure = resolveArguments(node.argumentsNode); |
| 1174 Selector selector = callStructure.callSelector; | 1335 Selector selector = callStructure.callSelector; |
| 1175 // TODO(johnniwinther): Handle invalid this access as an | 1336 // TODO(johnniwinther): Handle invalid this access as an |
| 1176 // [AccessSemantics]. | 1337 // [AccessSemantics]. |
| 1177 if (checkThisAccess(node)) { | 1338 if (checkThisAccess(node)) { |
| 1178 registry.registerDynamicInvocation(selector); | 1339 registry.registerDynamicInvocation(selector); |
| 1179 registry.registerSendStructure(node, | 1340 registry.registerSendStructure(node, |
| 1180 new InvokeStructure(accessSemantics, selector)); | 1341 new InvokeStructure(accessSemantics, selector)); |
| 1181 } | 1342 } |
| 1182 // TODO(johnniwinther): Remove this when all information goes through | 1343 // TODO(johnniwinther): Remove this when all information goes through |
| 1183 // the [SendStructure]. | 1344 // the [SendStructure]. |
| 1184 registry.setSelector(node, selector); | 1345 registry.setSelector(node, selector); |
| 1185 } else { | 1346 } else { |
| 1186 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. | 1347 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. |
| 1187 internalError(node, "Unexpected node '$node'."); | 1348 internalError(node, "Unexpected node '$node'."); |
| 1188 } | 1349 } |
| 1189 return null; | 1350 return const NoneResult(); |
| 1190 } | 1351 } |
| 1191 | 1352 |
| 1192 /// Handle access of a super property, like `super.foo` and `super.foo()`. | 1353 /// Handle access of a super property, like `super.foo` and `super.foo()`. |
| 1193 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { | 1354 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { |
| 1194 Element target; | 1355 Element target; |
| 1195 Selector selector; | 1356 Selector selector; |
| 1196 CallStructure callStructure = CallStructure.NO_ARGS; | 1357 CallStructure callStructure = CallStructure.NO_ARGS; |
| 1197 if (node.isCall) { | 1358 if (node.isCall) { |
| 1198 callStructure = resolveArguments(node.argumentsNode); | 1359 callStructure = resolveArguments(node.argumentsNode); |
| 1199 selector = new Selector(SelectorKind.CALL, name, callStructure); | 1360 selector = new Selector(SelectorKind.CALL, name, callStructure); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1258 registry.registerSendStructure(node, | 1419 registry.registerSendStructure(node, |
| 1259 new GetStructure(semantics, selector)); | 1420 new GetStructure(semantics, selector)); |
| 1260 } | 1421 } |
| 1261 target = semantics.element; | 1422 target = semantics.element; |
| 1262 } | 1423 } |
| 1263 | 1424 |
| 1264 // TODO(johnniwinther): Remove these when all information goes through | 1425 // TODO(johnniwinther): Remove these when all information goes through |
| 1265 // the [SendStructure]. | 1426 // the [SendStructure]. |
| 1266 registry.useElement(node, target); | 1427 registry.useElement(node, target); |
| 1267 registry.setSelector(node, selector); | 1428 registry.setSelector(node, selector); |
| 1268 return null; | 1429 return const NoneResult(); |
| 1269 } | 1430 } |
| 1270 | 1431 |
| 1271 /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`, | 1432 /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`, |
| 1272 /// `a + b`, and `~a`. | 1433 /// `a + b`, and `~a`. |
| 1273 ResolutionResult handleOperatorSend(Send node) { | 1434 ResolutionResult handleOperatorSend(Send node) { |
| 1274 String operatorText = node.selector.asOperator().source; | 1435 String operatorText = node.selector.asOperator().source; |
| 1275 if (operatorText == 'is') { | 1436 if (operatorText == 'is') { |
| 1276 return handleIs(node); | 1437 return handleIs(node); |
| 1277 } else if (operatorText == 'as') { | 1438 } else if (operatorText == 'as') { |
| 1278 return handleAs(node); | 1439 return handleAs(node); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1334 Identifier selector = node.selector.asIdentifier(); | 1495 Identifier selector = node.selector.asIdentifier(); |
| 1335 Name name = new Name(selector.source, enclosingElement.library); | 1496 Name name = new Name(selector.source, enclosingElement.library); |
| 1336 if (node.isSuperCall) { | 1497 if (node.isSuperCall) { |
| 1337 return handleSuperPropertyAccess(node, name); | 1498 return handleSuperPropertyAccess(node, name); |
| 1338 } else if (node.receiver.isThis()) { | 1499 } else if (node.receiver.isThis()) { |
| 1339 if (checkThisAccess(node)) { | 1500 if (checkThisAccess(node)) { |
| 1340 return handleThisPropertyAccess(node, name); | 1501 return handleThisPropertyAccess(node, name); |
| 1341 } | 1502 } |
| 1342 // TODO(johnniwinther): Handle invalid this access as an | 1503 // TODO(johnniwinther): Handle invalid this access as an |
| 1343 // [AccessSemantics]. | 1504 // [AccessSemantics]. |
| 1344 return null; | 1505 return const NoneResult(); |
| 1345 } | 1506 } |
| 1346 // TODO(johnniwinther): Handle remaining qualified sends. | 1507 // TODO(johnniwinther): Handle remaining qualified sends. |
| 1347 return oldVisitSend(node); | 1508 return oldVisitSend(node); |
| 1348 } | 1509 } |
| 1349 | 1510 |
| 1350 /// Handle access unresolved access to [name] in a non-instance context. | 1511 /// Handle access unresolved access to [name] in a non-instance context. |
| 1351 ResolutionResult handleUnresolvedAccess( | 1512 ResolutionResult handleUnresolvedAccess( |
| 1352 Send node, Name name, Element element) { | 1513 Send node, Name name, Element element) { |
| 1353 // TODO(johnniwinther): Support unresolved top level access as an | 1514 // TODO(johnniwinther): Support unresolved top level access as an |
| 1354 // [AccessSemantics]. | 1515 // [AccessSemantics]. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1365 selector = new Selector( | 1526 selector = new Selector( |
| 1366 SelectorKind.GETTER, name, CallStructure.NO_ARGS); | 1527 SelectorKind.GETTER, name, CallStructure.NO_ARGS); |
| 1367 registry.registerDynamicGetter(selector); | 1528 registry.registerDynamicGetter(selector); |
| 1368 sendStructure = new GetStructure(accessSemantics, selector); | 1529 sendStructure = new GetStructure(accessSemantics, selector); |
| 1369 } | 1530 } |
| 1370 // TODO(johnniwinther): Remove this when all information goes through | 1531 // TODO(johnniwinther): Remove this when all information goes through |
| 1371 // the [SendStructure]. | 1532 // the [SendStructure]. |
| 1372 registry.setSelector(node, selector); | 1533 registry.setSelector(node, selector); |
| 1373 registry.useElement(node, element); | 1534 registry.useElement(node, element); |
| 1374 registry.registerSendStructure(node, sendStructure); | 1535 registry.registerSendStructure(node, sendStructure); |
| 1375 return null; | 1536 return const NoneResult(); |
| 1376 } | 1537 } |
| 1377 | 1538 |
| 1378 /// Handle an unqualified [Send], that is where the `node.receiver` is null, | 1539 /// Handle an unqualified [Send], that is where the `node.receiver` is null, |
| 1379 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. | 1540 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. |
| 1380 ResolutionResult handleUnqualifiedSend(Send node) { | 1541 ResolutionResult handleUnqualifiedSend(Send node) { |
| 1381 Identifier selector = node.selector.asIdentifier(); | 1542 Identifier selector = node.selector.asIdentifier(); |
| 1382 if (selector == null) { | 1543 if (selector == null) { |
| 1383 // `(){}()` and `(foo)()`. | 1544 // `(){}()` and `(foo)()`. |
| 1384 return handleExpressionInvoke(node); | 1545 return handleExpressionInvoke(node); |
| 1385 } | 1546 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1422 return oldVisitSend(node); | 1583 return oldVisitSend(node); |
| 1423 } | 1584 } |
| 1424 | 1585 |
| 1425 ResolutionResult oldVisitSend(Send node) { | 1586 ResolutionResult oldVisitSend(Send node) { |
| 1426 bool oldSendIsMemberAccess = sendIsMemberAccess; | 1587 bool oldSendIsMemberAccess = sendIsMemberAccess; |
| 1427 sendIsMemberAccess = node.isPropertyAccess || node.isCall; | 1588 sendIsMemberAccess = node.isPropertyAccess || node.isCall; |
| 1428 | 1589 |
| 1429 ResolutionResult result = resolveSend(node); | 1590 ResolutionResult result = resolveSend(node); |
| 1430 sendIsMemberAccess = oldSendIsMemberAccess; | 1591 sendIsMemberAccess = oldSendIsMemberAccess; |
| 1431 | 1592 |
| 1432 Element target = result != null ? result.element : null; | 1593 Element target = result.element; |
| 1433 | 1594 |
| 1434 if (target != null | 1595 if (target != null |
| 1435 && target == compiler.mirrorSystemGetNameFunction | 1596 && target == compiler.mirrorSystemGetNameFunction |
| 1436 && !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { | 1597 && !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { |
| 1437 compiler.reportHint( | 1598 compiler.reportHint( |
| 1438 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, | 1599 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, |
| 1439 {'class': compiler.mirrorSystemClass.name, | 1600 {'class': compiler.mirrorSystemClass.name, |
| 1440 'name': compiler.mirrorSystemGetNameFunction.name}); | 1601 'name': compiler.mirrorSystemGetNameFunction.name}); |
| 1441 } | 1602 } |
| 1442 | 1603 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1475 } | 1636 } |
| 1476 } | 1637 } |
| 1477 } | 1638 } |
| 1478 | 1639 |
| 1479 bool resolvedArguments = false; | 1640 bool resolvedArguments = false; |
| 1480 resolveArguments(node.argumentsNode); | 1641 resolveArguments(node.argumentsNode); |
| 1481 | 1642 |
| 1482 // If the selector is null, it means that we will not be generating | 1643 // If the selector is null, it means that we will not be generating |
| 1483 // code for this as a send. | 1644 // code for this as a send. |
| 1484 Selector selector = registry.getSelector(node); | 1645 Selector selector = registry.getSelector(node); |
| 1485 if (selector == null) return null; | 1646 if (selector == null) return const NoneResult(); |
| 1486 | 1647 |
| 1487 if (node.isCall) { | 1648 if (node.isCall) { |
| 1488 if (Elements.isUnresolved(target) || | 1649 if (Elements.isUnresolved(target) || |
| 1489 target.isGetter || | 1650 target.isGetter || |
| 1490 target.isField || | 1651 target.isField || |
| 1491 Elements.isClosureSend(node, target)) { | 1652 Elements.isClosureSend(node, target)) { |
| 1492 // If we don't know what we're calling or if we are calling a getter, | 1653 // If we don't know what we're calling or if we are calling a getter, |
| 1493 // we need to register that fact that we may be calling a closure | 1654 // we need to register that fact that we may be calling a closure |
| 1494 // with the same arguments. | 1655 // with the same arguments. |
| 1495 Selector call = new Selector.callClosureFrom(selector); | 1656 Selector call = new Selector.callClosureFrom(selector); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1528 } | 1689 } |
| 1529 } | 1690 } |
| 1530 } | 1691 } |
| 1531 } | 1692 } |
| 1532 | 1693 |
| 1533 registry.useElement(node, target); | 1694 registry.useElement(node, target); |
| 1534 registerSend(selector, target); | 1695 registerSend(selector, target); |
| 1535 if (node.isPropertyAccess && Elements.isStaticOrTopLevelFunction(target)) { | 1696 if (node.isPropertyAccess && Elements.isStaticOrTopLevelFunction(target)) { |
| 1536 registry.registerGetOfStaticFunction(target.declaration); | 1697 registry.registerGetOfStaticFunction(target.declaration); |
| 1537 } | 1698 } |
| 1538 return node.isPropertyAccess ? new ElementResult(target) : null; | 1699 return node.isPropertyAccess |
| 1700 ? new ResolutionResult.forElement(target) : const NoneResult(); |
| 1539 } | 1701 } |
| 1540 | 1702 |
| 1541 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. | 1703 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. |
| 1542 DartType resolveTypeFromString(Node node, String typeName) { | 1704 DartType resolveTypeFromString(Node node, String typeName) { |
| 1543 Element element = lookupInScope(compiler, node, scope, typeName); | 1705 Element element = lookupInScope(compiler, node, scope, typeName); |
| 1544 if (element == null) return null; | 1706 if (element == null) return null; |
| 1545 if (element is! ClassElement) return null; | 1707 if (element is! ClassElement) return null; |
| 1546 ClassElement cls = element; | 1708 ClassElement cls = element; |
| 1547 cls.ensureResolved(compiler); | 1709 cls.ensureResolved(compiler); |
| 1548 return cls.computeType(compiler); | 1710 return cls.computeType(compiler); |
| 1549 } | 1711 } |
| 1550 | 1712 |
| 1551 ResolutionResult visitSendSet(SendSet node) { | 1713 ResolutionResult visitSendSet(SendSet node) { |
| 1552 bool oldSendIsMemberAccess = sendIsMemberAccess; | 1714 bool oldSendIsMemberAccess = sendIsMemberAccess; |
| 1553 sendIsMemberAccess = node.isPropertyAccess || node.isCall; | 1715 sendIsMemberAccess = node.isPropertyAccess || node.isCall; |
| 1554 ResolutionResult result = resolveSend(node); | 1716 ResolutionResult result = resolveSend(node); |
| 1555 sendIsMemberAccess = oldSendIsMemberAccess; | 1717 sendIsMemberAccess = oldSendIsMemberAccess; |
| 1556 Element target = result != null ? result.element : null; | 1718 Element target = result.element; |
| 1557 Element setter = target; | 1719 Element setter = target; |
| 1558 Element getter = target; | 1720 Element getter = target; |
| 1559 String operatorName = node.assignmentOperator.source; | 1721 String operatorName = node.assignmentOperator.source; |
| 1560 String source = operatorName; | 1722 String source = operatorName; |
| 1561 bool isComplex = !identical(source, '='); | 1723 bool isComplex = !identical(source, '='); |
| 1562 if (!(result is AssertResult || Elements.isUnresolved(target))) { | 1724 if (!(result is AssertResult || Elements.isUnresolved(target))) { |
| 1563 if (target.isAbstractField) { | 1725 if (target.isAbstractField) { |
| 1564 AbstractFieldElement field = target; | 1726 AbstractFieldElement field = target; |
| 1565 setter = field.setter; | 1727 setter = field.setter; |
| 1566 getter = field.getter; | 1728 getter = field.getter; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1670 registry.registerInstantiatedClass(compiler.intClass); | 1832 registry.registerInstantiatedClass(compiler.intClass); |
| 1671 } else if (identical(source, '--')) { | 1833 } else if (identical(source, '--')) { |
| 1672 registerBinaryOperator('-'); | 1834 registerBinaryOperator('-'); |
| 1673 registry.registerInstantiatedClass(compiler.intClass); | 1835 registry.registerInstantiatedClass(compiler.intClass); |
| 1674 } else if (source.endsWith('=')) { | 1836 } else if (source.endsWith('=')) { |
| 1675 registerBinaryOperator(Elements.mapToUserOperator(operatorName)); | 1837 registerBinaryOperator(Elements.mapToUserOperator(operatorName)); |
| 1676 } | 1838 } |
| 1677 } | 1839 } |
| 1678 | 1840 |
| 1679 registerSend(selector, setter); | 1841 registerSend(selector, setter); |
| 1680 return new ElementResult(registry.useElement(node, setter)); | 1842 return new ResolutionResult.forElement(registry.useElement(node, setter)); |
| 1681 } | 1843 } |
| 1682 | 1844 |
| 1683 void registerSend(Selector selector, Element target) { | 1845 void registerSend(Selector selector, Element target) { |
| 1684 if (target == null || target.isInstanceMember) { | 1846 if (target == null || target.isInstanceMember) { |
| 1685 if (selector.isGetter) { | 1847 if (selector.isGetter) { |
| 1686 registry.registerDynamicGetter(selector); | 1848 registry.registerDynamicGetter(selector); |
| 1687 } else if (selector.isSetter) { | 1849 } else if (selector.isSetter) { |
| 1688 registry.registerDynamicSetter(selector); | 1850 registry.registerDynamicSetter(selector); |
| 1689 } else { | 1851 } else { |
| 1690 registry.registerDynamicInvocation(selector); | 1852 registry.registerDynamicInvocation(selector); |
| 1691 } | 1853 } |
| 1692 } else if (Elements.isStaticOrTopLevel(target)) { | 1854 } else if (Elements.isStaticOrTopLevel(target)) { |
| 1693 // Avoid registration of type variables since they are not analyzable but | 1855 // Avoid registration of type variables since they are not analyzable but |
| 1694 // instead resolved through their enclosing type declaration. | 1856 // instead resolved through their enclosing type declaration. |
| 1695 if (!target.isTypeVariable) { | 1857 if (!target.isTypeVariable) { |
| 1696 // [target] might be the implementation element and only declaration | 1858 // [target] might be the implementation element and only declaration |
| 1697 // elements may be registered. | 1859 // elements may be registered. |
| 1698 registry.registerStaticUse(target.declaration); | 1860 registry.registerStaticUse(target.declaration); |
| 1699 } | 1861 } |
| 1700 } | 1862 } |
| 1701 } | 1863 } |
| 1702 | 1864 |
| 1703 visitLiteralInt(LiteralInt node) { | 1865 ConstantResult visitLiteralInt(LiteralInt node) { |
| 1704 registry.registerInstantiatedClass(compiler.intClass); | 1866 registry.registerInstantiatedType(coreTypes.intType); |
| 1867 ConstantExpression constant = new IntConstantExpression(node.value); |
| 1868 registry.setConstant(node, constant); |
| 1869 return new ConstantResult(node, constant); |
| 1705 } | 1870 } |
| 1706 | 1871 |
| 1707 visitLiteralDouble(LiteralDouble node) { | 1872 ConstantResult visitLiteralDouble(LiteralDouble node) { |
| 1708 registry.registerInstantiatedClass(compiler.doubleClass); | 1873 registry.registerInstantiatedType(coreTypes.doubleType); |
| 1874 ConstantExpression constant = new DoubleConstantExpression(node.value); |
| 1875 registry.setConstant(node, constant); |
| 1876 return new ConstantResult(node, constant); |
| 1709 } | 1877 } |
| 1710 | 1878 |
| 1711 visitLiteralBool(LiteralBool node) { | 1879 ConstantResult visitLiteralBool(LiteralBool node) { |
| 1712 registry.registerInstantiatedClass(compiler.boolClass); | 1880 registry.registerInstantiatedType(coreTypes.boolType); |
| 1881 ConstantExpression constant = new BoolConstantExpression(node.value); |
| 1882 registry.setConstant(node, constant); |
| 1883 return new ConstantResult(node, constant); |
| 1713 } | 1884 } |
| 1714 | 1885 |
| 1715 visitLiteralString(LiteralString node) { | 1886 ResolutionResult visitLiteralString(LiteralString node) { |
| 1716 registry.registerInstantiatedClass(compiler.stringClass); | 1887 registry.registerInstantiatedType(coreTypes.stringType); |
| 1888 if (node.dartString != null) { |
| 1889 // [dartString] might be null on parser errors. |
| 1890 ConstantExpression constant = |
| 1891 new StringConstantExpression(node.dartString.slowToString()); |
| 1892 registry.setConstant(node, constant); |
| 1893 return new ConstantResult(node, constant); |
| 1894 } |
| 1895 return const NoneResult(); |
| 1717 } | 1896 } |
| 1718 | 1897 |
| 1719 visitLiteralNull(LiteralNull node) { | 1898 ConstantResult visitLiteralNull(LiteralNull node) { |
| 1720 registry.registerInstantiatedClass(compiler.nullClass); | 1899 registry.registerInstantiatedType(coreTypes.nullType); |
| 1900 ConstantExpression constant = new NullConstantExpression(); |
| 1901 registry.setConstant(node, constant); |
| 1902 return new ConstantResult(node, constant); |
| 1721 } | 1903 } |
| 1722 | 1904 |
| 1723 visitLiteralSymbol(LiteralSymbol node) { | 1905 ConstantResult visitLiteralSymbol(LiteralSymbol node) { |
| 1724 registry.registerInstantiatedClass(compiler.symbolClass); | 1906 registry.registerInstantiatedClass(compiler.symbolClass); |
| 1725 registry.registerStaticUse(compiler.symbolConstructor.declaration); | 1907 registry.registerStaticUse(compiler.symbolConstructor.declaration); |
| 1726 registry.registerConstSymbol(node.slowNameString); | 1908 String name = node.slowNameString; |
| 1727 if (!validateSymbol(node, node.slowNameString, reportError: false)) { | 1909 registry.registerConstSymbol(name); |
| 1910 if (!validateSymbol(node, name, reportError: false)) { |
| 1728 compiler.reportError(node, | 1911 compiler.reportError(node, |
| 1729 MessageKind.UNSUPPORTED_LITERAL_SYMBOL, | 1912 MessageKind.UNSUPPORTED_LITERAL_SYMBOL, |
| 1730 {'value': node.slowNameString}); | 1913 {'value': name}); |
| 1731 } | 1914 } |
| 1732 analyzeConstantDeferred(node); | 1915 analyzeConstantDeferred(node); |
| 1916 ConstantExpression constant = new SymbolConstantExpression(name); |
| 1917 registry.setConstant(node, constant); |
| 1918 return new ConstantResult(node, constant); |
| 1733 } | 1919 } |
| 1734 | 1920 |
| 1735 visitStringJuxtaposition(StringJuxtaposition node) { | 1921 ResolutionResult visitStringJuxtaposition(StringJuxtaposition node) { |
| 1736 registry.registerInstantiatedClass(compiler.stringClass); | 1922 registry.registerInstantiatedType(coreTypes.stringType); |
| 1737 node.visitChildren(this); | 1923 ResolutionResult first = visit(node.first); |
| 1924 ResolutionResult second = visit(node.second); |
| 1925 if (first.isConstant && second.isConstant) { |
| 1926 ConstantExpression constant = new ConcatenateConstantExpression( |
| 1927 <ConstantExpression>[first.constant, second.constant]); |
| 1928 registry.setConstant(node, constant); |
| 1929 return new ConstantResult(node, constant); |
| 1930 } |
| 1931 return const NoneResult(); |
| 1738 } | 1932 } |
| 1739 | 1933 |
| 1740 visitNodeList(NodeList node) { | 1934 ResolutionResult visitNodeList(NodeList node) { |
| 1741 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 1935 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
| 1742 visit(link.head); | 1936 visit(link.head); |
| 1743 } | 1937 } |
| 1938 return const NoneResult(); |
| 1744 } | 1939 } |
| 1745 | 1940 |
| 1746 visitOperator(Operator node) { | 1941 ResolutionResult visitRethrow(Rethrow node) { |
| 1747 internalError(node, 'operator'); | |
| 1748 } | |
| 1749 | |
| 1750 visitRethrow(Rethrow node) { | |
| 1751 if (!inCatchBlock) { | 1942 if (!inCatchBlock) { |
| 1752 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); | 1943 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); |
| 1753 } | 1944 } |
| 1945 return const NoneResult(); |
| 1754 } | 1946 } |
| 1755 | 1947 |
| 1756 visitReturn(Return node) { | 1948 ResolutionResult visitReturn(Return node) { |
| 1757 Node expression = node.expression; | 1949 Node expression = node.expression; |
| 1758 if (expression != null) { | 1950 if (expression != null) { |
| 1759 if (enclosingElement.isGenerativeConstructor) { | 1951 if (enclosingElement.isGenerativeConstructor) { |
| 1760 // It is a compile-time error if a return statement of the form | 1952 // It is a compile-time error if a return statement of the form |
| 1761 // `return e;` appears in a generative constructor. (Dart Language | 1953 // `return e;` appears in a generative constructor. (Dart Language |
| 1762 // Specification 13.12.) | 1954 // Specification 13.12.) |
| 1763 compiler.reportError(expression, | 1955 compiler.reportError(expression, |
| 1764 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); | 1956 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); |
| 1765 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { | 1957 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { |
| 1766 compiler.reportError( | 1958 compiler.reportError( |
| 1767 node, | 1959 node, |
| 1768 MessageKind.RETURN_IN_GENERATOR, | 1960 MessageKind.RETURN_IN_GENERATOR, |
| 1769 {'modifier': currentAsyncMarker}); | 1961 {'modifier': currentAsyncMarker}); |
| 1770 } | 1962 } |
| 1771 } | 1963 } |
| 1772 visit(node.expression); | 1964 visit(node.expression); |
| 1965 return const NoneResult(); |
| 1773 } | 1966 } |
| 1774 | 1967 |
| 1775 visitYield(Yield node) { | 1968 ResolutionResult visitYield(Yield node) { |
| 1776 compiler.streamClass.ensureResolved(compiler); | 1969 compiler.streamClass.ensureResolved(compiler); |
| 1777 compiler.iterableClass.ensureResolved(compiler); | 1970 compiler.iterableClass.ensureResolved(compiler); |
| 1778 visit(node.expression); | 1971 visit(node.expression); |
| 1972 return const NoneResult(); |
| 1779 } | 1973 } |
| 1780 | 1974 |
| 1781 visitRedirectingFactoryBody(RedirectingFactoryBody node) { | 1975 ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { |
| 1782 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; | 1976 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; |
| 1783 if (!enclosingElement.isFactoryConstructor) { | 1977 if (!enclosingElement.isFactoryConstructor) { |
| 1784 compiler.reportError( | 1978 compiler.reportError( |
| 1785 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); | 1979 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); |
| 1786 compiler.reportHint( | 1980 compiler.reportHint( |
| 1787 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); | 1981 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); |
| 1788 } | 1982 } |
| 1789 ConstructorElementX constructor = enclosingElement; | 1983 ConstructorElementX constructor = enclosingElement; |
| 1790 bool isConstConstructor = constructor.isConst; | 1984 bool isConstConstructor = constructor.isConst; |
| 1791 ConstructorElement redirectionTarget = resolveRedirectingFactory( | 1985 ConstructorElement redirectionTarget = resolveRedirectingFactory( |
| 1792 node, inConstContext: isConstConstructor); | 1986 node, inConstContext: isConstConstructor); |
| 1793 constructor.immediateRedirectionTarget = redirectionTarget; | 1987 constructor.immediateRedirectionTarget = redirectionTarget; |
| 1794 | 1988 |
| 1795 Node constructorReference = node.constructorReference; | 1989 Node constructorReference = node.constructorReference; |
| 1796 if (constructorReference is Send) { | 1990 if (constructorReference is Send) { |
| 1797 constructor.redirectionDeferredPrefix = | 1991 constructor.redirectionDeferredPrefix = |
| 1798 compiler.deferredLoadTask.deferredPrefixElement(constructorReference, | 1992 compiler.deferredLoadTask.deferredPrefixElement(constructorReference, |
| 1799 registry.mapping); | 1993 registry.mapping); |
| 1800 } | 1994 } |
| 1801 | 1995 |
| 1802 registry.setRedirectingTargetConstructor(node, redirectionTarget); | 1996 registry.setRedirectingTargetConstructor(node, redirectionTarget); |
| 1803 if (Elements.isUnresolved(redirectionTarget)) { | 1997 if (Elements.isUnresolved(redirectionTarget)) { |
| 1804 registry.registerThrowNoSuchMethod(); | 1998 registry.registerThrowNoSuchMethod(); |
| 1805 return; | 1999 return const NoneResult(); |
| 1806 } else { | 2000 } else { |
| 1807 if (isConstConstructor && | 2001 if (isConstConstructor && |
| 1808 !redirectionTarget.isConst) { | 2002 !redirectionTarget.isConst) { |
| 1809 compiler.reportError(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | 2003 compiler.reportError(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
| 1810 } | 2004 } |
| 1811 if (redirectionTarget == constructor) { | 2005 if (redirectionTarget == constructor) { |
| 1812 compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); | 2006 compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); |
| 1813 } | 2007 } |
| 1814 } | 2008 } |
| 1815 | 2009 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1841 compiler.resolver.resolveRedirectionChain(constructor, node); | 2035 compiler.resolver.resolveRedirectionChain(constructor, node); |
| 1842 }); | 2036 }); |
| 1843 | 2037 |
| 1844 registry.registerStaticUse(redirectionTarget); | 2038 registry.registerStaticUse(redirectionTarget); |
| 1845 // TODO(johnniwinther): Register the effective target type instead. | 2039 // TODO(johnniwinther): Register the effective target type instead. |
| 1846 registry.registerInstantiatedClass( | 2040 registry.registerInstantiatedClass( |
| 1847 redirectionTarget.enclosingClass.declaration); | 2041 redirectionTarget.enclosingClass.declaration); |
| 1848 if (isSymbolConstructor) { | 2042 if (isSymbolConstructor) { |
| 1849 registry.registerSymbolConstructor(); | 2043 registry.registerSymbolConstructor(); |
| 1850 } | 2044 } |
| 2045 return const NoneResult(); |
| 1851 } | 2046 } |
| 1852 | 2047 |
| 1853 visitThrow(Throw node) { | 2048 ResolutionResult visitThrow(Throw node) { |
| 1854 registry.registerThrowExpression(); | 2049 registry.registerThrowExpression(); |
| 1855 visit(node.expression); | 2050 visit(node.expression); |
| 2051 return const NoneResult(); |
| 1856 } | 2052 } |
| 1857 | 2053 |
| 1858 visitAwait(Await node) { | 2054 ResolutionResult visitAwait(Await node) { |
| 1859 compiler.futureClass.ensureResolved(compiler); | 2055 compiler.futureClass.ensureResolved(compiler); |
| 1860 visit(node.expression); | 2056 visit(node.expression); |
| 2057 return const NoneResult(); |
| 1861 } | 2058 } |
| 1862 | 2059 |
| 1863 visitVariableDefinitions(VariableDefinitions node) { | 2060 ResolutionResult visitVariableDefinitions(VariableDefinitions node) { |
| 1864 DartType type; | 2061 DartType type; |
| 1865 if (node.type != null) { | 2062 if (node.type != null) { |
| 1866 type = resolveTypeAnnotation(node.type); | 2063 type = resolveTypeAnnotation(node.type); |
| 1867 } else { | 2064 } else { |
| 1868 type = const DynamicType(); | 2065 type = const DynamicType(); |
| 1869 } | 2066 } |
| 1870 VariableList variables = new VariableList.node(node, type); | 2067 VariableList variables = new VariableList.node(node, type); |
| 1871 VariableDefinitionsVisitor visitor = | 2068 VariableDefinitionsVisitor visitor = |
| 1872 new VariableDefinitionsVisitor(compiler, node, this, variables); | 2069 new VariableDefinitionsVisitor(compiler, node, this, variables); |
| 1873 | 2070 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1898 } | 2095 } |
| 1899 if (modifiers.isStatic) { | 2096 if (modifiers.isStatic) { |
| 1900 reportExtraModifier('static'); | 2097 reportExtraModifier('static'); |
| 1901 } | 2098 } |
| 1902 } | 2099 } |
| 1903 if (node.metadata != null) { | 2100 if (node.metadata != null) { |
| 1904 variables.metadata = | 2101 variables.metadata = |
| 1905 compiler.resolver.resolveMetadata(enclosingElement, node); | 2102 compiler.resolver.resolveMetadata(enclosingElement, node); |
| 1906 } | 2103 } |
| 1907 visitor.visit(node.definitions); | 2104 visitor.visit(node.definitions); |
| 2105 return const NoneResult(); |
| 1908 } | 2106 } |
| 1909 | 2107 |
| 1910 visitWhile(While node) { | 2108 ResolutionResult visitWhile(While node) { |
| 1911 visit(node.condition); | 2109 visit(node.condition); |
| 1912 visitLoopBodyIn(node, node.body, new BlockScope(scope)); | 2110 visitLoopBodyIn(node, node.body, new BlockScope(scope)); |
| 2111 return const NoneResult(); |
| 1913 } | 2112 } |
| 1914 | 2113 |
| 1915 visitParenthesizedExpression(ParenthesizedExpression node) { | 2114 ResolutionResult visitParenthesizedExpression(ParenthesizedExpression node) { |
| 1916 bool oldSendIsMemberAccess = sendIsMemberAccess; | 2115 bool oldSendIsMemberAccess = sendIsMemberAccess; |
| 1917 sendIsMemberAccess = false; | 2116 sendIsMemberAccess = false; |
| 1918 var oldCategory = allowedCategory; | 2117 var oldCategory = allowedCategory; |
| 1919 allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION | 2118 allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION |
| 1920 | ElementCategory.IMPLIES_TYPE; | 2119 | ElementCategory.IMPLIES_TYPE; |
| 1921 visit(node.expression); | 2120 ResolutionResult result = visit(node.expression); |
| 1922 allowedCategory = oldCategory; | 2121 allowedCategory = oldCategory; |
| 1923 sendIsMemberAccess = oldSendIsMemberAccess; | 2122 sendIsMemberAccess = oldSendIsMemberAccess; |
| 2123 if (result.kind == ResultKind.CONSTANT) { |
| 2124 return result; |
| 2125 } |
| 2126 return const NoneResult(); |
| 1924 } | 2127 } |
| 1925 | 2128 |
| 1926 ResolutionResult visitNewExpression(NewExpression node) { | 2129 ResolutionResult visitNewExpression(NewExpression node) { |
| 1927 Node selector = node.send.selector; | 2130 Node selector = node.send.selector; |
| 1928 FunctionElement constructor = resolveConstructor(node); | 2131 FunctionElement constructor = resolveConstructor(node); |
| 1929 final bool isSymbolConstructor = constructor == compiler.symbolConstructor; | 2132 final bool isSymbolConstructor = constructor == compiler.symbolConstructor; |
| 1930 final bool isMirrorsUsedConstant = | 2133 final bool isMirrorsUsedConstant = |
| 1931 node.isConst && (constructor == compiler.mirrorsUsedConstructor); | 2134 node.isConst && (constructor == compiler.mirrorsUsedConstructor); |
| 1932 Selector callSelector = resolveSelector(node.send, constructor); | 2135 Selector callSelector = resolveSelector(node.send, constructor); |
| 1933 resolveArguments(node.send.argumentsNode); | 2136 resolveArguments(node.send.argumentsNode); |
| 1934 registry.useElement(node.send, constructor); | 2137 registry.useElement(node.send, constructor); |
| 1935 if (Elements.isUnresolved(constructor)) { | 2138 if (Elements.isUnresolved(constructor)) { |
| 1936 return new ElementResult(constructor); | 2139 return new ResolutionResult.forElement(constructor); |
| 1937 } | 2140 } |
| 1938 constructor.computeSignature(compiler); | 2141 constructor.computeSignature(compiler); |
| 1939 if (!callSelector.applies(constructor, compiler.world)) { | 2142 if (!callSelector.applies(constructor, compiler.world)) { |
| 1940 registry.registerThrowNoSuchMethod(); | 2143 registry.registerThrowNoSuchMethod(); |
| 1941 } | 2144 } |
| 1942 | 2145 |
| 1943 // [constructor] might be the implementation element | 2146 // [constructor] might be the implementation element |
| 1944 // and only declaration elements may be registered. | 2147 // and only declaration elements may be registered. |
| 1945 registry.registerStaticUse(constructor.declaration); | 2148 registry.registerStaticUse(constructor.declaration); |
| 1946 ClassElement cls = constructor.enclosingClass; | 2149 ClassElement cls = constructor.enclosingClass; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1964 } | 2167 } |
| 1965 | 2168 |
| 1966 if (isSymbolConstructor) { | 2169 if (isSymbolConstructor) { |
| 1967 if (node.isConst) { | 2170 if (node.isConst) { |
| 1968 Node argumentNode = node.send.arguments.head; | 2171 Node argumentNode = node.send.arguments.head; |
| 1969 ConstantExpression constant = | 2172 ConstantExpression constant = |
| 1970 compiler.resolver.constantCompiler.compileNode( | 2173 compiler.resolver.constantCompiler.compileNode( |
| 1971 argumentNode, registry.mapping); | 2174 argumentNode, registry.mapping); |
| 1972 ConstantValue name = compiler.constants.getConstantValue(constant); | 2175 ConstantValue name = compiler.constants.getConstantValue(constant); |
| 1973 if (!name.isString) { | 2176 if (!name.isString) { |
| 1974 DartType type = name.getType(compiler.coreTypes); | 2177 DartType type = name.getType(coreTypes); |
| 1975 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, | 2178 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, |
| 1976 {'type': type}); | 2179 {'type': type}); |
| 1977 } else { | 2180 } else { |
| 1978 StringConstantValue stringConstant = name; | 2181 StringConstantValue stringConstant = name; |
| 1979 String nameString = stringConstant.toDartString().slowToString(); | 2182 String nameString = stringConstant.toDartString().slowToString(); |
| 1980 if (validateSymbol(argumentNode, nameString)) { | 2183 if (validateSymbol(argumentNode, nameString)) { |
| 1981 registry.registerConstSymbol(nameString); | 2184 registry.registerConstSymbol(nameString); |
| 1982 } | 2185 } |
| 1983 } | 2186 } |
| 1984 } else { | 2187 } else { |
| 1985 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( | 2188 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( |
| 1986 enclosingElement)) { | 2189 enclosingElement)) { |
| 1987 compiler.reportHint( | 2190 compiler.reportHint( |
| 1988 node.newToken, MessageKind.NON_CONST_BLOAT, | 2191 node.newToken, MessageKind.NON_CONST_BLOAT, |
| 1989 {'name': compiler.symbolClass.name}); | 2192 {'name': compiler.symbolClass.name}); |
| 1990 } | 2193 } |
| 1991 registry.registerNewSymbol(); | 2194 registry.registerNewSymbol(); |
| 1992 } | 2195 } |
| 1993 } else if (isMirrorsUsedConstant) { | 2196 } else if (isMirrorsUsedConstant) { |
| 1994 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); | 2197 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); |
| 1995 } | 2198 } |
| 1996 if (node.isConst) { | 2199 if (node.isConst) { |
| 1997 analyzeConstantDeferred(node); | 2200 analyzeConstantDeferred(node); |
| 1998 } | 2201 } |
| 1999 | 2202 |
| 2000 return null; | 2203 return const NoneResult(); |
| 2001 } | 2204 } |
| 2002 | 2205 |
| 2003 void checkConstMapKeysDontOverrideEquals(Spannable spannable, | 2206 void checkConstMapKeysDontOverrideEquals(Spannable spannable, |
| 2004 MapConstantValue map) { | 2207 MapConstantValue map) { |
| 2005 for (ConstantValue key in map.keys) { | 2208 for (ConstantValue key in map.keys) { |
| 2006 if (!key.isObject) continue; | 2209 if (!key.isObject) continue; |
| 2007 ObjectConstantValue objectConstant = key; | 2210 ObjectConstantValue objectConstant = key; |
| 2008 DartType keyType = objectConstant.type; | 2211 DartType keyType = objectConstant.type; |
| 2009 ClassElement cls = keyType.element; | 2212 ClassElement cls = keyType.element; |
| 2010 if (cls == compiler.stringClass) continue; | 2213 if (cls == compiler.stringClass) continue; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2098 DartType type = typeResolver.resolveTypeAnnotation( | 2301 DartType type = typeResolver.resolveTypeAnnotation( |
| 2099 this, node, malformedIsError: malformedIsError, | 2302 this, node, malformedIsError: malformedIsError, |
| 2100 deferredIsMalformed: deferredIsMalformed); | 2303 deferredIsMalformed: deferredIsMalformed); |
| 2101 if (inCheckContext) { | 2304 if (inCheckContext) { |
| 2102 registry.registerIsCheck(type); | 2305 registry.registerIsCheck(type); |
| 2103 registry.registerRequiredType(type, enclosingElement); | 2306 registry.registerRequiredType(type, enclosingElement); |
| 2104 } | 2307 } |
| 2105 return type; | 2308 return type; |
| 2106 } | 2309 } |
| 2107 | 2310 |
| 2108 visitModifiers(Modifiers node) { | 2311 ResolutionResult visitLiteralList(LiteralList node) { |
| 2109 internalError(node, 'modifiers'); | 2312 bool isValidAsConstant = true; |
| 2110 } | |
| 2111 | |
| 2112 visitLiteralList(LiteralList node) { | |
| 2113 bool oldSendIsMemberAccess = sendIsMemberAccess; | |
| 2114 sendIsMemberAccess = false; | 2313 sendIsMemberAccess = false; |
| 2115 | 2314 |
| 2116 NodeList arguments = node.typeArguments; | 2315 NodeList arguments = node.typeArguments; |
| 2117 DartType typeArgument; | 2316 DartType typeArgument; |
| 2118 if (arguments != null) { | 2317 if (arguments != null) { |
| 2119 Link<Node> nodes = arguments.nodes; | 2318 Link<Node> nodes = arguments.nodes; |
| 2120 if (nodes.isEmpty) { | 2319 if (nodes.isEmpty) { |
| 2121 // The syntax [: <>[] :] is not allowed. | 2320 // The syntax [: <>[] :] is not allowed. |
| 2122 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT); | 2321 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT); |
| 2322 isValidAsConstant = false; |
| 2123 } else { | 2323 } else { |
| 2124 typeArgument = resolveTypeAnnotation(nodes.head); | 2324 typeArgument = resolveTypeAnnotation(nodes.head); |
| 2125 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 2325 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
| 2126 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 2326 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
| 2127 resolveTypeAnnotation(nodes.head); | 2327 resolveTypeAnnotation(nodes.head); |
| 2128 } | 2328 } |
| 2129 } | 2329 } |
| 2130 } | 2330 } |
| 2131 DartType listType; | 2331 DartType listType; |
| 2132 if (typeArgument != null) { | 2332 if (typeArgument != null) { |
| 2133 if (node.isConst && typeArgument.containsTypeVariables) { | 2333 if (node.isConst && typeArgument.containsTypeVariables) { |
| 2134 compiler.reportError(arguments.nodes.head, | 2334 compiler.reportError(arguments.nodes.head, |
| 2135 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 2335 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 2336 isValidAsConstant = false; |
| 2136 } | 2337 } |
| 2137 listType = new InterfaceType(compiler.listClass, [typeArgument]); | 2338 listType = coreTypes.listType(typeArgument); |
| 2138 } else { | 2339 } else { |
| 2139 compiler.listClass.computeType(compiler); | 2340 listType = coreTypes.listType(); |
| 2140 listType = compiler.listClass.rawType; | |
| 2141 } | 2341 } |
| 2142 registry.setType(node, listType); | 2342 registry.setType(node, listType); |
| 2143 registry.registerInstantiatedType(listType); | 2343 registry.registerInstantiatedType(listType); |
| 2144 registry.registerRequiredType(listType, enclosingElement); | 2344 registry.registerRequiredType(listType, enclosingElement); |
| 2145 visit(node.elements); | |
| 2146 if (node.isConst) { | 2345 if (node.isConst) { |
| 2346 List<ConstantExpression> constantExpressions = <ConstantExpression>[]; |
| 2347 for (Node element in node.elements) { |
| 2348 ResolutionResult elementResult = visit(element); |
| 2349 if (isValidAsConstant && elementResult.isConstant) { |
| 2350 constantExpressions.add(elementResult.constant); |
| 2351 } else { |
| 2352 isValidAsConstant = false; |
| 2353 } |
| 2354 } |
| 2147 analyzeConstantDeferred(node); | 2355 analyzeConstantDeferred(node); |
| 2356 sendIsMemberAccess = false; |
| 2357 if (isValidAsConstant) { |
| 2358 ConstantExpression constant = |
| 2359 new ListConstantExpression(listType, constantExpressions); |
| 2360 registry.setConstant(node, constant); |
| 2361 return new ConstantResult(node, constant); |
| 2362 } |
| 2363 } else { |
| 2364 visit(node.elements); |
| 2365 sendIsMemberAccess = false; |
| 2366 } |
| 2367 return const NoneResult(); |
| 2368 |
| 2369 } |
| 2370 |
| 2371 ResolutionResult visitConditional(Conditional node) { |
| 2372 ResolutionResult conditionResult = |
| 2373 doInPromotionScope(node.condition, () => visit(node.condition)); |
| 2374 ResolutionResult thenResult = |
| 2375 doInPromotionScope(node.thenExpression, () => visit(node.thenExpression)
); |
| 2376 ResolutionResult elseResult = visit(node.elseExpression); |
| 2377 if (conditionResult.isConstant && |
| 2378 thenResult.isConstant && |
| 2379 elseResult.isConstant) { |
| 2380 ConstantExpression constant = new ConditionalConstantExpression( |
| 2381 conditionResult.constant, |
| 2382 thenResult.constant, |
| 2383 elseResult.constant); |
| 2384 registry.setConstant(node, constant); |
| 2385 return new ConstantResult(node, constant); |
| 2386 } |
| 2387 return const NoneResult(); |
| 2388 } |
| 2389 |
| 2390 ResolutionResult visitStringInterpolation(StringInterpolation node) { |
| 2391 registry.registerInstantiatedType(coreTypes.stringType); |
| 2392 registry.registerStringInterpolation(); |
| 2393 registerImplicitInvocation('toString', 0); |
| 2394 |
| 2395 bool isValidAsConstant = true; |
| 2396 List<ConstantExpression> parts = <ConstantExpression>[]; |
| 2397 |
| 2398 void resolvePart(Node subnode) { |
| 2399 ResolutionResult result = visit(subnode); |
| 2400 if (isValidAsConstant && result.isConstant) { |
| 2401 parts.add(result.constant); |
| 2402 } else { |
| 2403 isValidAsConstant = false; |
| 2404 } |
| 2148 } | 2405 } |
| 2149 | 2406 |
| 2150 sendIsMemberAccess = false; | 2407 resolvePart(node.string); |
| 2408 for (StringInterpolationPart part in node.parts) { |
| 2409 resolvePart(part.expression); |
| 2410 resolvePart(part.string); |
| 2411 } |
| 2412 |
| 2413 if (isValidAsConstant) { |
| 2414 ConstantExpression constant = new ConcatenateConstantExpression(parts); |
| 2415 registry.setConstant(node, constant); |
| 2416 return new ConstantResult(node, constant); |
| 2417 } |
| 2418 return const NoneResult(); |
| 2151 } | 2419 } |
| 2152 | 2420 |
| 2153 visitConditional(Conditional node) { | 2421 ResolutionResult visitBreakStatement(BreakStatement node) { |
| 2154 doInPromotionScope(node.condition, () => visit(node.condition)); | |
| 2155 doInPromotionScope(node.thenExpression, () => visit(node.thenExpression)); | |
| 2156 visit(node.elseExpression); | |
| 2157 } | |
| 2158 | |
| 2159 visitStringInterpolation(StringInterpolation node) { | |
| 2160 registry.registerInstantiatedClass(compiler.stringClass); | |
| 2161 registry.registerStringInterpolation(); | |
| 2162 node.visitChildren(this); | |
| 2163 } | |
| 2164 | |
| 2165 visitStringInterpolationPart(StringInterpolationPart node) { | |
| 2166 registerImplicitInvocation('toString', 0); | |
| 2167 node.visitChildren(this); | |
| 2168 } | |
| 2169 | |
| 2170 visitBreakStatement(BreakStatement node) { | |
| 2171 JumpTarget target; | 2422 JumpTarget target; |
| 2172 if (node.target == null) { | 2423 if (node.target == null) { |
| 2173 target = statementScope.currentBreakTarget(); | 2424 target = statementScope.currentBreakTarget(); |
| 2174 if (target == null) { | 2425 if (target == null) { |
| 2175 error(node, MessageKind.NO_BREAK_TARGET); | 2426 error(node, MessageKind.NO_BREAK_TARGET); |
| 2176 return; | 2427 return const NoneResult(); |
| 2177 } | 2428 } |
| 2178 target.isBreakTarget = true; | 2429 target.isBreakTarget = true; |
| 2179 } else { | 2430 } else { |
| 2180 String labelName = node.target.source; | 2431 String labelName = node.target.source; |
| 2181 LabelDefinition label = statementScope.lookupLabel(labelName); | 2432 LabelDefinition label = statementScope.lookupLabel(labelName); |
| 2182 if (label == null) { | 2433 if (label == null) { |
| 2183 error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); | 2434 error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
| 2184 return; | 2435 return const NoneResult(); |
| 2185 } | 2436 } |
| 2186 target = label.target; | 2437 target = label.target; |
| 2187 if (!target.statement.isValidBreakTarget()) { | 2438 if (!target.statement.isValidBreakTarget()) { |
| 2188 error(node.target, MessageKind.INVALID_BREAK); | 2439 error(node.target, MessageKind.INVALID_BREAK); |
| 2189 return; | 2440 return const NoneResult(); |
| 2190 } | 2441 } |
| 2191 label.setBreakTarget(); | 2442 label.setBreakTarget(); |
| 2192 registry.useLabel(node, label); | 2443 registry.useLabel(node, label); |
| 2193 } | 2444 } |
| 2194 registry.registerTargetOf(node, target); | 2445 registry.registerTargetOf(node, target); |
| 2446 return const NoneResult(); |
| 2195 } | 2447 } |
| 2196 | 2448 |
| 2197 visitContinueStatement(ContinueStatement node) { | 2449 ResolutionResult visitContinueStatement(ContinueStatement node) { |
| 2198 JumpTarget target; | 2450 JumpTarget target; |
| 2199 if (node.target == null) { | 2451 if (node.target == null) { |
| 2200 target = statementScope.currentContinueTarget(); | 2452 target = statementScope.currentContinueTarget(); |
| 2201 if (target == null) { | 2453 if (target == null) { |
| 2202 error(node, MessageKind.NO_CONTINUE_TARGET); | 2454 error(node, MessageKind.NO_CONTINUE_TARGET); |
| 2203 return; | 2455 return const NoneResult(); |
| 2204 } | 2456 } |
| 2205 target.isContinueTarget = true; | 2457 target.isContinueTarget = true; |
| 2206 } else { | 2458 } else { |
| 2207 String labelName = node.target.source; | 2459 String labelName = node.target.source; |
| 2208 LabelDefinition label = statementScope.lookupLabel(labelName); | 2460 LabelDefinition label = statementScope.lookupLabel(labelName); |
| 2209 if (label == null) { | 2461 if (label == null) { |
| 2210 error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); | 2462 error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
| 2211 return; | 2463 return const NoneResult(); |
| 2212 } | 2464 } |
| 2213 target = label.target; | 2465 target = label.target; |
| 2214 if (!target.statement.isValidContinueTarget()) { | 2466 if (!target.statement.isValidContinueTarget()) { |
| 2215 error(node.target, MessageKind.INVALID_CONTINUE); | 2467 error(node.target, MessageKind.INVALID_CONTINUE); |
| 2216 } | 2468 } |
| 2217 label.setContinueTarget(); | 2469 label.setContinueTarget(); |
| 2218 registry.useLabel(node, label); | 2470 registry.useLabel(node, label); |
| 2219 } | 2471 } |
| 2220 registry.registerTargetOf(node, target); | 2472 registry.registerTargetOf(node, target); |
| 2473 return const NoneResult(); |
| 2221 } | 2474 } |
| 2222 | 2475 |
| 2223 registerImplicitInvocation(String name, int arity) { | 2476 registerImplicitInvocation(String name, int arity) { |
| 2224 Selector selector = new Selector.call(name, null, arity); | 2477 Selector selector = new Selector.call(name, null, arity); |
| 2225 registry.registerDynamicInvocation(selector); | 2478 registry.registerDynamicInvocation(selector); |
| 2226 } | 2479 } |
| 2227 | 2480 |
| 2228 visitAsyncForIn(AsyncForIn node) { | 2481 ResolutionResult visitAsyncForIn(AsyncForIn node) { |
| 2229 registry.registerAsyncForIn(node); | 2482 registry.registerAsyncForIn(node); |
| 2230 registry.setCurrentSelector(node, compiler.currentSelector); | 2483 registry.setCurrentSelector(node, compiler.currentSelector); |
| 2231 registry.registerDynamicGetter(compiler.currentSelector); | 2484 registry.registerDynamicGetter(compiler.currentSelector); |
| 2232 registry.setMoveNextSelector(node, compiler.moveNextSelector); | 2485 registry.setMoveNextSelector(node, compiler.moveNextSelector); |
| 2233 registry.registerDynamicInvocation(compiler.moveNextSelector); | 2486 registry.registerDynamicInvocation(compiler.moveNextSelector); |
| 2234 | 2487 |
| 2235 visit(node.expression); | 2488 visit(node.expression); |
| 2236 | 2489 |
| 2237 Scope blockScope = new BlockScope(scope); | 2490 Scope blockScope = new BlockScope(scope); |
| 2238 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); | 2491 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); |
| 2239 visitLoopBodyIn(node, node.body, blockScope); | 2492 visitLoopBodyIn(node, node.body, blockScope); |
| 2493 return const NoneResult(); |
| 2240 } | 2494 } |
| 2241 | 2495 |
| 2242 visitSyncForIn(SyncForIn node) { | 2496 ResolutionResult visitSyncForIn(SyncForIn node) { |
| 2243 registry.registerSyncForIn(node); | 2497 registry.registerSyncForIn(node); |
| 2244 registry.setIteratorSelector(node, compiler.iteratorSelector); | 2498 registry.setIteratorSelector(node, compiler.iteratorSelector); |
| 2245 registry.registerDynamicGetter(compiler.iteratorSelector); | 2499 registry.registerDynamicGetter(compiler.iteratorSelector); |
| 2246 registry.setCurrentSelector(node, compiler.currentSelector); | 2500 registry.setCurrentSelector(node, compiler.currentSelector); |
| 2247 registry.registerDynamicGetter(compiler.currentSelector); | 2501 registry.registerDynamicGetter(compiler.currentSelector); |
| 2248 registry.setMoveNextSelector(node, compiler.moveNextSelector); | 2502 registry.setMoveNextSelector(node, compiler.moveNextSelector); |
| 2249 registry.registerDynamicInvocation(compiler.moveNextSelector); | 2503 registry.registerDynamicInvocation(compiler.moveNextSelector); |
| 2250 | 2504 |
| 2251 visit(node.expression); | 2505 visit(node.expression); |
| 2252 | 2506 |
| 2253 Scope blockScope = new BlockScope(scope); | 2507 Scope blockScope = new BlockScope(scope); |
| 2254 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); | 2508 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); |
| 2255 visitLoopBodyIn(node, node.body, blockScope); | 2509 visitLoopBodyIn(node, node.body, blockScope); |
| 2510 return const NoneResult(); |
| 2256 } | 2511 } |
| 2257 | 2512 |
| 2258 visitForInDeclaredIdentifierIn(Node declaration, ForIn node, | 2513 void visitForInDeclaredIdentifierIn( |
| 2259 Scope blockScope) { | 2514 Node declaration, |
| 2515 ForIn node, |
| 2516 Scope blockScope) { |
| 2260 LibraryElement library = enclosingElement.library; | 2517 LibraryElement library = enclosingElement.library; |
| 2261 | 2518 |
| 2262 bool oldAllowFinalWithoutInitializer = allowFinalWithoutInitializer; | 2519 bool oldAllowFinalWithoutInitializer = allowFinalWithoutInitializer; |
| 2263 allowFinalWithoutInitializer = true; | 2520 allowFinalWithoutInitializer = true; |
| 2264 visitIn(declaration, blockScope); | 2521 visitIn(declaration, blockScope); |
| 2265 allowFinalWithoutInitializer = oldAllowFinalWithoutInitializer; | 2522 allowFinalWithoutInitializer = oldAllowFinalWithoutInitializer; |
| 2266 | 2523 |
| 2267 Send send = declaration.asSend(); | 2524 Send send = declaration.asSend(); |
| 2268 VariableDefinitions variableDefinitions = | 2525 VariableDefinitions variableDefinitions = |
| 2269 declaration.asVariableDefinitions(); | 2526 declaration.asVariableDefinitions(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2306 if (loopVariable != null) { | 2563 if (loopVariable != null) { |
| 2307 // loopVariable may be null if it could not be resolved. | 2564 // loopVariable may be null if it could not be resolved. |
| 2308 registry.setForInVariable(node, loopVariable); | 2565 registry.setForInVariable(node, loopVariable); |
| 2309 } | 2566 } |
| 2310 } | 2567 } |
| 2311 | 2568 |
| 2312 visitLabel(Label node) { | 2569 visitLabel(Label node) { |
| 2313 // Labels are handled by their containing statements/cases. | 2570 // Labels are handled by their containing statements/cases. |
| 2314 } | 2571 } |
| 2315 | 2572 |
| 2316 visitLabeledStatement(LabeledStatement node) { | 2573 ResolutionResult visitLabeledStatement(LabeledStatement node) { |
| 2317 Statement body = node.statement; | 2574 Statement body = node.statement; |
| 2318 JumpTarget targetElement = getOrDefineTarget(body); | 2575 JumpTarget targetElement = getOrDefineTarget(body); |
| 2319 Map<String, LabelDefinition> labelElements = <String, LabelDefinition>{}; | 2576 Map<String, LabelDefinition> labelElements = <String, LabelDefinition>{}; |
| 2320 for (Label label in node.labels) { | 2577 for (Label label in node.labels) { |
| 2321 String labelName = label.labelName; | 2578 String labelName = label.labelName; |
| 2322 if (labelElements.containsKey(labelName)) continue; | 2579 if (labelElements.containsKey(labelName)) continue; |
| 2323 LabelDefinition element = targetElement.addLabel(label, labelName); | 2580 LabelDefinition element = targetElement.addLabel(label, labelName); |
| 2324 labelElements[labelName] = element; | 2581 labelElements[labelName] = element; |
| 2325 } | 2582 } |
| 2326 statementScope.enterLabelScope(labelElements); | 2583 statementScope.enterLabelScope(labelElements); |
| 2327 visit(node.statement); | 2584 visit(node.statement); |
| 2328 statementScope.exitLabelScope(); | 2585 statementScope.exitLabelScope(); |
| 2329 labelElements.forEach((String labelName, LabelDefinition element) { | 2586 labelElements.forEach((String labelName, LabelDefinition element) { |
| 2330 if (element.isTarget) { | 2587 if (element.isTarget) { |
| 2331 registry.defineLabel(element.label, element); | 2588 registry.defineLabel(element.label, element); |
| 2332 } else { | 2589 } else { |
| 2333 warning(element.label, MessageKind.UNUSED_LABEL, | 2590 warning(element.label, MessageKind.UNUSED_LABEL, |
| 2334 {'labelName': labelName}); | 2591 {'labelName': labelName}); |
| 2335 } | 2592 } |
| 2336 }); | 2593 }); |
| 2337 if (!targetElement.isTarget) { | 2594 if (!targetElement.isTarget) { |
| 2338 registry.undefineTarget(body); | 2595 registry.undefineTarget(body); |
| 2339 } | 2596 } |
| 2597 return const NoneResult(); |
| 2340 } | 2598 } |
| 2341 | 2599 |
| 2342 visitLiteralMap(LiteralMap node) { | 2600 ResolutionResult visitLiteralMap(LiteralMap node) { |
| 2601 bool isValidAsConstant = true; |
| 2343 sendIsMemberAccess = false; | 2602 sendIsMemberAccess = false; |
| 2344 | 2603 |
| 2345 NodeList arguments = node.typeArguments; | 2604 NodeList arguments = node.typeArguments; |
| 2346 DartType keyTypeArgument; | 2605 DartType keyTypeArgument; |
| 2347 DartType valueTypeArgument; | 2606 DartType valueTypeArgument; |
| 2348 if (arguments != null) { | 2607 if (arguments != null) { |
| 2349 Link<Node> nodes = arguments.nodes; | 2608 Link<Node> nodes = arguments.nodes; |
| 2350 if (nodes.isEmpty) { | 2609 if (nodes.isEmpty) { |
| 2351 // The syntax [: <>{} :] is not allowed. | 2610 // The syntax [: <>{} :] is not allowed. |
| 2352 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT); | 2611 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT); |
| 2612 isValidAsConstant = false; |
| 2353 } else { | 2613 } else { |
| 2354 keyTypeArgument = resolveTypeAnnotation(nodes.head); | 2614 keyTypeArgument = resolveTypeAnnotation(nodes.head); |
| 2355 nodes = nodes.tail; | 2615 nodes = nodes.tail; |
| 2356 if (nodes.isEmpty) { | 2616 if (nodes.isEmpty) { |
| 2357 warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT); | 2617 warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT); |
| 2358 } else { | 2618 } else { |
| 2359 valueTypeArgument = resolveTypeAnnotation(nodes.head); | 2619 valueTypeArgument = resolveTypeAnnotation(nodes.head); |
| 2360 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 2620 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
| 2361 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 2621 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
| 2362 resolveTypeAnnotation(nodes.head); | 2622 resolveTypeAnnotation(nodes.head); |
| 2363 } | 2623 } |
| 2364 } | 2624 } |
| 2365 } | 2625 } |
| 2366 } | 2626 } |
| 2367 DartType mapType; | 2627 DartType mapType; |
| 2368 if (valueTypeArgument != null) { | 2628 if (valueTypeArgument != null) { |
| 2369 mapType = new InterfaceType(compiler.mapClass, | 2629 mapType = coreTypes.mapType(keyTypeArgument, valueTypeArgument); |
| 2370 [keyTypeArgument, valueTypeArgument]); | |
| 2371 } else { | 2630 } else { |
| 2372 compiler.mapClass.computeType(compiler); | 2631 mapType = coreTypes.mapType(); |
| 2373 mapType = compiler.mapClass.rawType; | |
| 2374 } | 2632 } |
| 2375 if (node.isConst && mapType.containsTypeVariables) { | 2633 if (node.isConst && mapType.containsTypeVariables) { |
| 2376 compiler.reportError(arguments, | 2634 compiler.reportError(arguments, |
| 2377 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 2635 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 2636 isValidAsConstant = false; |
| 2378 } | 2637 } |
| 2379 registry.registerMapLiteral(node, mapType, node.isConst); | 2638 registry.registerMapLiteral(node, mapType, node.isConst); |
| 2380 registry.registerRequiredType(mapType, enclosingElement); | 2639 registry.registerRequiredType(mapType, enclosingElement); |
| 2381 node.visitChildren(this); | |
| 2382 if (node.isConst) { | 2640 if (node.isConst) { |
| 2641 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; |
| 2642 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; |
| 2643 for (LiteralMapEntry entry in node.entries) { |
| 2644 ResolutionResult keyResult = visit(entry.key); |
| 2645 ResolutionResult valueResult = visit(entry.value); |
| 2646 if (isValidAsConstant && |
| 2647 keyResult.isConstant && |
| 2648 valueResult.isConstant) { |
| 2649 keyExpressions.add(keyResult.constant); |
| 2650 valueExpressions.add(valueResult.constant); |
| 2651 } else { |
| 2652 isValidAsConstant = false; |
| 2653 } |
| 2654 } |
| 2383 analyzeConstantDeferred(node); | 2655 analyzeConstantDeferred(node); |
| 2656 sendIsMemberAccess = false; |
| 2657 if (isValidAsConstant) { |
| 2658 ConstantExpression constant = new MapConstantExpression( |
| 2659 mapType, keyExpressions, valueExpressions); |
| 2660 registry.setConstant(node, constant); |
| 2661 return new ConstantResult(node, constant); |
| 2662 } |
| 2663 } else { |
| 2664 node.visitChildren(this); |
| 2665 sendIsMemberAccess = false; |
| 2384 } | 2666 } |
| 2385 | 2667 return const NoneResult(); |
| 2386 sendIsMemberAccess = false; | |
| 2387 } | 2668 } |
| 2388 | 2669 |
| 2389 visitLiteralMapEntry(LiteralMapEntry node) { | 2670 ResolutionResult visitLiteralMapEntry(LiteralMapEntry node) { |
| 2390 node.visitChildren(this); | 2671 node.visitChildren(this); |
| 2672 return const NoneResult(); |
| 2391 } | 2673 } |
| 2392 | 2674 |
| 2393 visitNamedArgument(NamedArgument node) { | 2675 ResolutionResult visitNamedArgument(NamedArgument node) { |
| 2394 visit(node.expression); | 2676 return visit(node.expression); |
| 2395 } | 2677 } |
| 2396 | 2678 |
| 2397 DartType typeOfConstant(ConstantValue constant) { | 2679 DartType typeOfConstant(ConstantValue constant) { |
| 2398 if (constant.isInt) return compiler.intClass.rawType; | 2680 if (constant.isInt) return compiler.intClass.rawType; |
| 2399 if (constant.isBool) return compiler.boolClass.rawType; | 2681 if (constant.isBool) return compiler.boolClass.rawType; |
| 2400 if (constant.isDouble) return compiler.doubleClass.rawType; | 2682 if (constant.isDouble) return compiler.doubleClass.rawType; |
| 2401 if (constant.isString) return compiler.stringClass.rawType; | 2683 if (constant.isString) return compiler.stringClass.rawType; |
| 2402 if (constant.isNull) return compiler.nullClass.rawType; | 2684 if (constant.isNull) return compiler.nullClass.rawType; |
| 2403 if (constant.isFunction) return compiler.functionClass.rawType; | 2685 if (constant.isFunction) return compiler.functionClass.rawType; |
| 2404 assert(constant.isObject); | 2686 assert(constant.isObject); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2469 compiler.reportInfo( | 2751 compiler.reportInfo( |
| 2470 caseMatch.expression, | 2752 caseMatch.expression, |
| 2471 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, | 2753 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, |
| 2472 {'type': caseType}); | 2754 {'type': caseType}); |
| 2473 } | 2755 } |
| 2474 } | 2756 } |
| 2475 } | 2757 } |
| 2476 } | 2758 } |
| 2477 } | 2759 } |
| 2478 | 2760 |
| 2479 visitSwitchStatement(SwitchStatement node) { | 2761 ResolutionResult visitSwitchStatement(SwitchStatement node) { |
| 2480 node.expression.accept(this); | 2762 node.expression.accept(this); |
| 2481 | 2763 |
| 2482 JumpTarget breakElement = getOrDefineTarget(node); | 2764 JumpTarget breakElement = getOrDefineTarget(node); |
| 2483 Map<String, LabelDefinition> continueLabels = <String, LabelDefinition>{}; | 2765 Map<String, LabelDefinition> continueLabels = <String, LabelDefinition>{}; |
| 2484 Link<Node> cases = node.cases.nodes; | 2766 Link<Node> cases = node.cases.nodes; |
| 2485 while (!cases.isEmpty) { | 2767 while (!cases.isEmpty) { |
| 2486 SwitchCase switchCase = cases.head; | 2768 SwitchCase switchCase = cases.head; |
| 2487 for (Node labelOrCase in switchCase.labelsAndCases) { | 2769 for (Node labelOrCase in switchCase.labelsAndCases) { |
| 2488 CaseMatch caseMatch = labelOrCase.asCaseMatch(); | 2770 CaseMatch caseMatch = labelOrCase.asCaseMatch(); |
| 2489 if (caseMatch != null) { | 2771 if (caseMatch != null) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2540 if (!label.isContinueTarget) { | 2822 if (!label.isContinueTarget) { |
| 2541 JumpTarget targetElement = label.target; | 2823 JumpTarget targetElement = label.target; |
| 2542 SwitchCase switchCase = targetElement.statement; | 2824 SwitchCase switchCase = targetElement.statement; |
| 2543 registry.undefineTarget(switchCase); | 2825 registry.undefineTarget(switchCase); |
| 2544 registry.undefineLabel(label.label); | 2826 registry.undefineLabel(label.label); |
| 2545 } | 2827 } |
| 2546 }); | 2828 }); |
| 2547 // TODO(15575): We should warn if we can detect a fall through | 2829 // TODO(15575): We should warn if we can detect a fall through |
| 2548 // error. | 2830 // error. |
| 2549 registry.registerFallThroughError(); | 2831 registry.registerFallThroughError(); |
| 2832 return const NoneResult(); |
| 2550 } | 2833 } |
| 2551 | 2834 |
| 2552 visitSwitchCase(SwitchCase node) { | 2835 ResolutionResult visitSwitchCase(SwitchCase node) { |
| 2553 node.labelsAndCases.accept(this); | 2836 node.labelsAndCases.accept(this); |
| 2554 visitIn(node.statements, new BlockScope(scope)); | 2837 visitIn(node.statements, new BlockScope(scope)); |
| 2838 return const NoneResult(); |
| 2555 } | 2839 } |
| 2556 | 2840 |
| 2557 visitCaseMatch(CaseMatch node) { | 2841 ResolutionResult visitCaseMatch(CaseMatch node) { |
| 2558 visit(node.expression); | 2842 visit(node.expression); |
| 2843 return const NoneResult(); |
| 2559 } | 2844 } |
| 2560 | 2845 |
| 2561 visitTryStatement(TryStatement node) { | 2846 ResolutionResult visitTryStatement(TryStatement node) { |
| 2562 visit(node.tryBlock); | 2847 visit(node.tryBlock); |
| 2563 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { | 2848 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { |
| 2564 error(node.getEndToken().next, MessageKind.NO_CATCH_NOR_FINALLY); | 2849 error(node.getEndToken().next, MessageKind.NO_CATCH_NOR_FINALLY); |
| 2565 } | 2850 } |
| 2566 visit(node.catchBlocks); | 2851 visit(node.catchBlocks); |
| 2567 visit(node.finallyBlock); | 2852 visit(node.finallyBlock); |
| 2853 return const NoneResult(); |
| 2568 } | 2854 } |
| 2569 | 2855 |
| 2570 visitCatchBlock(CatchBlock node) { | 2856 ResolutionResult visitCatchBlock(CatchBlock node) { |
| 2571 registry.registerCatchStatement(); | 2857 registry.registerCatchStatement(); |
| 2572 // Check that if catch part is present, then | 2858 // Check that if catch part is present, then |
| 2573 // it has one or two formal parameters. | 2859 // it has one or two formal parameters. |
| 2574 VariableDefinitions exceptionDefinition; | 2860 VariableDefinitions exceptionDefinition; |
| 2575 VariableDefinitions stackTraceDefinition; | 2861 VariableDefinitions stackTraceDefinition; |
| 2576 if (node.formals != null) { | 2862 if (node.formals != null) { |
| 2577 Link<Node> formalsToProcess = node.formals.nodes; | 2863 Link<Node> formalsToProcess = node.formals.nodes; |
| 2578 if (formalsToProcess.isEmpty) { | 2864 if (formalsToProcess.isEmpty) { |
| 2579 error(node, MessageKind.EMPTY_CATCH_DECLARATION); | 2865 error(node, MessageKind.EMPTY_CATCH_DECLARATION); |
| 2580 } else { | 2866 } else { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2630 registry.getDefinition(exceptionVariable); | 2916 registry.getDefinition(exceptionVariable); |
| 2631 exceptionElement.variables.type = exceptionType; | 2917 exceptionElement.variables.type = exceptionType; |
| 2632 } | 2918 } |
| 2633 if (stackTraceDefinition != null) { | 2919 if (stackTraceDefinition != null) { |
| 2634 Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head; | 2920 Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head; |
| 2635 VariableElementX stackTraceElement = | 2921 VariableElementX stackTraceElement = |
| 2636 registry.getDefinition(stackTraceVariable); | 2922 registry.getDefinition(stackTraceVariable); |
| 2637 registry.registerInstantiatedClass(compiler.stackTraceClass); | 2923 registry.registerInstantiatedClass(compiler.stackTraceClass); |
| 2638 stackTraceElement.variables.type = compiler.stackTraceClass.rawType; | 2924 stackTraceElement.variables.type = compiler.stackTraceClass.rawType; |
| 2639 } | 2925 } |
| 2640 } | 2926 return const NoneResult(); |
| 2641 | |
| 2642 visitTypedef(Typedef node) { | |
| 2643 internalError(node, 'typedef'); | |
| 2644 } | 2927 } |
| 2645 } | 2928 } |
| 2646 | 2929 |
| 2647 /// Looks up [name] in [scope] and unwraps the result. | 2930 /// Looks up [name] in [scope] and unwraps the result. |
| 2648 Element lookupInScope(Compiler compiler, Node node, | 2931 Element lookupInScope(Compiler compiler, Node node, |
| 2649 Scope scope, String name) { | 2932 Scope scope, String name) { |
| 2650 return Elements.unwrap(scope.lookup(name), compiler, node); | 2933 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 2651 } | 2934 } |
| OLD | NEW |