Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/resolution/members.dart (revision 18614) |
| +++ sdk/lib/_internal/compiler/implementation/resolution/members.dart (working copy) |
| @@ -384,6 +384,14 @@ |
| ResolverVisitor visitor = visitorFor(element); |
| initializerDo(tree, visitor.visit); |
| + if (Elements.isStaticOrTopLevelField(element)) { |
| + if (tree.asSendSet() != null) { |
| + // TODO(ngeoffray): We could do better here by using the |
| + // constant handler to figure out if it's a lazy field or not. |
| + compiler.backend.registerLazyField(); |
| + } |
| + } |
| + |
| // Perform various checks as side effect of "computing" the type. |
| element.computeType(compiler); |
| @@ -1458,6 +1466,7 @@ |
| } |
| } else if (element.isTypeVariable()) { |
| if (enclosingElement.isInStaticMember()) { |
| + compiler.backend.registerThrowRuntimeError(); |
| compiler.reportWarning(node, |
| MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message( |
| {'typeVariableName': node})); |
| @@ -1642,6 +1651,7 @@ |
| element = warnAndCreateErroneousElement(node, node.source, |
| MessageKind.CANNOT_RESOLVE, |
| {'name': node}); |
| + compiler.backend.registerThrowNoSuchMethod(); |
| } |
| } else if (element.isErroneous()) { |
| // Use the erroneous element. |
| @@ -1652,10 +1662,10 @@ |
| {'text': "is not an expression $element"}); |
| } |
| } |
| - if (!Elements.isUnresolved(element) |
| - && element.kind == ElementKind.CLASS) { |
| + if (!Elements.isUnresolved(element) && element.isClass()) { |
| ClassElement classElement = element; |
| classElement.ensureResolved(compiler); |
| + compiler.backend.registerTypeLiteral(); |
| } |
| return useElement(node, element); |
| } |
| @@ -1833,7 +1843,6 @@ |
| } else { |
| name = node.name.asIdentifier().source; |
| } |
| - |
| FunctionElement function = new FunctionElementX.node( |
| name, node, ElementKind.FUNCTION, Modifiers.EMPTY, |
| enclosingElement); |
| @@ -1925,9 +1934,12 @@ |
| target = currentClass.lookupSuperMember(name); |
| // [target] may be null which means invoking noSuchMethod on |
| // super. |
| + if (target == null) { |
| + compiler.backend.registerSuperNoSuchMethod(); |
| + } |
| } else if (Elements.isUnresolved(resolvedReceiver)) { |
| return null; |
| - } else if (identical(resolvedReceiver.kind, ElementKind.CLASS)) { |
| + } else if (resolvedReceiver.isClass()) { |
| ClassElement receiverClass = resolvedReceiver; |
| receiverClass.ensureResolved(compiler); |
| if (node.isOperator) { |
| @@ -1941,6 +1953,7 @@ |
| } |
| target = receiverClass.lookupLocalMember(name); |
| if (target == null) { |
| + compiler.backend.registerThrowNoSuchMethod(); |
| // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
| // try to resolve injected elements if [currentClass] is in the patch |
| // library of [receiverClass]. |
| @@ -1961,6 +1974,7 @@ |
| PrefixElement prefix = resolvedReceiver; |
| target = prefix.lookupLocalMember(name); |
| if (Elements.isUnresolved(target)) { |
| + compiler.backend.registerThrowNoSuchMethod(); |
| return warnAndCreateErroneousElement( |
| node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, |
| {'libraryName': prefix.name, 'memberName': name}); |
| @@ -2071,6 +2085,7 @@ |
| AbstractFieldElement field = target; |
| target = field.getter; |
| if (target == null && !inInstanceContext) { |
| + compiler.backend.registerThrowNoSuchMethod(); |
| target = |
| warnAndCreateErroneousElement(node.selector, field.name, |
| MessageKind.CANNOT_RESOLVE_GETTER); |
| @@ -2080,11 +2095,15 @@ |
| bool resolvedArguments = false; |
| if (node.isOperator) { |
| String operatorString = node.selector.asOperator().source.stringValue; |
| - if (identical(operatorString, 'is') || identical(operatorString, 'as')) { |
| + if (operatorString == 'is' || operatorString == 'as') { |
|
ahe
2013/02/18 12:38:04
This has to be identical.
|
| assert(node.arguments.tail.isEmpty); |
| DartType type = resolveTypeTest(node.arguments.head); |
| if (type != null) { |
| - compiler.enqueuer.resolution.registerIsCheck(type); |
| + if (operatorString == 'as') { |
|
ahe
2013/02/18 12:38:04
Identical.
|
| + compiler.enqueuer.resolution.registerAsCheck(type); |
| + } else { |
| + compiler.enqueuer.resolution.registerIsCheck(type); |
| + } |
| } |
| resolvedArguments = true; |
| } else if (identical(operatorString, '?')) { |
| @@ -2143,6 +2162,7 @@ |
| } |
| void warnArgumentMismatch(Send node, Element target) { |
| + compiler.backend.registerThrowNoSuchMethod(); |
| // TODO(karlklose): we can be more precise about the reason of the |
| // mismatch. |
| warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS, |
| @@ -2165,21 +2185,26 @@ |
| SourceString operatorName = node.assignmentOperator.source; |
| String source = operatorName.stringValue; |
| bool isComplex = !identical(source, '='); |
| - if (!Elements.isUnresolved(target) |
| - && target.kind == ElementKind.ABSTRACT_FIELD) { |
| - AbstractFieldElement field = target; |
| - setter = field.setter; |
| - getter = field.getter; |
| - if (setter == null && !inInstanceContext) { |
| - setter = |
| - warnAndCreateErroneousElement(node.selector, field.name, |
| - MessageKind.CANNOT_RESOLVE_SETTER); |
| + if (!Elements.isUnresolved(target)) { |
| + if (target.isAbstractField()) { |
| + AbstractFieldElement field = target; |
| + setter = field.setter; |
| + getter = field.getter; |
| + if (setter == null && !inInstanceContext) { |
| + setter = |
| + warnAndCreateErroneousElement(node.selector, field.name, |
| + MessageKind.CANNOT_RESOLVE_SETTER); |
| + compiler.backend.registerThrowNoSuchMethod(); |
| + } |
| + if (isComplex && getter == null && !inInstanceContext) { |
| + getter = |
| + warnAndCreateErroneousElement(node.selector, field.name, |
| + MessageKind.CANNOT_RESOLVE_GETTER); |
| + compiler.backend.registerThrowNoSuchMethod(); |
| + } |
| + } else if (target.impliesType()) { |
| + compiler.backend.registerThrowNoSuchMethod(); |
| } |
| - if (isComplex && getter == null && !inInstanceContext) { |
| - getter = |
| - warnAndCreateErroneousElement(node.selector, field.name, |
| - MessageKind.CANNOT_RESOLVE_GETTER); |
| - } |
| } |
| visit(node.argumentsNode); |
| @@ -2330,6 +2355,7 @@ |
| if (!inCatchBlock && node.expression == null) { |
| error(node, MessageKind.THROW_WITHOUT_EXPRESSION); |
| } |
| + compiler.backend.registerThrow(); |
| visit(node.expression); |
| } |
| @@ -2365,11 +2391,10 @@ |
| resolveArguments(node.send.argumentsNode); |
| useElement(node.send, constructor); |
| if (Elements.isUnresolved(constructor)) return constructor; |
| - // TODO(karlklose): handle optional arguments. |
| - if (node.send.argumentCount() != constructor.parameterCount(compiler)) { |
| - // TODO(ngeoffray): resolution error with wrong number of |
| - // parameters. We cannot do this rigth now because of the |
| - // List constructor. |
| + Selector callSelector = mapping.getSelector(node.send); |
| + if (!callSelector.applies(constructor, compiler)) { |
| + warnArgumentMismatch(node.send, constructor); |
|
ahe
2013/02/18 12:38:04
I would prefer if you did this change separately a
|
| + compiler.backend.registerThrowNoSuchMethod(); |
| } |
| // [constructor] might be the implementation element and only declaration |
| // elements may be registered. |
| @@ -2385,6 +2410,9 @@ |
| // [cls] might be the implementation element and only declaration elements |
| // may be registered. |
| world.registerInstantiatedClass(cls.declaration); |
| + if (cls.isAbstract(compiler)) { |
| + compiler.backend.registerAbstractClassInstantiation(); |
| + } |
| // [cls] might be the declaration element and we want to include injected |
| // members. |
| cls.implementation.forEachInstanceField( |
| @@ -2487,6 +2515,7 @@ |
| visitStringInterpolation(StringInterpolation node) { |
| world.registerInstantiatedClass(compiler.stringClass); |
| + compiler.backend.registerStringInterpolation(); |
| node.visitChildren(this); |
| } |
| @@ -2627,6 +2656,9 @@ |
| visitLiteralMap(LiteralMap node) { |
| world.registerInstantiatedClass(compiler.mapClass); |
| + if (node.isConst()) { |
| + compiler.backend.registerConstantMap(); |
| + } |
| node.visitChildren(this); |
| } |
| @@ -2704,6 +2736,9 @@ |
| mapping.remove(label.label); |
| } |
| }); |
| + // TODO(ngeoffray): We should check here instead of the SSA backend if |
| + // there might be an error. |
| + compiler.backend.registerFallThroughError(); |
| } |
| visitSwitchCase(SwitchCase node) { |
| @@ -2727,17 +2762,20 @@ |
| } |
| visitCatchBlock(CatchBlock node) { |
| + compiler.backend.registerCatchStatement(); |
| // Check that if catch part is present, then |
| // it has one or two formal parameters. |
| if (node.formals != null) { |
| if (node.formals.isEmpty) { |
| error(node, MessageKind.EMPTY_CATCH_DECLARATION); |
| } |
| - if (!node.formals.nodes.tail.isEmpty && |
| - !node.formals.nodes.tail.tail.isEmpty) { |
| - for (Node extra in node.formals.nodes.tail.tail) { |
| - error(extra, MessageKind.EXTRA_CATCH_DECLARATION); |
| + if (!node.formals.nodes.tail.isEmpty) { |
| + if (!node.formals.nodes.tail.tail.isEmpty) { |
|
ahe
2013/02/18 12:38:04
Generally, I really like going from && to nested i
|
| + for (Node extra in node.formals.nodes.tail.tail) { |
| + error(extra, MessageKind.EXTRA_CATCH_DECLARATION); |
| + } |
| } |
| + compiler.backend.registerStackTraceInCatch(); |
| } |
| // Check that the formals aren't optional and that they have no |
| @@ -2751,7 +2789,7 @@ |
| if (nodeList != null) { |
| error(nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH); |
| } else { |
| - VariableDefinitions declaration = link.head; |
| + VariableDefinitions declaration = link.head; |
| for (Node modifier in declaration.modifiers.nodes) { |
| error(modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH); |
| } |
| @@ -3516,6 +3554,11 @@ |
| failOrReturnErroneousElement(Element enclosing, Node diagnosticNode, |
| SourceString targetName, MessageKind kind, |
| Map arguments) { |
| + if (kind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
| + compiler.backend.registerThrowNoSuchMethod(); |
| + } else { |
| + compiler.backend.registerThrowRuntimeError(); |
| + } |
| if (inConstContext) { |
| error(diagnosticNode, kind, arguments); |
| } else { |