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 { |