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

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

Issue 1055923002: Don't call dinvoke on Object methods (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Refactor dynamic target logic Created 5 years, 8 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/src/checker/resolver.dart
diff --git a/lib/src/checker/resolver.dart b/lib/src/checker/resolver.dart
index 8a35e0d153243515af63a9bc370e5b866547f738..24efb989ff12f9c0d90a7d83cd3b12a4a02d8afa 100644
--- a/lib/src/checker/resolver.dart
+++ b/lib/src/checker/resolver.dart
@@ -664,12 +664,72 @@ class RestrictedStaticTypeAnalyzer extends StaticTypeAnalyzer {
}
}
+ Map<String, DartType> _objectMemberMap = null;
+
+ Map<String, DartType> _getObjectMemberMap() {
+ if (_objectMemberMap == null) {
+ _objectMemberMap = new Map<String, DartType>();
+ var objectType = _typeProvider.objectType;
+ var element = objectType.element;
+ // Only record methods (including getters) with no parameters. As parameters are contravariant wrt
+ // type, using Object's version may be too strict.
+ // Add instance methods.
+ element.methods
+ .where((method) => !method.isStatic && method.parameters.isEmpty)
+ .forEach((method) {
+ _objectMemberMap[method.name] = method.type;
+ });
+ // Add getters.
+ element.accessors
+ .where((member) => !member.isStatic && member.isGetter)
+ .forEach((member) {
+ _objectMemberMap[member.name] = member.type.returnType;
+ });
+ }
+ return _objectMemberMap;
+ }
+
+ List<DartType> _sealedTypes = null;
+
+ bool _isSealed(DartType t) {
+ if (_sealedTypes == null) {
+ // TODO(vsm): Use the analyzer's list - see dartbug.com/23125.
+ _sealedTypes = <DartType>[
+ _typeProvider.nullType,
+ _typeProvider.numType,
+ _typeProvider.intType,
+ _typeProvider.doubleType,
+ _typeProvider.boolType,
+ _typeProvider.stringType
+ ];
+ }
+ return _sealedTypes.contains(t);
+ }
+
@override // to propagate types to identifiers
visitMethodInvocation(MethodInvocation node) {
// TODO(sigmund): follow up with analyzer team - why is this needed?
visitSimpleIdentifier(node.methodName);
super.visitMethodInvocation(node);
+ // Search for Object methods.
+ var objectMap = _getObjectMemberMap();
+ var name = node.methodName.name;
+ if (node.staticType.isDynamic &&
+ objectMap.containsKey(name) &&
+ isDynamicTarget(node.target)) {
+ var type = objectMap[name];
+ if (type is FunctionType && node.argumentList.arguments.isEmpty) {
+ node.target.staticType = _typeProvider.objectType;
+ node.methodName.staticType = type;
+ // Only infer the type of the overall expression if we have an exact
+ // type - e.g., a sealed type. Otherwise, it may be too strict.
+ if (_isSealed(type.returnType)) {
+ node.staticType = type.returnType;
+ }
+ }
+ }
+
var e = node.methodName.staticElement;
if (e is FunctionElement &&
e.library.name == '_foreign_helper' &&
@@ -690,6 +750,39 @@ class RestrictedStaticTypeAnalyzer extends StaticTypeAnalyzer {
}
}
+ void _inferObjectAccess(
+ Expression node, Expression target, SimpleIdentifier id) {
+ // Search for Object accesses.
+ var objectMap = _getObjectMemberMap();
+ var name = id.name;
+ if (node.staticType.isDynamic &&
+ objectMap.containsKey(name) &&
+ isDynamicTarget(target)) {
+ target.staticType = _typeProvider.objectType;
+ var type = objectMap[name];
+ id.staticType = type;
+ // Only infer the type of the overall expression if we have an exact
+ // type - e.g., a sealed type. Otherwise, it may be too strict.
+ if (_isSealed(type)) {
+ node.staticType = type;
+ }
+ }
+ }
+
+ @override
+ visitPropertyAccess(PropertyAccess node) {
+ super.visitPropertyAccess(node);
+
+ _inferObjectAccess(node, node.target, node.propertyName);
+ }
+
+ @override
+ visitPrefixedIdentifier(PrefixedIdentifier node) {
+ super.visitPrefixedIdentifier(node);
+
+ _inferObjectAccess(node, node.prefix, node.identifier);
+ }
+
@override
visitConditionalExpression(ConditionalExpression node) {
// TODO(vsm): The static type of a conditional should be the LUB of the

Powered by Google App Engine
This is Rietveld 408576698