Chromium Code Reviews| Index: dart/tests/compiler/dart2js_extra/mirror_printer_test.dart |
| diff --git a/dart/tests/compiler/dart2js_extra/mirror_printer_test.dart b/dart/tests/compiler/dart2js_extra/mirror_printer_test.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..28219e7b0e0a7fb63423bfccf31e242acc08c9d2 |
| --- /dev/null |
| +++ b/dart/tests/compiler/dart2js_extra/mirror_printer_test.dart |
| @@ -0,0 +1,169 @@ |
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
|
ngeoffray
2013/08/16 12:52:45
Why in dart2js_extra?
ahe
2013/08/30 13:43:47
Because I import dart:html.
|
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +// Prints all information about all mirrors. |
|
karlklose
2013/08/16 12:53:09
'Tests that it is possible to enumerate all metada
ahe
2013/08/30 13:43:47
Done.
|
| + |
| +library test.mirror_printer_test; |
| + |
| +@MirrorsUsed(targets: '*') |
| +import 'dart:mirrors'; |
| + |
| +// Importing dart:html to make things interesting. |
| +import 'dart:html'; |
| + |
| +class MirrorPrinter { |
| + final StringBuffer buffer; |
| + final TypeMirror dynamicType = currentMirrorSystem().dynamicType; |
| + |
| + int indentationLevel = 0; |
| + |
| + MirrorPrinter(this.buffer); |
| + |
| + void w(object) { |
| + buffer.write(object); |
| + } |
| + |
| + n(Symbol symbol) => MirrorSystem.getName(symbol); |
| + |
| + void indented(action) { |
| + indentationLevel++; |
| + action(); |
| + indentationLevel--; |
| + } |
| + |
| + get indent { |
| + for (int i = 0; i < indentationLevel; i++) { |
| + w(' '); |
| + } |
| + } |
| + |
| + String stringifyInstance(InstanceMirror mirror) { |
| + var reflectee = mirror.reflectee; |
| + if (reflectee is String) return '"${reflectee}"'; |
| + if (reflectee is Null || reflectee is bool || reflectee is num || |
| + reflectee is List || reflectee is Map) { |
| + return '$reflectee'; |
| + } |
| + StringBuffer buffer = new StringBuffer(); |
| + var variables = mirror.type.variables; |
|
karlklose
2013/08/16 12:53:09
Could you add a type annotation here?
ahe
2013/08/30 13:43:47
Done.
|
| + buffer |
| + ..write(n(mirror.type.simpleName)) |
| + ..write('('); |
| + bool first = true; |
| + variables.forEach((Symbol name, VariableMirror variable) { |
| + if (variable.isStatic) return; |
| + // TODO(ahe): Include superclasses. |
| + if (first) { |
| + first = false; |
| + } else { |
| + buffer.write(', '); |
| + } |
| + buffer |
| + ..write(n(name)) |
| + ..write(': ') |
| + ..write(stringifyInstance(mirror.getField(name))); |
| + }); |
| + return buffer |
| + ..write(')') |
| + ..toString(); |
| + } |
| + |
| + String stringifyMetadata(InstanceMirror mirror) { |
| + return '@${stringifyInstance(mirror)}'; |
| + } |
| + |
| + bool writeType(TypeMirror mirror) { |
| + if (mirror == null || mirror == dynamicType) return false; |
| + w('${n(mirror.simpleName)} '); |
| + return true; |
| + } |
| + |
| + writeVariable(VariableMirror mirror) { |
| + bool needsVar = true; |
| + if (mirror.isStatic) w('static '); |
| + // TODO(ahe): What about const? |
| + if (mirror.isFinal) { |
| + w('final '); |
| + needsVar = false; |
| + } |
| + |
| + if (writeType(mirror.type)) needsVar = false; |
| + |
| + if (needsVar) { |
| + w('var '); |
| + } |
| + w('${n(mirror.simpleName)};'); |
| + } |
| + |
| + writeMethod(MethodMirror mirror) { |
| + writeType(mirror.returnType); |
| + if (mirror.isOperator) { |
| + w('operator '); |
| + } |
| + if (mirror.isGetter) { |
| + w('get '); |
| + } |
| + if (mirror.isSetter) { |
| + w('set '); |
| + } |
| + w('${n(mirror.simpleName)}'); |
| + if (!mirror.isGetter) { |
| + w('()'); |
| + } |
| + w(';'); |
| + } |
| + |
| + dumpClass(ClassMirror mirror) { |
|
karlklose
2013/08/16 12:53:09
'dumpClass' -> 'writeClass'.
ahe
2013/08/30 13:43:47
Done.
|
| + w('class ${n(mirror.simpleName)}'); |
| + w(' {'); |
| + bool first = true; |
| + indented(() { |
| + for (DeclarationMirror declaration in mirror.members.values) { |
| + if (first) { |
| + first = false; |
| + } else { |
| + w('\n'); |
| + } |
| + writeDeclaration(declaration); |
| + } |
| + }); |
| + w('\n}\n'); |
| + } |
| + |
| + writeDeclaration(DeclarationMirror declaration) { |
| + w('\n'); |
| + var metadata = declaration.metadata; |
| + if (!metadata.isEmpty) { |
| + indent; |
| + buffer.writeAll(metadata.map(stringifyMetadata), ' '); |
| + w('\n'); |
| + } |
| + indent; |
| + if (declaration is ClassMirror) { |
| + dumpClass(declaration); |
| + } else if (declaration is VariableMirror) { |
| + writeVariable(declaration); |
| + } else if (declaration is MethodMirror) { |
| + writeMethod(declaration); |
| + } else { |
| + w('$declaration'); |
|
karlklose
2013/08/16 12:53:09
Add a TODO what is missing here.
ahe
2013/08/30 13:43:47
Done.
|
| + } |
| + } |
| + |
| + writeLibrary(LibraryMirror library) { |
| + w('library ${n(library.simpleName)};\n\n'); |
| + library.members.values.forEach(writeDeclaration); |
| + w('\n'); |
| + } |
| + |
| + static StringBuffer stringify(Map<Uri, LibraryMirror> libraries) { |
| + StringBuffer buffer = new StringBuffer(); |
| + libraries.values.forEach(new MirrorPrinter(buffer).writeLibrary); |
| + return buffer; |
| + } |
| +} |
| + |
| +main() { |
| + print(MirrorPrinter.stringify(currentMirrorSystem().libraries)); |
| +} |