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..9a1cb147e58f3183910dfee2803d6399c1d53abf 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, getMetadata(_typeVariable.bound)); |
| } |
| } |
| @@ -503,8 +503,7 @@ TypeMirror reflectClassByName(Symbol symbol, String mangledName) { |
| if (constructorOrInterceptor == null) { |
| int index = JS('int|Null', 'init.functionAliases[#]', mangledName); |
| if (index != null) { |
| - mirror = new JsTypedefMirror( |
| - symbol, mangledName, JS('=Object', 'init.metadata[#]', index)); |
| + mirror = new JsTypedefMirror(symbol, mangledName, getMetadata(index)); |
| JsCache.update(classMirrors, mangledName, mirror); |
| return mirror; |
| } |
| @@ -744,7 +743,7 @@ class JsInstanceMirror extends JsObjectMirror implements InstanceMirror { |
| var defaultValueIndices = |
| JS('List|Null', '#[#].\$defaultValues', reflectee, mangledName); |
| var defaultValues = |
| - defaultValueIndices.map((int i) => JS('', 'init.metadata[#]', i)) |
| + defaultValueIndices.map((int i) => getMetadata(i)) |
| .iterator; |
| var defaultArguments = new Map(); |
| reflectiveName = mangledNames[mangledName]; |
| @@ -891,13 +890,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 { |
| @@ -909,7 +910,7 @@ class JsTypeBoundClassMirror extends JsDeclarationMirror implements ClassMirror |
| if (parsedIndex == -1) { |
| result.add(reflectClassByMangledName(typeArgument.trim())); |
| } else { |
| - TypeVariable typeVariable = JS('', 'init.metadata[#]', parsedIndex); |
| + TypeVariable typeVariable = getMetadata(parsedIndex); |
| TypeMirror owner = reflectClass(typeVariable.owner); |
| TypeVariableMirror typeMirror = |
| new JsTypeVariableMirror(typeVariable, owner); |
| @@ -1013,7 +1014,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) { |
|
Johnni Winther
2013/10/30 10:27:18
Change to assert(typeInformation != null).
zarah
2013/10/30 11:51:40
Done.
|
| + var type = getMetadata(typeInformation[0]); |
| + return _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type); |
| + } |
| + } |
| InstanceMirror invoke(Symbol memberName, |
| List positionalArguments, |
| @@ -1025,7 +1035,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 +1366,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 = getMetadata(typeInformation[0]); |
| + _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type); |
| } else { |
| // Use _superclass == this to represent class with no superclass (Object). |
|
Johnni Winther
2013/10/30 10:27:18
Long line.
zarah
2013/10/30 11:51:40
Done.
|
| - _superclass = (superclassName == '') |
| - ? this : reflectClassByMangledName(superclassName); |
| + _superclass = this; |
| } |
| } |
| return _superclass == this ? null : _superclass; |
| @@ -1394,19 +1404,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); |
| - var result = const []; |
| - if (interfaces != null) { |
| + List<ClassMirror> _getSuperinterfacesWithOwner(DeclarationMirror owner) { |
| + List<int> typeInformation = |
| + JS('List|Null', 'init.typeInformation[#]', _mangledName); |
| + List<ClassMirror> result = const <ClassMirror>[]; |
| + if (typeInformation != null) { |
| ClassMirror lookupType(int i) { |
| - var type = JS('=Object', 'init.metadata[#]', i); |
| - return typeMirrorFromRuntimeTypeRepresentation(type); |
| + var type = getMetadata(i); |
| + 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 { |
| @@ -1416,7 +1433,7 @@ class JsClassMirror extends JsTypeMirror with JsObjectMirror |
| JS('JSExtendableArray|Null', '#.prototype["<>"]', _jsConstructor); |
| if (typeVariables == null) return result; |
| for (int i = 0; i < typeVariables.length; i++) { |
| - TypeVariable typeVariable = JS('', 'init.metadata[#]', typeVariables[i]); |
| + TypeVariable typeVariable = getMetadata(typeVariables[i]); |
| result.add(new JsTypeVariableMirror(typeVariable, this)); |
| } |
| return _cachedTypeVariables = new UnmodifiableListView(result); |
| @@ -1659,7 +1676,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 +1775,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 +1836,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 +1916,20 @@ 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; |
| + } |
| + } |
| + throw new ArgumentError('Type variable not present in list.'); |
| } |
| -TypeMirror computeTypeMirror(DeclarationMirror owner, var type) { |
| - if (type is! int) { |
| - return typeMirrorFromRuntimeTypeRepresentation(type); |
| - } |
| - |
| +getMetadata(int index) => JS('', 'init.metadata[#]', index); |
| + |
| +TypeMirror typeMirrorFromRuntimeTypeRepresentation( |
| + DeclarationMirror owner, |
| + var /*int|List|JsFunction*/ type) { |
| ClassMirror ownerClass; |
| DeclarationMirror context = owner; |
| while(context != null) { |
| @@ -1919,19 +1939,36 @@ 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 = getMetadata(type); |
| + List<TypeVariableMirror> typeVariables = ownerClass.typeVariables; |
| + int variableIndex = findTypeVariableIndex(typeVariables, typeVariable.name); |
| + return typeVariables[variableIndex]; |
| + } else { |
| + String substituteTypeVariable(int index) { |
| + TypeVariable typeVariable = getMetadata(index); |
| + int variableIndex = |
| + findTypeVariableIndex(ownerClass.typeVariables, typeVariable.name); |
| + 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) { |
| @@ -1951,7 +1988,7 @@ List extractMetadata(victim) { |
| index++; |
| int endQuote = source.indexOf('"', index); |
| return source.substring(index, endQuote).split(',').map(int.parse).map( |
| - (int i) => JS('', 'init.metadata[#]', i)).toList(); |
| + (int i) => getMetadata(i)).toList(); |
| } |
| List<JsVariableMirror> parseCompactFieldSpecification( |