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 library dart2js.resolution.members; | 5 library dart2js.resolution.members; |
6 | 6 |
7 import '../common/names.dart' show | 7 import '../common/names.dart' show |
8 Selectors; | 8 Selectors; |
9 import '../compiler.dart' show | 9 import '../compiler.dart' show |
10 Compiler; | 10 Compiler; |
11 import '../constants/constructors.dart' show | 11 import '../constants/constructors.dart' show |
12 RedirectingFactoryConstantConstructor; | 12 RedirectingFactoryConstantConstructor; |
13 import '../constants/expressions.dart'; | 13 import '../constants/expressions.dart'; |
14 import '../constants/values.dart'; | 14 import '../constants/values.dart'; |
15 import '../core_types.dart'; | 15 import '../core_types.dart'; |
16 import '../dart_types.dart'; | 16 import '../dart_types.dart'; |
| 17 import '../diagnostics/diagnostic_listener.dart' show |
| 18 DiagnosticMessage; |
17 import '../diagnostics/invariant.dart' show | 19 import '../diagnostics/invariant.dart' show |
18 invariant; | 20 invariant; |
19 import '../diagnostics/messages.dart' show | 21 import '../diagnostics/messages.dart' show |
20 MessageKind; | 22 MessageKind; |
21 import '../diagnostics/spannable.dart' show | 23 import '../diagnostics/spannable.dart' show |
22 Spannable; | 24 Spannable; |
23 import '../elements/elements.dart'; | 25 import '../elements/elements.dart'; |
24 import '../elements/modelx.dart' show | 26 import '../elements/modelx.dart' show |
25 ConstructorElementX, | 27 ConstructorElementX, |
26 ErroneousElementX, | 28 ErroneousElementX, |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 if (enclosingElement is FunctionElement) { | 203 if (enclosingElement is FunctionElement) { |
202 FunctionElement function = enclosingElement; | 204 FunctionElement function = enclosingElement; |
203 return function.asyncMarker; | 205 return function.asyncMarker; |
204 } | 206 } |
205 return AsyncMarker.SYNC; | 207 return AsyncMarker.SYNC; |
206 } | 208 } |
207 | 209 |
208 Element reportLookupErrorIfAny(Element result, Node node, String name) { | 210 Element reportLookupErrorIfAny(Element result, Node node, String name) { |
209 if (!Elements.isUnresolved(result)) { | 211 if (!Elements.isUnresolved(result)) { |
210 if (!inInstanceContext && result.isInstanceMember) { | 212 if (!inInstanceContext && result.isInstanceMember) { |
211 compiler.reportError( | 213 compiler.reportErrorMessage( |
212 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); | 214 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); |
213 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, | 215 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, |
214 {'name': name}, | 216 {'name': name}, |
215 name, enclosingElement); | 217 name, enclosingElement); |
216 } else if (result.isAmbiguous) { | 218 } else if (result.isAmbiguous) { |
217 AmbiguousElement ambiguous = result; | 219 AmbiguousElement ambiguous = result; |
218 compiler.reportError( | 220 return reportAndCreateErroneousElement( |
219 node, ambiguous.messageKind, ambiguous.messageArguments); | 221 node, |
220 ambiguous.diagnose(enclosingElement, compiler); | 222 name, |
221 return new ErroneousElementX(ambiguous.messageKind, | 223 ambiguous.messageKind, |
222 ambiguous.messageArguments, | 224 ambiguous.messageArguments, |
223 name, enclosingElement); | 225 infos: ambiguous.computeInfos(enclosingElement, compiler), |
| 226 isError: true); |
224 } | 227 } |
225 } | 228 } |
226 return result; | 229 return result; |
227 } | 230 } |
228 | 231 |
229 // Create, or reuse an already created, target element for a statement. | 232 // Create, or reuse an already created, target element for a statement. |
230 JumpTarget getOrDefineTarget(Node statement) { | 233 JumpTarget getOrDefineTarget(Node statement) { |
231 JumpTarget element = registry.getTargetDefinition(statement); | 234 JumpTarget element = registry.getTargetDefinition(statement); |
232 if (element == null) { | 235 if (element == null) { |
233 element = new JumpTargetX(statement, | 236 element = new JumpTargetX(statement, |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 message: "No resolution result for $node.")); | 297 message: "No resolution result for $node.")); |
295 | 298 |
296 return result; | 299 return result; |
297 } | 300 } |
298 | 301 |
299 ErroneousElement reportAndCreateErroneousElement( | 302 ErroneousElement reportAndCreateErroneousElement( |
300 Node node, | 303 Node node, |
301 String name, | 304 String name, |
302 MessageKind kind, | 305 MessageKind kind, |
303 Map arguments, | 306 Map arguments, |
304 {bool isError: false}) { | 307 {List<DiagnosticMessage> infos: const <DiagnosticMessage>[], |
| 308 bool isError: false}) { |
305 if (isError) { | 309 if (isError) { |
306 compiler.reportError(node, kind, arguments); | 310 compiler.reportError( |
| 311 compiler.createMessage(node, kind, arguments), infos); |
307 } else { | 312 } else { |
308 compiler.reportWarning(node, kind, arguments); | 313 compiler.reportWarning( |
| 314 compiler.createMessage(node, kind, arguments), infos); |
309 } | 315 } |
310 // TODO(ahe): Use [allowedCategory] to synthesize a more precise subclass | 316 // TODO(ahe): Use [allowedCategory] to synthesize a more precise subclass |
311 // of [ErroneousElementX]. For example, [ErroneousFieldElementX], | 317 // of [ErroneousElementX]. For example, [ErroneousFieldElementX], |
312 // [ErroneousConstructorElementX], etc. | 318 // [ErroneousConstructorElementX], etc. |
313 return new ErroneousElementX(kind, arguments, name, enclosingElement); | 319 return new ErroneousElementX(kind, arguments, name, enclosingElement); |
314 } | 320 } |
315 | 321 |
316 /// Report a warning or error on an unresolved access in non-instance context. | 322 /// Report a warning or error on an unresolved access in non-instance context. |
317 /// | 323 /// |
318 /// The [ErroneousElement] corresponding to the message is returned. | 324 /// The [ErroneousElement] corresponding to the message is returned. |
(...skipping 28 matching lines...) Expand all Loading... |
347 kind = MessageKind.CANNOT_RESOLVE; | 353 kind = MessageKind.CANNOT_RESOLVE; |
348 } | 354 } |
349 registry.registerThrowNoSuchMethod(); | 355 registry.registerThrowNoSuchMethod(); |
350 return reportAndCreateErroneousElement( | 356 return reportAndCreateErroneousElement( |
351 node, name, kind, arguments, isError: inInitializer); | 357 node, name, kind, arguments, isError: inInitializer); |
352 } | 358 } |
353 | 359 |
354 ResolutionResult visitIdentifier(Identifier node) { | 360 ResolutionResult visitIdentifier(Identifier node) { |
355 if (node.isThis()) { | 361 if (node.isThis()) { |
356 if (!inInstanceContext) { | 362 if (!inInstanceContext) { |
357 error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); | 363 compiler.reportErrorMessage( |
| 364 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); |
358 } | 365 } |
359 return const NoneResult(); | 366 return const NoneResult(); |
360 } else if (node.isSuper()) { | 367 } else if (node.isSuper()) { |
361 if (!inInstanceContext) { | 368 if (!inInstanceContext) { |
362 error(node, MessageKind.NO_SUPER_IN_STATIC); | 369 compiler.reportErrorMessage( |
| 370 node, MessageKind.NO_SUPER_IN_STATIC); |
363 } | 371 } |
364 if ((ElementCategory.SUPER & allowedCategory) == 0) { | 372 if ((ElementCategory.SUPER & allowedCategory) == 0) { |
365 error(node, MessageKind.INVALID_USE_OF_SUPER); | 373 compiler.reportErrorMessage( |
| 374 node, MessageKind.INVALID_USE_OF_SUPER); |
366 } | 375 } |
367 return const NoneResult(); | 376 return const NoneResult(); |
368 } else { | 377 } else { |
369 String name = node.source; | 378 String name = node.source; |
370 Element element = lookupInScope(compiler, node, scope, name); | 379 Element element = lookupInScope(compiler, node, scope, name); |
371 if (Elements.isUnresolved(element) && name == 'dynamic') { | 380 if (Elements.isUnresolved(element) && name == 'dynamic') { |
372 // TODO(johnniwinther): Remove this hack when we can return more complex | 381 // TODO(johnniwinther): Remove this hack when we can return more complex |
373 // objects than [Element] from this method. | 382 // objects than [Element] from this method. |
374 element = compiler.typeClass; | 383 element = compiler.typeClass; |
375 // Set the type to be `dynamic` to mark that this is a type literal. | 384 // Set the type to be `dynamic` to mark that this is a type literal. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 final ClassElement classElement = constructor.enclosingClass; | 450 final ClassElement classElement = constructor.enclosingClass; |
442 return classElement.lookupConstructor(selector.name); | 451 return classElement.lookupConstructor(selector.name); |
443 } | 452 } |
444 return null; | 453 return null; |
445 } | 454 } |
446 | 455 |
447 void setupFunction(FunctionExpression node, FunctionElement function) { | 456 void setupFunction(FunctionExpression node, FunctionElement function) { |
448 Element enclosingElement = function.enclosingElement; | 457 Element enclosingElement = function.enclosingElement; |
449 if (node.modifiers.isStatic && | 458 if (node.modifiers.isStatic && |
450 enclosingElement.kind != ElementKind.CLASS) { | 459 enclosingElement.kind != ElementKind.CLASS) { |
451 compiler.reportError(node, MessageKind.ILLEGAL_STATIC); | 460 compiler.reportErrorMessage(node, MessageKind.ILLEGAL_STATIC); |
452 } | 461 } |
453 | 462 |
454 scope = new MethodScope(scope, function); | 463 scope = new MethodScope(scope, function); |
455 // Put the parameters in scope. | 464 // Put the parameters in scope. |
456 FunctionSignature functionParameters = function.functionSignature; | 465 FunctionSignature functionParameters = function.functionSignature; |
457 Link<Node> parameterNodes = (node.parameters == null) | 466 Link<Node> parameterNodes = (node.parameters == null) |
458 ? const Link<Node>() : node.parameters.nodes; | 467 ? const Link<Node>() : node.parameters.nodes; |
459 functionParameters.forEachParameter((ParameterElementX element) { | 468 functionParameters.forEachParameter((ParameterElementX element) { |
460 // TODO(karlklose): should be a list of [FormalElement]s, but the actual | 469 // TODO(karlklose): should be a list of [FormalElement]s, but the actual |
461 // implementation uses [Element]. | 470 // implementation uses [Element]. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 if (inCheckContext) { | 506 if (inCheckContext) { |
498 functionParameters.forEachParameter((ParameterElement element) { | 507 functionParameters.forEachParameter((ParameterElement element) { |
499 registry.registerIsCheck(element.type); | 508 registry.registerIsCheck(element.type); |
500 }); | 509 }); |
501 } | 510 } |
502 } | 511 } |
503 | 512 |
504 ResolutionResult visitAssert(Assert node) { | 513 ResolutionResult visitAssert(Assert node) { |
505 if (!compiler.enableAssertMessage) { | 514 if (!compiler.enableAssertMessage) { |
506 if (node.hasMessage) { | 515 if (node.hasMessage) { |
507 compiler.reportError(node, MessageKind.EXPERIMENTAL_ASSERT_MESSAGE); | 516 compiler.reportErrorMessage( |
| 517 node, MessageKind.EXPERIMENTAL_ASSERT_MESSAGE); |
508 } | 518 } |
509 } | 519 } |
510 // TODO(sra): We could completely ignore the assert in production mode if we | 520 // TODO(sra): We could completely ignore the assert in production mode if we |
511 // didn't need it to be resolved for type checking. | 521 // didn't need it to be resolved for type checking. |
512 registry.registerAssert(node.hasMessage); | 522 registry.registerAssert(node.hasMessage); |
513 visit(node.condition); | 523 visit(node.condition); |
514 visit(node.message); | 524 visit(node.message); |
515 return const NoneResult(); | 525 return const NoneResult(); |
516 } | 526 } |
517 | 527 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 /// [inFunctionDeclaration] is `true` when the current node is the immediate | 601 /// [inFunctionDeclaration] is `true` when the current node is the immediate |
592 /// child of a function declaration. | 602 /// child of a function declaration. |
593 /// | 603 /// |
594 /// This is used to distinguish local function declarations from anonymous | 604 /// This is used to distinguish local function declarations from anonymous |
595 /// function expressions. | 605 /// function expressions. |
596 ResolutionResult visitFunctionExpression( | 606 ResolutionResult visitFunctionExpression( |
597 FunctionExpression node, | 607 FunctionExpression node, |
598 {bool inFunctionDeclaration: false}) { | 608 {bool inFunctionDeclaration: false}) { |
599 bool doAddToScope = inFunctionDeclaration; | 609 bool doAddToScope = inFunctionDeclaration; |
600 if (!inFunctionDeclaration && node.name != null) { | 610 if (!inFunctionDeclaration && node.name != null) { |
601 compiler.reportError( | 611 compiler.reportErrorMessage( |
602 node.name, | 612 node.name, |
603 MessageKind.NAMED_FUNCTION_EXPRESSION, | 613 MessageKind.NAMED_FUNCTION_EXPRESSION, |
604 {'name': node.name}); | 614 {'name': node.name}); |
605 } | 615 } |
606 visit(node.returnType); | 616 visit(node.returnType); |
607 String name; | 617 String name; |
608 if (node.name == null) { | 618 if (node.name == null) { |
609 name = ""; | 619 name = ""; |
610 } else { | 620 } else { |
611 name = node.name.asIdentifier().source; | 621 name = node.name.asIdentifier().source; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 if (seenNamedArguments.containsKey(source)) { | 766 if (seenNamedArguments.containsKey(source)) { |
757 reportDuplicateDefinition( | 767 reportDuplicateDefinition( |
758 source, | 768 source, |
759 argument, | 769 argument, |
760 seenNamedArguments[source]); | 770 seenNamedArguments[source]); |
761 isValidAsConstant = false; | 771 isValidAsConstant = false; |
762 } else { | 772 } else { |
763 seenNamedArguments[source] = namedArgument; | 773 seenNamedArguments[source] = namedArgument; |
764 } | 774 } |
765 } else if (!seenNamedArguments.isEmpty) { | 775 } else if (!seenNamedArguments.isEmpty) { |
766 error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); | 776 compiler.reportErrorMessage( |
| 777 argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); |
767 isValidAsConstant = false; | 778 isValidAsConstant = false; |
768 } | 779 } |
769 argumentCount++; | 780 argumentCount++; |
770 } | 781 } |
771 sendIsMemberAccess = oldSendIsMemberAccess; | 782 sendIsMemberAccess = oldSendIsMemberAccess; |
772 return new ArgumentsResult( | 783 return new ArgumentsResult( |
773 new CallStructure(argumentCount, namedArguments), | 784 new CallStructure(argumentCount, namedArguments), |
774 argumentResults, | 785 argumentResults, |
775 isValidAsConstant: isValidAsConstant); | 786 isValidAsConstant: isValidAsConstant); |
776 } | 787 } |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1241 case UnaryOperatorKind.COMPLEMENT: | 1252 case UnaryOperatorKind.COMPLEMENT: |
1242 isValidConstant = | 1253 isValidConstant = |
1243 knownExpressionType == coreTypes.intType; | 1254 knownExpressionType == coreTypes.intType; |
1244 break; | 1255 break; |
1245 case UnaryOperatorKind.NEGATE: | 1256 case UnaryOperatorKind.NEGATE: |
1246 isValidConstant = | 1257 isValidConstant = |
1247 knownExpressionType == coreTypes.intType || | 1258 knownExpressionType == coreTypes.intType || |
1248 knownExpressionType == coreTypes.doubleType; | 1259 knownExpressionType == coreTypes.doubleType; |
1249 break; | 1260 break; |
1250 case UnaryOperatorKind.NOT: | 1261 case UnaryOperatorKind.NOT: |
1251 internalError(node, | 1262 compiler.internalError(node, |
1252 "Unexpected user definable unary operator: $operator"); | 1263 "Unexpected user definable unary operator: $operator"); |
1253 } | 1264 } |
1254 if (isValidConstant) { | 1265 if (isValidConstant) { |
1255 // TODO(johnniwinther): Handle potentially invalid constant | 1266 // TODO(johnniwinther): Handle potentially invalid constant |
1256 // expressions. | 1267 // expressions. |
1257 ConstantExpression constant = | 1268 ConstantExpression constant = |
1258 new UnaryConstantExpression(operator, expressionConstant); | 1269 new UnaryConstantExpression(operator, expressionConstant); |
1259 registry.setConstant(node, constant); | 1270 registry.setConstant(node, constant); |
1260 result = new ConstantResult(node, constant); | 1271 result = new ConstantResult(node, constant); |
1261 } | 1272 } |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1459 isValidConstant = | 1470 isValidConstant = |
1460 knownLeftType == coreTypes.intType && | 1471 knownLeftType == coreTypes.intType && |
1461 knownRightType == coreTypes.intType; | 1472 knownRightType == coreTypes.intType; |
1462 break; | 1473 break; |
1463 case BinaryOperatorKind.INDEX: | 1474 case BinaryOperatorKind.INDEX: |
1464 isValidConstant = false; | 1475 isValidConstant = false; |
1465 break; | 1476 break; |
1466 case BinaryOperatorKind.LOGICAL_AND: | 1477 case BinaryOperatorKind.LOGICAL_AND: |
1467 case BinaryOperatorKind.LOGICAL_OR: | 1478 case BinaryOperatorKind.LOGICAL_OR: |
1468 case BinaryOperatorKind.IF_NULL: | 1479 case BinaryOperatorKind.IF_NULL: |
1469 internalError(node, "Unexpected binary operator '${operator}'."); | 1480 compiler.internalError( |
| 1481 node, "Unexpected binary operator '${operator}'."); |
1470 break; | 1482 break; |
1471 } | 1483 } |
1472 if (isValidConstant) { | 1484 if (isValidConstant) { |
1473 // TODO(johnniwinther): Handle potentially invalid constant | 1485 // TODO(johnniwinther): Handle potentially invalid constant |
1474 // expressions. | 1486 // expressions. |
1475 ConstantExpression constant = new BinaryConstantExpression( | 1487 ConstantExpression constant = new BinaryConstantExpression( |
1476 leftResult.constant, | 1488 leftResult.constant, |
1477 operator, | 1489 operator, |
1478 rightResult.constant); | 1490 rightResult.constant); |
1479 registry.setConstant(node, constant); | 1491 registry.setConstant(node, constant); |
(...skipping 29 matching lines...) Expand all Loading... |
1509 case BinaryOperatorKind.LTEQ: | 1521 case BinaryOperatorKind.LTEQ: |
1510 case BinaryOperatorKind.LT: | 1522 case BinaryOperatorKind.LT: |
1511 case BinaryOperatorKind.AND: | 1523 case BinaryOperatorKind.AND: |
1512 case BinaryOperatorKind.OR: | 1524 case BinaryOperatorKind.OR: |
1513 case BinaryOperatorKind.XOR: | 1525 case BinaryOperatorKind.XOR: |
1514 sendStructure = new BinaryStructure(semantics, operator); | 1526 sendStructure = new BinaryStructure(semantics, operator); |
1515 break; | 1527 break; |
1516 case BinaryOperatorKind.LOGICAL_AND: | 1528 case BinaryOperatorKind.LOGICAL_AND: |
1517 case BinaryOperatorKind.LOGICAL_OR: | 1529 case BinaryOperatorKind.LOGICAL_OR: |
1518 case BinaryOperatorKind.IF_NULL: | 1530 case BinaryOperatorKind.IF_NULL: |
1519 internalError(node, "Unexpected binary operator '${operator}'."); | 1531 compiler.internalError( |
| 1532 node, "Unexpected binary operator '${operator}'."); |
1520 break; | 1533 break; |
1521 } | 1534 } |
1522 registry.registerSendStructure(node, sendStructure); | 1535 registry.registerSendStructure(node, sendStructure); |
1523 } | 1536 } |
1524 return result; | 1537 return result; |
1525 } | 1538 } |
1526 | 1539 |
1527 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. | 1540 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. |
1528 ResolutionResult handleExpressionInvoke(Send node) { | 1541 ResolutionResult handleExpressionInvoke(Send node) { |
1529 assert(invariant(node, node.isCall, | 1542 assert(invariant(node, node.isCall, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1573 new UniverseSelector(selector, null)); | 1586 new UniverseSelector(selector, null)); |
1574 } | 1587 } |
1575 registry.registerSendStructure(node, | 1588 registry.registerSendStructure(node, |
1576 new InvokeStructure(accessSemantics, selector)); | 1589 new InvokeStructure(accessSemantics, selector)); |
1577 // TODO(23998): Remove this when all information goes through | 1590 // TODO(23998): Remove this when all information goes through |
1578 // the [SendStructure]. | 1591 // the [SendStructure]. |
1579 registry.setSelector(node, selector); | 1592 registry.setSelector(node, selector); |
1580 return const NoneResult(); | 1593 return const NoneResult(); |
1581 } else { | 1594 } else { |
1582 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. | 1595 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. |
1583 internalError(node, "Unexpected node '$node'."); | 1596 compiler.internalError( |
| 1597 node, "Unexpected node '$node'."); |
1584 } | 1598 } |
1585 return const NoneResult(); | 1599 return const NoneResult(); |
1586 } | 1600 } |
1587 | 1601 |
1588 /// Handle access of a super property, like `super.foo` and `super.foo()`. | 1602 /// Handle access of a super property, like `super.foo` and `super.foo()`. |
1589 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { | 1603 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { |
1590 Element target; | 1604 Element target; |
1591 Selector selector; | 1605 Selector selector; |
1592 CallStructure callStructure; | 1606 CallStructure callStructure; |
1593 if (node.isCall) { | 1607 if (node.isCall) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1627 new UniverseSelector(selector, null)); | 1641 new UniverseSelector(selector, null)); |
1628 break; | 1642 break; |
1629 case AccessKind.SUPER_SETTER: | 1643 case AccessKind.SUPER_SETTER: |
1630 case AccessKind.UNRESOLVED_SUPER: | 1644 case AccessKind.UNRESOLVED_SUPER: |
1631 // NoSuchMethod registered in [computeSuperSemantics]. | 1645 // NoSuchMethod registered in [computeSuperSemantics]. |
1632 break; | 1646 break; |
1633 case AccessKind.INVALID: | 1647 case AccessKind.INVALID: |
1634 // 'super' is not allowed. | 1648 // 'super' is not allowed. |
1635 break; | 1649 break; |
1636 default: | 1650 default: |
1637 internalError(node, "Unexpected super property access $semantics."); | 1651 compiler.internalError( |
| 1652 node, "Unexpected super property access $semantics."); |
1638 break; | 1653 break; |
1639 } | 1654 } |
1640 registry.registerSendStructure(node, | 1655 registry.registerSendStructure(node, |
1641 isIncompatibleInvoke | 1656 isIncompatibleInvoke |
1642 ? new IncompatibleInvokeStructure(semantics, selector) | 1657 ? new IncompatibleInvokeStructure(semantics, selector) |
1643 : new InvokeStructure(semantics, selector)); | 1658 : new InvokeStructure(semantics, selector)); |
1644 } else { | 1659 } else { |
1645 switch (semantics.kind) { | 1660 switch (semantics.kind) { |
1646 case AccessKind.SUPER_METHOD: | 1661 case AccessKind.SUPER_METHOD: |
1647 // TODO(johnniwinther): Method this should be registered as a | 1662 // TODO(johnniwinther): Method this should be registered as a |
1648 // closurization. | 1663 // closurization. |
1649 registry.registerStaticUse(semantics.element); | 1664 registry.registerStaticUse(semantics.element); |
1650 break; | 1665 break; |
1651 case AccessKind.SUPER_FIELD: | 1666 case AccessKind.SUPER_FIELD: |
1652 case AccessKind.SUPER_FINAL_FIELD: | 1667 case AccessKind.SUPER_FINAL_FIELD: |
1653 case AccessKind.SUPER_GETTER: | 1668 case AccessKind.SUPER_GETTER: |
1654 registry.registerStaticUse(semantics.element); | 1669 registry.registerStaticUse(semantics.element); |
1655 break; | 1670 break; |
1656 case AccessKind.SUPER_SETTER: | 1671 case AccessKind.SUPER_SETTER: |
1657 case AccessKind.UNRESOLVED_SUPER: | 1672 case AccessKind.UNRESOLVED_SUPER: |
1658 // NoSuchMethod registered in [computeSuperSemantics]. | 1673 // NoSuchMethod registered in [computeSuperSemantics]. |
1659 break; | 1674 break; |
1660 case AccessKind.INVALID: | 1675 case AccessKind.INVALID: |
1661 // 'super' is not allowed. | 1676 // 'super' is not allowed. |
1662 break; | 1677 break; |
1663 default: | 1678 default: |
1664 internalError(node, "Unexpected super property access $semantics."); | 1679 compiler.internalError( |
| 1680 node, "Unexpected super property access $semantics."); |
1665 break; | 1681 break; |
1666 } | 1682 } |
1667 registry.registerSendStructure(node, new GetStructure(semantics)); | 1683 registry.registerSendStructure(node, new GetStructure(semantics)); |
1668 } | 1684 } |
1669 target = semantics.element; | 1685 target = semantics.element; |
1670 | 1686 |
1671 // TODO(23998): Remove these when all information goes through | 1687 // TODO(23998): Remove these when all information goes through |
1672 // the [SendStructure]. | 1688 // the [SendStructure]. |
1673 registry.useElement(node, target); | 1689 registry.useElement(node, target); |
1674 registry.setSelector(node, selector); | 1690 registry.setSelector(node, selector); |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2500 /// Handle access to an ambiguous element, that is, a name imported twice. | 2516 /// Handle access to an ambiguous element, that is, a name imported twice. |
2501 ResolutionResult handleAmbiguousSend( | 2517 ResolutionResult handleAmbiguousSend( |
2502 Send node, | 2518 Send node, |
2503 Name name, | 2519 Name name, |
2504 AmbiguousElement element) { | 2520 AmbiguousElement element) { |
2505 | 2521 |
2506 ErroneousElement error = reportAndCreateErroneousElement( | 2522 ErroneousElement error = reportAndCreateErroneousElement( |
2507 node, | 2523 node, |
2508 name.text, | 2524 name.text, |
2509 element.messageKind, | 2525 element.messageKind, |
2510 element.messageArguments); | 2526 element.messageArguments, |
2511 element.diagnose(enclosingElement, compiler); | 2527 infos: element.computeInfos(enclosingElement, compiler)); |
2512 registry.registerThrowNoSuchMethod(); | 2528 registry.registerThrowNoSuchMethod(); |
2513 | 2529 |
2514 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. | 2530 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. |
2515 AccessSemantics semantics = new StaticAccess.unresolved(error); | 2531 AccessSemantics semantics = new StaticAccess.unresolved(error); |
2516 return handleErroneousAccess(node, name, semantics); | 2532 return handleErroneousAccess(node, name, semantics); |
2517 } | 2533 } |
2518 | 2534 |
2519 /// Handle update to an ambiguous element, that is, a name imported twice. | 2535 /// Handle update to an ambiguous element, that is, a name imported twice. |
2520 ResolutionResult handleAmbiguousUpdate( | 2536 ResolutionResult handleAmbiguousUpdate( |
2521 SendSet node, | 2537 SendSet node, |
2522 Name name, | 2538 Name name, |
2523 AmbiguousElement element) { | 2539 AmbiguousElement element) { |
2524 | 2540 |
2525 ErroneousElement error = reportAndCreateErroneousElement( | 2541 ErroneousElement error = reportAndCreateErroneousElement( |
2526 node, | 2542 node, |
2527 name.text, | 2543 name.text, |
2528 element.messageKind, | 2544 element.messageKind, |
2529 element.messageArguments); | 2545 element.messageArguments, |
2530 element.diagnose(enclosingElement, compiler); | 2546 infos: element.computeInfos(enclosingElement, compiler)); |
2531 registry.registerThrowNoSuchMethod(); | 2547 registry.registerThrowNoSuchMethod(); |
2532 | 2548 |
2533 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. | 2549 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. |
2534 AccessSemantics accessSemantics = new StaticAccess.unresolved(error); | 2550 AccessSemantics accessSemantics = new StaticAccess.unresolved(error); |
2535 return handleUpdate(node, name, accessSemantics); | 2551 return handleUpdate(node, name, accessSemantics); |
2536 } | 2552 } |
2537 | 2553 |
2538 /// Report access of an instance [member] from a non-instance context. | 2554 /// Report access of an instance [member] from a non-instance context. |
2539 AccessSemantics reportStaticInstanceAccess(Send node, Name name) { | 2555 AccessSemantics reportStaticInstanceAccess(Send node, Name name) { |
2540 ErroneousElement error = reportAndCreateErroneousElement( | 2556 ErroneousElement error = reportAndCreateErroneousElement( |
(...skipping 29 matching lines...) Expand all Loading... |
2570 break; | 2586 break; |
2571 case AccessKind.PARAMETER: | 2587 case AccessKind.PARAMETER: |
2572 case AccessKind.FINAL_PARAMETER: | 2588 case AccessKind.FINAL_PARAMETER: |
2573 case AccessKind.LOCAL_VARIABLE: | 2589 case AccessKind.LOCAL_VARIABLE: |
2574 case AccessKind.FINAL_LOCAL_VARIABLE: | 2590 case AccessKind.FINAL_LOCAL_VARIABLE: |
2575 selector = callStructure.callSelector; | 2591 selector = callStructure.callSelector; |
2576 registry.registerDynamicInvocation( | 2592 registry.registerDynamicInvocation( |
2577 new UniverseSelector(selector, null)); | 2593 new UniverseSelector(selector, null)); |
2578 break; | 2594 break; |
2579 default: | 2595 default: |
2580 internalError(node, | 2596 compiler.internalError(node, |
2581 "Unexpected local access $semantics."); | 2597 "Unexpected local access $semantics."); |
2582 break; | 2598 break; |
2583 } | 2599 } |
2584 registry.registerSendStructure(node, | 2600 registry.registerSendStructure(node, |
2585 isIncompatibleInvoke | 2601 isIncompatibleInvoke |
2586 ? new IncompatibleInvokeStructure(semantics, selector) | 2602 ? new IncompatibleInvokeStructure(semantics, selector) |
2587 : new InvokeStructure(semantics, selector)); | 2603 : new InvokeStructure(semantics, selector)); |
2588 } else { | 2604 } else { |
2589 switch (semantics.kind) { | 2605 switch (semantics.kind) { |
2590 case AccessKind.LOCAL_VARIABLE: | 2606 case AccessKind.LOCAL_VARIABLE: |
(...skipping 25 matching lines...) Expand all Loading... |
2616 if (element.isConst) { | 2632 if (element.isConst) { |
2617 result = new ConstantResult( | 2633 result = new ConstantResult( |
2618 node, | 2634 node, |
2619 new VariableConstantExpression(element), | 2635 new VariableConstantExpression(element), |
2620 element: element); | 2636 element: element); |
2621 } else { | 2637 } else { |
2622 result = new ElementResult(element); | 2638 result = new ElementResult(element); |
2623 } | 2639 } |
2624 break; | 2640 break; |
2625 default: | 2641 default: |
2626 internalError(node, | 2642 compiler.internalError(node, |
2627 "Unexpected local access $semantics."); | 2643 "Unexpected local access $semantics."); |
2628 break; | 2644 break; |
2629 } | 2645 } |
2630 selector = new Selector.getter(name); | 2646 selector = new Selector.getter(name); |
2631 registry.registerSendStructure(node, new GetStructure(semantics)); | 2647 registry.registerSendStructure(node, new GetStructure(semantics)); |
2632 } | 2648 } |
2633 | 2649 |
2634 // TODO(23998): Remove these when all information goes through | 2650 // TODO(23998): Remove these when all information goes through |
2635 // the [SendStructure]. | 2651 // the [SendStructure]. |
2636 registry.useElement(node, element); | 2652 registry.useElement(node, element); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2706 } else { | 2722 } else { |
2707 member = element; | 2723 member = element; |
2708 } | 2724 } |
2709 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery | 2725 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery |
2710 // of parse errors to make [element] erroneous. Fix this! | 2726 // of parse errors to make [element] erroneous. Fix this! |
2711 member.computeType(compiler); | 2727 member.computeType(compiler); |
2712 | 2728 |
2713 | 2729 |
2714 if (member == compiler.mirrorSystemGetNameFunction && | 2730 if (member == compiler.mirrorSystemGetNameFunction && |
2715 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { | 2731 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { |
2716 compiler.reportHint( | 2732 compiler.reportHintMessage( |
2717 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, | 2733 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, |
2718 {'class': compiler.mirrorSystemClass.name, | 2734 {'class': compiler.mirrorSystemClass.name, |
2719 'name': compiler.mirrorSystemGetNameFunction.name}); | 2735 'name': compiler.mirrorSystemGetNameFunction.name}); |
2720 } | 2736 } |
2721 | 2737 |
2722 Selector selector; | 2738 Selector selector; |
2723 AccessSemantics semantics = | 2739 AccessSemantics semantics = |
2724 computeStaticOrTopLevelAccessSemantics(node, member); | 2740 computeStaticOrTopLevelAccessSemantics(node, member); |
2725 if (node.isCall) { | 2741 if (node.isCall) { |
2726 ArgumentsResult argumentsResult = | 2742 ArgumentsResult argumentsResult = |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2764 break; | 2780 break; |
2765 case AccessKind.STATIC_SETTER: | 2781 case AccessKind.STATIC_SETTER: |
2766 case AccessKind.TOPLEVEL_SETTER: | 2782 case AccessKind.TOPLEVEL_SETTER: |
2767 case AccessKind.UNRESOLVED: | 2783 case AccessKind.UNRESOLVED: |
2768 registry.registerThrowNoSuchMethod(); | 2784 registry.registerThrowNoSuchMethod(); |
2769 member = reportAndCreateErroneousElement( | 2785 member = reportAndCreateErroneousElement( |
2770 node.selector, name.text, | 2786 node.selector, name.text, |
2771 MessageKind.CANNOT_RESOLVE_GETTER, const {}); | 2787 MessageKind.CANNOT_RESOLVE_GETTER, const {}); |
2772 break; | 2788 break; |
2773 default: | 2789 default: |
2774 internalError(node, | 2790 compiler.internalError(node, |
2775 "Unexpected statically resolved access $semantics."); | 2791 "Unexpected statically resolved access $semantics."); |
2776 break; | 2792 break; |
2777 } | 2793 } |
2778 registry.registerSendStructure(node, | 2794 registry.registerSendStructure(node, |
2779 isIncompatibleInvoke | 2795 isIncompatibleInvoke |
2780 ? new IncompatibleInvokeStructure(semantics, selector) | 2796 ? new IncompatibleInvokeStructure(semantics, selector) |
2781 : new InvokeStructure(semantics, selector)); | 2797 : new InvokeStructure(semantics, selector)); |
2782 } else { | 2798 } else { |
2783 selector = new Selector.getter(name); | 2799 selector = new Selector.getter(name); |
2784 switch (semantics.kind) { | 2800 switch (semantics.kind) { |
(...skipping 14 matching lines...) Expand all Loading... |
2799 break; | 2815 break; |
2800 case AccessKind.STATIC_SETTER: | 2816 case AccessKind.STATIC_SETTER: |
2801 case AccessKind.TOPLEVEL_SETTER: | 2817 case AccessKind.TOPLEVEL_SETTER: |
2802 case AccessKind.UNRESOLVED: | 2818 case AccessKind.UNRESOLVED: |
2803 registry.registerThrowNoSuchMethod(); | 2819 registry.registerThrowNoSuchMethod(); |
2804 member = reportAndCreateErroneousElement( | 2820 member = reportAndCreateErroneousElement( |
2805 node.selector, name.text, | 2821 node.selector, name.text, |
2806 MessageKind.CANNOT_RESOLVE_GETTER, const {}); | 2822 MessageKind.CANNOT_RESOLVE_GETTER, const {}); |
2807 break; | 2823 break; |
2808 default: | 2824 default: |
2809 internalError(node, | 2825 compiler.internalError(node, |
2810 "Unexpected statically resolved access $semantics."); | 2826 "Unexpected statically resolved access $semantics."); |
2811 break; | 2827 break; |
2812 } | 2828 } |
2813 registry.registerSendStructure(node, new GetStructure(semantics)); | 2829 registry.registerSendStructure(node, new GetStructure(semantics)); |
2814 if (member.isConst) { | 2830 if (member.isConst) { |
2815 FieldElement field = member; | 2831 FieldElement field = member; |
2816 result = new ConstantResult( | 2832 result = new ConstantResult( |
2817 node, new VariableConstantExpression(field), element: field); | 2833 node, new VariableConstantExpression(field), element: field); |
2818 } else { | 2834 } else { |
2819 result = new ElementResult(member); | 2835 result = new ElementResult(member); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2962 return handleTypedefTypeLiteralAccess(node, name, element); | 2978 return handleTypedefTypeLiteralAccess(node, name, element); |
2963 } else if (element.isTypeVariable) { | 2979 } else if (element.isTypeVariable) { |
2964 return handleTypeVariableTypeLiteralAccess(node, name, element); | 2980 return handleTypeVariableTypeLiteralAccess(node, name, element); |
2965 } else if (element.isPrefix) { | 2981 } else if (element.isPrefix) { |
2966 return handleLibraryPrefix(node, name, element); | 2982 return handleLibraryPrefix(node, name, element); |
2967 } else if (element.isLocal) { | 2983 } else if (element.isLocal) { |
2968 return handleLocalAccess(node, name, element); | 2984 return handleLocalAccess(node, name, element); |
2969 } else if (element.isStatic || element.isTopLevel) { | 2985 } else if (element.isStatic || element.isTopLevel) { |
2970 return handleStaticOrTopLevelAccess(node, name, element); | 2986 return handleStaticOrTopLevelAccess(node, name, element); |
2971 } | 2987 } |
2972 return internalError(node, "Unexpected resolved send: $element"); | 2988 return compiler.internalError(node, "Unexpected resolved send: $element"); |
2973 } | 2989 } |
2974 | 2990 |
2975 /// Handle update to resolved [element]. | 2991 /// Handle update to resolved [element]. |
2976 ResolutionResult handleResolvedSendSet( | 2992 ResolutionResult handleResolvedSendSet( |
2977 SendSet node, Name name, Element element) { | 2993 SendSet node, Name name, Element element) { |
2978 if (element.isAmbiguous) { | 2994 if (element.isAmbiguous) { |
2979 return handleAmbiguousUpdate(node, name, element); | 2995 return handleAmbiguousUpdate(node, name, element); |
2980 } | 2996 } |
2981 if (element.isErroneous) { | 2997 if (element.isErroneous) { |
2982 // This handles elements with parser errors. | 2998 // This handles elements with parser errors. |
(...skipping 17 matching lines...) Expand all Loading... |
3000 // `C = b`, `C++`, or 'C += b` where 'F' is a typedef. | 3016 // `C = b`, `C++`, or 'C += b` where 'F' is a typedef. |
3001 return handleTypedefTypeLiteralUpdate(node, name, element); | 3017 return handleTypedefTypeLiteralUpdate(node, name, element); |
3002 } else if (element.isTypeVariable) { | 3018 } else if (element.isTypeVariable) { |
3003 // `T = b`, `T++`, or 'T += b` where 'T' is a type variable. | 3019 // `T = b`, `T++`, or 'T += b` where 'T' is a type variable. |
3004 return handleTypeVariableTypeLiteralUpdate(node, name, element); | 3020 return handleTypeVariableTypeLiteralUpdate(node, name, element); |
3005 } else if (element.isLocal) { | 3021 } else if (element.isLocal) { |
3006 return handleLocalUpdate(node, name, element); | 3022 return handleLocalUpdate(node, name, element); |
3007 } else if (element.isStatic || element.isTopLevel) { | 3023 } else if (element.isStatic || element.isTopLevel) { |
3008 return handleStaticOrTopLevelUpdate(node, name, element); | 3024 return handleStaticOrTopLevelUpdate(node, name, element); |
3009 } | 3025 } |
3010 return internalError(node, "Unexpected resolved send: $element"); | 3026 return compiler.internalError(node, "Unexpected resolved send: $element"); |
3011 } | 3027 } |
3012 | 3028 |
3013 /// Handle an unqualified [Send], that is where the `node.receiver` is null, | 3029 /// Handle an unqualified [Send], that is where the `node.receiver` is null, |
3014 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. | 3030 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. |
3015 ResolutionResult handleUnqualifiedSend(Send node) { | 3031 ResolutionResult handleUnqualifiedSend(Send node) { |
3016 Identifier selector = node.selector.asIdentifier(); | 3032 Identifier selector = node.selector.asIdentifier(); |
3017 if (selector == null) { | 3033 if (selector == null) { |
3018 // `(){}()` and `(foo)()`. | 3034 // `(){}()` and `(foo)()`. |
3019 return handleExpressionInvoke(node); | 3035 return handleExpressionInvoke(node); |
3020 } | 3036 } |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3331 AssignmentOperator operator = AssignmentOperator.parse(operatorText); | 3347 AssignmentOperator operator = AssignmentOperator.parse(operatorText); |
3332 if (operator.kind == AssignmentOperatorKind.ASSIGN) { | 3348 if (operator.kind == AssignmentOperatorKind.ASSIGN) { |
3333 // `super.a = b`. | 3349 // `super.a = b`. |
3334 if (semantics == null) { | 3350 if (semantics == null) { |
3335 semantics = | 3351 semantics = |
3336 computeSuperAccessSemanticsForSelector( | 3352 computeSuperAccessSemanticsForSelector( |
3337 node, setterSelector, alternateName: name); | 3353 node, setterSelector, alternateName: name); |
3338 registry.registerStaticInvocation(semantics.setter); | 3354 registry.registerStaticInvocation(semantics.setter); |
3339 switch (semantics.kind) { | 3355 switch (semantics.kind) { |
3340 case AccessKind.SUPER_FINAL_FIELD: | 3356 case AccessKind.SUPER_FINAL_FIELD: |
3341 compiler.reportWarning( | 3357 compiler.reportWarningMessage( |
3342 node, | 3358 node, |
3343 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, | 3359 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, |
3344 {'name': name, | 3360 {'name': name, |
3345 'superclassName': semantics.setter.enclosingClass.name}); | 3361 'superclassName': semantics.setter.enclosingClass.name}); |
3346 // TODO(johnniwinther): This shouldn't be needed. | 3362 // TODO(johnniwinther): This shouldn't be needed. |
3347 registry.registerDynamicInvocation( | 3363 registry.registerDynamicInvocation( |
3348 new UniverseSelector(setterSelector, null)); | 3364 new UniverseSelector(setterSelector, null)); |
3349 registry.registerSuperNoSuchMethod(); | 3365 registry.registerSuperNoSuchMethod(); |
3350 break; | 3366 break; |
3351 case AccessKind.SUPER_METHOD: | 3367 case AccessKind.SUPER_METHOD: |
3352 compiler.reportWarning( | 3368 compiler.reportWarningMessage( |
3353 node, MessageKind.ASSIGNING_METHOD_IN_SUPER, | 3369 node, MessageKind.ASSIGNING_METHOD_IN_SUPER, |
3354 {'name': name, | 3370 {'name': name, |
3355 'superclassName': semantics.setter.enclosingClass.name}); | 3371 'superclassName': semantics.setter.enclosingClass.name}); |
3356 // TODO(johnniwinther): This shouldn't be needed. | 3372 // TODO(johnniwinther): This shouldn't be needed. |
3357 registry.registerDynamicInvocation( | 3373 registry.registerDynamicInvocation( |
3358 new UniverseSelector(setterSelector, null)); | 3374 new UniverseSelector(setterSelector, null)); |
3359 registry.registerSuperNoSuchMethod(); | 3375 registry.registerSuperNoSuchMethod(); |
3360 break; | 3376 break; |
3361 default: | 3377 default: |
3362 registry.registerStaticInvocation(semantics.setter); | 3378 registry.registerStaticInvocation(semantics.setter); |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3544 registry.setConstant(node, constant); | 3560 registry.setConstant(node, constant); |
3545 return new ConstantResult(node, constant); | 3561 return new ConstantResult(node, constant); |
3546 } | 3562 } |
3547 | 3563 |
3548 ConstantResult visitLiteralSymbol(LiteralSymbol node) { | 3564 ConstantResult visitLiteralSymbol(LiteralSymbol node) { |
3549 registry.registerInstantiatedClass(compiler.symbolClass); | 3565 registry.registerInstantiatedClass(compiler.symbolClass); |
3550 registry.registerStaticUse(compiler.symbolConstructor.declaration); | 3566 registry.registerStaticUse(compiler.symbolConstructor.declaration); |
3551 String name = node.slowNameString; | 3567 String name = node.slowNameString; |
3552 registry.registerConstSymbol(name); | 3568 registry.registerConstSymbol(name); |
3553 if (!validateSymbol(node, name, reportError: false)) { | 3569 if (!validateSymbol(node, name, reportError: false)) { |
3554 compiler.reportError(node, | 3570 compiler.reportErrorMessage( |
| 3571 node, |
3555 MessageKind.UNSUPPORTED_LITERAL_SYMBOL, | 3572 MessageKind.UNSUPPORTED_LITERAL_SYMBOL, |
3556 {'value': name}); | 3573 {'value': name}); |
3557 } | 3574 } |
3558 analyzeConstantDeferred(node); | 3575 analyzeConstantDeferred(node); |
3559 ConstantExpression constant = new SymbolConstantExpression(name); | 3576 ConstantExpression constant = new SymbolConstantExpression(name); |
3560 registry.setConstant(node, constant); | 3577 registry.setConstant(node, constant); |
3561 return new ConstantResult(node, constant); | 3578 return new ConstantResult(node, constant); |
3562 } | 3579 } |
3563 | 3580 |
3564 ResolutionResult visitStringJuxtaposition(StringJuxtaposition node) { | 3581 ResolutionResult visitStringJuxtaposition(StringJuxtaposition node) { |
(...skipping 11 matching lines...) Expand all Loading... |
3576 | 3593 |
3577 ResolutionResult visitNodeList(NodeList node) { | 3594 ResolutionResult visitNodeList(NodeList node) { |
3578 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 3595 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
3579 visit(link.head); | 3596 visit(link.head); |
3580 } | 3597 } |
3581 return const NoneResult(); | 3598 return const NoneResult(); |
3582 } | 3599 } |
3583 | 3600 |
3584 ResolutionResult visitRethrow(Rethrow node) { | 3601 ResolutionResult visitRethrow(Rethrow node) { |
3585 if (!inCatchBlock) { | 3602 if (!inCatchBlock) { |
3586 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); | 3603 compiler.reportErrorMessage( |
| 3604 node, MessageKind.THROW_WITHOUT_EXPRESSION); |
3587 } | 3605 } |
3588 return const NoneResult(); | 3606 return const NoneResult(); |
3589 } | 3607 } |
3590 | 3608 |
3591 ResolutionResult visitReturn(Return node) { | 3609 ResolutionResult visitReturn(Return node) { |
3592 Node expression = node.expression; | 3610 Node expression = node.expression; |
3593 if (expression != null) { | 3611 if (expression != null) { |
3594 if (enclosingElement.isGenerativeConstructor) { | 3612 if (enclosingElement.isGenerativeConstructor) { |
3595 // It is a compile-time error if a return statement of the form | 3613 // It is a compile-time error if a return statement of the form |
3596 // `return e;` appears in a generative constructor. (Dart Language | 3614 // `return e;` appears in a generative constructor. (Dart Language |
3597 // Specification 13.12.) | 3615 // Specification 13.12.) |
3598 compiler.reportError(expression, | 3616 compiler.reportErrorMessage( |
3599 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); | 3617 expression, |
| 3618 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); |
3600 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { | 3619 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { |
3601 compiler.reportError( | 3620 compiler.reportErrorMessage( |
3602 node, | 3621 node, |
3603 MessageKind.RETURN_IN_GENERATOR, | 3622 MessageKind.RETURN_IN_GENERATOR, |
3604 {'modifier': currentAsyncMarker}); | 3623 {'modifier': currentAsyncMarker}); |
3605 } | 3624 } |
3606 } | 3625 } |
3607 visit(node.expression); | 3626 visit(node.expression); |
3608 return const NoneResult(); | 3627 return const NoneResult(); |
3609 } | 3628 } |
3610 | 3629 |
3611 ResolutionResult visitYield(Yield node) { | 3630 ResolutionResult visitYield(Yield node) { |
3612 compiler.streamClass.ensureResolved(compiler); | 3631 compiler.streamClass.ensureResolved(compiler); |
3613 compiler.iterableClass.ensureResolved(compiler); | 3632 compiler.iterableClass.ensureResolved(compiler); |
3614 visit(node.expression); | 3633 visit(node.expression); |
3615 return const NoneResult(); | 3634 return const NoneResult(); |
3616 } | 3635 } |
3617 | 3636 |
3618 ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { | 3637 ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { |
3619 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; | 3638 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; |
3620 if (!enclosingElement.isFactoryConstructor) { | 3639 if (!enclosingElement.isFactoryConstructor) { |
3621 compiler.reportError( | 3640 compiler.reportErrorMessage( |
3622 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); | 3641 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); |
3623 compiler.reportHint( | 3642 compiler.reportHintMessage( |
3624 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); | 3643 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); |
3625 } | 3644 } |
3626 ConstructorElementX constructor = enclosingElement; | 3645 ConstructorElementX constructor = enclosingElement; |
3627 bool isConstConstructor = constructor.isConst; | 3646 bool isConstConstructor = constructor.isConst; |
3628 bool isValidAsConstant = isConstConstructor; | 3647 bool isValidAsConstant = isConstConstructor; |
3629 ConstructorElement redirectionTarget = resolveRedirectingFactory( | 3648 ConstructorElement redirectionTarget = resolveRedirectingFactory( |
3630 node, inConstContext: isConstConstructor).element; | 3649 node, inConstContext: isConstConstructor).element; |
3631 constructor.immediateRedirectionTarget = redirectionTarget; | 3650 constructor.immediateRedirectionTarget = redirectionTarget; |
3632 | 3651 |
3633 Node constructorReference = node.constructorReference; | 3652 Node constructorReference = node.constructorReference; |
3634 if (constructorReference is Send) { | 3653 if (constructorReference is Send) { |
3635 constructor.redirectionDeferredPrefix = | 3654 constructor.redirectionDeferredPrefix = |
3636 compiler.deferredLoadTask.deferredPrefixElement(constructorReference, | 3655 compiler.deferredLoadTask.deferredPrefixElement(constructorReference, |
3637 registry.mapping); | 3656 registry.mapping); |
3638 } | 3657 } |
3639 | 3658 |
3640 registry.setRedirectingTargetConstructor(node, redirectionTarget); | 3659 registry.setRedirectingTargetConstructor(node, redirectionTarget); |
3641 if (Elements.isUnresolved(redirectionTarget)) { | 3660 if (Elements.isUnresolved(redirectionTarget)) { |
3642 registry.registerThrowNoSuchMethod(); | 3661 registry.registerThrowNoSuchMethod(); |
3643 return const NoneResult(); | 3662 return const NoneResult(); |
3644 } else { | 3663 } else { |
3645 if (isConstConstructor && | 3664 if (isConstConstructor && |
3646 !redirectionTarget.isConst) { | 3665 !redirectionTarget.isConst) { |
3647 compiler.reportError(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | 3666 compiler.reportErrorMessage( |
| 3667 node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
3648 isValidAsConstant = false; | 3668 isValidAsConstant = false; |
3649 } | 3669 } |
3650 if (redirectionTarget == constructor) { | 3670 if (redirectionTarget == constructor) { |
3651 compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); | 3671 compiler.reportErrorMessage( |
| 3672 node, MessageKind.CYCLIC_REDIRECTING_FACTORY); |
3652 // TODO(johnniwinther): Create constant constructor for this case and | 3673 // TODO(johnniwinther): Create constant constructor for this case and |
3653 // let evaluation detect the cyclicity. | 3674 // let evaluation detect the cyclicity. |
3654 isValidAsConstant = false; | 3675 isValidAsConstant = false; |
3655 } | 3676 } |
3656 } | 3677 } |
3657 | 3678 |
3658 // Check that the target constructor is type compatible with the | 3679 // Check that the target constructor is type compatible with the |
3659 // redirecting constructor. | 3680 // redirecting constructor. |
3660 ClassElement targetClass = redirectionTarget.enclosingClass; | 3681 ClassElement targetClass = redirectionTarget.enclosingClass; |
3661 InterfaceType type = registry.getType(node); | 3682 InterfaceType type = registry.getType(node); |
3662 FunctionType targetType = redirectionTarget.computeType(compiler) | 3683 FunctionType targetType = redirectionTarget.computeType(compiler) |
3663 .subst(type.typeArguments, targetClass.typeVariables); | 3684 .subst(type.typeArguments, targetClass.typeVariables); |
3664 FunctionType constructorType = constructor.computeType(compiler); | 3685 FunctionType constructorType = constructor.computeType(compiler); |
3665 bool isSubtype = compiler.types.isSubtype(targetType, constructorType); | 3686 bool isSubtype = compiler.types.isSubtype(targetType, constructorType); |
3666 if (!isSubtype) { | 3687 if (!isSubtype) { |
3667 warning(node, MessageKind.NOT_ASSIGNABLE, | 3688 compiler.reportWarningMessage( |
3668 {'fromType': targetType, 'toType': constructorType}); | 3689 node, |
| 3690 MessageKind.NOT_ASSIGNABLE, |
| 3691 {'fromType': targetType, 'toType': constructorType}); |
3669 // TODO(johnniwinther): Handle this (potentially) erroneous case. | 3692 // TODO(johnniwinther): Handle this (potentially) erroneous case. |
3670 isValidAsConstant = false; | 3693 isValidAsConstant = false; |
3671 } | 3694 } |
3672 | 3695 |
3673 redirectionTarget.computeType(compiler); | 3696 redirectionTarget.computeType(compiler); |
3674 FunctionSignature targetSignature = redirectionTarget.functionSignature; | 3697 FunctionSignature targetSignature = redirectionTarget.functionSignature; |
3675 constructor.computeType(compiler); | 3698 constructor.computeType(compiler); |
3676 FunctionSignature constructorSignature = constructor.functionSignature; | 3699 FunctionSignature constructorSignature = constructor.functionSignature; |
3677 if (!targetSignature.isCompatibleWith(constructorSignature)) { | 3700 if (!targetSignature.isCompatibleWith(constructorSignature)) { |
3678 assert(!isSubtype); | 3701 assert(!isSubtype); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3748 Node modifierNode; | 3771 Node modifierNode; |
3749 for (Link<Node> nodes = modifiers.nodes.nodes; | 3772 for (Link<Node> nodes = modifiers.nodes.nodes; |
3750 !nodes.isEmpty; | 3773 !nodes.isEmpty; |
3751 nodes = nodes.tail) { | 3774 nodes = nodes.tail) { |
3752 if (modifier == nodes.head.asIdentifier().source) { | 3775 if (modifier == nodes.head.asIdentifier().source) { |
3753 modifierNode = nodes.head; | 3776 modifierNode = nodes.head; |
3754 break; | 3777 break; |
3755 } | 3778 } |
3756 } | 3779 } |
3757 assert(modifierNode != null); | 3780 assert(modifierNode != null); |
3758 compiler.reportError(modifierNode, MessageKind.EXTRANEOUS_MODIFIER, | 3781 compiler.reportErrorMessage( |
| 3782 modifierNode, MessageKind.EXTRANEOUS_MODIFIER, |
3759 {'modifier': modifier}); | 3783 {'modifier': modifier}); |
3760 } | 3784 } |
3761 if (modifiers.isFinal && (modifiers.isConst || modifiers.isVar)) { | 3785 if (modifiers.isFinal && (modifiers.isConst || modifiers.isVar)) { |
3762 reportExtraModifier('final'); | 3786 reportExtraModifier('final'); |
3763 } | 3787 } |
3764 if (modifiers.isVar && (modifiers.isConst || node.type != null)) { | 3788 if (modifiers.isVar && (modifiers.isConst || node.type != null)) { |
3765 reportExtraModifier('var'); | 3789 reportExtraModifier('var'); |
3766 } | 3790 } |
3767 if (enclosingElement.isFunction) { | 3791 if (enclosingElement.isFunction) { |
3768 if (modifiers.isAbstract) { | 3792 if (modifiers.isAbstract) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3824 constructor.computeType(compiler); | 3848 constructor.computeType(compiler); |
3825 if (!callSelector.applies(constructor, compiler.world)) { | 3849 if (!callSelector.applies(constructor, compiler.world)) { |
3826 registry.registerThrowNoSuchMethod(); | 3850 registry.registerThrowNoSuchMethod(); |
3827 } | 3851 } |
3828 | 3852 |
3829 // [constructor] might be the implementation element | 3853 // [constructor] might be the implementation element |
3830 // and only declaration elements may be registered. | 3854 // and only declaration elements may be registered. |
3831 registry.registerStaticUse(constructor.declaration); | 3855 registry.registerStaticUse(constructor.declaration); |
3832 ClassElement cls = constructor.enclosingClass; | 3856 ClassElement cls = constructor.enclosingClass; |
3833 if (cls.isEnumClass && currentClass != cls) { | 3857 if (cls.isEnumClass && currentClass != cls) { |
3834 compiler.reportError(node, | 3858 compiler.reportErrorMessage( |
3835 MessageKind.CANNOT_INSTANTIATE_ENUM, | 3859 node, |
3836 {'enumName': cls.name}); | 3860 MessageKind.CANNOT_INSTANTIATE_ENUM, |
| 3861 {'enumName': cls.name}); |
3837 isValidAsConstant = false; | 3862 isValidAsConstant = false; |
3838 } | 3863 } |
3839 | 3864 |
3840 InterfaceType type = registry.getType(node); | 3865 InterfaceType type = registry.getType(node); |
3841 if (node.isConst && type.containsTypeVariables) { | 3866 if (node.isConst && type.containsTypeVariables) { |
3842 compiler.reportError(node.send.selector, | 3867 compiler.reportErrorMessage( |
3843 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 3868 node.send.selector, |
| 3869 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
3844 isValidAsConstant = false; | 3870 isValidAsConstant = false; |
3845 } | 3871 } |
3846 // TODO(johniwinther): Avoid registration of `type` in face of redirecting | 3872 // TODO(johniwinther): Avoid registration of `type` in face of redirecting |
3847 // factory constructors. | 3873 // factory constructors. |
3848 registry.registerInstantiatedType(type); | 3874 registry.registerInstantiatedType(type); |
3849 if (constructor.isGenerativeConstructor && cls.isAbstract) { | 3875 if (constructor.isGenerativeConstructor && cls.isAbstract) { |
3850 isValidAsConstant = false; | 3876 isValidAsConstant = false; |
3851 } | 3877 } |
3852 | 3878 |
3853 if (isSymbolConstructor) { | 3879 if (isSymbolConstructor) { |
3854 if (node.isConst) { | 3880 if (node.isConst) { |
3855 Node argumentNode = node.send.arguments.head; | 3881 Node argumentNode = node.send.arguments.head; |
3856 ConstantExpression constant = | 3882 ConstantExpression constant = |
3857 compiler.resolver.constantCompiler.compileNode( | 3883 compiler.resolver.constantCompiler.compileNode( |
3858 argumentNode, registry.mapping); | 3884 argumentNode, registry.mapping); |
3859 ConstantValue name = compiler.constants.getConstantValue(constant); | 3885 ConstantValue name = compiler.constants.getConstantValue(constant); |
3860 if (!name.isString) { | 3886 if (!name.isString) { |
3861 DartType type = name.getType(coreTypes); | 3887 DartType type = name.getType(coreTypes); |
3862 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, | 3888 compiler.reportErrorMessage( |
3863 {'type': type}); | 3889 argumentNode, |
| 3890 MessageKind.STRING_EXPECTED, |
| 3891 {'type': type}); |
3864 } else { | 3892 } else { |
3865 StringConstantValue stringConstant = name; | 3893 StringConstantValue stringConstant = name; |
3866 String nameString = stringConstant.toDartString().slowToString(); | 3894 String nameString = stringConstant.toDartString().slowToString(); |
3867 if (validateSymbol(argumentNode, nameString)) { | 3895 if (validateSymbol(argumentNode, nameString)) { |
3868 registry.registerConstSymbol(nameString); | 3896 registry.registerConstSymbol(nameString); |
3869 } | 3897 } |
3870 } | 3898 } |
3871 } else { | 3899 } else { |
3872 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( | 3900 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( |
3873 enclosingElement)) { | 3901 enclosingElement)) { |
3874 compiler.reportHint( | 3902 compiler.reportHintMessage( |
3875 node.newToken, MessageKind.NON_CONST_BLOAT, | 3903 node.newToken, MessageKind.NON_CONST_BLOAT, |
3876 {'name': compiler.symbolClass.name}); | 3904 {'name': compiler.symbolClass.name}); |
3877 } | 3905 } |
3878 registry.registerNewSymbol(); | 3906 registry.registerNewSymbol(); |
3879 } | 3907 } |
3880 } else if (isMirrorsUsedConstant) { | 3908 } else if (isMirrorsUsedConstant) { |
3881 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); | 3909 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); |
3882 } | 3910 } |
3883 if (node.isConst) { | 3911 if (node.isConst) { |
3884 analyzeConstantDeferred(node); | 3912 analyzeConstantDeferred(node); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3918 void checkConstMapKeysDontOverrideEquals(Spannable spannable, | 3946 void checkConstMapKeysDontOverrideEquals(Spannable spannable, |
3919 MapConstantValue map) { | 3947 MapConstantValue map) { |
3920 for (ConstantValue key in map.keys) { | 3948 for (ConstantValue key in map.keys) { |
3921 if (!key.isObject) continue; | 3949 if (!key.isObject) continue; |
3922 ObjectConstantValue objectConstant = key; | 3950 ObjectConstantValue objectConstant = key; |
3923 DartType keyType = objectConstant.type; | 3951 DartType keyType = objectConstant.type; |
3924 ClassElement cls = keyType.element; | 3952 ClassElement cls = keyType.element; |
3925 if (cls == compiler.stringClass) continue; | 3953 if (cls == compiler.stringClass) continue; |
3926 Element equals = cls.lookupMember('=='); | 3954 Element equals = cls.lookupMember('=='); |
3927 if (equals.enclosingClass != compiler.objectClass) { | 3955 if (equals.enclosingClass != compiler.objectClass) { |
3928 compiler.reportError(spannable, | 3956 compiler.reportErrorMessage( |
3929 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, | 3957 spannable, |
3930 {'type': keyType}); | 3958 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, |
| 3959 {'type': keyType}); |
3931 } | 3960 } |
3932 } | 3961 } |
3933 } | 3962 } |
3934 | 3963 |
3935 void analyzeConstant(Node node, {enforceConst: true}) { | 3964 void analyzeConstant(Node node, {enforceConst: true}) { |
3936 ConstantExpression constant = | 3965 ConstantExpression constant = |
3937 compiler.resolver.constantCompiler.compileNode( | 3966 compiler.resolver.constantCompiler.compileNode( |
3938 node, registry.mapping, enforceConst: enforceConst); | 3967 node, registry.mapping, enforceConst: enforceConst); |
3939 | 3968 |
3940 if (constant == null) { | 3969 if (constant == null) { |
3941 assert(invariant(node, compiler.compilationFailed)); | 3970 assert(invariant(node, compiler.compilationFailed)); |
3942 return; | 3971 return; |
3943 } | 3972 } |
3944 | 3973 |
3945 ConstantValue value = compiler.constants.getConstantValue(constant); | 3974 ConstantValue value = compiler.constants.getConstantValue(constant); |
3946 if (value.isMap) { | 3975 if (value.isMap) { |
3947 checkConstMapKeysDontOverrideEquals(node, value); | 3976 checkConstMapKeysDontOverrideEquals(node, value); |
3948 } | 3977 } |
3949 | 3978 |
3950 // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names | 3979 // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names |
3951 // a class that will be instantiated outside the program by attaching a | 3980 // a class that will be instantiated outside the program by attaching a |
3952 // native class dispatch record referencing the interceptor. | 3981 // native class dispatch record referencing the interceptor. |
3953 if (argumentsToJsInterceptorConstant != null && | 3982 if (argumentsToJsInterceptorConstant != null && |
3954 argumentsToJsInterceptorConstant.contains(node)) { | 3983 argumentsToJsInterceptorConstant.contains(node)) { |
3955 if (value.isType) { | 3984 if (value.isType) { |
3956 TypeConstantValue typeConstant = value; | 3985 TypeConstantValue typeConstant = value; |
3957 if (typeConstant.representedType is InterfaceType) { | 3986 if (typeConstant.representedType is InterfaceType) { |
3958 registry.registerInstantiatedType(typeConstant.representedType); | 3987 registry.registerInstantiatedType(typeConstant.representedType); |
3959 } else { | 3988 } else { |
3960 compiler.reportError(node, | 3989 compiler.reportErrorMessage( |
| 3990 node, |
3961 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 3991 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
3962 } | 3992 } |
3963 } else { | 3993 } else { |
3964 compiler.reportError(node, | 3994 compiler.reportErrorMessage( |
| 3995 node, |
3965 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 3996 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
3966 } | 3997 } |
3967 } | 3998 } |
3968 } | 3999 } |
3969 | 4000 |
3970 void analyzeConstantDeferred(Node node, {bool enforceConst: true}) { | 4001 void analyzeConstantDeferred(Node node, {bool enforceConst: true}) { |
3971 addDeferredAction(enclosingElement, () { | 4002 addDeferredAction(enclosingElement, () { |
3972 analyzeConstant(node, enforceConst: enforceConst); | 4003 analyzeConstant(node, enforceConst: enforceConst); |
3973 }); | 4004 }); |
3974 } | 4005 } |
3975 | 4006 |
3976 bool validateSymbol(Node node, String name, {bool reportError: true}) { | 4007 bool validateSymbol(Node node, String name, {bool reportError: true}) { |
3977 if (name.isEmpty) return true; | 4008 if (name.isEmpty) return true; |
3978 if (name.startsWith('_')) { | 4009 if (name.startsWith('_')) { |
3979 if (reportError) { | 4010 if (reportError) { |
3980 compiler.reportError(node, MessageKind.PRIVATE_IDENTIFIER, | 4011 compiler.reportErrorMessage( |
3981 {'value': name}); | 4012 node, MessageKind.PRIVATE_IDENTIFIER, {'value': name}); |
3982 } | 4013 } |
3983 return false; | 4014 return false; |
3984 } | 4015 } |
3985 if (!symbolValidationPattern.hasMatch(name)) { | 4016 if (!symbolValidationPattern.hasMatch(name)) { |
3986 if (reportError) { | 4017 if (reportError) { |
3987 compiler.reportError(node, MessageKind.INVALID_SYMBOL, | 4018 compiler.reportErrorMessage( |
3988 {'value': name}); | 4019 node, MessageKind.INVALID_SYMBOL, {'value': name}); |
3989 } | 4020 } |
3990 return false; | 4021 return false; |
3991 } | 4022 } |
3992 return true; | 4023 return true; |
3993 } | 4024 } |
3994 | 4025 |
3995 /** | 4026 /** |
3996 * Try to resolve the constructor that is referred to by [node]. | 4027 * Try to resolve the constructor that is referred to by [node]. |
3997 * Note: this function may return an ErroneousFunctionElement instead of | 4028 * Note: this function may return an ErroneousFunctionElement instead of |
3998 * [:null:], if there is no corresponding constructor, class or library. | 4029 * [:null:], if there is no corresponding constructor, class or library. |
(...skipping 25 matching lines...) Expand all Loading... |
4024 ResolutionResult visitLiteralList(LiteralList node) { | 4055 ResolutionResult visitLiteralList(LiteralList node) { |
4025 bool isValidAsConstant = true; | 4056 bool isValidAsConstant = true; |
4026 sendIsMemberAccess = false; | 4057 sendIsMemberAccess = false; |
4027 | 4058 |
4028 NodeList arguments = node.typeArguments; | 4059 NodeList arguments = node.typeArguments; |
4029 DartType typeArgument; | 4060 DartType typeArgument; |
4030 if (arguments != null) { | 4061 if (arguments != null) { |
4031 Link<Node> nodes = arguments.nodes; | 4062 Link<Node> nodes = arguments.nodes; |
4032 if (nodes.isEmpty) { | 4063 if (nodes.isEmpty) { |
4033 // The syntax [: <>[] :] is not allowed. | 4064 // The syntax [: <>[] :] is not allowed. |
4034 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT); | 4065 compiler.reportErrorMessage( |
| 4066 arguments, MessageKind.MISSING_TYPE_ARGUMENT); |
4035 isValidAsConstant = false; | 4067 isValidAsConstant = false; |
4036 } else { | 4068 } else { |
4037 typeArgument = resolveTypeAnnotation(nodes.head); | 4069 typeArgument = resolveTypeAnnotation(nodes.head); |
4038 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 4070 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
4039 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 4071 compiler.reportWarningMessage( |
| 4072 nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
4040 resolveTypeAnnotation(nodes.head); | 4073 resolveTypeAnnotation(nodes.head); |
4041 } | 4074 } |
4042 } | 4075 } |
4043 } | 4076 } |
4044 DartType listType; | 4077 DartType listType; |
4045 if (typeArgument != null) { | 4078 if (typeArgument != null) { |
4046 if (node.isConst && typeArgument.containsTypeVariables) { | 4079 if (node.isConst && typeArgument.containsTypeVariables) { |
4047 compiler.reportError(arguments.nodes.head, | 4080 compiler.reportErrorMessage( |
| 4081 arguments.nodes.head, |
4048 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 4082 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
4049 isValidAsConstant = false; | 4083 isValidAsConstant = false; |
4050 } | 4084 } |
4051 listType = coreTypes.listType(typeArgument); | 4085 listType = coreTypes.listType(typeArgument); |
4052 } else { | 4086 } else { |
4053 listType = coreTypes.listType(); | 4087 listType = coreTypes.listType(); |
4054 } | 4088 } |
4055 registry.setType(node, listType); | 4089 registry.setType(node, listType); |
4056 registry.registerInstantiatedType(listType); | 4090 registry.registerInstantiatedType(listType); |
4057 registry.registerRequiredType(listType, enclosingElement); | 4091 registry.registerRequiredType(listType, enclosingElement); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4131 return new ConstantResult(node, constant); | 4165 return new ConstantResult(node, constant); |
4132 } | 4166 } |
4133 return const NoneResult(); | 4167 return const NoneResult(); |
4134 } | 4168 } |
4135 | 4169 |
4136 ResolutionResult visitBreakStatement(BreakStatement node) { | 4170 ResolutionResult visitBreakStatement(BreakStatement node) { |
4137 JumpTarget target; | 4171 JumpTarget target; |
4138 if (node.target == null) { | 4172 if (node.target == null) { |
4139 target = statementScope.currentBreakTarget(); | 4173 target = statementScope.currentBreakTarget(); |
4140 if (target == null) { | 4174 if (target == null) { |
4141 error(node, MessageKind.NO_BREAK_TARGET); | 4175 compiler.reportErrorMessage( |
| 4176 node, MessageKind.NO_BREAK_TARGET); |
4142 return const NoneResult(); | 4177 return const NoneResult(); |
4143 } | 4178 } |
4144 target.isBreakTarget = true; | 4179 target.isBreakTarget = true; |
4145 } else { | 4180 } else { |
4146 String labelName = node.target.source; | 4181 String labelName = node.target.source; |
4147 LabelDefinition label = statementScope.lookupLabel(labelName); | 4182 LabelDefinition label = statementScope.lookupLabel(labelName); |
4148 if (label == null) { | 4183 if (label == null) { |
4149 error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); | 4184 compiler.reportErrorMessage( |
| 4185 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
4150 return const NoneResult(); | 4186 return const NoneResult(); |
4151 } | 4187 } |
4152 target = label.target; | 4188 target = label.target; |
4153 if (!target.statement.isValidBreakTarget()) { | 4189 if (!target.statement.isValidBreakTarget()) { |
4154 error(node.target, MessageKind.INVALID_BREAK); | 4190 compiler.reportErrorMessage( |
| 4191 node.target, MessageKind.INVALID_BREAK); |
4155 return const NoneResult(); | 4192 return const NoneResult(); |
4156 } | 4193 } |
4157 label.setBreakTarget(); | 4194 label.setBreakTarget(); |
4158 registry.useLabel(node, label); | 4195 registry.useLabel(node, label); |
4159 } | 4196 } |
4160 registry.registerTargetOf(node, target); | 4197 registry.registerTargetOf(node, target); |
4161 return const NoneResult(); | 4198 return const NoneResult(); |
4162 } | 4199 } |
4163 | 4200 |
4164 ResolutionResult visitContinueStatement(ContinueStatement node) { | 4201 ResolutionResult visitContinueStatement(ContinueStatement node) { |
4165 JumpTarget target; | 4202 JumpTarget target; |
4166 if (node.target == null) { | 4203 if (node.target == null) { |
4167 target = statementScope.currentContinueTarget(); | 4204 target = statementScope.currentContinueTarget(); |
4168 if (target == null) { | 4205 if (target == null) { |
4169 error(node, MessageKind.NO_CONTINUE_TARGET); | 4206 compiler.reportErrorMessage( |
| 4207 node, MessageKind.NO_CONTINUE_TARGET); |
4170 return const NoneResult(); | 4208 return const NoneResult(); |
4171 } | 4209 } |
4172 target.isContinueTarget = true; | 4210 target.isContinueTarget = true; |
4173 } else { | 4211 } else { |
4174 String labelName = node.target.source; | 4212 String labelName = node.target.source; |
4175 LabelDefinition label = statementScope.lookupLabel(labelName); | 4213 LabelDefinition label = statementScope.lookupLabel(labelName); |
4176 if (label == null) { | 4214 if (label == null) { |
4177 error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); | 4215 compiler.reportErrorMessage( |
| 4216 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
4178 return const NoneResult(); | 4217 return const NoneResult(); |
4179 } | 4218 } |
4180 target = label.target; | 4219 target = label.target; |
4181 if (!target.statement.isValidContinueTarget()) { | 4220 if (!target.statement.isValidContinueTarget()) { |
4182 error(node.target, MessageKind.INVALID_CONTINUE); | 4221 compiler.reportErrorMessage( |
| 4222 node.target, MessageKind.INVALID_CONTINUE); |
4183 } | 4223 } |
4184 label.setContinueTarget(); | 4224 label.setContinueTarget(); |
4185 registry.useLabel(node, label); | 4225 registry.useLabel(node, label); |
4186 } | 4226 } |
4187 registry.registerTargetOf(node, target); | 4227 registry.registerTargetOf(node, target); |
4188 return const NoneResult(); | 4228 return const NoneResult(); |
4189 } | 4229 } |
4190 | 4230 |
4191 registerImplicitInvocation(Selector selector) { | 4231 registerImplicitInvocation(Selector selector) { |
4192 registry.registerDynamicInvocation(new UniverseSelector(selector, null)); | 4232 registry.registerDynamicInvocation(new UniverseSelector(selector, null)); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4242 | 4282 |
4243 Send send = declaration.asSend(); | 4283 Send send = declaration.asSend(); |
4244 VariableDefinitions variableDefinitions = | 4284 VariableDefinitions variableDefinitions = |
4245 declaration.asVariableDefinitions(); | 4285 declaration.asVariableDefinitions(); |
4246 Element loopVariable; | 4286 Element loopVariable; |
4247 Selector loopVariableSelector; | 4287 Selector loopVariableSelector; |
4248 if (send != null) { | 4288 if (send != null) { |
4249 loopVariable = registry.getDefinition(send); | 4289 loopVariable = registry.getDefinition(send); |
4250 Identifier identifier = send.selector.asIdentifier(); | 4290 Identifier identifier = send.selector.asIdentifier(); |
4251 if (identifier == null) { | 4291 if (identifier == null) { |
4252 compiler.reportError(send.selector, MessageKind.INVALID_FOR_IN); | 4292 compiler.reportErrorMessage( |
| 4293 send.selector, MessageKind.INVALID_FOR_IN); |
4253 } else { | 4294 } else { |
4254 loopVariableSelector = new Selector.setter( | 4295 loopVariableSelector = new Selector.setter( |
4255 new Name(identifier.source, library)); | 4296 new Name(identifier.source, library)); |
4256 } | 4297 } |
4257 if (send.receiver != null) { | 4298 if (send.receiver != null) { |
4258 compiler.reportError(send.receiver, MessageKind.INVALID_FOR_IN); | 4299 compiler.reportErrorMessage( |
| 4300 send.receiver, MessageKind.INVALID_FOR_IN); |
4259 } | 4301 } |
4260 } else if (variableDefinitions != null) { | 4302 } else if (variableDefinitions != null) { |
4261 Link<Node> nodes = variableDefinitions.definitions.nodes; | 4303 Link<Node> nodes = variableDefinitions.definitions.nodes; |
4262 if (!nodes.tail.isEmpty) { | 4304 if (!nodes.tail.isEmpty) { |
4263 compiler.reportError(nodes.tail.head, MessageKind.INVALID_FOR_IN); | 4305 compiler.reportErrorMessage( |
| 4306 nodes.tail.head, MessageKind.INVALID_FOR_IN); |
4264 } | 4307 } |
4265 Node first = nodes.head; | 4308 Node first = nodes.head; |
4266 Identifier identifier = first.asIdentifier(); | 4309 Identifier identifier = first.asIdentifier(); |
4267 if (identifier == null) { | 4310 if (identifier == null) { |
4268 compiler.reportError(first, MessageKind.INVALID_FOR_IN); | 4311 compiler.reportErrorMessage( |
| 4312 first, MessageKind.INVALID_FOR_IN); |
4269 } else { | 4313 } else { |
4270 loopVariableSelector = new Selector.setter( | 4314 loopVariableSelector = new Selector.setter( |
4271 new Name(identifier.source, library)); | 4315 new Name(identifier.source, library)); |
4272 loopVariable = registry.getDefinition(identifier); | 4316 loopVariable = registry.getDefinition(identifier); |
4273 } | 4317 } |
4274 } else { | 4318 } else { |
4275 compiler.reportError(declaration, MessageKind.INVALID_FOR_IN); | 4319 compiler.reportErrorMessage( |
| 4320 declaration, MessageKind.INVALID_FOR_IN); |
4276 } | 4321 } |
4277 if (loopVariableSelector != null) { | 4322 if (loopVariableSelector != null) { |
4278 registry.setSelector(declaration, loopVariableSelector); | 4323 registry.setSelector(declaration, loopVariableSelector); |
4279 registerSend(loopVariableSelector, loopVariable); | 4324 registerSend(loopVariableSelector, loopVariable); |
4280 } else { | 4325 } else { |
4281 // The selector may only be null if we reported an error. | 4326 // The selector may only be null if we reported an error. |
4282 assert(invariant(declaration, compiler.compilationFailed)); | 4327 assert(invariant(declaration, compiler.compilationFailed)); |
4283 } | 4328 } |
4284 if (loopVariable != null) { | 4329 if (loopVariable != null) { |
4285 // loopVariable may be null if it could not be resolved. | 4330 // loopVariable may be null if it could not be resolved. |
(...skipping 15 matching lines...) Expand all Loading... |
4301 LabelDefinition element = targetElement.addLabel(label, labelName); | 4346 LabelDefinition element = targetElement.addLabel(label, labelName); |
4302 labelElements[labelName] = element; | 4347 labelElements[labelName] = element; |
4303 } | 4348 } |
4304 statementScope.enterLabelScope(labelElements); | 4349 statementScope.enterLabelScope(labelElements); |
4305 visit(node.statement); | 4350 visit(node.statement); |
4306 statementScope.exitLabelScope(); | 4351 statementScope.exitLabelScope(); |
4307 labelElements.forEach((String labelName, LabelDefinition element) { | 4352 labelElements.forEach((String labelName, LabelDefinition element) { |
4308 if (element.isTarget) { | 4353 if (element.isTarget) { |
4309 registry.defineLabel(element.label, element); | 4354 registry.defineLabel(element.label, element); |
4310 } else { | 4355 } else { |
4311 warning(element.label, MessageKind.UNUSED_LABEL, | 4356 compiler.reportWarningMessage( |
4312 {'labelName': labelName}); | 4357 element.label, |
| 4358 MessageKind.UNUSED_LABEL, |
| 4359 {'labelName': labelName}); |
4313 } | 4360 } |
4314 }); | 4361 }); |
4315 if (!targetElement.isTarget) { | 4362 if (!targetElement.isTarget) { |
4316 registry.undefineTarget(body); | 4363 registry.undefineTarget(body); |
4317 } | 4364 } |
4318 return const NoneResult(); | 4365 return const NoneResult(); |
4319 } | 4366 } |
4320 | 4367 |
4321 ResolutionResult visitLiteralMap(LiteralMap node) { | 4368 ResolutionResult visitLiteralMap(LiteralMap node) { |
4322 bool isValidAsConstant = true; | 4369 bool isValidAsConstant = true; |
4323 sendIsMemberAccess = false; | 4370 sendIsMemberAccess = false; |
4324 | 4371 |
4325 NodeList arguments = node.typeArguments; | 4372 NodeList arguments = node.typeArguments; |
4326 DartType keyTypeArgument; | 4373 DartType keyTypeArgument; |
4327 DartType valueTypeArgument; | 4374 DartType valueTypeArgument; |
4328 if (arguments != null) { | 4375 if (arguments != null) { |
4329 Link<Node> nodes = arguments.nodes; | 4376 Link<Node> nodes = arguments.nodes; |
4330 if (nodes.isEmpty) { | 4377 if (nodes.isEmpty) { |
4331 // The syntax [: <>{} :] is not allowed. | 4378 // The syntax [: <>{} :] is not allowed. |
4332 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT); | 4379 compiler.reportErrorMessage( |
| 4380 arguments, MessageKind.MISSING_TYPE_ARGUMENT); |
4333 isValidAsConstant = false; | 4381 isValidAsConstant = false; |
4334 } else { | 4382 } else { |
4335 keyTypeArgument = resolveTypeAnnotation(nodes.head); | 4383 keyTypeArgument = resolveTypeAnnotation(nodes.head); |
4336 nodes = nodes.tail; | 4384 nodes = nodes.tail; |
4337 if (nodes.isEmpty) { | 4385 if (nodes.isEmpty) { |
4338 warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT); | 4386 compiler.reportWarningMessage( |
| 4387 arguments, MessageKind.MISSING_TYPE_ARGUMENT); |
4339 } else { | 4388 } else { |
4340 valueTypeArgument = resolveTypeAnnotation(nodes.head); | 4389 valueTypeArgument = resolveTypeAnnotation(nodes.head); |
4341 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 4390 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
4342 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 4391 compiler.reportWarningMessage( |
| 4392 nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
4343 resolveTypeAnnotation(nodes.head); | 4393 resolveTypeAnnotation(nodes.head); |
4344 } | 4394 } |
4345 } | 4395 } |
4346 } | 4396 } |
4347 } | 4397 } |
4348 DartType mapType; | 4398 DartType mapType; |
4349 if (valueTypeArgument != null) { | 4399 if (valueTypeArgument != null) { |
4350 mapType = coreTypes.mapType(keyTypeArgument, valueTypeArgument); | 4400 mapType = coreTypes.mapType(keyTypeArgument, valueTypeArgument); |
4351 } else { | 4401 } else { |
4352 mapType = coreTypes.mapType(); | 4402 mapType = coreTypes.mapType(); |
4353 } | 4403 } |
4354 if (node.isConst && mapType.containsTypeVariables) { | 4404 if (node.isConst && mapType.containsTypeVariables) { |
4355 compiler.reportError(arguments, | 4405 compiler.reportErrorMessage( |
| 4406 arguments, |
4356 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 4407 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
4357 isValidAsConstant = false; | 4408 isValidAsConstant = false; |
4358 } | 4409 } |
4359 registry.registerMapLiteral(node, mapType, node.isConst); | 4410 registry.registerMapLiteral(node, mapType, node.isConst); |
4360 registry.registerRequiredType(mapType, enclosingElement); | 4411 registry.registerRequiredType(mapType, enclosingElement); |
4361 if (node.isConst) { | 4412 if (node.isConst) { |
4362 | 4413 |
4363 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; | 4414 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; |
4364 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; | 4415 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; |
4365 inConstantContext(() { | 4416 inConstantContext(() { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4414 | 4465 |
4415 bool overridesEquals(DartType type) { | 4466 bool overridesEquals(DartType type) { |
4416 ClassElement cls = type.element; | 4467 ClassElement cls = type.element; |
4417 Element equals = cls.lookupMember('=='); | 4468 Element equals = cls.lookupMember('=='); |
4418 return equals.enclosingClass != compiler.objectClass; | 4469 return equals.enclosingClass != compiler.objectClass; |
4419 } | 4470 } |
4420 | 4471 |
4421 void checkCaseExpressions(SwitchStatement node) { | 4472 void checkCaseExpressions(SwitchStatement node) { |
4422 CaseMatch firstCase = null; | 4473 CaseMatch firstCase = null; |
4423 DartType firstCaseType = null; | 4474 DartType firstCaseType = null; |
4424 bool hasReportedProblem = false; | 4475 DiagnosticMessage error; |
| 4476 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
4425 | 4477 |
4426 for (Link<Node> cases = node.cases.nodes; | 4478 for (Link<Node> cases = node.cases.nodes; |
4427 !cases.isEmpty; | 4479 !cases.isEmpty; |
4428 cases = cases.tail) { | 4480 cases = cases.tail) { |
4429 SwitchCase switchCase = cases.head; | 4481 SwitchCase switchCase = cases.head; |
4430 | 4482 |
4431 for (Node labelOrCase in switchCase.labelsAndCases) { | 4483 for (Node labelOrCase in switchCase.labelsAndCases) { |
4432 CaseMatch caseMatch = labelOrCase.asCaseMatch(); | 4484 CaseMatch caseMatch = labelOrCase.asCaseMatch(); |
4433 if (caseMatch == null) continue; | 4485 if (caseMatch == null) continue; |
4434 | 4486 |
4435 // Analyze the constant. | 4487 // Analyze the constant. |
4436 ConstantExpression constant = | 4488 ConstantExpression constant = |
4437 registry.getConstant(caseMatch.expression); | 4489 registry.getConstant(caseMatch.expression); |
4438 assert(invariant(node, constant != null, | 4490 assert(invariant(node, constant != null, |
4439 message: 'No constant computed for $node')); | 4491 message: 'No constant computed for $node')); |
4440 | 4492 |
4441 ConstantValue value = compiler.constants.getConstantValue(constant); | 4493 ConstantValue value = compiler.constants.getConstantValue(constant); |
4442 DartType caseType = typeOfConstant(value); | 4494 DartType caseType = typeOfConstant(value); |
4443 | 4495 |
4444 if (firstCaseType == null) { | 4496 if (firstCaseType == null) { |
4445 firstCase = caseMatch; | 4497 firstCase = caseMatch; |
4446 firstCaseType = caseType; | 4498 firstCaseType = caseType; |
4447 | 4499 |
4448 // We only report the bad type on the first class element. All others | 4500 // We only report the bad type on the first class element. All others |
4449 // get a "type differs" error. | 4501 // get a "type differs" error. |
4450 if (caseType.element == compiler.doubleClass) { | 4502 if (caseType.element == compiler.doubleClass) { |
4451 compiler.reportError(node, | 4503 compiler.reportErrorMessage( |
4452 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, | 4504 node, |
4453 {'type': "double"}); | 4505 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, |
| 4506 {'type': "double"}); |
4454 } else if (caseType.element == compiler.functionClass) { | 4507 } else if (caseType.element == compiler.functionClass) { |
4455 compiler.reportError(node, MessageKind.SWITCH_CASE_FORBIDDEN, | 4508 compiler.reportErrorMessage( |
4456 {'type': "Function"}); | 4509 node, MessageKind.SWITCH_CASE_FORBIDDEN, |
| 4510 {'type': "Function"}); |
4457 } else if (value.isObject && overridesEquals(caseType)) { | 4511 } else if (value.isObject && overridesEquals(caseType)) { |
4458 compiler.reportError(firstCase.expression, | 4512 compiler.reportErrorMessage( |
| 4513 firstCase.expression, |
4459 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, | 4514 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, |
4460 {'type': caseType}); | 4515 {'type': caseType}); |
4461 } | 4516 } |
4462 } else { | 4517 } else { |
4463 if (caseType != firstCaseType) { | 4518 if (caseType != firstCaseType) { |
4464 if (!hasReportedProblem) { | 4519 if (error == null) { |
4465 compiler.reportError( | 4520 error = compiler.createMessage( |
4466 node, | 4521 node, |
4467 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL, | 4522 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL, |
4468 {'type': firstCaseType}); | 4523 {'type': firstCaseType}); |
4469 compiler.reportInfo( | 4524 infos.add(compiler.createMessage( |
4470 firstCase.expression, | 4525 firstCase.expression, |
4471 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, | 4526 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, |
4472 {'type': firstCaseType}); | 4527 {'type': firstCaseType})); |
4473 hasReportedProblem = true; | |
4474 } | 4528 } |
4475 compiler.reportInfo( | 4529 infos.add(compiler.createMessage( |
4476 caseMatch.expression, | 4530 caseMatch.expression, |
4477 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, | 4531 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, |
4478 {'type': caseType}); | 4532 {'type': caseType})); |
4479 } | 4533 } |
4480 } | 4534 } |
4481 } | 4535 } |
4482 } | 4536 } |
| 4537 if (error != null) { |
| 4538 compiler.reportError(error, infos); |
| 4539 } |
4483 } | 4540 } |
4484 | 4541 |
4485 ResolutionResult visitSwitchStatement(SwitchStatement node) { | 4542 ResolutionResult visitSwitchStatement(SwitchStatement node) { |
4486 node.expression.accept(this); | 4543 node.expression.accept(this); |
4487 | 4544 |
4488 JumpTarget breakElement = getOrDefineTarget(node); | 4545 JumpTarget breakElement = getOrDefineTarget(node); |
4489 Map<String, LabelDefinition> continueLabels = <String, LabelDefinition>{}; | 4546 Map<String, LabelDefinition> continueLabels = <String, LabelDefinition>{}; |
4490 Link<Node> cases = node.cases.nodes; | 4547 Link<Node> cases = node.cases.nodes; |
4491 while (!cases.isEmpty) { | 4548 while (!cases.isEmpty) { |
4492 SwitchCase switchCase = cases.head; | 4549 SwitchCase switchCase = cases.head; |
4493 for (Node labelOrCase in switchCase.labelsAndCases) { | 4550 for (Node labelOrCase in switchCase.labelsAndCases) { |
4494 CaseMatch caseMatch = labelOrCase.asCaseMatch(); | 4551 CaseMatch caseMatch = labelOrCase.asCaseMatch(); |
4495 if (caseMatch != null) { | 4552 if (caseMatch != null) { |
4496 analyzeConstantDeferred(caseMatch.expression); | 4553 analyzeConstantDeferred(caseMatch.expression); |
4497 continue; | 4554 continue; |
4498 } | 4555 } |
4499 Label label = labelOrCase; | 4556 Label label = labelOrCase; |
4500 String labelName = label.labelName; | 4557 String labelName = label.labelName; |
4501 | 4558 |
4502 LabelDefinition existingElement = continueLabels[labelName]; | 4559 LabelDefinition existingElement = continueLabels[labelName]; |
4503 if (existingElement != null) { | 4560 if (existingElement != null) { |
4504 // It's an error if the same label occurs twice in the same switch. | 4561 // It's an error if the same label occurs twice in the same switch. |
4505 compiler.reportError( | 4562 compiler.reportError( |
4506 label, | 4563 compiler.createMessage( |
4507 MessageKind.DUPLICATE_LABEL, {'labelName': labelName}); | 4564 label, |
4508 compiler.reportInfo( | 4565 MessageKind.DUPLICATE_LABEL, |
4509 existingElement.label, | 4566 {'labelName': labelName}), |
4510 MessageKind.EXISTING_LABEL, {'labelName': labelName}); | 4567 <DiagnosticMessage>[ |
| 4568 compiler.createMessage( |
| 4569 existingElement.label, |
| 4570 MessageKind.EXISTING_LABEL, |
| 4571 {'labelName': labelName}), |
| 4572 ]); |
4511 } else { | 4573 } else { |
4512 // It's only a warning if it shadows another label. | 4574 // It's only a warning if it shadows another label. |
4513 existingElement = statementScope.lookupLabel(labelName); | 4575 existingElement = statementScope.lookupLabel(labelName); |
4514 if (existingElement != null) { | 4576 if (existingElement != null) { |
4515 compiler.reportWarning( | 4577 compiler.reportWarning( |
4516 label, | 4578 compiler.createMessage( |
4517 MessageKind.DUPLICATE_LABEL, {'labelName': labelName}); | 4579 label, |
4518 compiler.reportInfo( | 4580 MessageKind.DUPLICATE_LABEL, |
4519 existingElement.label, | 4581 {'labelName': labelName}), |
4520 MessageKind.EXISTING_LABEL, {'labelName': labelName}); | 4582 <DiagnosticMessage>[ |
| 4583 compiler.createMessage( |
| 4584 existingElement.label, |
| 4585 MessageKind.EXISTING_LABEL, |
| 4586 {'labelName': labelName}), |
| 4587 ]); |
4521 } | 4588 } |
4522 } | 4589 } |
4523 | 4590 |
4524 JumpTarget targetElement = getOrDefineTarget(switchCase); | 4591 JumpTarget targetElement = getOrDefineTarget(switchCase); |
4525 LabelDefinition labelElement = targetElement.addLabel(label, labelName); | 4592 LabelDefinition labelElement = targetElement.addLabel(label, labelName); |
4526 registry.defineLabel(label, labelElement); | 4593 registry.defineLabel(label, labelElement); |
4527 continueLabels[labelName] = labelElement; | 4594 continueLabels[labelName] = labelElement; |
4528 } | 4595 } |
4529 cases = cases.tail; | 4596 cases = cases.tail; |
4530 // Test that only the last case, if any, is a default case. | 4597 // Test that only the last case, if any, is a default case. |
4531 if (switchCase.defaultKeyword != null && !cases.isEmpty) { | 4598 if (switchCase.defaultKeyword != null && !cases.isEmpty) { |
4532 error(switchCase, MessageKind.INVALID_CASE_DEFAULT); | 4599 compiler.reportErrorMessage( |
| 4600 switchCase, MessageKind.INVALID_CASE_DEFAULT); |
4533 } | 4601 } |
4534 } | 4602 } |
4535 | 4603 |
4536 addDeferredAction(enclosingElement, () { | 4604 addDeferredAction(enclosingElement, () { |
4537 checkCaseExpressions(node); | 4605 checkCaseExpressions(node); |
4538 }); | 4606 }); |
4539 | 4607 |
4540 statementScope.enterSwitch(breakElement, continueLabels); | 4608 statementScope.enterSwitch(breakElement, continueLabels); |
4541 node.cases.accept(this); | 4609 node.cases.accept(this); |
4542 statementScope.exitSwitch(); | 4610 statementScope.exitSwitch(); |
(...skipping 24 matching lines...) Expand all Loading... |
4567 return const NoneResult(); | 4635 return const NoneResult(); |
4568 } | 4636 } |
4569 | 4637 |
4570 ResolutionResult visitTryStatement(TryStatement node) { | 4638 ResolutionResult visitTryStatement(TryStatement node) { |
4571 // TODO(karlklose): also track the information about mutated variables, | 4639 // TODO(karlklose): also track the information about mutated variables, |
4572 // catch, and finally-block. | 4640 // catch, and finally-block. |
4573 registry.registerTryStatement(); | 4641 registry.registerTryStatement(); |
4574 | 4642 |
4575 visit(node.tryBlock); | 4643 visit(node.tryBlock); |
4576 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { | 4644 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { |
4577 error(node.getEndToken().next, MessageKind.NO_CATCH_NOR_FINALLY); | 4645 compiler.reportErrorMessage( |
| 4646 node.getEndToken().next, MessageKind.NO_CATCH_NOR_FINALLY); |
4578 } | 4647 } |
4579 visit(node.catchBlocks); | 4648 visit(node.catchBlocks); |
4580 visit(node.finallyBlock); | 4649 visit(node.finallyBlock); |
4581 return const NoneResult(); | 4650 return const NoneResult(); |
4582 } | 4651 } |
4583 | 4652 |
4584 ResolutionResult visitCatchBlock(CatchBlock node) { | 4653 ResolutionResult visitCatchBlock(CatchBlock node) { |
4585 registry.registerCatchStatement(); | 4654 registry.registerCatchStatement(); |
4586 // Check that if catch part is present, then | 4655 // Check that if catch part is present, then |
4587 // it has one or two formal parameters. | 4656 // it has one or two formal parameters. |
4588 VariableDefinitions exceptionDefinition; | 4657 VariableDefinitions exceptionDefinition; |
4589 VariableDefinitions stackTraceDefinition; | 4658 VariableDefinitions stackTraceDefinition; |
4590 if (node.formals != null) { | 4659 if (node.formals != null) { |
4591 Link<Node> formalsToProcess = node.formals.nodes; | 4660 Link<Node> formalsToProcess = node.formals.nodes; |
4592 if (formalsToProcess.isEmpty) { | 4661 if (formalsToProcess.isEmpty) { |
4593 error(node, MessageKind.EMPTY_CATCH_DECLARATION); | 4662 compiler.reportErrorMessage( |
| 4663 node, MessageKind.EMPTY_CATCH_DECLARATION); |
4594 } else { | 4664 } else { |
4595 exceptionDefinition = formalsToProcess.head.asVariableDefinitions(); | 4665 exceptionDefinition = formalsToProcess.head.asVariableDefinitions(); |
4596 formalsToProcess = formalsToProcess.tail; | 4666 formalsToProcess = formalsToProcess.tail; |
4597 if (!formalsToProcess.isEmpty) { | 4667 if (!formalsToProcess.isEmpty) { |
4598 stackTraceDefinition = formalsToProcess.head.asVariableDefinitions(); | 4668 stackTraceDefinition = formalsToProcess.head.asVariableDefinitions(); |
4599 formalsToProcess = formalsToProcess.tail; | 4669 formalsToProcess = formalsToProcess.tail; |
4600 if (!formalsToProcess.isEmpty) { | 4670 if (!formalsToProcess.isEmpty) { |
4601 for (Node extra in formalsToProcess) { | 4671 for (Node extra in formalsToProcess) { |
4602 error(extra, MessageKind.EXTRA_CATCH_DECLARATION); | 4672 compiler.reportErrorMessage( |
| 4673 extra, MessageKind.EXTRA_CATCH_DECLARATION); |
4603 } | 4674 } |
4604 } | 4675 } |
4605 registry.registerStackTraceInCatch(); | 4676 registry.registerStackTraceInCatch(); |
4606 } | 4677 } |
4607 } | 4678 } |
4608 | 4679 |
4609 // Check that the formals aren't optional and that they have no | 4680 // Check that the formals aren't optional and that they have no |
4610 // modifiers or type. | 4681 // modifiers or type. |
4611 for (Link<Node> link = node.formals.nodes; | 4682 for (Link<Node> link = node.formals.nodes; |
4612 !link.isEmpty; | 4683 !link.isEmpty; |
4613 link = link.tail) { | 4684 link = link.tail) { |
4614 // If the formal parameter is a node list, it means that it is a | 4685 // If the formal parameter is a node list, it means that it is a |
4615 // sequence of optional parameters. | 4686 // sequence of optional parameters. |
4616 NodeList nodeList = link.head.asNodeList(); | 4687 NodeList nodeList = link.head.asNodeList(); |
4617 if (nodeList != null) { | 4688 if (nodeList != null) { |
4618 error(nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH); | 4689 compiler.reportErrorMessage( |
| 4690 nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH); |
4619 } else { | 4691 } else { |
4620 VariableDefinitions declaration = link.head; | 4692 VariableDefinitions declaration = link.head; |
4621 for (Node modifier in declaration.modifiers.nodes) { | 4693 for (Node modifier in declaration.modifiers.nodes) { |
4622 error(modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH); | 4694 compiler.reportErrorMessage( |
| 4695 modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH); |
4623 } | 4696 } |
4624 TypeAnnotation type = declaration.type; | 4697 TypeAnnotation type = declaration.type; |
4625 if (type != null) { | 4698 if (type != null) { |
4626 error(type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); | 4699 compiler.reportErrorMessage( |
| 4700 type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); |
4627 } | 4701 } |
4628 } | 4702 } |
4629 } | 4703 } |
4630 } | 4704 } |
4631 | 4705 |
4632 Scope blockScope = new BlockScope(scope); | 4706 Scope blockScope = new BlockScope(scope); |
4633 doInCheckContext(() => visitIn(node.type, blockScope)); | 4707 doInCheckContext(() => visitIn(node.type, blockScope)); |
4634 visitIn(node.formals, blockScope); | 4708 visitIn(node.formals, blockScope); |
4635 var oldInCatchBlock = inCatchBlock; | 4709 var oldInCatchBlock = inCatchBlock; |
4636 inCatchBlock = true; | 4710 inCatchBlock = true; |
(...skipping 16 matching lines...) Expand all Loading... |
4653 } | 4727 } |
4654 return const NoneResult(); | 4728 return const NoneResult(); |
4655 } | 4729 } |
4656 } | 4730 } |
4657 | 4731 |
4658 /// Looks up [name] in [scope] and unwraps the result. | 4732 /// Looks up [name] in [scope] and unwraps the result. |
4659 Element lookupInScope(Compiler compiler, Node node, | 4733 Element lookupInScope(Compiler compiler, Node node, |
4660 Scope scope, String name) { | 4734 Scope scope, String name) { |
4661 return Elements.unwrap(scope.lookup(name), compiler, node); | 4735 return Elements.unwrap(scope.lookup(name), compiler, node); |
4662 } | 4736 } |
OLD | NEW |