OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of resolution; | 5 part of resolution; |
6 | 6 |
7 abstract class TreeElements { | 7 abstract class TreeElements { |
8 Element get currentElement; | 8 Element get currentElement; |
9 Set<Node> get superUses; | 9 Set<Node> get superUses; |
10 | 10 |
(...skipping 1409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1420 if (identical(stringValue, 'void')) { | 1420 if (identical(stringValue, 'void')) { |
1421 return compiler.types.voidType.element; | 1421 return compiler.types.voidType.element; |
1422 } else if (identical(stringValue, 'dynamic')) { | 1422 } else if (identical(stringValue, 'dynamic')) { |
1423 return compiler.dynamicClass; | 1423 return compiler.dynamicClass; |
1424 } else { | 1424 } else { |
1425 return scope.lookup(typeName.source); | 1425 return scope.lookup(typeName.source); |
1426 } | 1426 } |
1427 } | 1427 } |
1428 } | 1428 } |
1429 | 1429 |
1430 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean | 1430 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, |
1431 // flags instead of closures. | 1431 {bool malformedIsError: false, |
1432 DartType resolveTypeAnnotation( | 1432 bool ambiguousIsError: false}) { |
1433 MappingVisitor visitor, | |
1434 TypeAnnotation node, | |
1435 {onFailure(Node node, DualKind kind, [Map arguments])}) { | |
1436 if (onFailure == null) { | |
1437 onFailure = (n, k, [arguments]) {}; | |
1438 } | |
1439 return resolveTypeAnnotationInContext(visitor, node, onFailure); | |
1440 } | |
1441 | |
1442 DartType resolveTypeAnnotationInContext( | |
1443 MappingVisitor visitor, | |
1444 TypeAnnotation node, | |
1445 onFailure(Node node, DualKind kind, [Map arguments])) { | |
1446 Identifier typeName; | 1433 Identifier typeName; |
1447 SourceString prefixName; | 1434 SourceString prefixName; |
1448 Send send = node.typeName.asSend(); | 1435 Send send = node.typeName.asSend(); |
1449 if (send != null) { | 1436 if (send != null) { |
1450 // The type name is of the form [: prefix . identifier :]. | 1437 // The type name is of the form [: prefix . identifier :]. |
1451 prefixName = send.receiver.asIdentifier().source; | 1438 prefixName = send.receiver.asIdentifier().source; |
1452 typeName = send.selector.asIdentifier(); | 1439 typeName = send.selector.asIdentifier(); |
1453 } else { | 1440 } else { |
1454 typeName = node.typeName.asIdentifier(); | 1441 typeName = node.typeName.asIdentifier(); |
1455 } | 1442 } |
1456 | 1443 |
1457 Element element = resolveTypeName(visitor.scope, prefixName, typeName); | 1444 Element element = resolveTypeName(visitor.scope, prefixName, typeName); |
1458 DartType type; | 1445 DartType type; |
1459 | 1446 |
1460 DartType reportFailureAndCreateType(DualKind messageKind, | 1447 DartType reportFailureAndCreateType(DualKind messageKind, |
1461 Map messageArguments) { | 1448 Map messageArguments, |
1462 onFailure(node, messageKind, messageArguments); | 1449 {DartType userProvidedBadType, |
| 1450 bool isError: false, |
| 1451 bool isAmbiguous: false}) { |
| 1452 if (isError) { |
| 1453 visitor.error(node, messageKind.error, messageArguments); |
| 1454 } else { |
| 1455 visitor.warning(node, messageKind.warning, messageArguments); |
| 1456 } |
1463 var erroneousElement = new ErroneousElementX( | 1457 var erroneousElement = new ErroneousElementX( |
1464 messageKind.error, messageArguments, typeName.source, | 1458 messageKind.error, messageArguments, typeName.source, |
1465 visitor.enclosingElement); | 1459 visitor.enclosingElement); |
1466 var arguments = new LinkBuilder<DartType>(); | 1460 var arguments = new LinkBuilder<DartType>(); |
1467 resolveTypeArguments( | 1461 resolveTypeArguments(visitor, node, null, arguments); |
1468 visitor, node, null, | 1462 return isAmbiguous |
1469 onFailure, arguments); | 1463 ? new AmbiguousType(erroneousElement, arguments.toLink()) |
1470 return new MalformedType(erroneousElement, null, arguments.toLink()); | 1464 : new MalformedType(erroneousElement, |
| 1465 userProvidedBadType, arguments.toLink()); |
1471 } | 1466 } |
1472 | 1467 |
1473 DartType checkNoTypeArguments(DartType type) { | 1468 DartType checkNoTypeArguments(DartType type) { |
1474 var arguments = new LinkBuilder<DartType>(); | 1469 var arguments = new LinkBuilder<DartType>(); |
1475 bool hashTypeArgumentMismatch = resolveTypeArguments( | 1470 bool hasTypeArgumentMismatch = resolveTypeArguments( |
1476 visitor, node, const Link<DartType>(), | 1471 visitor, node, const Link<DartType>(), arguments); |
1477 onFailure, arguments); | 1472 if (hasTypeArgumentMismatch) { |
1478 if (hashTypeArgumentMismatch) { | |
1479 type = new MalformedType( | 1473 type = new MalformedType( |
1480 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 1474 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, |
1481 {'type': node}, typeName.source, visitor.enclosingElement), | 1475 {'type': node}, typeName.source, visitor.enclosingElement), |
1482 type, arguments.toLink()); | 1476 type, arguments.toLink()); |
1483 } | 1477 } |
1484 return type; | 1478 return type; |
1485 } | 1479 } |
1486 | 1480 |
1487 if (element == null) { | 1481 if (element == null) { |
1488 type = reportFailureAndCreateType( | 1482 type = reportFailureAndCreateType( |
1489 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); | 1483 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}, |
| 1484 isError: malformedIsError); |
1490 } else if (element.isAmbiguous()) { | 1485 } else if (element.isAmbiguous()) { |
1491 AmbiguousElement ambiguous = element; | 1486 AmbiguousElement ambiguous = element; |
1492 type = reportFailureAndCreateType( | 1487 type = reportFailureAndCreateType( |
1493 ambiguous.messageKind, ambiguous.messageArguments); | 1488 ambiguous.messageKind, ambiguous.messageArguments, |
| 1489 isError: ambiguousIsError, isAmbiguous: true); |
1494 ambiguous.diagnose(visitor.mapping.currentElement, compiler); | 1490 ambiguous.diagnose(visitor.mapping.currentElement, compiler); |
1495 } else if (!element.impliesType()) { | 1491 } else if (!element.impliesType()) { |
1496 type = reportFailureAndCreateType( | 1492 type = reportFailureAndCreateType( |
1497 MessageKind.NOT_A_TYPE, {'node': node.typeName}); | 1493 MessageKind.NOT_A_TYPE, {'node': node.typeName}, |
| 1494 isError: malformedIsError); |
1498 } else { | 1495 } else { |
1499 if (identical(element, compiler.types.voidType.element) || | 1496 if (identical(element, compiler.types.voidType.element) || |
1500 identical(element, compiler.types.dynamicType.element)) { | 1497 identical(element, compiler.dynamicClass)) { |
1501 type = checkNoTypeArguments(element.computeType(compiler)); | 1498 type = checkNoTypeArguments(element.computeType(compiler)); |
1502 } else if (element.isClass()) { | 1499 } else if (element.isClass()) { |
1503 ClassElement cls = element; | 1500 ClassElement cls = element; |
1504 compiler.resolver._ensureClassWillBeResolved(cls); | 1501 compiler.resolver._ensureClassWillBeResolved(cls); |
1505 element.computeType(compiler); | 1502 element.computeType(compiler); |
1506 var arguments = new LinkBuilder<DartType>(); | 1503 var arguments = new LinkBuilder<DartType>(); |
1507 bool hashTypeArgumentMismatch = resolveTypeArguments( | 1504 bool hasTypeArgumentMismatch = resolveTypeArguments( |
1508 visitor, node, cls.typeVariables, | 1505 visitor, node, cls.typeVariables, arguments); |
1509 onFailure, arguments); | 1506 if (hasTypeArgumentMismatch) { |
1510 if (hashTypeArgumentMismatch) { | 1507 type = new BadInterfaceType(cls.declaration, |
1511 type = new MalformedType( | 1508 new InterfaceType.forUserProvidedBadType(cls.declaration, |
1512 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 1509 arguments.toLink())); |
1513 {'type': node}, typeName.source, visitor.enclosingElement), | |
1514 new InterfaceType.userProvidedBadType(cls.declaration, | |
1515 arguments.toLink())); | |
1516 } else { | 1510 } else { |
1517 if (arguments.isEmpty) { | 1511 if (arguments.isEmpty) { |
1518 type = cls.rawType; | 1512 type = cls.rawType; |
1519 } else { | 1513 } else { |
1520 type = new InterfaceType(cls.declaration, arguments.toLink()); | 1514 type = new InterfaceType(cls.declaration, arguments.toLink()); |
1521 } | 1515 } |
1522 } | 1516 } |
1523 } else if (element.isTypedef()) { | 1517 } else if (element.isTypedef()) { |
1524 TypedefElement typdef = element; | 1518 TypedefElement typdef = element; |
1525 // TODO(ahe): Should be [ensureResolved]. | 1519 // TODO(ahe): Should be [ensureResolved]. |
1526 compiler.resolveTypedef(typdef); | 1520 compiler.resolveTypedef(typdef); |
1527 var arguments = new LinkBuilder<DartType>(); | 1521 var arguments = new LinkBuilder<DartType>(); |
1528 bool hashTypeArgumentMismatch = resolveTypeArguments( | 1522 bool hasTypeArgumentMismatch = resolveTypeArguments( |
1529 visitor, node, typdef.typeVariables, | 1523 visitor, node, typdef.typeVariables, arguments); |
1530 onFailure, arguments); | 1524 if (hasTypeArgumentMismatch) { |
1531 if (hashTypeArgumentMismatch) { | 1525 type = new BadTypedefType(typdef, |
1532 type = new MalformedType( | 1526 new TypedefType.forUserProvidedBadType(typdef, |
1533 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 1527 arguments.toLink())); |
1534 {'type': node}, typeName.source, visitor.enclosingElement), | |
1535 new TypedefType.userProvidedBadType(typdef, arguments.toLink())); | |
1536 } else { | 1528 } else { |
1537 if (arguments.isEmpty) { | 1529 if (arguments.isEmpty) { |
1538 type = typdef.rawType; | 1530 type = typdef.rawType; |
1539 } else { | 1531 } else { |
1540 type = new TypedefType(typdef, arguments.toLink()); | 1532 type = new TypedefType(typdef, arguments.toLink()); |
1541 } | 1533 } |
1542 } | 1534 } |
1543 } else if (element.isTypeVariable()) { | 1535 } else if (element.isTypeVariable()) { |
1544 Element outer = | 1536 Element outer = |
1545 visitor.enclosingElement.getOutermostEnclosingMemberOrTopLevel(); | 1537 visitor.enclosingElement.getOutermostEnclosingMemberOrTopLevel(); |
1546 bool isInFactoryConstructor = | 1538 bool isInFactoryConstructor = |
1547 outer != null && outer.isFactoryConstructor(); | 1539 outer != null && outer.isFactoryConstructor(); |
1548 if (!outer.isClass() && | 1540 if (!outer.isClass() && |
1549 !outer.isTypedef() && | 1541 !outer.isTypedef() && |
1550 !isInFactoryConstructor && | 1542 !isInFactoryConstructor && |
1551 Elements.isInStaticContext(visitor.enclosingElement)) { | 1543 Elements.isInStaticContext(visitor.enclosingElement)) { |
1552 compiler.backend.registerThrowRuntimeError(visitor.mapping); | 1544 compiler.backend.registerThrowRuntimeError(visitor.mapping); |
1553 compiler.reportWarningCode( | 1545 type = reportFailureAndCreateType( |
1554 node, | 1546 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
1555 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.warning, | 1547 {'typeVariableName': node}, |
1556 {'typeVariableName': node}); | 1548 userProvidedBadType: element.computeType(compiler), |
1557 type = new MalformedType( | 1549 isError: malformedIsError); |
1558 new ErroneousElementX( | |
1559 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.error, | |
1560 {'typeVariableName': node}, | |
1561 typeName.source, visitor.enclosingElement), | |
1562 element.computeType(compiler)); | |
1563 } else { | 1550 } else { |
1564 type = element.computeType(compiler); | 1551 type = element.computeType(compiler); |
1565 } | 1552 } |
1566 type = checkNoTypeArguments(type); | 1553 type = checkNoTypeArguments(type); |
1567 } else { | 1554 } else { |
1568 compiler.cancel("unexpected element kind ${element.kind}", | 1555 compiler.cancel("unexpected element kind ${element.kind}", |
1569 node: node); | 1556 node: node); |
1570 } | 1557 } |
1571 } | 1558 } |
1572 visitor.useType(node, type); | 1559 visitor.useType(node, type); |
1573 return type; | 1560 return type; |
1574 } | 1561 } |
1575 | 1562 |
1576 /** | 1563 /** |
1577 * Resolves the type arguments of [node] and adds these to [arguments]. | 1564 * Resolves the type arguments of [node] and adds these to [arguments]. |
1578 * | 1565 * |
1579 * Returns [: true :] if the number of type arguments did not match the | 1566 * Returns [: true :] if the number of type arguments did not match the |
1580 * number of type variables. | 1567 * number of type variables. |
1581 */ | 1568 */ |
1582 bool resolveTypeArguments( | 1569 bool resolveTypeArguments( |
1583 MappingVisitor visitor, | 1570 MappingVisitor visitor, |
1584 TypeAnnotation node, | 1571 TypeAnnotation node, |
1585 Link<DartType> typeVariables, | 1572 Link<DartType> typeVariables, |
1586 onFailure(Node node, DualKind kind, [Map arguments]), | 1573 LinkBuilder<DartType> arguments, |
1587 LinkBuilder<DartType> arguments) { | 1574 {bool ambiguousIsError: false}) { |
1588 if (node.typeArguments == null) { | 1575 if (node.typeArguments == null) { |
1589 return false; | 1576 return false; |
1590 } | 1577 } |
1591 bool typeArgumentCountMismatch = false; | 1578 bool typeArgumentCountMismatch = false; |
1592 for (Link<Node> typeArguments = node.typeArguments.nodes; | 1579 for (Link<Node> typeArguments = node.typeArguments.nodes; |
1593 !typeArguments.isEmpty; | 1580 !typeArguments.isEmpty; |
1594 typeArguments = typeArguments.tail) { | 1581 typeArguments = typeArguments.tail) { |
1595 if (typeVariables != null && typeVariables.isEmpty) { | 1582 if (typeVariables != null && typeVariables.isEmpty) { |
1596 onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 1583 visitor.warning( |
| 1584 typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning); |
1597 typeArgumentCountMismatch = true; | 1585 typeArgumentCountMismatch = true; |
1598 } | 1586 } |
1599 DartType argType = resolveTypeAnnotationInContext(visitor, | 1587 DartType argType = resolveTypeAnnotation(visitor, typeArguments.head, |
1600 typeArguments.head, | 1588 ambiguousIsError: ambiguousIsError); |
1601 onFailure); | |
1602 arguments.addLast(argType); | 1589 arguments.addLast(argType); |
1603 if (typeVariables != null && !typeVariables.isEmpty) { | 1590 if (typeVariables != null && !typeVariables.isEmpty) { |
1604 typeVariables = typeVariables.tail; | 1591 typeVariables = typeVariables.tail; |
1605 } | 1592 } |
1606 } | 1593 } |
1607 if (typeVariables != null && !typeVariables.isEmpty) { | 1594 if (typeVariables != null && !typeVariables.isEmpty) { |
1608 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); | 1595 visitor.warning(node.typeArguments, |
| 1596 MessageKind.MISSING_TYPE_ARGUMENT.warning); |
1609 typeArgumentCountMismatch = true; | 1597 typeArgumentCountMismatch = true; |
1610 } | 1598 } |
1611 return typeArgumentCountMismatch; | 1599 return typeArgumentCountMismatch; |
1612 } | 1600 } |
1613 } | 1601 } |
1614 | 1602 |
1615 /** | 1603 /** |
1616 * Common supertype for resolver visitors that record resolutions in a | 1604 * Common supertype for resolver visitors that record resolutions in a |
1617 * [TreeElements] mapping. | 1605 * [TreeElements] mapping. |
1618 */ | 1606 */ |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1654 * | 1642 * |
1655 * This field is updated when nested closures are visited. | 1643 * This field is updated when nested closures are visited. |
1656 */ | 1644 */ |
1657 Element enclosingElement; | 1645 Element enclosingElement; |
1658 bool inInstanceContext; | 1646 bool inInstanceContext; |
1659 bool inCheckContext; | 1647 bool inCheckContext; |
1660 bool inCatchBlock; | 1648 bool inCatchBlock; |
1661 Scope scope; | 1649 Scope scope; |
1662 ClassElement currentClass; | 1650 ClassElement currentClass; |
1663 ExpressionStatement currentExpressionStatement; | 1651 ExpressionStatement currentExpressionStatement; |
1664 bool typeRequired = false; | |
1665 bool sendIsMemberAccess = false; | 1652 bool sendIsMemberAccess = false; |
1666 StatementScope statementScope; | 1653 StatementScope statementScope; |
1667 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION | 1654 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION |
1668 | ElementCategory.IMPLIES_TYPE; | 1655 | ElementCategory.IMPLIES_TYPE; |
1669 | 1656 |
1670 // TODO(ahe): Find a way to share this with runtime implementation. | 1657 // TODO(ahe): Find a way to share this with runtime implementation. |
1671 static final RegExp symbolValidationPattern = | 1658 static final RegExp symbolValidationPattern = |
1672 new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|' | 1659 new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|' |
1673 r'-|' | 1660 r'-|' |
1674 r'unary-|' | 1661 r'unary-|' |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2273 mapping.setType(node, compiler.typeClass.computeType(compiler)); | 2260 mapping.setType(node, compiler.typeClass.computeType(compiler)); |
2274 world.registerTypeLiteral(target, mapping); | 2261 world.registerTypeLiteral(target, mapping); |
2275 } | 2262 } |
2276 } | 2263 } |
2277 | 2264 |
2278 bool resolvedArguments = false; | 2265 bool resolvedArguments = false; |
2279 if (node.isOperator) { | 2266 if (node.isOperator) { |
2280 String operatorString = node.selector.asOperator().source.stringValue; | 2267 String operatorString = node.selector.asOperator().source.stringValue; |
2281 if (operatorString == 'is') { | 2268 if (operatorString == 'is') { |
2282 DartType type = | 2269 DartType type = |
2283 resolveTypeRequired(node.typeAnnotationFromIsCheckOrCast); | 2270 resolveTypeExpression(node.typeAnnotationFromIsCheckOrCast); |
2284 if (type != null) { | 2271 if (type != null) { |
2285 compiler.enqueuer.resolution.registerIsCheck(type, mapping); | 2272 compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
2286 } | 2273 } |
2287 resolvedArguments = true; | 2274 resolvedArguments = true; |
2288 } else if (operatorString == 'as') { | 2275 } else if (operatorString == 'as') { |
2289 DartType type = resolveTypeRequired(node.arguments.head); | 2276 DartType type = resolveTypeExpression(node.arguments.head); |
2290 if (type != null) { | 2277 if (type != null) { |
2291 compiler.enqueuer.resolution.registerAsCheck(type, mapping); | 2278 compiler.enqueuer.resolution.registerAsCheck(type, mapping); |
2292 } | 2279 } |
2293 resolvedArguments = true; | 2280 resolvedArguments = true; |
2294 } | 2281 } |
2295 } | 2282 } |
2296 | 2283 |
2297 if (!resolvedArguments) { | 2284 if (!resolvedArguments) { |
2298 oldSendIsMemberAccess = sendIsMemberAccess; | 2285 oldSendIsMemberAccess = sendIsMemberAccess; |
2299 sendIsMemberAccess = false; | 2286 sendIsMemberAccess = false; |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2691 * [null], if there is no corresponding constructor, class or library. | 2678 * [null], if there is no corresponding constructor, class or library. |
2692 */ | 2679 */ |
2693 FunctionElement resolveConstructor(NewExpression node) { | 2680 FunctionElement resolveConstructor(NewExpression node) { |
2694 return node.accept(new ConstructorResolver(compiler, this)); | 2681 return node.accept(new ConstructorResolver(compiler, this)); |
2695 } | 2682 } |
2696 | 2683 |
2697 FunctionElement resolveRedirectingFactory(Return node) { | 2684 FunctionElement resolveRedirectingFactory(Return node) { |
2698 return node.accept(new ConstructorResolver(compiler, this)); | 2685 return node.accept(new ConstructorResolver(compiler, this)); |
2699 } | 2686 } |
2700 | 2687 |
2701 DartType resolveTypeRequired(TypeAnnotation node) { | 2688 DartType resolveTypeExpression(TypeAnnotation node) { |
2702 bool old = typeRequired; | 2689 return resolveTypeAnnotation(node, isTypeExpression: true); |
2703 typeRequired = true; | |
2704 DartType result = resolveTypeAnnotation(node); | |
2705 typeRequired = old; | |
2706 return result; | |
2707 } | 2690 } |
2708 | 2691 |
2709 DartType resolveTypeAnnotation(TypeAnnotation node) { | 2692 DartType resolveTypeAnnotation(TypeAnnotation node, |
2710 Function report = typeRequired ? dualError : dualWarning; | 2693 {bool isTypeExpression: false}) { |
2711 DartType type = typeResolver.resolveTypeAnnotation( | 2694 DartType type = typeResolver.resolveTypeAnnotation( |
2712 this, node, onFailure: report); | 2695 this, node, ambiguousIsError: isTypeExpression); |
2713 if (type == null) return null; | 2696 if (type == null) return null; |
2714 if (inCheckContext) { | 2697 if (inCheckContext) { |
2715 compiler.enqueuer.resolution.registerIsCheck(type, mapping); | 2698 compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
2716 } | |
2717 if (typeRequired || inCheckContext) { | |
2718 compiler.backend.registerRequiredType(type, enclosingElement); | 2699 compiler.backend.registerRequiredType(type, enclosingElement); |
2719 } | 2700 } |
2720 return type; | 2701 return type; |
2721 } | 2702 } |
2722 | 2703 |
2723 visitModifiers(Modifiers node) { | 2704 visitModifiers(Modifiers node) { |
2724 // TODO(ngeoffray): Implement this. | 2705 // TODO(ngeoffray): Implement this. |
2725 unimplemented(node, 'modifiers'); | 2706 unimplemented(node, 'modifiers'); |
2726 } | 2707 } |
2727 | 2708 |
2728 visitLiteralList(LiteralList node) { | 2709 visitLiteralList(LiteralList node) { |
2729 NodeList arguments = node.typeArguments; | 2710 NodeList arguments = node.typeArguments; |
2730 DartType typeArgument; | 2711 DartType typeArgument; |
2731 if (arguments != null) { | 2712 if (arguments != null) { |
2732 Link<Node> nodes = arguments.nodes; | 2713 Link<Node> nodes = arguments.nodes; |
2733 if (nodes.isEmpty) { | 2714 if (nodes.isEmpty) { |
| 2715 // The syntax [: <>[] :] is not allowed. |
2734 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error); | 2716 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error); |
2735 } else { | 2717 } else { |
2736 typeArgument = resolveTypeRequired(nodes.head); | 2718 typeArgument = resolveTypeExpression(nodes.head); |
2737 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 2719 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
2738 error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.error); | 2720 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning); |
2739 resolveTypeRequired(nodes.head); | 2721 resolveTypeAnnotation(nodes.head); |
2740 } | 2722 } |
2741 } | 2723 } |
2742 } | 2724 } |
2743 DartType listType; | 2725 DartType listType; |
2744 if (typeArgument != null) { | 2726 if (typeArgument != null) { |
2745 if (node.isConst() && typeArgument.containsTypeVariables) { | 2727 if (node.isConst() && typeArgument.containsTypeVariables) { |
2746 compiler.reportError(arguments.nodes.head, | 2728 compiler.reportError(arguments.nodes.head, |
2747 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 2729 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
2748 } | 2730 } |
2749 listType = new InterfaceType(compiler.listClass, | 2731 listType = new InterfaceType(compiler.listClass, |
2750 new Link<DartType>.fromList([typeArgument])); | 2732 new Link<DartType>.fromList([typeArgument])); |
2751 } else { | 2733 } else { |
2752 compiler.listClass.computeType(compiler); | 2734 compiler.listClass.computeType(compiler); |
2753 listType = compiler.listClass.rawType; | 2735 listType = compiler.listClass.rawType; |
2754 } | 2736 } |
2755 mapping.setType(node, listType); | 2737 mapping.setType(node, listType); |
2756 world.registerInstantiatedType(listType, mapping); | 2738 world.registerInstantiatedType(listType, mapping); |
| 2739 compiler.backend.registerRequiredType(listType, enclosingElement); |
2757 visit(node.elements); | 2740 visit(node.elements); |
2758 } | 2741 } |
2759 | 2742 |
2760 visitConditional(Conditional node) { | 2743 visitConditional(Conditional node) { |
2761 node.visitChildren(this); | 2744 node.visitChildren(this); |
2762 } | 2745 } |
2763 | 2746 |
2764 visitStringInterpolation(StringInterpolation node) { | 2747 visitStringInterpolation(StringInterpolation node) { |
2765 world.registerInstantiatedClass(compiler.stringClass, mapping); | 2748 world.registerInstantiatedClass(compiler.stringClass, mapping); |
2766 compiler.backend.registerStringInterpolation(mapping); | 2749 compiler.backend.registerStringInterpolation(mapping); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2928 } | 2911 } |
2929 } | 2912 } |
2930 | 2913 |
2931 visitLiteralMap(LiteralMap node) { | 2914 visitLiteralMap(LiteralMap node) { |
2932 NodeList arguments = node.typeArguments; | 2915 NodeList arguments = node.typeArguments; |
2933 DartType keyTypeArgument; | 2916 DartType keyTypeArgument; |
2934 DartType valueTypeArgument; | 2917 DartType valueTypeArgument; |
2935 if (arguments != null) { | 2918 if (arguments != null) { |
2936 Link<Node> nodes = arguments.nodes; | 2919 Link<Node> nodes = arguments.nodes; |
2937 if (nodes.isEmpty) { | 2920 if (nodes.isEmpty) { |
| 2921 // The syntax [: <>{} :] is not allowed. |
2938 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error); | 2922 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error); |
2939 } else { | 2923 } else { |
2940 keyTypeArgument = resolveTypeRequired(nodes.head); | 2924 keyTypeArgument = resolveTypeExpression(nodes.head); |
2941 nodes = nodes.tail; | 2925 nodes = nodes.tail; |
2942 if (nodes.isEmpty) { | 2926 if (nodes.isEmpty) { |
2943 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error); | 2927 warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT.warning); |
2944 } else { | 2928 } else { |
2945 valueTypeArgument = resolveTypeRequired(nodes.head); | 2929 valueTypeArgument = resolveTypeExpression(nodes.head); |
2946 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 2930 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
2947 error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.error); | 2931 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning); |
2948 resolveTypeRequired(nodes.head); | 2932 resolveTypeAnnotation(nodes.head); |
2949 } | 2933 } |
2950 } | 2934 } |
2951 } | 2935 } |
2952 } | 2936 } |
2953 DartType mapType; | 2937 DartType mapType; |
2954 if (valueTypeArgument != null) { | 2938 if (valueTypeArgument != null) { |
2955 mapType = new InterfaceType(compiler.mapClass, | 2939 mapType = new InterfaceType(compiler.mapClass, |
2956 new Link<DartType>.fromList([keyTypeArgument, valueTypeArgument])); | 2940 new Link<DartType>.fromList([keyTypeArgument, valueTypeArgument])); |
2957 } else { | 2941 } else { |
2958 compiler.mapClass.computeType(compiler); | 2942 compiler.mapClass.computeType(compiler); |
2959 mapType = compiler.mapClass.rawType; | 2943 mapType = compiler.mapClass.rawType; |
2960 } | 2944 } |
2961 if (node.isConst() && mapType.containsTypeVariables) { | 2945 if (node.isConst() && mapType.containsTypeVariables) { |
2962 compiler.reportError(arguments, | 2946 compiler.reportError(arguments, |
2963 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 2947 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
2964 } | 2948 } |
2965 mapping.setType(node, mapType); | 2949 mapping.setType(node, mapType); |
2966 world.registerInstantiatedClass(compiler.mapClass, mapping); | 2950 world.registerInstantiatedClass(compiler.mapClass, mapping); |
2967 if (node.isConst()) { | 2951 if (node.isConst()) { |
2968 compiler.backend.registerConstantMap(mapping); | 2952 compiler.backend.registerConstantMap(mapping); |
2969 } | 2953 } |
| 2954 compiler.backend.registerRequiredType(mapType, enclosingElement); |
2970 node.visitChildren(this); | 2955 node.visitChildren(this); |
2971 } | 2956 } |
2972 | 2957 |
2973 visitLiteralMapEntry(LiteralMapEntry node) { | 2958 visitLiteralMapEntry(LiteralMapEntry node) { |
2974 node.visitChildren(this); | 2959 node.visitChildren(this); |
2975 } | 2960 } |
2976 | 2961 |
2977 visitNamedArgument(NamedArgument node) { | 2962 visitNamedArgument(NamedArgument node) { |
2978 visit(node.expression); | 2963 visit(node.expression); |
2979 } | 2964 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3105 } | 3090 } |
3106 TypeAnnotation type = declaration.type; | 3091 TypeAnnotation type = declaration.type; |
3107 if (type != null) { | 3092 if (type != null) { |
3108 error(type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); | 3093 error(type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); |
3109 } | 3094 } |
3110 } | 3095 } |
3111 } | 3096 } |
3112 } | 3097 } |
3113 | 3098 |
3114 Scope blockScope = new BlockScope(scope); | 3099 Scope blockScope = new BlockScope(scope); |
3115 var wasTypeRequired = typeRequired; | |
3116 typeRequired = true; | |
3117 doInCheckContext(() => visitIn(node.type, blockScope)); | 3100 doInCheckContext(() => visitIn(node.type, blockScope)); |
3118 typeRequired = wasTypeRequired; | |
3119 visitIn(node.formals, blockScope); | 3101 visitIn(node.formals, blockScope); |
3120 var oldInCatchBlock = inCatchBlock; | 3102 var oldInCatchBlock = inCatchBlock; |
3121 inCatchBlock = true; | 3103 inCatchBlock = true; |
3122 visitIn(node.block, blockScope); | 3104 visitIn(node.block, blockScope); |
3123 inCatchBlock = oldInCatchBlock; | 3105 inCatchBlock = oldInCatchBlock; |
3124 | 3106 |
3125 if (node.type != null && exceptionDefinition != null) { | 3107 if (node.type != null && exceptionDefinition != null) { |
3126 DartType exceptionType = mapping.getType(node.type); | 3108 DartType exceptionType = mapping.getType(node.type); |
3127 Node exceptionVariable = exceptionDefinition.definitions.nodes.head; | 3109 Node exceptionVariable = exceptionDefinition.definitions.nodes.head; |
3128 VariableElementX exceptionElement = mapping[exceptionVariable]; | 3110 VariableElementX exceptionElement = mapping[exceptionVariable]; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3166 TypeVariable typeNode = nodeLink.head; | 3148 TypeVariable typeNode = nodeLink.head; |
3167 if (nameSet.contains(typeName)) { | 3149 if (nameSet.contains(typeName)) { |
3168 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, | 3150 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, |
3169 {'typeVariableName': typeName}); | 3151 {'typeVariableName': typeName}); |
3170 } | 3152 } |
3171 nameSet.add(typeName); | 3153 nameSet.add(typeName); |
3172 | 3154 |
3173 TypeVariableElement variableElement = typeVariable.element; | 3155 TypeVariableElement variableElement = typeVariable.element; |
3174 if (typeNode.bound != null) { | 3156 if (typeNode.bound != null) { |
3175 DartType boundType = typeResolver.resolveTypeAnnotation( | 3157 DartType boundType = typeResolver.resolveTypeAnnotation( |
3176 this, typeNode.bound, onFailure: dualWarning); | 3158 this, typeNode.bound); |
3177 variableElement.bound = boundType; | 3159 variableElement.bound = boundType; |
3178 | 3160 |
3179 void checkTypeVariableBound() { | 3161 void checkTypeVariableBound() { |
3180 Link<TypeVariableElement> seenTypeVariables = | 3162 Link<TypeVariableElement> seenTypeVariables = |
3181 const Link<TypeVariableElement>(); | 3163 const Link<TypeVariableElement>(); |
3182 seenTypeVariables = seenTypeVariables.prepend(variableElement); | 3164 seenTypeVariables = seenTypeVariables.prepend(variableElement); |
3183 DartType bound = boundType; | 3165 DartType bound = boundType; |
3184 while (bound.element.isTypeVariable()) { | 3166 while (bound.element.isTypeVariable()) { |
3185 TypeVariableElement element = bound.element; | 3167 TypeVariableElement element = bound.element; |
3186 if (seenTypeVariables.contains(element)) { | 3168 if (seenTypeVariables.contains(element)) { |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3438 return mixin; | 3420 return mixin; |
3439 } | 3421 } |
3440 | 3422 |
3441 DartType resolveType(TypeAnnotation node) { | 3423 DartType resolveType(TypeAnnotation node) { |
3442 // TODO(johnniwinther): Report errors/warnings on resolution failures. | 3424 // TODO(johnniwinther): Report errors/warnings on resolution failures. |
3443 return typeResolver.resolveTypeAnnotation(this, node); | 3425 return typeResolver.resolveTypeAnnotation(this, node); |
3444 } | 3426 } |
3445 | 3427 |
3446 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { | 3428 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { |
3447 DartType supertype = typeResolver.resolveTypeAnnotation( | 3429 DartType supertype = typeResolver.resolveTypeAnnotation( |
3448 this, superclass, onFailure: dualError); | 3430 this, superclass, malformedIsError: true); |
3449 if (supertype != null) { | 3431 if (supertype != null) { |
3450 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) { | 3432 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) { |
3451 // Error has already been reported. | 3433 // Error has already been reported. |
3452 return null; | 3434 return null; |
3453 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) { | 3435 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) { |
3454 // TODO(johnniwinther): Handle dynamic. | 3436 // TODO(johnniwinther): Handle dynamic. |
3455 error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED); | 3437 error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED); |
3456 return null; | 3438 return null; |
3457 } else if (isBlackListed(supertype)) { | 3439 } else if (isBlackListed(supertype)) { |
3458 error(superclass, MessageKind.CANNOT_EXTEND, {'type': supertype}); | 3440 error(superclass, MessageKind.CANNOT_EXTEND, {'type': supertype}); |
3459 return null; | 3441 return null; |
3460 } | 3442 } |
3461 } | 3443 } |
3462 return supertype; | 3444 return supertype; |
3463 } | 3445 } |
3464 | 3446 |
3465 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { | 3447 Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) { |
3466 Link<DartType> result = const Link<DartType>(); | 3448 Link<DartType> result = const Link<DartType>(); |
3467 if (interfaces == null) return result; | 3449 if (interfaces == null) return result; |
3468 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { | 3450 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { |
3469 DartType interfaceType = typeResolver.resolveTypeAnnotation( | 3451 DartType interfaceType = typeResolver.resolveTypeAnnotation( |
3470 this, link.head, onFailure: dualError); | 3452 this, link.head, malformedIsError: true); |
3471 if (interfaceType != null) { | 3453 if (interfaceType != null) { |
3472 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) { | 3454 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) { |
3473 // Error has already been reported. | 3455 // Error has already been reported. |
3474 } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) { | 3456 } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) { |
3475 // TODO(johnniwinther): Handle dynamic. | 3457 // TODO(johnniwinther): Handle dynamic. |
3476 TypeAnnotation typeAnnotation = link.head; | 3458 TypeAnnotation typeAnnotation = link.head; |
3477 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); | 3459 error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); |
3478 } else { | 3460 } else { |
3479 if (interfaceType == element.supertype) { | 3461 if (interfaceType == element.supertype) { |
3480 compiler.reportError( | 3462 compiler.reportError( |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3576 supertypes = supertypes.tail; | 3558 supertypes = supertypes.tail; |
3577 } | 3559 } |
3578 } | 3560 } |
3579 | 3561 |
3580 isBlackListed(DartType type) { | 3562 isBlackListed(DartType type) { |
3581 LibraryElement lib = element.getLibrary(); | 3563 LibraryElement lib = element.getLibrary(); |
3582 return | 3564 return |
3583 !identical(lib, compiler.coreLibrary) && | 3565 !identical(lib, compiler.coreLibrary) && |
3584 !identical(lib, compiler.jsHelperLibrary) && | 3566 !identical(lib, compiler.jsHelperLibrary) && |
3585 !identical(lib, compiler.interceptorsLibrary) && | 3567 !identical(lib, compiler.interceptorsLibrary) && |
3586 (identical(type.element, compiler.dynamicClass) || | 3568 (identical(type, compiler.types.dynamicType) || |
3587 identical(type.element, compiler.boolClass) || | 3569 identical(type.element, compiler.boolClass) || |
3588 identical(type.element, compiler.numClass) || | 3570 identical(type.element, compiler.numClass) || |
3589 identical(type.element, compiler.intClass) || | 3571 identical(type.element, compiler.intClass) || |
3590 identical(type.element, compiler.doubleClass) || | 3572 identical(type.element, compiler.doubleClass) || |
3591 identical(type.element, compiler.stringClass) || | 3573 identical(type.element, compiler.stringClass) || |
3592 identical(type.element, compiler.nullClass) || | 3574 identical(type.element, compiler.nullClass) || |
3593 identical(type.element, compiler.functionClass)); | 3575 identical(type.element, compiler.functionClass)); |
3594 } | 3576 } |
3595 } | 3577 } |
3596 | 3578 |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4020 // Find the unnamed constructor if the reference resolved to a | 4002 // Find the unnamed constructor if the reference resolved to a |
4021 // class. | 4003 // class. |
4022 if (!Elements.isUnresolved(e) && e.isClass()) { | 4004 if (!Elements.isUnresolved(e) && e.isClass()) { |
4023 ClassElement cls = e; | 4005 ClassElement cls = e; |
4024 cls.ensureResolved(compiler); | 4006 cls.ensureResolved(compiler); |
4025 // The unnamed constructor may not exist, so [e] may become unresolved. | 4007 // The unnamed constructor may not exist, so [e] may become unresolved. |
4026 e = lookupConstructor(cls, diagnosticNode, const SourceString('')); | 4008 e = lookupConstructor(cls, diagnosticNode, const SourceString('')); |
4027 } | 4009 } |
4028 if (type == null) { | 4010 if (type == null) { |
4029 if (Elements.isUnresolved(e)) { | 4011 if (Elements.isUnresolved(e)) { |
4030 type = compiler.dynamicClass.computeType(compiler); | 4012 type = compiler.types.dynamicType; |
4031 } else { | 4013 } else { |
4032 type = e.getEnclosingClass().computeType(compiler).asRaw(); | 4014 type = e.getEnclosingClass().computeType(compiler).asRaw(); |
4033 } | 4015 } |
4034 } | 4016 } |
4035 resolver.mapping.setType(expression, type); | 4017 resolver.mapping.setType(expression, type); |
4036 return e; | 4018 return e; |
4037 } | 4019 } |
4038 | 4020 |
4039 visitTypeAnnotation(TypeAnnotation node) { | 4021 visitTypeAnnotation(TypeAnnotation node) { |
4040 assert(invariant(node, type == null)); | 4022 assert(invariant(node, type == null)); |
4041 type = resolver.resolveTypeRequired(node); | 4023 type = resolver.resolveTypeExpression(node); |
| 4024 compiler.backend.registerRequiredType(type, resolver.enclosingElement); |
4042 return resolver.mapping[node]; | 4025 return resolver.mapping[node]; |
4043 } | 4026 } |
4044 | 4027 |
4045 visitSend(Send node) { | 4028 visitSend(Send node) { |
4046 Element e = visit(node.receiver); | 4029 Element e = visit(node.receiver); |
4047 if (Elements.isUnresolved(e)) return e; | 4030 if (Elements.isUnresolved(e)) return e; |
4048 Identifier name = node.selector.asIdentifier(); | 4031 Identifier name = node.selector.asIdentifier(); |
4049 if (name == null) internalError(node.selector, 'unexpected node'); | 4032 if (name == null) internalError(node.selector, 'unexpected node'); |
4050 | 4033 |
4051 if (identical(e.kind, ElementKind.CLASS)) { | 4034 if (identical(e.kind, ElementKind.CLASS)) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4093 return e; | 4076 return e; |
4094 } | 4077 } |
4095 | 4078 |
4096 /// Assumed to be called by [resolveRedirectingFactory]. | 4079 /// Assumed to be called by [resolveRedirectingFactory]. |
4097 Element visitReturn(Return node) { | 4080 Element visitReturn(Return node) { |
4098 Node expression = node.expression; | 4081 Node expression = node.expression; |
4099 return finishConstructorReference(visit(expression), | 4082 return finishConstructorReference(visit(expression), |
4100 expression, expression); | 4083 expression, expression); |
4101 } | 4084 } |
4102 } | 4085 } |
OLD | NEW |