Index: dart/sdk/lib/_internal/lib/js_mirrors.dart |
diff --git a/dart/sdk/lib/_internal/lib/js_mirrors.dart b/dart/sdk/lib/_internal/lib/js_mirrors.dart |
index 7beac1b977276fdc35186a881791421081fa0cfa..ef388d562afcfd093f7ae83e0825e8f15d3339ea 100644 |
--- a/dart/sdk/lib/_internal/lib/js_mirrors.dart |
+++ b/dart/sdk/lib/_internal/lib/js_mirrors.dart |
@@ -149,7 +149,7 @@ abstract class JsDeclarationMirror extends JsMirror |
bool get isTopLevel => owner != null && owner is LibraryMirror; |
- String toString() => "$_prettyName on '${n(simpleName)}'"; |
+ String toString() => "$_prettyName on '${n(qualifiedName)}'"; |
List<JsMethodMirror> get _methods { |
throw new RuntimeError('Should not call _methods'); |
@@ -207,9 +207,11 @@ class JsLibraryMirror extends JsDeclarationMirror with JsObjectMirror |
Map<Symbol, ClassMirror> get classes { |
var result = new Map<Symbol, ClassMirror>(); |
for (String className in _classes) { |
- JsClassMirror cls = reflectClassByMangledName(className); |
- result[cls.simpleName] = cls; |
- cls._owner = this; |
+ var cls = reflectClassByMangledName(className); |
+ if (cls is JsClassMirror) { |
+ result[cls.simpleName] = cls; |
+ cls._owner = this; |
+ } |
} |
return result; |
} |
@@ -366,6 +368,9 @@ InstanceMirror reflect(Object reflectee) { |
final Expando<ClassMirror> classMirrors = new Expando<ClassMirror>(); |
ClassMirror reflectType(Type key) { |
+ // TODO(ahe): Don't discard type arguments to support |
+ // [ClassMirror.isOriginalDeclaration] and [ClassMirror.originalDeclaration] |
+ // correctly. |
return reflectClassByMangledName('$key'.split('<')[0]); |
} |
@@ -405,15 +410,120 @@ ClassMirror reflectClassByName(Symbol symbol, String mangledName) { |
fields = ''; |
} |
} |
+ |
var mirror = classMirrors[constructorOrInterceptor]; |
if (mirror == null) { |
- mirror = new JsClassMirror( |
- symbol, mangledName, constructorOrInterceptor, fields, fieldsMetadata); |
- classMirrors[constructorOrInterceptor] = mirror; |
+ var superclassName = fields.split(';')[0]; |
+ var mixins = superclassName.split('+'); |
+ if (mixins.length > 1 && mangledGlobalNames[mangledName] == null) { |
+ mirror = reflectMixinApplication(mixins); |
+ } else { |
+ mirror = new JsClassMirror( |
+ symbol, mangledName, constructorOrInterceptor, fields, |
+ fieldsMetadata); |
+ classMirrors[constructorOrInterceptor] = mirror; |
+ } |
} |
return mirror; |
} |
+int counter = 0; |
+ |
+ClassMirror reflectMixinApplication(mixinNames) { |
+ disableTreeShaking(); |
+ var mixins = []; |
+ for (String mangledName in mixinNames) { |
+ mixins.add(reflectClassByMangledName(mangledName)); |
+ } |
+ var it = mixins.iterator; |
+ it.moveNext(); |
+ var superclass = it.current; |
+ while (it.moveNext()) { |
+ superclass = new JsMixinApplication(superclass, it.current); |
+ } |
+ return superclass; |
+} |
+ |
+class JsMixinApplication extends JsTypeMirror with JsObjectMirror |
+ implements ClassMirror { |
+ final ClassMirror superclass; |
+ final ClassMirror mixin; |
+ |
+ JsMixinApplication(ClassMirror superclass, ClassMirror mixin) |
+ : this.superclass = superclass, |
+ this.mixin = mixin, |
+ super(s('${n(mixin.simpleName)}(${n(superclass.simpleName)})')); |
+ |
+ String get _prettyName => 'ClassMirror'; |
+ |
+ Symbol get simpleName { |
+ return s('${n(mixin.qualifiedName)}(${n(superclass.qualifiedName)})'); |
Johnni Winther
2013/08/09 06:31:01
What naming convention is this? What will the simp
ahe
2013/08/09 12:17:49
It is this naming convention: mixin(superclass). I
|
+ } |
+ |
+ Symbol get qualifiedName => simpleName; |
+ |
+ Map<Symbol, Mirror> get members => mixin.members; |
+ |
+ Map<Symbol, MethodMirror> get methods => mixin.methods; |
+ |
+ Map<Symbol, MethodMirror> get getters => mixin.getters; |
+ |
+ Map<Symbol, MethodMirror> get setters => mixin.setters; |
+ |
+ Map<Symbol, VariableMirror> get variables => mixin.variables; |
+ |
+ InstanceMirror invoke( |
+ Symbol memberName, |
+ List positionalArguments, |
+ [Map<Symbol,dynamic> namedArguments]) { |
+ // TODO(ahe): Pass namedArguments when NoSuchMethodError has |
+ // been fixed to use Symbol. |
+ // TODO(ahe): What receiver to use? |
+ throw new NoSuchMethodError(this, n(memberName), positionalArguments, null); |
+ } |
+ |
+ InstanceMirror getField(Symbol fieldName) { |
+ // TODO(ahe): What receiver to use? |
+ throw new NoSuchMethodError(this, n(memberName), null, null); |
+ } |
+ |
+ InstanceMirror setField(Symbol fieldName, Object arg) { |
+ // TODO(ahe): What receiver to use? |
+ throw new NoSuchMethodError(this, '${n(fieldName)}=', [arg], null); |
+ } |
+ |
+ List<ClassMirror> get superinterfaces => mixin.superinterfaces; |
+ |
+ Map<Symbol, MethodMirror> get constructors => mixin.constructors; |
+ |
+ InstanceMirror newInstance( |
+ Symbol constructorName, |
+ List positionalArguments, |
+ [Map<Symbol,dynamic> namedArguments]) { |
+ throw new UnsupportedError( |
+ "Can't instantiate mixin application '${n(qualifiedName)}'"); |
+ } |
+ |
+ Future<InstanceMirror> newInstanceAsync( |
+ Symbol constructorName, |
+ List positionalArguments, |
+ [Map<Symbol, dynamic> namedArguments]) { |
+ return new Future<InstanceMirror>( |
+ () => this.newInstance( |
+ constructorName, positionalArguments, namedArguments)); |
+ } |
+ |
+ bool get isOriginalDeclaration => true; |
+ |
+ ClassMirror get originalDeclaration => this; |
+ |
+ // TODO(ahe): Implement these. |
+ Map<Symbol, TypeVariableMirror> get typeVariables { |
+ throw new UnimplementedError(); |
+ } |
+ Map<Symbol, TypeMirror> get typeArguments => throw new UnimplementedError(); |
+} |
+ |
abstract class JsObjectMirror implements ObjectMirror { |
Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) { |
return new Future<InstanceMirror>(() => this.setField(fieldName, value)); |
@@ -779,9 +889,17 @@ class JsClassMirror extends JsTypeMirror with JsObjectMirror |
ClassMirror get superclass { |
if (_superclass == null) { |
var superclassName = _fieldsDescriptor.split(';')[0]; |
- // Use _superclass == this to represent class with no superclass (Object). |
- _superclass = (superclassName == '') |
- ? this : reflectClassByMangledName(superclassName); |
+ var mixins = superclassName.split('+'); |
+ if (mixins.length > 1) { |
+ if (mixins.length != 2) { |
+ throw new RuntimeError('Strange mixin: $_fieldsDescriptor'); |
+ } |
+ _superclass = reflectClassByMangledName(mixins[0]); |
+ } else { |
+ // Use _superclass == this to represent class with no superclass (Object). |
Johnni Winther
2013/08/09 06:31:01
Long line.
|
+ _superclass = (superclassName == '') |
+ ? this : reflectClassByMangledName(superclassName); |
+ } |
} |
return _superclass == this ? null : _superclass; |
} |
@@ -806,15 +924,15 @@ class JsClassMirror extends JsTypeMirror with JsObjectMirror |
return reflect(mirror._invoke(positionalArguments, namedArguments)); |
} |
+ bool get isOriginalDeclaration => true; |
+ |
+ ClassMirror get originalDeclaration => this; |
+ |
// TODO(ahe): Implement these. |
List<ClassMirror> get superinterfaces => throw new UnimplementedError(); |
Map<Symbol, TypeVariableMirror> get typeVariables |
=> throw new UnimplementedError(); |
Map<Symbol, TypeMirror> get typeArguments => throw new UnimplementedError(); |
- bool get isOriginalDeclaration => throw new UnimplementedError(); |
- ClassMirror get originalDeclaration => throw new UnimplementedError(); |
- bool get isClass => throw new UnimplementedError(); |
- ClassMirror get defaultFactory => throw new UnimplementedError(); |
} |
class JsVariableMirror extends JsDeclarationMirror implements VariableMirror { |
@@ -1131,6 +1249,9 @@ class JsParameterMirror extends JsDeclarationMirror implements ParameterMirror { |
// TODO(ahe): Implement this. |
get defaultValue => null; |
+ |
+ // TODO(ahe): Implement this. |
+ List<InstanceMirror> get metadata => throw new UnimplementedError(); |
} |
TypeMirror typeMirrorFromRuntimeTypeRepresentation(type) { |