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

Unified Diff: sdk/lib/_internal/lib/js_mirrors.dart

Issue 39783003: Substitute types in instances of generic classes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Added regression test and updated dart2js_extra.status. Created 7 years, 2 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 | tests/compiler/dart2js_extra/dart2js_extra.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/lib/js_mirrors.dart
diff --git a/sdk/lib/_internal/lib/js_mirrors.dart b/sdk/lib/_internal/lib/js_mirrors.dart
index e5d73b04329280aa3c0c20c4520ac5cfe7852b44..f6a438a6e42b65c6ebd1d5ffbf17afa2af287c44 100644
--- a/sdk/lib/_internal/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/lib/js_mirrors.dart
@@ -535,6 +535,48 @@ TypeMirror reflectClassByName(Symbol symbol, String mangledName) {
return mirror;
}
+Map<Symbol, MethodMirror> filterMethods(List<MethodMirror> methods) {
+ var result = new Map();
+ for (JsMethodMirror method in methods) {
+ if (!method.isConstructor && !method.isGetter && !method.isSetter) {
+ result[method.simpleName] = method;
+ }
+ }
+ return result;
+}
+
+Map<Symbol, MethodMirror> filterGetters(List<MethodMirror> methods,
+ Map<Symbol, VariableMirror> fields) {
+ var result = new Map();
+ for (JsMethodMirror method in methods) {
+ if (method.isGetter) {
+
+ // TODO(ahe): This is a hack to remove getters corresponding to a field.
+ if (fields[method.simpleName] != null) continue;
+
+ result[method.simpleName] = method;
+ }
+ }
+ return result;
+}
+
+Map<Symbol, MethodMirror> filterSetters(List<MethodMirror> methods,
+ Map<Symbol, VariableMirror> fields) {
+ var result = new Map();
+ for (JsMethodMirror method in methods) {
+ if (method.isSetter) {
+
+ // TODO(ahe): This is a hack to remove setters corresponding to a field.
+ String name = n(method.simpleName);
+ name = name.substring(0, name.length - 1); // Remove '='.
+ if (fields[s(name)] != null) continue;
+
+ result[method.simpleName] = method;
+ }
+ }
+ return result;
+}
+
int counter = 0;
ClassMirror reflectMixinApplication(mixinNames, String mangledName) {
@@ -817,7 +859,7 @@ class JsInstanceMirror extends JsObjectMirror implements InstanceMirror {
* to JsCLassMirror that returns an empty list since it represents original
* declarations and classes that are not generic.
*/
-class JsTypeBoundClassMirror implements ClassMirror {
+class JsTypeBoundClassMirror extends JsDeclarationMirror implements ClassMirror {
final JsClassMirror _class;
/**
@@ -832,8 +874,18 @@ class JsTypeBoundClassMirror implements ClassMirror {
*/
var _typeArguments;
- JsTypeBoundClassMirror(this._class, this._typeArguments);
+ Map<Symbol, VariableMirror> _cachedVariables;
+ Map<Symbol, MethodMirror> _cachedGetters;
+ Map<Symbol, MethodMirror> _cachedSetters;
+ Map<Symbol, MethodMirror> _cachedMethodsMap;
+ List<JsMethodMirror> _cachedMethods;
+
+ JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments)
+ : _class = originalDeclaration,
+ super(originalDeclaration.simpleName);
+ String get _prettyName => 'ClassMirror';
+
List<TypeVariableMirror> get typeVariables => _class.typeVariables;
List<TypeMirror> get typeArguments {
@@ -887,13 +939,38 @@ class JsTypeBoundClassMirror implements ClassMirror {
Map<Symbol, MethodMirror> get constructors => _class.constructors;
- Map<Symbol, MethodMirror> get methods => _class.methods;
+ List<JsMethodMirror> get _methods {
+ if (_cachedMethods != null) return _cachedMethods;
+ return _cachedMethods =_class._getMethodsWithOwner(this);
+ }
+
+ Map<Symbol, MethodMirror> get methods {
+ if (_cachedMethodsMap != null) return _cachedMethodsMap;
+ return _cachedMethodsMap = new UnmodifiableMapView<Symbol, MethodMirror>(
+ filterMethods(_methods));
+ }
- Map<Symbol, MethodMirror> get getters => _class.getters;
+ Map<Symbol, MethodMirror> get getters {
+ if (_cachedGetters != null) return _cachedGetters;
+ return _cachedGetters = new UnmodifiableMapView<Symbol, MethodMirror>(
+ filterGetters(_methods, variables));
+ }
- Map<Symbol, MethodMirror> get setters => _class.setters;
+ Map<Symbol, MethodMirror> get setters {
+ if (_cachedSetters != null) return _cachedSetters;
+ return _cachedSetters = new UnmodifiableMapView<Symbol, MethodMirror>(
+ filterSetters(_methods, variables));
+ }
- Map<Symbol, VariableMirror> get variables => _class.variables;
+ Map<Symbol, VariableMirror> get variables {
+ if (_cachedVariables != null) return _cachedVariables;
+ var result = new Map();
+ for (JsVariableMirror mirror in _class._getFieldsWithOwner(this)) {
+ result[mirror.simpleName] = mirror;
+ }
+ return _cachedVariables =
+ new UnmodifiableMapView<Symbol, VariableMirror>(result);
+ }
Map<Symbol, Mirror> get members => _class.members;
@@ -1022,8 +1099,7 @@ class JsClassMirror extends JsTypeMirror with JsObjectMirror
new UnmodifiableMapView<Symbol, MethodMirror>(result);
}
- List<JsMethodMirror> get _methods {
- if (_cachedMethods != null) return _cachedMethods;
+ List<JsMethodMirror> _getMethodsWithOwner(DeclarationMirror methodOwner) {
var prototype = JS('', '#.prototype', _jsConstructor);
List<String> keys = extractKeys(prototype);
var result = <JsMethodMirror>[];
@@ -1040,7 +1116,7 @@ class JsClassMirror extends JsTypeMirror with JsObjectMirror
new JsMethodMirror.fromUnmangledName(
simpleName, function, false, false);
result.add(mirror);
- mirror._owner = this;
+ mirror._owner = methodOwner;
}
keys = extractKeys(JS('', 'init.statics[#]', _mangledName));
@@ -1069,14 +1145,18 @@ class JsClassMirror extends JsTypeMirror with JsObjectMirror
new JsMethodMirror.fromUnmangledName(
unmangledName, jsFunction, isStatic, isConstructor);
result.add(mirror);
- mirror._owner = this;
+ mirror._owner = methodOwner;
}
- return _cachedMethods = result;
+ return result;
}
- List<VariableMirror> get _fields {
- if (_cachedFields != null) return _cachedFields;
+ List<JsMethodMirror> get _methods {
+ if (_cachedMethods != null) return _cachedMethods;
+ return _cachedMethods = _getMethodsWithOwner(this);
+ }
+
+ List<VariableMirror> _getFieldsWithOwner(DeclarationMirror fieldOwner) {
var result = <VariableMirror>[];
var instanceFieldSpecfication = _fieldsDescriptor.split(';')[1];
@@ -1085,67 +1165,37 @@ class JsClassMirror extends JsTypeMirror with JsObjectMirror
[instanceFieldSpecfication]..addAll(_fieldsMetadata);
}
parseCompactFieldSpecification(
- this, instanceFieldSpecfication, false, result);
+ fieldOwner, instanceFieldSpecfication, false, result);
var staticDescriptor = JS('', 'init.statics[#]', _mangledName);
if (staticDescriptor != null) {
parseCompactFieldSpecification(
- this, JS('', '#[""]', staticDescriptor), true, result);
+ fieldOwner, JS('', '#[""]', staticDescriptor), true, result);
}
- _cachedFields = result;
- return _cachedFields;
+ return result;
+ }
+
+ List<VariableMirror> get _fields {
+ if (_cachedFields != null) return _cachedFields;
+ return _cachedFields = _getFieldsWithOwner(this);
}
Map<Symbol, MethodMirror> get methods {
if (_cachedMethodsMap != null) return _cachedMethodsMap;
- var result = new Map();
- for (JsMethodMirror method in _methods) {
- if (!method.isConstructor && !method.isGetter && !method.isSetter) {
- result[method.simpleName] = method;
- }
- }
return _cachedMethodsMap =
- new UnmodifiableMapView<Symbol, MethodMirror>(result);
+ new UnmodifiableMapView<Symbol, MethodMirror>(filterMethods(_methods));
}
Map<Symbol, MethodMirror> get getters {
if (_cachedGetters != null) return _cachedGetters;
- // TODO(ahe): This is a hack to remove getters corresponding to a field.
- var fields = variables;
-
- var result = new Map();
- for (JsMethodMirror method in _methods) {
- if (method.isGetter) {
-
- // TODO(ahe): This is a hack to remove getters corresponding to a field.
- if (fields[method.simpleName] != null) continue;
-
- result[method.simpleName] = method;
- }
- }
- return _cachedGetters =
- new UnmodifiableMapView<Symbol, MethodMirror>(result);
+ return _cachedGetters = new UnmodifiableMapView<Symbol, MethodMirror>(
+ filterGetters(_methods, variables));
}
Map<Symbol, MethodMirror> get setters {
if (_cachedSetters != null) return _cachedSetters;
- // TODO(ahe): This is a hack to remove setters corresponding to a field.
- var fields = variables;
-
- var result = new Map();
- for (JsMethodMirror method in _methods) {
- if (method.isSetter) {
-
- // TODO(ahe): This is a hack to remove setters corresponding to a field.
- String name = n(method.simpleName);
- name = name.substring(0, name.length - 1); // Remove '='.
- if (fields[s(name)] != null) continue;
-
- result[method.simpleName] = method;
- }
- }
- return _cachedSetters =
- new UnmodifiableMapView<Symbol, MethodMirror>(result);
+ return _cachedSetters = new UnmodifiableMapView<Symbol, MethodMirror>(
+ filterSetters(_methods, variables));
}
Map<Symbol, VariableMirror> get variables {
@@ -1336,11 +1386,11 @@ class JsClassMirror extends JsTypeMirror with JsObjectMirror
List<TypeVariableMirror> get typeVariables {
if (_cachedTypeVariables != null) return _cachedTypeVariables;
List result = new List();
- List typeVars =
+ List typeVariables =
JS('JSExtendableArray|Null', '#.prototype["<>"]', _jsConstructor);
- if (typeVars == null) return result;
- for (int i = 0; i < typeVars.length; i++) {
- TypeVariable typeVariable = JS('', 'init.metadata[#]', typeVars[i]);
+ if (typeVariables == null) return result;
+ for (int i = 0; i < typeVariables.length; i++) {
+ TypeVariable typeVariable = JS('', 'init.metadata[#]', typeVariables[i]);
result.add(new JsTypeVariableMirror(typeVariable, this));
}
return _cachedTypeVariables = new UnmodifiableListView(result);
@@ -1583,7 +1633,7 @@ class JsMethodMirror extends JsDeclarationMirror implements MethodMirror {
TypeMirror get returnType {
metadata; // Compute _returnType as a side-effect of extracting metadata.
- return typeMirrorFromRuntimeTypeRepresentation(_returnType);
+ return computeTypeMirror(owner, _returnType);
}
List<InstanceMirror> get metadata {
@@ -1681,7 +1731,9 @@ class JsParameterMirror extends JsDeclarationMirror implements ParameterMirror {
String get _prettyName => 'ParameterMirror';
- TypeMirror get type => typeMirrorFromRuntimeTypeRepresentation(_type);
+ TypeMirror get type {
+ return computeTypeMirror(owner, _type);
+ }
// Only true for static fields, never for a parameter.
bool get isStatic => false;
@@ -1707,11 +1759,12 @@ class JsParameterMirror extends JsDeclarationMirror implements ParameterMirror {
class JsTypedefMirror extends JsDeclarationMirror implements TypedefMirror {
final String _mangledName;
- final JsFunctionTypeMirror referent;
+ JsFunctionTypeMirror referent;
JsTypedefMirror(Symbol simpleName, this._mangledName, _typeData)
- : referent = new JsFunctionTypeMirror(_typeData),
- super(simpleName);
+ : super(simpleName) {
+ referent = new JsFunctionTypeMirror(_typeData, this);
+ }
JsFunctionTypeMirror get value => referent;
@@ -1723,8 +1776,9 @@ class JsFunctionTypeMirror implements FunctionTypeMirror {
String _cachedToString;
TypeMirror _cachedReturnType;
UnmodifiableListView<ParameterMirror> _cachedParameters;
+ DeclarationMirror owner;
- JsFunctionTypeMirror(this._typeData);
+ JsFunctionTypeMirror(this._typeData, this.owner);
bool get _hasReturnType => JS('bool', '"ret" in #', _typeData);
get _returnType => JS('', '#.ret', _typeData);
@@ -1825,6 +1879,35 @@ TypeMirror typeMirrorFromRuntimeTypeRepresentation(type) {
return reflectType(createRuntimeType(representation));
}
+TypeMirror computeTypeMirror(DeclarationMirror owner, var type) {
+ if (type is! int) {
+ return typeMirrorFromRuntimeTypeRepresentation(type);
+ }
+
+ ClassMirror ownerClass;
+ DeclarationMirror context = owner;
+ while(context != null) {
+ if (context is ClassMirror) {
+ ownerClass = context;
+ break;
+ }
+ context = context.owner;
+ }
+
+ TypeVariable typeVariable = JS('', 'init.metadata[#]', type);
+ Symbol name = new Symbol(typeVariable.name);
+ List<TypeVariableMirror> typeVariables = ownerClass.typeVariables;
+ for (int i = 0; i < typeVariables.length; i++) {
+ if (typeVariables[i].simpleName == name) {
+ if (ownerClass.isOriginalDeclaration) {
+ return typeVariables[i];
+ } else {
+ return ownerClass.typeArguments[i];
+ }
+ }
+ }
+}
+
Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
if (owner == null) return simpleName;
String ownerName = n(owner.qualifiedName);
« no previous file with comments | « no previous file | tests/compiler/dart2js_extra/dart2js_extra.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698