Chromium Code Reviews| 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 f6f521d524500d01411df71a547ba077ada94bd1..a40e88163a9c2d26ca6dd91dc31d31080fcb09d2 100644 |
| --- a/sdk/lib/_internal/lib/js_mirrors.dart |
| +++ b/sdk/lib/_internal/lib/js_mirrors.dart |
| @@ -208,7 +208,7 @@ class JsTypeVariableMirror extends JsTypeMirror implements TypeVariableMirror { |
| TypeMirror get upperBound { |
| if (_cachedUpperBound != null) return _cachedUpperBound; |
| return _cachedUpperBound = typeMirrorFromRuntimeTypeRepresentation( |
| - JS('', 'init.metadata[#]', _typeVariable.bound)); |
| + owner, JS('', 'init.metadata[#]', _typeVariable.bound)); |
| } |
| } |
| @@ -891,13 +891,15 @@ class JsTypeBoundClassMirror extends JsDeclarationMirror implements ClassMirror |
| Map<Symbol, MethodMirror> _cachedSetters; |
| Map<Symbol, MethodMirror> _cachedMethodsMap; |
| List<JsMethodMirror> _cachedMethods; |
| + ClassMirror _superclass; |
| + List<ClassMirror> _cachedSuperinterfaces; |
| JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments) |
| - : _class = originalDeclaration, |
| + : _class = originalDeclaration, |
| super(originalDeclaration.simpleName); |
| String get _prettyName => 'ClassMirror'; |
| - |
| + |
| List<TypeVariableMirror> get typeVariables => _class.typeVariables; |
| List<TypeMirror> get typeArguments { |
| @@ -1013,7 +1015,16 @@ class JsTypeBoundClassMirror extends JsDeclarationMirror implements ClassMirror |
| List<InstanceMirror> get metadata => _class.metadata; |
| - ClassMirror get superclass => _class.superclass; |
| + ClassMirror get superclass { |
| + if (_superclass != null) return _superclass; |
| + |
| + List<int> typeInformation = |
| + JS('List|Null', 'init.typeInformation[#]', _class._mangledName); |
| + if (typeInformation != null) { |
| + var type = JS('=Object', 'init.metadata[#]', typeInformation[0]); |
| + return _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type); |
| + } |
| + } |
| InstanceMirror invoke(Symbol memberName, |
| List positionalArguments, |
| @@ -1025,7 +1036,10 @@ class JsTypeBoundClassMirror extends JsDeclarationMirror implements ClassMirror |
| ClassMirror get originalDeclaration => _class; |
| - List<ClassMirror> get superinterfaces => _class.superinterfaces; |
| + List<ClassMirror> get superinterfaces { |
| + if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces; |
| + return _cachedSuperinterfaces = _class._getSuperinterfacesWithOwner(this); |
| + } |
| Future<InstanceMirror> getFieldAsync(Symbol fieldName) { |
| return _class.getFieldAsync(fieldName); |
| @@ -1353,17 +1367,14 @@ class JsClassMirror extends JsTypeMirror with JsObjectMirror |
| ClassMirror get superclass { |
| if (_superclass == null) { |
| - var superclassName = _fieldsDescriptor.split(';')[0]; |
| - var mixins = superclassName.split('+'); |
| - if (mixins.length > 1) { |
| - if (mixins.length != 2) { |
| - throw new RuntimeError('Strange mixin: $_fieldsDescriptor'); |
| - } |
| - _superclass = reflectClassByMangledName(mixins[0]); |
| + List<int> typeInformation = |
| + JS('List|Null', 'init.typeInformation[#]', _mangledName); |
| + if (typeInformation != null) { |
| + var type = JS('=Object', 'init.metadata[#]', typeInformation[0]); |
| + _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type); |
| } else { |
| // Use _superclass == this to represent class with no superclass (Object). |
| - _superclass = (superclassName == '') |
| - ? this : reflectClassByMangledName(superclassName); |
| + _superclass = this; |
| } |
| } |
| return _superclass == this ? null : _superclass; |
| @@ -1394,19 +1405,26 @@ class JsClassMirror extends JsTypeMirror with JsObjectMirror |
| ClassMirror get originalDeclaration => this; |
| - List<ClassMirror> get superinterfaces { |
| - if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces; |
| - List<int> interfaces = JS('List|Null', 'init.interfaces[#]', _mangledName); |
| + List<ClassMirror> _getSuperinterfacesWithOwner(DeclarationMirror owner) { |
| + List<int> typeInformation = |
| + JS('List|Null', 'init.typeInformation[#]', _mangledName); |
| var result = const []; |
|
karlklose
2013/10/29 15:14:09
List<ClassMirror> result = const <ClassMirror>[];
zarah
2013/10/30 11:51:40
Done.
|
| - if (interfaces != null) { |
| + if (typeInformation != null) { |
| ClassMirror lookupType(int i) { |
| var type = JS('=Object', 'init.metadata[#]', i); |
| - return typeMirrorFromRuntimeTypeRepresentation(type); |
| + return typeMirrorFromRuntimeTypeRepresentation(owner, type); |
| } |
| - result = interfaces.map(lookupType).toList(); |
| + |
| + //We skip the first since it is the supertype. |
| + result = typeInformation.skip(1).map(lookupType).toList(); |
| } |
| - return _cachedSuperinterfaces = |
| - new UnmodifiableListView<ClassMirror>(result); |
| + |
| + return new UnmodifiableListView<ClassMirror>(result); |
| + } |
| + |
| + List<ClassMirror> get superinterfaces { |
| + if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces; |
| + return _cachedSuperinterfaces = _getSuperinterfacesWithOwner(this); |
| } |
| List<TypeVariableMirror> get typeVariables { |
| @@ -1659,7 +1677,7 @@ class JsMethodMirror extends JsDeclarationMirror implements MethodMirror { |
| TypeMirror get returnType { |
| metadata; // Compute _returnType as a side-effect of extracting metadata. |
| - return computeTypeMirror(owner, _returnType); |
| + return typeMirrorFromRuntimeTypeRepresentation(owner, _returnType); |
| } |
| List<InstanceMirror> get metadata { |
| @@ -1758,7 +1776,7 @@ class JsParameterMirror extends JsDeclarationMirror implements ParameterMirror { |
| String get _prettyName => 'ParameterMirror'; |
| TypeMirror get type { |
| - return computeTypeMirror(owner, _type); |
| + return typeMirrorFromRuntimeTypeRepresentation(owner, _type); |
| } |
| // Only true for static fields, never for a parameter. |
| @@ -1819,13 +1837,14 @@ class JsFunctionTypeMirror implements FunctionTypeMirror { |
| bool get _hasNamedArguments => JS('bool', '"named" in #', _typeData); |
| get _namedArguments => JS('=Object', '#.named', _typeData); |
| + bool get isOriginalDeclaration => true; |
| TypeMirror get returnType { |
| if (_cachedReturnType != null) return _cachedReturnType; |
| if (_isVoid) return _cachedReturnType = JsMirrorSystem._voidType; |
| if (!_hasReturnType) return _cachedReturnType = JsMirrorSystem._dynamicType; |
| return _cachedReturnType = |
| - typeMirrorFromRuntimeTypeRepresentation(_returnType); |
| + typeMirrorFromRuntimeTypeRepresentation(this, _returnType); |
| } |
| List<ParameterMirror> get parameters { |
| @@ -1898,18 +1917,17 @@ class JsFunctionTypeMirror implements FunctionTypeMirror { |
| } |
| } |
| -TypeMirror typeMirrorFromRuntimeTypeRepresentation(type) { |
| - if (type == null) return JsMirrorSystem._dynamicType; |
| - String representation = runtimeTypeToString(type); |
| - if (representation == null) return reflectClass(Function); |
| - return reflectType(createRuntimeType(representation)); |
| +int findTypeVariableIndex(List<TypeVariableMirror> typeVariables, String name) { |
| + for (int i = 0; i < typeVariables.length; i++) { |
| + if (typeVariables[i].simpleName == s(name)) { |
| + return i; |
| + } |
| + } |
| + return -1; |
|
karlklose
2013/10/29 15:14:09
You could just throw here.
zarah
2013/10/30 11:51:40
Done.
|
| } |
| -TypeMirror computeTypeMirror(DeclarationMirror owner, var type) { |
| - if (type is! int) { |
| - return typeMirrorFromRuntimeTypeRepresentation(type); |
| - } |
| - |
| +TypeMirror typeMirrorFromRuntimeTypeRepresentation(DeclarationMirror owner, |
| + var type) { |
|
karlklose
2013/10/29 15:14:09
You could document the possible types like this
zarah
2013/10/30 11:51:40
Done.
|
| ClassMirror ownerClass; |
| DeclarationMirror context = owner; |
| while(context != null) { |
| @@ -1919,19 +1937,38 @@ TypeMirror computeTypeMirror(DeclarationMirror owner, var type) { |
| } |
| 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]; |
| - } |
| + |
| + if (type == null){ |
| + return JsMirrorSystem._dynamicType; |
| + } else if (type is int && ownerClass.isOriginalDeclaration) { |
| + // 'type' represents a type variable so in the context of an original |
| + // declaration the corresponding type variable should be returned. |
| + TypeVariable typeVariable = JS('', 'init.metadata[#]', type); |
|
karlklose
2013/10/29 15:14:09
Perhaps add a helper to get metadata:
getMetaData
zarah
2013/10/30 11:51:40
Done.
|
| + List<TypeVariableMirror> typeVariables = ownerClass.typeVariables; |
| + int variableIndex = findTypeVariableIndex(typeVariables, typeVariable.name); |
| + assert(variableIndex != -1); |
| + return typeVariables[variableIndex]; |
| + } else { |
| + String substituteTypeVariable(int index) { |
| + TypeVariable typeVariable = JS('', 'init.metadata[#]', index); |
| + int variableIndex = |
| + findTypeVariableIndex(ownerClass.typeVariables, typeVariable.name); |
| + assert(variableIndex != -1); |
| + return n(ownerClass.typeArguments[variableIndex].simpleName); |
| + } |
| + |
| + String representation; |
| + if (ownerClass.isOriginalDeclaration) { |
| + representation = runtimeTypeToString(type); |
| + } else { |
| + representation = |
| + runtimeTypeToString(type, onTypeVariable: substituteTypeVariable); |
| + } |
| + if (representation != null) { |
| + return reflectType(createRuntimeType(representation)); |
| } |
| } |
| + return reflectClass(Function); |
| } |
| Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) { |