Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(499)

Unified Diff: lib/compiler/implementation/ssa/builder.dart

Issue 10920089: Generate a warning and a runtime error for calls to nonexistent static calls, getters and setters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/compiler/implementation/ssa/builder.dart
diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart
index b5d0b128082b5e8944a8cda3db67fb12e656ea36..e1e88de98e95886cd1fb0e7dfd393b508ee9c04e 100644
--- a/lib/compiler/implementation/ssa/builder.dart
+++ b/lib/compiler/implementation/ssa/builder.dart
@@ -1964,6 +1964,14 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
return pop();
}
+ String getTargetName(ErroneousElement error, [String prefix]) {
+ String targetName = error.errorMessage.arguments[0].toString();
+ if (prefix != null) {
+ return prefix.concat(targetName);
+ }
+ return targetName;
+ }
+
void generateInstanceGetterWithCompiledReceiver(Send send,
HInstruction receiver) {
assert(Elements.isInstanceSend(send, elements));
@@ -2008,6 +2016,11 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
push(new HStatic(element));
// TODO(ahe): This should be registered in codegen.
compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
+ } else if (element != null && Element.isInvalid(element)) {
+ // An erroneous element indicates an unresolved static getter.
+ generateThrowNoSuchMethod(send,
+ getTargetName(element, 'get '),
+ const EmptyLink<Node>());
} else {
stack.add(localsHandler.readLocal(element));
}
@@ -2048,6 +2061,11 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
} else if (element === null || Elements.isInstanceField(element)) {
HInstruction receiver = generateInstanceSendReceiver(send);
generateInstanceSetterWithCompiledReceiver(send, receiver, value);
+ } else if (element != null && Element.isInvalid(element)) {
+ // An erroneous element indicates an unresolved static setter.
+ generateThrowNoSuchMethod(send,
+ getTargetName(element, 'set '),
+ send.arguments);
} else {
stack.add(value);
// If the value does not already have a name, give it here.
@@ -2608,6 +2626,10 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
visitStaticSend(Send node) {
Selector selector = elements.getSelector(node);
Element element = elements[node];
+ if (element.isErroneous()) {
+ generateThrowNoSuchMethod(node, getTargetName(element), node.arguments);
+ return;
+ }
if (element === compiler.assertMethod && !compiler.enableUserAssertions) {
stack.add(graph.addConstantNull());
return;
@@ -2663,28 +2685,39 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
pushInvokeHelper1(helper, errorMessage);
}
+ void generateThrowNoSuchMethod(Node diagnosticNode,
+ String methodName,
+ [Link<Node> argumentNodes,
+ List<HInstruction> argumentValues]) {
+ Element helper =
+ compiler.findHelper(const SourceString('throwNoSuchMethod'));
+ HInstruction receiver =
+ graph.addConstantString(new DartString.empty(), diagnosticNode);
+ DartString dartString = new DartString.literal(methodName);
+ HInstruction name = graph.addConstantString(dartString, diagnosticNode);
+ if (argumentValues == null) {
+ argumentValues = <HInstruction>[];
kasperl 2012/09/05 11:16:01 Could this be done using argumentNodes.map?
karlklose 2012/09/05 14:53:42 No, this is a Link, which does not have map.
+ argumentNodes.forEach((argumentNode) {
+ visit(argumentNode);
+ HInstruction value = pop();
+ argumentValues.add(value);
+ });
+ }
+ HInstruction arguments = new HLiteralList(argumentValues);
+ add(arguments);
+ pushInvokeHelper3(helper, receiver, name, arguments);
+ }
+
visitNewExpression(NewExpression node) {
Element element = elements[node.send];
if (element != null && element.isErroneous()) {
ErroneousElement error = element;
Message message = error.errorMessage;
if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) {
- Element helper =
- compiler.findHelper(const SourceString('throwNoSuchMethod'));
- DartString receiverLiteral = new DartString.literal('');
- HInstruction receiver = graph.addConstantString(receiverLiteral, node);
String constructorName = 'constructor ${message.arguments[0]}';
- DartString nameLiteral = new DartString.literal(constructorName);
- HInstruction name = graph.addConstantString(nameLiteral, node.send);
- List<HInstruction> inputs = <HInstruction>[];
- node.send.arguments.forEach((argumentNode) {
- visit(argumentNode);
- HInstruction value = pop();
- inputs.add(value);
- });
- HInstruction arguments = new HLiteralList(inputs);
- add(arguments);
- pushInvokeHelper3(helper, receiver, name, arguments);
+ generateThrowNoSuchMethod(node.send,
+ getTargetName(error, 'constructor'),
+ node.send.arguments);
} else if (message.kind === MessageKind.CANNOT_RESOLVE) {
generateRuntimeError(node.send, message.message);
} else {
@@ -3054,7 +3087,17 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
VariableDefinitions variableDefinitions = node.declaredIdentifier;
variable = elements[variableDefinitions.definitions.nodes.head];
}
- localsHandler.updateLocal(variable, pop());
+ HInstruction oldVariable = pop();
+ if (variable == null) {
+ // Do nothing.
+ } else if (variable.isErroneous()) {
+ generateThrowNoSuchMethod(node,
+ getTargetName(variable, 'set '),
+ argumentValues: <HInstruction>[oldVariable]);
+ pop();
+ } else {
+ localsHandler.updateLocal(variable, oldVariable);
+ }
visit(node.body);
}

Powered by Google App Engine
This is Rietveld 408576698