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

Unified Diff: lib/src/checker/checker.dart

Issue 1184843002: fixes #192, encode dynamic info in checker (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 6 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
« no previous file with comments | « no previous file | lib/src/codegen/js_codegen.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/checker/checker.dart
diff --git a/lib/src/checker/checker.dart b/lib/src/checker/checker.dart
index 3c44e81204eee129dcaa8d7bce8b9a05bfb72128..9c0c279b9861cdc423a9d2e09628a17d9a0a5c8f 100644
--- a/lib/src/checker/checker.dart
+++ b/lib/src/checker/checker.dart
@@ -545,15 +545,35 @@ class CodeChecker extends RecursiveAstVisitor {
if (_rules.isDynamicCall(f)) {
// If f is Function and this is a method invocation, we should have
// gotten an analyzer error, so no need to issue another error.
- _recordDynamicInvoke(node);
+ _recordDynamicInvoke(node, f);
} else {
checkArgumentList(list, _rules.getTypeAsCaller(f));
}
}
@override
- void visitMethodInvocation(MethodInvocation node) {
- checkFunctionApplication(node, node.methodName, node.argumentList);
+ visitMethodInvocation(MethodInvocation node) {
+ var target = node.realTarget;
+ if (_rules.isDynamicTarget(target)) {
+ _recordDynamicInvoke(node, target);
+
+ // Mark the tear-off as being dynamic, too. This lets us distinguish
+ // cases like:
+ //
+ // dynamic d;
+ // d.someMethod(...); // the whole method call must be a dynamic send.
+ //
+ // ... from case like:
+ //
+ // SomeType s;
+ // s.someDynamicField(...); // static get, followed by dynamic call.
+ //
+ // The first case is handled here, the second case is handled below when
+ // we call [checkFunctionApplication].
+ DynamicInvoke.set(node.methodName, true);
+ } else {
+ checkFunctionApplication(node, node.methodName, node.argumentList);
+ }
node.visitChildren(this);
}
@@ -622,8 +642,9 @@ class CodeChecker extends RecursiveAstVisitor {
@override
void visitPropertyAccess(PropertyAccess node) {
- if (node.staticType.isDynamic && _rules.isDynamicTarget(node.realTarget)) {
- _recordDynamicInvoke(node);
+ var target = node.realTarget;
+ if (_rules.isDynamicTarget(target)) {
+ _recordDynamicInvoke(node, target);
}
node.visitChildren(this);
}
@@ -632,7 +653,7 @@ class CodeChecker extends RecursiveAstVisitor {
void visitPrefixedIdentifier(PrefixedIdentifier node) {
final target = node.prefix;
if (_rules.isDynamicTarget(target)) {
- _recordDynamicInvoke(node);
+ _recordDynamicInvoke(node, target);
}
node.visitChildren(this);
}
@@ -774,7 +795,7 @@ class CodeChecker extends RecursiveAstVisitor {
op.type == TokenType.PLUS_PLUS ||
op.type == TokenType.MINUS_MINUS) {
if (_rules.isDynamicTarget(node.operand)) {
- _recordDynamicInvoke(node);
+ _recordDynamicInvoke(node, node.operand);
}
// For ++ and --, even if it is not dynamic, we still need to check
// that the user defined method accepts an `int` as the RHS.
@@ -790,7 +811,7 @@ class CodeChecker extends RecursiveAstVisitor {
// Dynamic invocation
// TODO(vsm): Move this logic to the resolver?
if (op.type != TokenType.EQ_EQ && op.type != TokenType.BANG_EQ) {
- _recordDynamicInvoke(node);
+ _recordDynamicInvoke(node, node.leftOperand);
}
} else {
var element = node.staticElement;
@@ -831,8 +852,9 @@ class CodeChecker extends RecursiveAstVisitor {
@override
void visitIndexExpression(IndexExpression node) {
- if (_rules.isDynamicTarget(node.target)) {
- _recordDynamicInvoke(node);
+ var target = node.realTarget;
+ if (_rules.isDynamicTarget(target)) {
+ _recordDynamicInvoke(node, target);
} else {
var element = node.staticElement;
if (element is MethodElement) {
@@ -897,7 +919,7 @@ class CodeChecker extends RecursiveAstVisitor {
var methodElement = expr.staticElement;
if (methodElement == null) {
// Dynamic invocation
- _recordDynamicInvoke(expr);
+ _recordDynamicInvoke(expr, expr.leftHandSide);
} else {
// Sanity check the operator
assert(methodElement.isOperator);
@@ -941,8 +963,13 @@ class CodeChecker extends RecursiveAstVisitor {
}
}
- void _recordDynamicInvoke(AstNode node) {
- _reporter.log(new DynamicInvoke(_rules, node));
+ void _recordDynamicInvoke(AstNode node, AstNode target) {
+ var dinvoke = new DynamicInvoke(_rules, node);
+ _reporter.log(dinvoke);
+ // TODO(jmesserly): we may eventually want to record if the whole operation
+ // (node) was dynamic, rather than the target, but this is an easier fit
+ // with what we used to do.
+ DynamicInvoke.set(target, true);
}
void _recordMessage(StaticInfo info) {
« no previous file with comments | « no previous file | lib/src/codegen/js_codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698