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 abstract class TreeElements { | 5 abstract class TreeElements { |
6 Element operator[](Node node); | 6 Element operator[](Node node); |
7 Selector getSelector(Send send); | 7 Selector getSelector(Send send); |
8 DartType getType(Node node); | 8 DartType getType(Node node); |
9 bool isParameterChecked(Element element); | 9 bool isParameterChecked(Element element); |
10 } | 10 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 if (constructor.isPatched) { | 107 if (constructor.isPatched) { |
108 checkMatchingPatchSignatures(constructor, constructor.patch); | 108 checkMatchingPatchSignatures(constructor, constructor.patch); |
109 constructor = constructor.patch; | 109 constructor = constructor.patch; |
110 } | 110 } |
111 FunctionExpression node = constructor.parseNode(compiler); | 111 FunctionExpression node = constructor.parseNode(compiler); |
112 | 112 |
113 // A synthetic constructor does not have a node. | 113 // A synthetic constructor does not have a node. |
114 if (node == null) return null; | 114 if (node == null) return null; |
115 if (node.initializers == null) return null; | 115 if (node.initializers == null) return null; |
116 Link<Node> initializers = node.initializers.nodes; | 116 Link<Node> initializers = node.initializers.nodes; |
117 if (!initializers.isEmpty() && | 117 if (!initializers.isEmpty && |
118 Initializers.isConstructorRedirect(initializers.head)) { | 118 Initializers.isConstructorRedirect(initializers.head)) { |
119 final ClassElement classElement = constructor.getEnclosingClass(); | 119 final ClassElement classElement = constructor.getEnclosingClass(); |
120 Selector selector; | 120 Selector selector; |
121 if (isNamedConstructor(initializers.head)) { | 121 if (isNamedConstructor(initializers.head)) { |
122 SourceString constructorName = getConstructorName(initializers.head); | 122 SourceString constructorName = getConstructorName(initializers.head); |
123 selector = new Selector.callConstructor( | 123 selector = new Selector.callConstructor( |
124 constructorName, | 124 constructorName, |
125 resolver.visitor.enclosingElement.getLibrary()); | 125 resolver.visitor.enclosingElement.getLibrary()); |
126 } else { | 126 } else { |
127 selector = new Selector.callDefaultConstructor( | 127 selector = new Selector.callDefaultConstructor( |
(...skipping 16 matching lines...) Expand all Loading... |
144 return; | 144 return; |
145 } | 145 } |
146 seen.add(redirection); | 146 seen.add(redirection); |
147 redirection = resolveConstructorRedirection(resolver, redirection); | 147 redirection = resolveConstructorRedirection(resolver, redirection); |
148 } | 148 } |
149 } | 149 } |
150 | 150 |
151 void checkMatchingPatchParameters(FunctionElement origin, | 151 void checkMatchingPatchParameters(FunctionElement origin, |
152 Link<Element> originParameters, | 152 Link<Element> originParameters, |
153 Link<Element> patchParameters) { | 153 Link<Element> patchParameters) { |
154 while (!originParameters.isEmpty()) { | 154 while (!originParameters.isEmpty) { |
155 Element originParameter = originParameters.head; | 155 Element originParameter = originParameters.head; |
156 Element patchParameter = patchParameters.head; | 156 Element patchParameter = patchParameters.head; |
157 // Hack: Use unparser to test parameter equality. This only works because | 157 // Hack: Use unparser to test parameter equality. This only works because |
158 // we are restricting patch uses and the approach cannot be used | 158 // we are restricting patch uses and the approach cannot be used |
159 // elsewhere. | 159 // elsewhere. |
160 String originParameterText = | 160 String originParameterText = |
161 originParameter.parseNode(compiler).toString(); | 161 originParameter.parseNode(compiler).toString(); |
162 String patchParameterText = | 162 String patchParameterText = |
163 patchParameter.parseNode(compiler).toString(); | 163 patchParameter.parseNode(compiler).toString(); |
164 if (originParameterText != patchParameterText) { | 164 if (originParameterText != patchParameterText) { |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 element.isBeingResolved = false; | 617 element.isBeingResolved = false; |
618 element.isResolved = true; | 618 element.isResolved = true; |
619 }); | 619 }); |
620 }); | 620 }); |
621 } | 621 } |
622 | 622 |
623 FunctionType computeFunctionType(Element element, | 623 FunctionType computeFunctionType(Element element, |
624 FunctionSignature signature) { | 624 FunctionSignature signature) { |
625 LinkBuilder<DartType> parameterTypes = new LinkBuilder<DartType>(); | 625 LinkBuilder<DartType> parameterTypes = new LinkBuilder<DartType>(); |
626 for (Link<Element> link = signature.requiredParameters; | 626 for (Link<Element> link = signature.requiredParameters; |
627 !link.isEmpty(); | 627 !link.isEmpty; |
628 link = link.tail) { | 628 link = link.tail) { |
629 parameterTypes.addLast(link.head.computeType(compiler)); | 629 parameterTypes.addLast(link.head.computeType(compiler)); |
630 // TODO(karlklose): optional parameters. | 630 // TODO(karlklose): optional parameters. |
631 } | 631 } |
632 return new FunctionType(signature.returnType, | 632 return new FunctionType(signature.returnType, |
633 parameterTypes.toLink(), | 633 parameterTypes.toLink(), |
634 element); | 634 element); |
635 } | 635 } |
636 | 636 |
637 void resolveMetadataAnnotation(PartialMetadataAnnotation annotation) { | 637 void resolveMetadataAnnotation(PartialMetadataAnnotation annotation) { |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
832 : MessageKind.NO_MATCHING_CONSTRUCTOR; | 832 : MessageKind.NO_MATCHING_CONSTRUCTOR; |
833 error(diagnosticNode, kind); | 833 error(diagnosticNode, kind); |
834 } | 834 } |
835 } | 835 } |
836 } | 836 } |
837 | 837 |
838 FunctionElement resolveRedirection(FunctionElement constructor, | 838 FunctionElement resolveRedirection(FunctionElement constructor, |
839 FunctionExpression functionNode) { | 839 FunctionExpression functionNode) { |
840 if (functionNode.initializers == null) return null; | 840 if (functionNode.initializers == null) return null; |
841 Link<Node> link = functionNode.initializers.nodes; | 841 Link<Node> link = functionNode.initializers.nodes; |
842 if (!link.isEmpty() && Initializers.isConstructorRedirect(link.head)) { | 842 if (!link.isEmpty && Initializers.isConstructorRedirect(link.head)) { |
843 return resolveSuperOrThisForSend(constructor, functionNode, link.head); | 843 return resolveSuperOrThisForSend(constructor, functionNode, link.head); |
844 } | 844 } |
845 return null; | 845 return null; |
846 } | 846 } |
847 | 847 |
848 /** | 848 /** |
849 * Resolve all initializers of this constructor. In the case of a redirecting | 849 * Resolve all initializers of this constructor. In the case of a redirecting |
850 * constructor, the resolved constructor's function element is returned. | 850 * constructor, the resolved constructor's function element is returned. |
851 */ | 851 */ |
852 FunctionElement resolveInitializers(FunctionElement constructor, | 852 FunctionElement resolveInitializers(FunctionElement constructor, |
(...skipping 10 matching lines...) Expand all Loading... |
863 }); | 863 }); |
864 | 864 |
865 if (functionNode.initializers == null) { | 865 if (functionNode.initializers == null) { |
866 initializers = const Link<Node>(); | 866 initializers = const Link<Node>(); |
867 } else { | 867 } else { |
868 initializers = functionNode.initializers.nodes; | 868 initializers = functionNode.initializers.nodes; |
869 } | 869 } |
870 FunctionElement result; | 870 FunctionElement result; |
871 bool resolvedSuper = false; | 871 bool resolvedSuper = false; |
872 for (Link<Node> link = initializers; | 872 for (Link<Node> link = initializers; |
873 !link.isEmpty(); | 873 !link.isEmpty; |
874 link = link.tail) { | 874 link = link.tail) { |
875 if (link.head.asSendSet() != null) { | 875 if (link.head.asSendSet() != null) { |
876 final SendSet init = link.head.asSendSet(); | 876 final SendSet init = link.head.asSendSet(); |
877 resolveFieldInitializer(constructor, init); | 877 resolveFieldInitializer(constructor, init); |
878 } else if (link.head.asSend() != null) { | 878 } else if (link.head.asSend() != null) { |
879 final Send call = link.head.asSend(); | 879 final Send call = link.head.asSend(); |
880 if (Initializers.isSuperConstructorCall(call)) { | 880 if (Initializers.isSuperConstructorCall(call)) { |
881 if (resolvedSuper) { | 881 if (resolvedSuper) { |
882 error(call, MessageKind.DUPLICATE_SUPER_INITIALIZER); | 882 error(call, MessageKind.DUPLICATE_SUPER_INITIALIZER); |
883 } | 883 } |
884 resolveSuperOrThisForSend(constructor, functionNode, call); | 884 resolveSuperOrThisForSend(constructor, functionNode, call); |
885 resolvedSuper = true; | 885 resolvedSuper = true; |
886 } else if (Initializers.isConstructorRedirect(call)) { | 886 } else if (Initializers.isConstructorRedirect(call)) { |
887 // Check that there is no body (Language specification 7.5.1). | 887 // Check that there is no body (Language specification 7.5.1). |
888 if (functionNode.hasBody()) { | 888 if (functionNode.hasBody()) { |
889 error(functionNode, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY); | 889 error(functionNode, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY); |
890 } | 890 } |
891 // Check that there are no other initializers. | 891 // Check that there are no other initializers. |
892 if (!initializers.tail.isEmpty()) { | 892 if (!initializers.tail.isEmpty) { |
893 error(call, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER); | 893 error(call, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER); |
894 } | 894 } |
895 return resolveSuperOrThisForSend(constructor, functionNode, call); | 895 return resolveSuperOrThisForSend(constructor, functionNode, call); |
896 } else { | 896 } else { |
897 visitor.error(call, MessageKind.CONSTRUCTOR_CALL_EXPECTED); | 897 visitor.error(call, MessageKind.CONSTRUCTOR_CALL_EXPECTED); |
898 return null; | 898 return null; |
899 } | 899 } |
900 } else { | 900 } else { |
901 error(link.head, MessageKind.INVALID_INITIALIZER); | 901 error(link.head, MessageKind.INVALID_INITIALIZER); |
902 } | 902 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
994 StatementScope() | 994 StatementScope() |
995 : labels = const EmptyLabelScope(), | 995 : labels = const EmptyLabelScope(), |
996 breakTargetStack = const Link<TargetElement>(), | 996 breakTargetStack = const Link<TargetElement>(), |
997 continueTargetStack = const Link<TargetElement>(); | 997 continueTargetStack = const Link<TargetElement>(); |
998 | 998 |
999 LabelElement lookupLabel(String label) { | 999 LabelElement lookupLabel(String label) { |
1000 return labels.lookup(label); | 1000 return labels.lookup(label); |
1001 } | 1001 } |
1002 | 1002 |
1003 TargetElement currentBreakTarget() => | 1003 TargetElement currentBreakTarget() => |
1004 breakTargetStack.isEmpty() ? null : breakTargetStack.head; | 1004 breakTargetStack.isEmpty ? null : breakTargetStack.head; |
1005 | 1005 |
1006 TargetElement currentContinueTarget() => | 1006 TargetElement currentContinueTarget() => |
1007 continueTargetStack.isEmpty() ? null : continueTargetStack.head; | 1007 continueTargetStack.isEmpty ? null : continueTargetStack.head; |
1008 | 1008 |
1009 void enterLabelScope(Map<String, LabelElement> elements) { | 1009 void enterLabelScope(Map<String, LabelElement> elements) { |
1010 labels = new LabeledStatementLabelScope(labels, elements); | 1010 labels = new LabeledStatementLabelScope(labels, elements); |
1011 nestingLevel++; | 1011 nestingLevel++; |
1012 } | 1012 } |
1013 | 1013 |
1014 void exitLabelScope() { | 1014 void exitLabelScope() { |
1015 nestingLevel--; | 1015 nestingLevel--; |
1016 labels = labels.outer; | 1016 labels = labels.outer; |
1017 } | 1017 } |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1119 } else { | 1119 } else { |
1120 if (identical(element, compiler.types.voidType.element) || | 1120 if (identical(element, compiler.types.voidType.element) || |
1121 identical(element, compiler.types.dynamicType.element)) { | 1121 identical(element, compiler.types.dynamicType.element)) { |
1122 type = element.computeType(compiler); | 1122 type = element.computeType(compiler); |
1123 } else if (element.isClass()) { | 1123 } else if (element.isClass()) { |
1124 ClassElement cls = element; | 1124 ClassElement cls = element; |
1125 cls.ensureResolved(compiler); | 1125 cls.ensureResolved(compiler); |
1126 Link<DartType> arguments = | 1126 Link<DartType> arguments = |
1127 resolveTypeArguments(node, cls.typeVariables, scope, | 1127 resolveTypeArguments(node, cls.typeVariables, scope, |
1128 onFailure, whenResolved); | 1128 onFailure, whenResolved); |
1129 if (cls.typeVariables.isEmpty() && arguments.isEmpty()) { | 1129 if (cls.typeVariables.isEmpty && arguments.isEmpty) { |
1130 // Use the canonical type if it has no type parameters. | 1130 // Use the canonical type if it has no type parameters. |
1131 type = cls.computeType(compiler); | 1131 type = cls.computeType(compiler); |
1132 } else { | 1132 } else { |
1133 type = new InterfaceType(cls, arguments); | 1133 type = new InterfaceType(cls, arguments); |
1134 } | 1134 } |
1135 } else if (element.isTypedef()) { | 1135 } else if (element.isTypedef()) { |
1136 TypedefElement typdef = element; | 1136 TypedefElement typdef = element; |
1137 // TODO(ahe): Should be [ensureResolved]. | 1137 // TODO(ahe): Should be [ensureResolved]. |
1138 compiler.resolveTypedef(typdef); | 1138 compiler.resolveTypedef(typdef); |
1139 typdef.computeType(compiler); | 1139 typdef.computeType(compiler); |
1140 Link<DartType> arguments = resolveTypeArguments( | 1140 Link<DartType> arguments = resolveTypeArguments( |
1141 node, typdef.typeVariables, | 1141 node, typdef.typeVariables, |
1142 scope, onFailure, whenResolved); | 1142 scope, onFailure, whenResolved); |
1143 if (typdef.typeVariables.isEmpty() && arguments.isEmpty()) { | 1143 if (typdef.typeVariables.isEmpty && arguments.isEmpty) { |
1144 // Return the canonical type if it has no type parameters. | 1144 // Return the canonical type if it has no type parameters. |
1145 type = typdef.computeType(compiler); | 1145 type = typdef.computeType(compiler); |
1146 } else { | 1146 } else { |
1147 type = new TypedefType(typdef, arguments); | 1147 type = new TypedefType(typdef, arguments); |
1148 } | 1148 } |
1149 } else if (element.isTypeVariable()) { | 1149 } else if (element.isTypeVariable()) { |
1150 type = element.computeType(compiler); | 1150 type = element.computeType(compiler); |
1151 } else { | 1151 } else { |
1152 compiler.cancel("unexpected element kind ${element.kind}", | 1152 compiler.cancel("unexpected element kind ${element.kind}", |
1153 node: node); | 1153 node: node); |
1154 } | 1154 } |
1155 } | 1155 } |
1156 whenResolved(node, type); | 1156 whenResolved(node, type); |
1157 return type; | 1157 return type; |
1158 } | 1158 } |
1159 | 1159 |
1160 Link<DartType> resolveTypeArguments(TypeAnnotation node, | 1160 Link<DartType> resolveTypeArguments(TypeAnnotation node, |
1161 Link<DartType> typeVariables, | 1161 Link<DartType> typeVariables, |
1162 Scope scope, onFailure, whenResolved) { | 1162 Scope scope, onFailure, whenResolved) { |
1163 if (node.typeArguments == null) { | 1163 if (node.typeArguments == null) { |
1164 return const Link<DartType>(); | 1164 return const Link<DartType>(); |
1165 } | 1165 } |
1166 var arguments = new LinkBuilder<DartType>(); | 1166 var arguments = new LinkBuilder<DartType>(); |
1167 for (Link<Node> typeArguments = node.typeArguments.nodes; | 1167 for (Link<Node> typeArguments = node.typeArguments.nodes; |
1168 !typeArguments.isEmpty(); | 1168 !typeArguments.isEmpty; |
1169 typeArguments = typeArguments.tail) { | 1169 typeArguments = typeArguments.tail) { |
1170 if (typeVariables.isEmpty()) { | 1170 if (typeVariables.isEmpty) { |
1171 onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 1171 onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
1172 } | 1172 } |
1173 DartType argType = resolveTypeAnnotationInContext(scope, | 1173 DartType argType = resolveTypeAnnotationInContext(scope, |
1174 typeArguments.head, | 1174 typeArguments.head, |
1175 onFailure, | 1175 onFailure, |
1176 whenResolved); | 1176 whenResolved); |
1177 arguments.addLast(argType); | 1177 arguments.addLast(argType); |
1178 if (!typeVariables.isEmpty()) { | 1178 if (!typeVariables.isEmpty) { |
1179 typeVariables = typeVariables.tail; | 1179 typeVariables = typeVariables.tail; |
1180 } | 1180 } |
1181 } | 1181 } |
1182 if (!typeVariables.isEmpty()) { | 1182 if (!typeVariables.isEmpty) { |
1183 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); | 1183 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); |
1184 } | 1184 } |
1185 return arguments.toLink(); | 1185 return arguments.toLink(); |
1186 } | 1186 } |
1187 } | 1187 } |
1188 | 1188 |
1189 class ResolverVisitor extends CommonResolverVisitor<Element> { | 1189 class ResolverVisitor extends CommonResolverVisitor<Element> { |
1190 final TreeElementMapping mapping; | 1190 final TreeElementMapping mapping; |
1191 Element enclosingElement; | 1191 Element enclosingElement; |
1192 final TypeResolver typeResolver; | 1192 final TypeResolver typeResolver; |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1583 | 1583 |
1584 if (node.isOperator) { | 1584 if (node.isOperator) { |
1585 SourceString source = node.selector.asOperator().source; | 1585 SourceString source = node.selector.asOperator().source; |
1586 String string = source.stringValue; | 1586 String string = source.stringValue; |
1587 if (identical(string, '!') || identical(string, '&&') || string == '||'
|| | 1587 if (identical(string, '!') || identical(string, '&&') || string == '||'
|| |
1588 identical(string, 'is') || identical(string, 'as') || | 1588 identical(string, 'is') || identical(string, 'as') || |
1589 identical(string, '===') || identical(string, '!==') || | 1589 identical(string, '===') || identical(string, '!==') || |
1590 identical(string, '>>>')) { | 1590 identical(string, '>>>')) { |
1591 return null; | 1591 return null; |
1592 } | 1592 } |
1593 return node.arguments.isEmpty() | 1593 return node.arguments.isEmpty |
1594 ? new Selector.unaryOperator(source) | 1594 ? new Selector.unaryOperator(source) |
1595 : new Selector.binaryOperator(source); | 1595 : new Selector.binaryOperator(source); |
1596 } | 1596 } |
1597 | 1597 |
1598 Identifier identifier = node.selector.asIdentifier(); | 1598 Identifier identifier = node.selector.asIdentifier(); |
1599 if (node.isPropertyAccess) { | 1599 if (node.isPropertyAccess) { |
1600 assert(!isSet); | 1600 assert(!isSet); |
1601 return new Selector.getter(identifier.source, library); | 1601 return new Selector.getter(identifier.source, library); |
1602 } else if (isSet) { | 1602 } else if (isSet) { |
1603 return new Selector.setter(identifier.source, library); | 1603 return new Selector.setter(identifier.source, library); |
1604 } | 1604 } |
1605 | 1605 |
1606 // Compute the arity and the list of named arguments. | 1606 // Compute the arity and the list of named arguments. |
1607 int arity = 0; | 1607 int arity = 0; |
1608 List<SourceString> named = <SourceString>[]; | 1608 List<SourceString> named = <SourceString>[]; |
1609 for (Link<Node> link = node.argumentsNode.nodes; | 1609 for (Link<Node> link = node.argumentsNode.nodes; |
1610 !link.isEmpty(); | 1610 !link.isEmpty; |
1611 link = link.tail) { | 1611 link = link.tail) { |
1612 Expression argument = link.head; | 1612 Expression argument = link.head; |
1613 NamedArgument namedArgument = argument.asNamedArgument(); | 1613 NamedArgument namedArgument = argument.asNamedArgument(); |
1614 if (namedArgument != null) { | 1614 if (namedArgument != null) { |
1615 named.add(namedArgument.name.source); | 1615 named.add(namedArgument.name.source); |
1616 } | 1616 } |
1617 arity++; | 1617 arity++; |
1618 } | 1618 } |
1619 | 1619 |
1620 // If we're invoking a closure, we do not have an identifier. | 1620 // If we're invoking a closure, we do not have an identifier. |
1621 return (identifier == null) | 1621 return (identifier == null) |
1622 ? new Selector.callClosure(arity, named) | 1622 ? new Selector.callClosure(arity, named) |
1623 : new Selector.call(identifier.source, library, arity, named); | 1623 : new Selector.call(identifier.source, library, arity, named); |
1624 } | 1624 } |
1625 | 1625 |
1626 Selector resolveSelector(Send node) { | 1626 Selector resolveSelector(Send node) { |
1627 LibraryElement library = enclosingElement.getLibrary(); | 1627 LibraryElement library = enclosingElement.getLibrary(); |
1628 Selector selector = computeSendSelector(node, library); | 1628 Selector selector = computeSendSelector(node, library); |
1629 if (selector != null) mapping.setSelector(node, selector); | 1629 if (selector != null) mapping.setSelector(node, selector); |
1630 return selector; | 1630 return selector; |
1631 } | 1631 } |
1632 | 1632 |
1633 void resolveArguments(NodeList list) { | 1633 void resolveArguments(NodeList list) { |
1634 if (list == null) return; | 1634 if (list == null) return; |
1635 bool seenNamedArgument = false; | 1635 bool seenNamedArgument = false; |
1636 for (Link<Node> link = list.nodes; !link.isEmpty(); link = link.tail) { | 1636 for (Link<Node> link = list.nodes; !link.isEmpty; link = link.tail) { |
1637 Expression argument = link.head; | 1637 Expression argument = link.head; |
1638 visit(argument); | 1638 visit(argument); |
1639 if (argument.asNamedArgument() != null) { | 1639 if (argument.asNamedArgument() != null) { |
1640 seenNamedArgument = true; | 1640 seenNamedArgument = true; |
1641 } else if (seenNamedArgument) { | 1641 } else if (seenNamedArgument) { |
1642 error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); | 1642 error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); |
1643 } | 1643 } |
1644 } | 1644 } |
1645 } | 1645 } |
1646 | 1646 |
1647 visitSend(Send node) { | 1647 visitSend(Send node) { |
1648 Element target = resolveSend(node); | 1648 Element target = resolveSend(node); |
1649 if (!Elements.isUnresolved(target) | 1649 if (!Elements.isUnresolved(target) |
1650 && target.kind == ElementKind.ABSTRACT_FIELD) { | 1650 && target.kind == ElementKind.ABSTRACT_FIELD) { |
1651 AbstractFieldElement field = target; | 1651 AbstractFieldElement field = target; |
1652 target = field.getter; | 1652 target = field.getter; |
1653 if (target == null && !inInstanceContext) { | 1653 if (target == null && !inInstanceContext) { |
1654 target = | 1654 target = |
1655 warnAndCreateErroneousElement(node.selector, field.name, | 1655 warnAndCreateErroneousElement(node.selector, field.name, |
1656 MessageKind.CANNOT_RESOLVE_GETTER, | 1656 MessageKind.CANNOT_RESOLVE_GETTER, |
1657 [node.selector]); | 1657 [node.selector]); |
1658 } | 1658 } |
1659 } | 1659 } |
1660 | 1660 |
1661 bool resolvedArguments = false; | 1661 bool resolvedArguments = false; |
1662 if (node.isOperator) { | 1662 if (node.isOperator) { |
1663 String operatorString = node.selector.asOperator().source.stringValue; | 1663 String operatorString = node.selector.asOperator().source.stringValue; |
1664 if (identical(operatorString, 'is') || identical(operatorString, 'as')) { | 1664 if (identical(operatorString, 'is') || identical(operatorString, 'as')) { |
1665 assert(node.arguments.tail.isEmpty()); | 1665 assert(node.arguments.tail.isEmpty); |
1666 DartType type = resolveTypeTest(node.arguments.head); | 1666 DartType type = resolveTypeTest(node.arguments.head); |
1667 if (type != null) { | 1667 if (type != null) { |
1668 compiler.enqueuer.resolution.registerIsCheck(type); | 1668 compiler.enqueuer.resolution.registerIsCheck(type); |
1669 } | 1669 } |
1670 resolvedArguments = true; | 1670 resolvedArguments = true; |
1671 } else if (identical(operatorString, '?')) { | 1671 } else if (identical(operatorString, '?')) { |
1672 Element parameter = mapping[node.receiver]; | 1672 Element parameter = mapping[node.receiver]; |
1673 if (parameter == null | 1673 if (parameter == null |
1674 || !identical(parameter.kind, ElementKind.PARAMETER)) { | 1674 || !identical(parameter.kind, ElementKind.PARAMETER)) { |
1675 error(node.receiver, MessageKind.PARAMETER_NAME_EXPECTED); | 1675 error(node.receiver, MessageKind.PARAMETER_NAME_EXPECTED); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1815 } | 1815 } |
1816 | 1816 |
1817 visitLiteralNull(LiteralNull node) { | 1817 visitLiteralNull(LiteralNull node) { |
1818 } | 1818 } |
1819 | 1819 |
1820 visitStringJuxtaposition(StringJuxtaposition node) { | 1820 visitStringJuxtaposition(StringJuxtaposition node) { |
1821 node.visitChildren(this); | 1821 node.visitChildren(this); |
1822 } | 1822 } |
1823 | 1823 |
1824 visitNodeList(NodeList node) { | 1824 visitNodeList(NodeList node) { |
1825 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { | 1825 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
1826 visit(link.head); | 1826 visit(link.head); |
1827 } | 1827 } |
1828 } | 1828 } |
1829 | 1829 |
1830 visitOperator(Operator node) { | 1830 visitOperator(Operator node) { |
1831 unimplemented(node, 'operator'); | 1831 unimplemented(node, 'operator'); |
1832 } | 1832 } |
1833 | 1833 |
1834 visitReturn(Return node) { | 1834 visitReturn(Return node) { |
1835 if (node.isRedirectingFactoryBody) { | 1835 if (node.isRedirectingFactoryBody) { |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1984 | 1984 |
1985 visitModifiers(Modifiers node) { | 1985 visitModifiers(Modifiers node) { |
1986 // TODO(ngeoffray): Implement this. | 1986 // TODO(ngeoffray): Implement this. |
1987 unimplemented(node, 'modifiers'); | 1987 unimplemented(node, 'modifiers'); |
1988 } | 1988 } |
1989 | 1989 |
1990 visitLiteralList(LiteralList node) { | 1990 visitLiteralList(LiteralList node) { |
1991 NodeList arguments = node.typeArguments; | 1991 NodeList arguments = node.typeArguments; |
1992 if (arguments != null) { | 1992 if (arguments != null) { |
1993 Link<Node> nodes = arguments.nodes; | 1993 Link<Node> nodes = arguments.nodes; |
1994 if (nodes.isEmpty()) { | 1994 if (nodes.isEmpty) { |
1995 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT, []); | 1995 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT, []); |
1996 } else { | 1996 } else { |
1997 resolveTypeRequired(nodes.head); | 1997 resolveTypeRequired(nodes.head); |
1998 for (nodes = nodes.tail; !nodes.isEmpty(); nodes = nodes.tail) { | 1998 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
1999 error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT, []); | 1999 error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT, []); |
2000 resolveTypeRequired(nodes.head); | 2000 resolveTypeRequired(nodes.head); |
2001 } | 2001 } |
2002 } | 2002 } |
2003 } | 2003 } |
2004 visit(node.elements); | 2004 visit(node.elements); |
2005 } | 2005 } |
2006 | 2006 |
2007 visitConditional(Conditional node) { | 2007 visitConditional(Conditional node) { |
2008 node.visitChildren(this); | 2008 node.visitChildren(this); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2094 visit(node.expression); | 2094 visit(node.expression); |
2095 Scope blockScope = new BlockScope(scope); | 2095 Scope blockScope = new BlockScope(scope); |
2096 Node declaration = node.declaredIdentifier; | 2096 Node declaration = node.declaredIdentifier; |
2097 visitIn(declaration, blockScope); | 2097 visitIn(declaration, blockScope); |
2098 visitLoopBodyIn(node, node.body, blockScope); | 2098 visitLoopBodyIn(node, node.body, blockScope); |
2099 | 2099 |
2100 // TODO(lrn): Also allow a single identifier. | 2100 // TODO(lrn): Also allow a single identifier. |
2101 if ((declaration is !Send || declaration.asSend().selector is !Identifier | 2101 if ((declaration is !Send || declaration.asSend().selector is !Identifier |
2102 || declaration.asSend().receiver != null) | 2102 || declaration.asSend().receiver != null) |
2103 && (declaration is !VariableDefinitions || | 2103 && (declaration is !VariableDefinitions || |
2104 !declaration.asVariableDefinitions().definitions.nodes.tail.isEmpty())) | 2104 !declaration.asVariableDefinitions().definitions.nodes.tail.isEmpty)) |
2105 { | 2105 { |
2106 // The variable declaration is either not an identifier, not a | 2106 // The variable declaration is either not an identifier, not a |
2107 // declaration, or it's declaring more than one variable. | 2107 // declaration, or it's declaring more than one variable. |
2108 error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN, []); | 2108 error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN, []); |
2109 } | 2109 } |
2110 } | 2110 } |
2111 | 2111 |
2112 visitLabel(Label node) { | 2112 visitLabel(Label node) { |
2113 // Labels are handled by their containing statements/cases. | 2113 // Labels are handled by their containing statements/cases. |
2114 } | 2114 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2151 visitNamedArgument(NamedArgument node) { | 2151 visitNamedArgument(NamedArgument node) { |
2152 visit(node.expression); | 2152 visit(node.expression); |
2153 } | 2153 } |
2154 | 2154 |
2155 visitSwitchStatement(SwitchStatement node) { | 2155 visitSwitchStatement(SwitchStatement node) { |
2156 node.expression.accept(this); | 2156 node.expression.accept(this); |
2157 | 2157 |
2158 TargetElement breakElement = getOrCreateTargetElement(node); | 2158 TargetElement breakElement = getOrCreateTargetElement(node); |
2159 Map<String, LabelElement> continueLabels = <String, LabelElement>{}; | 2159 Map<String, LabelElement> continueLabels = <String, LabelElement>{}; |
2160 Link<Node> cases = node.cases.nodes; | 2160 Link<Node> cases = node.cases.nodes; |
2161 while (!cases.isEmpty()) { | 2161 while (!cases.isEmpty) { |
2162 SwitchCase switchCase = cases.head; | 2162 SwitchCase switchCase = cases.head; |
2163 for (Node labelOrCase in switchCase.labelsAndCases) { | 2163 for (Node labelOrCase in switchCase.labelsAndCases) { |
2164 if (labelOrCase is! Label) continue; | 2164 if (labelOrCase is! Label) continue; |
2165 Label label = labelOrCase; | 2165 Label label = labelOrCase; |
2166 String labelName = label.slowToString(); | 2166 String labelName = label.slowToString(); |
2167 | 2167 |
2168 LabelElement existingElement = continueLabels[labelName]; | 2168 LabelElement existingElement = continueLabels[labelName]; |
2169 if (existingElement != null) { | 2169 if (existingElement != null) { |
2170 // It's an error if the same label occurs twice in the same switch. | 2170 // It's an error if the same label occurs twice in the same switch. |
2171 warning(label, MessageKind.DUPLICATE_LABEL, [labelName]); | 2171 warning(label, MessageKind.DUPLICATE_LABEL, [labelName]); |
(...skipping 15 matching lines...) Expand all Loading... |
2187 mapping[switchCase] = targetElement; | 2187 mapping[switchCase] = targetElement; |
2188 | 2188 |
2189 LabelElement labelElement = | 2189 LabelElement labelElement = |
2190 new LabelElement(label, labelName, | 2190 new LabelElement(label, labelName, |
2191 targetElement, enclosingElement); | 2191 targetElement, enclosingElement); |
2192 mapping[label] = labelElement; | 2192 mapping[label] = labelElement; |
2193 continueLabels[labelName] = labelElement; | 2193 continueLabels[labelName] = labelElement; |
2194 } | 2194 } |
2195 cases = cases.tail; | 2195 cases = cases.tail; |
2196 // Test that only the last case, if any, is a default case. | 2196 // Test that only the last case, if any, is a default case. |
2197 if (switchCase.defaultKeyword != null && !cases.isEmpty()) { | 2197 if (switchCase.defaultKeyword != null && !cases.isEmpty) { |
2198 error(switchCase, MessageKind.INVALID_CASE_DEFAULT); | 2198 error(switchCase, MessageKind.INVALID_CASE_DEFAULT); |
2199 } | 2199 } |
2200 } | 2200 } |
2201 | 2201 |
2202 statementScope.enterSwitch(breakElement, continueLabels); | 2202 statementScope.enterSwitch(breakElement, continueLabels); |
2203 node.cases.accept(this); | 2203 node.cases.accept(this); |
2204 statementScope.exitSwitch(); | 2204 statementScope.exitSwitch(); |
2205 | 2205 |
2206 // Clean-up unused labels. | 2206 // Clean-up unused labels. |
2207 continueLabels.forEach((String key, LabelElement label) { | 2207 continueLabels.forEach((String key, LabelElement label) { |
(...skipping 10 matching lines...) Expand all Loading... |
2218 node.labelsAndCases.accept(this); | 2218 node.labelsAndCases.accept(this); |
2219 visitIn(node.statements, new BlockScope(scope)); | 2219 visitIn(node.statements, new BlockScope(scope)); |
2220 } | 2220 } |
2221 | 2221 |
2222 visitCaseMatch(CaseMatch node) { | 2222 visitCaseMatch(CaseMatch node) { |
2223 visit(node.expression); | 2223 visit(node.expression); |
2224 } | 2224 } |
2225 | 2225 |
2226 visitTryStatement(TryStatement node) { | 2226 visitTryStatement(TryStatement node) { |
2227 visit(node.tryBlock); | 2227 visit(node.tryBlock); |
2228 if (node.catchBlocks.isEmpty() && node.finallyBlock == null) { | 2228 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { |
2229 // TODO(ngeoffray): The precise location is | 2229 // TODO(ngeoffray): The precise location is |
2230 // node.getEndtoken.next. Adjust when issue #1581 is fixed. | 2230 // node.getEndtoken.next. Adjust when issue #1581 is fixed. |
2231 error(node, MessageKind.NO_CATCH_NOR_FINALLY); | 2231 error(node, MessageKind.NO_CATCH_NOR_FINALLY); |
2232 } | 2232 } |
2233 visit(node.catchBlocks); | 2233 visit(node.catchBlocks); |
2234 visit(node.finallyBlock); | 2234 visit(node.finallyBlock); |
2235 } | 2235 } |
2236 | 2236 |
2237 visitCatchBlock(CatchBlock node) { | 2237 visitCatchBlock(CatchBlock node) { |
2238 // Check that if catch part is present, then | 2238 // Check that if catch part is present, then |
2239 // it has one or two formal parameters. | 2239 // it has one or two formal parameters. |
2240 if (node.formals != null) { | 2240 if (node.formals != null) { |
2241 if (node.formals.isEmpty()) { | 2241 if (node.formals.isEmpty) { |
2242 error(node, MessageKind.EMPTY_CATCH_DECLARATION); | 2242 error(node, MessageKind.EMPTY_CATCH_DECLARATION); |
2243 } | 2243 } |
2244 if (!node.formals.nodes.tail.isEmpty() && | 2244 if (!node.formals.nodes.tail.isEmpty && |
2245 !node.formals.nodes.tail.tail.isEmpty()) { | 2245 !node.formals.nodes.tail.tail.isEmpty) { |
2246 for (Node extra in node.formals.nodes.tail.tail) { | 2246 for (Node extra in node.formals.nodes.tail.tail) { |
2247 error(extra, MessageKind.EXTRA_CATCH_DECLARATION); | 2247 error(extra, MessageKind.EXTRA_CATCH_DECLARATION); |
2248 } | 2248 } |
2249 } | 2249 } |
2250 | 2250 |
2251 // Check that the formals aren't optional and that they have no | 2251 // Check that the formals aren't optional and that they have no |
2252 // modifiers or type. | 2252 // modifiers or type. |
2253 for (Link<Node> link = node.formals.nodes; | 2253 for (Link<Node> link = node.formals.nodes; |
2254 !link.isEmpty(); | 2254 !link.isEmpty; |
2255 link = link.tail) { | 2255 link = link.tail) { |
2256 // If the formal parameter is a node list, it means that it is a | 2256 // If the formal parameter is a node list, it means that it is a |
2257 // sequence of optional parameters. | 2257 // sequence of optional parameters. |
2258 NodeList nodeList = link.head.asNodeList(); | 2258 NodeList nodeList = link.head.asNodeList(); |
2259 if (nodeList != null) { | 2259 if (nodeList != null) { |
2260 error(nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH); | 2260 error(nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH); |
2261 } else { | 2261 } else { |
2262 VariableDefinitions declaration = link.head; | 2262 VariableDefinitions declaration = link.head; |
2263 for (Node modifier in declaration.modifiers.nodes) { | 2263 for (Node modifier in declaration.modifiers.nodes) { |
2264 error(modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH); | 2264 error(modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2299 typeResolver = new TypeResolver(compiler), | 2299 typeResolver = new TypeResolver(compiler), |
2300 super(compiler); | 2300 super(compiler); |
2301 | 2301 |
2302 void resolveTypeVariableBounds(NodeList node) { | 2302 void resolveTypeVariableBounds(NodeList node) { |
2303 if (node == null) return; | 2303 if (node == null) return; |
2304 | 2304 |
2305 var nameSet = new Set<SourceString>(); | 2305 var nameSet = new Set<SourceString>(); |
2306 // Resolve the bounds of type variables. | 2306 // Resolve the bounds of type variables. |
2307 Link<DartType> typeLink = element.typeVariables; | 2307 Link<DartType> typeLink = element.typeVariables; |
2308 Link<Node> nodeLink = node.nodes; | 2308 Link<Node> nodeLink = node.nodes; |
2309 while (!nodeLink.isEmpty()) { | 2309 while (!nodeLink.isEmpty) { |
2310 TypeVariableType typeVariable = typeLink.head; | 2310 TypeVariableType typeVariable = typeLink.head; |
2311 SourceString typeName = typeVariable.name; | 2311 SourceString typeName = typeVariable.name; |
2312 TypeVariable typeNode = nodeLink.head; | 2312 TypeVariable typeNode = nodeLink.head; |
2313 if (nameSet.contains(typeName)) { | 2313 if (nameSet.contains(typeName)) { |
2314 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]); | 2314 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]); |
2315 } | 2315 } |
2316 nameSet.add(typeName); | 2316 nameSet.add(typeName); |
2317 | 2317 |
2318 TypeVariableElement variableElement = typeVariable.element; | 2318 TypeVariableElement variableElement = typeVariable.element; |
2319 if (typeNode.bound != null) { | 2319 if (typeNode.bound != null) { |
2320 DartType boundType = typeResolver.resolveTypeAnnotation( | 2320 DartType boundType = typeResolver.resolveTypeAnnotation( |
2321 typeNode.bound, inScope: scope, onFailure: warning); | 2321 typeNode.bound, inScope: scope, onFailure: warning); |
2322 if (boundType != null && boundType.element == variableElement) { | 2322 if (boundType != null && boundType.element == variableElement) { |
2323 // TODO(johnniwinther): Check for more general cycles, like | 2323 // TODO(johnniwinther): Check for more general cycles, like |
2324 // [: <A extends B, B extends C, C extends B> :]. | 2324 // [: <A extends B, B extends C, C extends B> :]. |
2325 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, | 2325 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, |
2326 [variableElement.name]); | 2326 [variableElement.name]); |
2327 } else if (boundType != null) { | 2327 } else if (boundType != null) { |
2328 variableElement.bound = boundType; | 2328 variableElement.bound = boundType; |
2329 } else { | 2329 } else { |
2330 // TODO(johnniwinther): Should be an erroneous type. | 2330 // TODO(johnniwinther): Should be an erroneous type. |
2331 variableElement.bound = compiler.objectClass.computeType(compiler); | 2331 variableElement.bound = compiler.objectClass.computeType(compiler); |
2332 } | 2332 } |
2333 } else { | 2333 } else { |
2334 variableElement.bound = compiler.objectClass.computeType(compiler); | 2334 variableElement.bound = compiler.objectClass.computeType(compiler); |
2335 } | 2335 } |
2336 nodeLink = nodeLink.tail; | 2336 nodeLink = nodeLink.tail; |
2337 typeLink = typeLink.tail; | 2337 typeLink = typeLink.tail; |
2338 } | 2338 } |
2339 assert(typeLink.isEmpty()); | 2339 assert(typeLink.isEmpty); |
2340 } | 2340 } |
2341 } | 2341 } |
2342 | 2342 |
2343 class TypedefResolverVisitor extends TypeDefinitionVisitor { | 2343 class TypedefResolverVisitor extends TypeDefinitionVisitor { |
2344 TypedefElement get element => super.element; | 2344 TypedefElement get element => super.element; |
2345 | 2345 |
2346 TypedefResolverVisitor(Compiler compiler, TypedefElement typedefElement) | 2346 TypedefResolverVisitor(Compiler compiler, TypedefElement typedefElement) |
2347 : super(compiler, typedefElement); | 2347 : super(compiler, typedefElement); |
2348 | 2348 |
2349 visitTypedef(Typedef node) { | 2349 visitTypedef(Typedef node) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2407 node: node); | 2407 node: node); |
2408 } else { | 2408 } else { |
2409 objectElement.ensureResolved(compiler); | 2409 objectElement.ensureResolved(compiler); |
2410 } | 2410 } |
2411 // TODO(ahe): This should be objectElement.computeType(...). | 2411 // TODO(ahe): This should be objectElement.computeType(...). |
2412 element.supertype = new InterfaceType(objectElement); | 2412 element.supertype = new InterfaceType(objectElement); |
2413 } | 2413 } |
2414 assert(element.interfaces == null); | 2414 assert(element.interfaces == null); |
2415 Link<DartType> interfaces = const Link<DartType>(); | 2415 Link<DartType> interfaces = const Link<DartType>(); |
2416 for (Link<Node> link = node.interfaces.nodes; | 2416 for (Link<Node> link = node.interfaces.nodes; |
2417 !link.isEmpty(); | 2417 !link.isEmpty; |
2418 link = link.tail) { | 2418 link = link.tail) { |
2419 DartType interfaceType = visit(link.head); | 2419 DartType interfaceType = visit(link.head); |
2420 if (interfaceType != null && interfaceType.element.isExtendable()) { | 2420 if (interfaceType != null && interfaceType.element.isExtendable()) { |
2421 interfaces = interfaces.prepend(interfaceType); | 2421 interfaces = interfaces.prepend(interfaceType); |
2422 if (isBlackListed(interfaceType)) { | 2422 if (isBlackListed(interfaceType)) { |
2423 error(link.head, MessageKind.CANNOT_IMPLEMENT, [interfaceType]); | 2423 error(link.head, MessageKind.CANNOT_IMPLEMENT, [interfaceType]); |
2424 } | 2424 } |
2425 } else { | 2425 } else { |
2426 error(link.head, MessageKind.TYPE_NAME_EXPECTED); | 2426 error(link.head, MessageKind.TYPE_NAME_EXPECTED); |
2427 } | 2427 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2488 // TODO(karlklose): check if type arguments match, if a classelement occurs | 2488 // TODO(karlklose): check if type arguments match, if a classelement occurs |
2489 // more than once in the supertypes. | 2489 // more than once in the supertypes. |
2490 if (cls.allSupertypes != null) return; | 2490 if (cls.allSupertypes != null) return; |
2491 final DartType supertype = cls.supertype; | 2491 final DartType supertype = cls.supertype; |
2492 if (supertype != null) { | 2492 if (supertype != null) { |
2493 ClassElement superElement = supertype.element; | 2493 ClassElement superElement = supertype.element; |
2494 Link<DartType> superSupertypes = superElement.allSupertypes; | 2494 Link<DartType> superSupertypes = superElement.allSupertypes; |
2495 assert(superSupertypes != null); | 2495 assert(superSupertypes != null); |
2496 Link<DartType> supertypes = superSupertypes.prepend(supertype); | 2496 Link<DartType> supertypes = superSupertypes.prepend(supertype); |
2497 for (Link<DartType> interfaces = cls.interfaces; | 2497 for (Link<DartType> interfaces = cls.interfaces; |
2498 !interfaces.isEmpty(); | 2498 !interfaces.isEmpty; |
2499 interfaces = interfaces.tail) { | 2499 interfaces = interfaces.tail) { |
2500 ClassElement element = interfaces.head.element; | 2500 ClassElement element = interfaces.head.element; |
2501 Link<DartType> interfaceSupertypes = element.allSupertypes; | 2501 Link<DartType> interfaceSupertypes = element.allSupertypes; |
2502 assert(interfaceSupertypes != null); | 2502 assert(interfaceSupertypes != null); |
2503 supertypes = supertypes.reversePrependAll(interfaceSupertypes); | 2503 supertypes = supertypes.reversePrependAll(interfaceSupertypes); |
2504 supertypes = supertypes.prepend(interfaces.head); | 2504 supertypes = supertypes.prepend(interfaces.head); |
2505 } | 2505 } |
2506 cls.allSupertypes = supertypes; | 2506 cls.allSupertypes = supertypes; |
2507 } else { | 2507 } else { |
2508 assert(identical(cls, compiler.objectClass)); | 2508 assert(identical(cls, compiler.objectClass)); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2562 | 2562 |
2563 void visitClassNode(ClassNode node) { | 2563 void visitClassNode(ClassNode node) { |
2564 if (node.superclass == null) { | 2564 if (node.superclass == null) { |
2565 if (!identical(classElement, compiler.objectClass)) { | 2565 if (!identical(classElement, compiler.objectClass)) { |
2566 loadSupertype(compiler.objectClass, node); | 2566 loadSupertype(compiler.objectClass, node); |
2567 } | 2567 } |
2568 } else { | 2568 } else { |
2569 node.superclass.accept(this); | 2569 node.superclass.accept(this); |
2570 } | 2570 } |
2571 for (Link<Node> link = node.interfaces.nodes; | 2571 for (Link<Node> link = node.interfaces.nodes; |
2572 !link.isEmpty(); | 2572 !link.isEmpty; |
2573 link = link.tail) { | 2573 link = link.tail) { |
2574 link.head.accept(this); | 2574 link.head.accept(this); |
2575 } | 2575 } |
2576 } | 2576 } |
2577 | 2577 |
2578 void visitTypeAnnotation(TypeAnnotation node) { | 2578 void visitTypeAnnotation(TypeAnnotation node) { |
2579 node.typeName.accept(this); | 2579 node.typeName.accept(this); |
2580 } | 2580 } |
2581 | 2581 |
2582 void visitIdentifier(Identifier node) { | 2582 void visitIdentifier(Identifier node) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2626 VariableListElement variables; | 2626 VariableListElement variables; |
2627 | 2627 |
2628 VariableDefinitionsVisitor(Compiler compiler, | 2628 VariableDefinitionsVisitor(Compiler compiler, |
2629 this.definitions, this.resolver, this.kind) | 2629 this.definitions, this.resolver, this.kind) |
2630 : super(compiler) { | 2630 : super(compiler) { |
2631 variables = new VariableListElement.node( | 2631 variables = new VariableListElement.node( |
2632 definitions, ElementKind.VARIABLE_LIST, resolver.enclosingElement); | 2632 definitions, ElementKind.VARIABLE_LIST, resolver.enclosingElement); |
2633 } | 2633 } |
2634 | 2634 |
2635 SourceString visitSendSet(SendSet node) { | 2635 SourceString visitSendSet(SendSet node) { |
2636 assert(node.arguments.tail.isEmpty()); // Sanity check | 2636 assert(node.arguments.tail.isEmpty); // Sanity check |
2637 resolver.visit(node.arguments.head); | 2637 resolver.visit(node.arguments.head); |
2638 return visit(node.selector); | 2638 return visit(node.selector); |
2639 } | 2639 } |
2640 | 2640 |
2641 SourceString visitIdentifier(Identifier node) => node.source; | 2641 SourceString visitIdentifier(Identifier node) => node.source; |
2642 | 2642 |
2643 visitNodeList(NodeList node) { | 2643 visitNodeList(NodeList node) { |
2644 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { | 2644 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
2645 SourceString name = visit(link.head); | 2645 SourceString name = visit(link.head); |
2646 VariableElement element = | 2646 VariableElement element = |
2647 new VariableElement(name, variables, kind, link.head); | 2647 new VariableElement(name, variables, kind, link.head); |
2648 resolver.defineElement(link.head, element); | 2648 resolver.defineElement(link.head, element); |
2649 } | 2649 } |
2650 } | 2650 } |
2651 } | 2651 } |
2652 | 2652 |
2653 /** | 2653 /** |
2654 * [SignatureResolver] resolves function signatures. | 2654 * [SignatureResolver] resolves function signatures. |
(...skipping 15 matching lines...) Expand all Loading... |
2670 } | 2670 } |
2671 optionalParametersAreNamed = (identical(value, '{')); | 2671 optionalParametersAreNamed = (identical(value, '{')); |
2672 LinkBuilder<Element> elements = analyzeNodes(node.nodes); | 2672 LinkBuilder<Element> elements = analyzeNodes(node.nodes); |
2673 optionalParameterCount = elements.length; | 2673 optionalParameterCount = elements.length; |
2674 optionalParameters = elements.toLink(); | 2674 optionalParameters = elements.toLink(); |
2675 return null; | 2675 return null; |
2676 } | 2676 } |
2677 | 2677 |
2678 Element visitVariableDefinitions(VariableDefinitions node) { | 2678 Element visitVariableDefinitions(VariableDefinitions node) { |
2679 Link<Node> definitions = node.definitions.nodes; | 2679 Link<Node> definitions = node.definitions.nodes; |
2680 if (definitions.isEmpty()) { | 2680 if (definitions.isEmpty) { |
2681 cancel(node, 'internal error: no parameter definition'); | 2681 cancel(node, 'internal error: no parameter definition'); |
2682 return null; | 2682 return null; |
2683 } | 2683 } |
2684 if (!definitions.tail.isEmpty()) { | 2684 if (!definitions.tail.isEmpty) { |
2685 cancel(definitions.tail.head, 'internal error: extra definition'); | 2685 cancel(definitions.tail.head, 'internal error: extra definition'); |
2686 return null; | 2686 return null; |
2687 } | 2687 } |
2688 Node definition = definitions.head; | 2688 Node definition = definitions.head; |
2689 if (definition is NodeList) { | 2689 if (definition is NodeList) { |
2690 cancel(node, 'optional parameters are not implemented'); | 2690 cancel(node, 'optional parameters are not implemented'); |
2691 } | 2691 } |
2692 | 2692 |
2693 if (currentDefinitions != null) { | 2693 if (currentDefinitions != null) { |
2694 cancel(node, 'function type parameters not supported'); | 2694 cancel(node, 'function type parameters not supported'); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2767 } | 2767 } |
2768 | 2768 |
2769 Element visitFunctionExpression(FunctionExpression node) { | 2769 Element visitFunctionExpression(FunctionExpression node) { |
2770 // This is a function typed parameter. | 2770 // This is a function typed parameter. |
2771 // TODO(ahe): Resolve the function type. | 2771 // TODO(ahe): Resolve the function type. |
2772 return visit(node.name); | 2772 return visit(node.name); |
2773 } | 2773 } |
2774 | 2774 |
2775 LinkBuilder<Element> analyzeNodes(Link<Node> link) { | 2775 LinkBuilder<Element> analyzeNodes(Link<Node> link) { |
2776 LinkBuilder<Element> elements = new LinkBuilder<Element>(); | 2776 LinkBuilder<Element> elements = new LinkBuilder<Element>(); |
2777 for (; !link.isEmpty(); link = link.tail) { | 2777 for (; !link.isEmpty; link = link.tail) { |
2778 Element element = link.head.accept(this); | 2778 Element element = link.head.accept(this); |
2779 if (element != null) { | 2779 if (element != null) { |
2780 elements.addLast(element); | 2780 elements.addLast(element); |
2781 } else { | 2781 } else { |
2782 // If parameter is null, the current node should be the last, | 2782 // If parameter is null, the current node should be the last, |
2783 // and a list of optional named parameters. | 2783 // and a list of optional named parameters. |
2784 if (!link.tail.isEmpty() || (link.head is !NodeList)) { | 2784 if (!link.tail.isEmpty || (link.head is !NodeList)) { |
2785 internalError(link.head, "expected optional parameters"); | 2785 internalError(link.head, "expected optional parameters"); |
2786 } | 2786 } |
2787 } | 2787 } |
2788 } | 2788 } |
2789 return elements; | 2789 return elements; |
2790 } | 2790 } |
2791 | 2791 |
2792 /** | 2792 /** |
2793 * Resolves formal parameters and return type to a [FunctionSignature]. | 2793 * Resolves formal parameters and return type to a [FunctionSignature]. |
2794 */ | 2794 */ |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2964 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [name]); | 2964 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [name]); |
2965 } else if (identical(e.kind, ElementKind.TYPE_VARIABLE)) { | 2965 } else if (identical(e.kind, ElementKind.TYPE_VARIABLE)) { |
2966 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, [name]); | 2966 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, [name]); |
2967 } else if (!identical(e.kind, ElementKind.CLASS) | 2967 } else if (!identical(e.kind, ElementKind.CLASS) |
2968 && !identical(e.kind, ElementKind.PREFIX)) { | 2968 && !identical(e.kind, ElementKind.PREFIX)) { |
2969 error(node, MessageKind.NOT_A_TYPE, [name]); | 2969 error(node, MessageKind.NOT_A_TYPE, [name]); |
2970 } | 2970 } |
2971 return e; | 2971 return e; |
2972 } | 2972 } |
2973 } | 2973 } |
OLD | NEW |