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

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: Fix for sealed types 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..a335ea7fe5e18b3a64afaabe269d2c38a9135c92 100644
--- a/lib/src/checker/resolver.dart
+++ b/lib/src/checker/resolver.dart
@@ -664,12 +664,73 @@ 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> _nonExtendableTypes = null;
+
+ bool _isExtendable(DartType t) {
+ if (_nonExtendableTypes == null) {
+ // TODO(vsm): Use the analyzer's list - see dartbug.com/23125.
+ _nonExtendableTypes = <DartType>[
+ _typeProvider.nullType,
+ _typeProvider.numType,
+ _typeProvider.intType,
+ _typeProvider.doubleType,
+ _typeProvider.boolType,
+ _typeProvider.stringType
+ ];
+ }
+ return !_nonExtendableTypes.contains(t);
Jennifer Messerly 2015/04/07 19:05:49 whenever you're calling _isExtendable it's being i
vsm 2015/04/07 19:48:46 Done.
+ }
+
@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)) {
+ var target = node.target;
+ if (target is SimpleIdentifier &&
Jennifer Messerly 2015/04/07 19:05:49 why does target need to be a SimpleIdentifier? doe
vsm 2015/04/07 19:48:46 Good point. Fixed and test added.
+ target.staticElement is! PrefixElement) {
Jennifer Messerly 2015/04/07 19:05:49 follow up to above suggestion, I wonder if somethi
vsm 2015/04/07 19:48:46 It cleans it up. Done.
+ var type = objectMap[name];
+ if (type is FunctionType && node.argumentList.arguments.isEmpty) {
+ node.methodName.staticType = type;
+ if (!_isExtendable(type.returnType)) {
+ // Don't infer the type of the overall expression in this case -
+ // it may be too strict.
Jennifer Messerly 2015/04/07 19:05:49 can this actually happen? I thought we didn't allo
vsm 2015/04/07 19:48:46 Note: my comment was in a confusing place - fixed
+ node.staticType = type.returnType;
+ }
+ }
+ }
+ }
+
var e = node.methodName.staticElement;
if (e is FunctionElement &&
e.library.name == '_foreign_helper' &&
@@ -690,6 +751,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)) {
+ if (target is SimpleIdentifier &&
+ target.staticElement is! PrefixElement) {
+ var type = objectMap[name];
+ id.staticType = type;
+ if (!_isExtendable(type)) {
+ // Don't infer the type of the overall expression in this case -
+ // it may be too strict.
+ 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