| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 /// Prints all information about all mirrors. This tests that it is possible to |
| 6 /// enumerate all reflective information without crashing. |
| 7 |
| 8 // Note: Adding imports below is fine for regression tests. For example, |
| 9 // 'crash_library_metadata.dart' is imported to ensure the compiler doesn't |
| 10 // crash. |
| 11 |
| 12 // TODO(ahe): This test should be extended until we are sure all data is |
| 13 // printed. |
| 14 |
| 15 library test.mirror_printer_test; |
| 16 |
| 17 @MirrorsUsed(targets: '*') |
| 18 import 'dart:mirrors'; |
| 19 |
| 20 import 'crash_library_metadata.dart'; // This would crash dart2js. |
| 21 |
| 22 // Importing dart:html to make things interesting. |
| 23 import 'dart:html'; |
| 24 |
| 25 class MirrorPrinter { |
| 26 final StringBuffer buffer; |
| 27 final TypeMirror dynamicType = currentMirrorSystem().dynamicType; |
| 28 |
| 29 int indentationLevel = 0; |
| 30 |
| 31 MirrorPrinter(this.buffer); |
| 32 |
| 33 void w(object) { |
| 34 buffer.write(object); |
| 35 } |
| 36 |
| 37 n(Symbol symbol) => MirrorSystem.getName(symbol); |
| 38 |
| 39 void indented(action) { |
| 40 indentationLevel++; |
| 41 action(); |
| 42 indentationLevel--; |
| 43 } |
| 44 |
| 45 get indent { |
| 46 for (int i = 0; i < indentationLevel; i++) { |
| 47 w(' '); |
| 48 } |
| 49 } |
| 50 |
| 51 String stringifyInstance(InstanceMirror mirror) { |
| 52 var reflectee = mirror.reflectee; |
| 53 if (reflectee is String) return '"${reflectee}"'; |
| 54 if (reflectee is Null || reflectee is bool || reflectee is num || |
| 55 reflectee is List || reflectee is Map) { |
| 56 return '$reflectee'; |
| 57 } |
| 58 StringBuffer buffer = new StringBuffer(); |
| 59 Map<Symbol, VariableMirror> variables = mirror.type.variables; |
| 60 buffer |
| 61 ..write(n(mirror.type.simpleName)) |
| 62 ..write('('); |
| 63 bool first = true; |
| 64 variables.forEach((Symbol name, VariableMirror variable) { |
| 65 if (variable.isStatic) return; |
| 66 // TODO(ahe): Include superclasses. |
| 67 if (first) { |
| 68 first = false; |
| 69 } else { |
| 70 buffer.write(', '); |
| 71 } |
| 72 buffer |
| 73 ..write(n(name)) |
| 74 ..write(': ') |
| 75 ..write(stringifyInstance(mirror.getField(name))); |
| 76 }); |
| 77 return buffer |
| 78 ..write(')') |
| 79 ..toString(); |
| 80 } |
| 81 |
| 82 String stringifyMetadata(InstanceMirror mirror) { |
| 83 return '@${stringifyInstance(mirror)}'; |
| 84 } |
| 85 |
| 86 bool writeType(TypeMirror mirror) { |
| 87 if (mirror == null || mirror == dynamicType) return false; |
| 88 w('${n(mirror.simpleName)} '); |
| 89 return true; |
| 90 } |
| 91 |
| 92 writeVariable(VariableMirror mirror) { |
| 93 bool needsVar = true; |
| 94 if (mirror.isStatic) w('static '); |
| 95 // TODO(ahe): What about const? |
| 96 if (mirror.isFinal) { |
| 97 w('final '); |
| 98 needsVar = false; |
| 99 } |
| 100 |
| 101 if (writeType(mirror.type)) needsVar = false; |
| 102 |
| 103 if (needsVar) { |
| 104 w('var '); |
| 105 } |
| 106 w('${n(mirror.simpleName)};'); |
| 107 } |
| 108 |
| 109 writeMethod(MethodMirror mirror) { |
| 110 writeType(mirror.returnType); |
| 111 if (mirror.isOperator) { |
| 112 w('operator '); |
| 113 } |
| 114 if (mirror.isGetter) { |
| 115 w('get '); |
| 116 } |
| 117 if (mirror.isSetter) { |
| 118 w('set '); |
| 119 } |
| 120 w('${n(mirror.simpleName)}'); |
| 121 if (!mirror.isGetter) { |
| 122 w('()'); |
| 123 } |
| 124 w(';'); |
| 125 } |
| 126 |
| 127 writeClass(ClassMirror mirror) { |
| 128 // TODO(ahe): Write 'abstract' if [mirror] is abstract. |
| 129 w('class ${n(mirror.simpleName)}'); |
| 130 // TODO(ahe): Write superclass and interfaces. |
| 131 w(' {'); |
| 132 bool first = true; |
| 133 indented(() { |
| 134 for (DeclarationMirror declaration in mirror.members.values) { |
| 135 if (first) { |
| 136 first = false; |
| 137 } else { |
| 138 w('\n'); |
| 139 } |
| 140 writeDeclaration(declaration); |
| 141 } |
| 142 }); |
| 143 w('\n}\n'); |
| 144 } |
| 145 |
| 146 writeDeclaration(DeclarationMirror declaration) { |
| 147 w('\n'); |
| 148 var metadata = declaration.metadata; |
| 149 if (!metadata.isEmpty) { |
| 150 indent; |
| 151 buffer.writeAll(metadata.map(stringifyMetadata), ' '); |
| 152 w('\n'); |
| 153 } |
| 154 indent; |
| 155 if (declaration is ClassMirror) { |
| 156 writeClass(declaration); |
| 157 } else if (declaration is VariableMirror) { |
| 158 writeVariable(declaration); |
| 159 } else if (declaration is MethodMirror) { |
| 160 writeMethod(declaration); |
| 161 } else { |
| 162 // TODO(ahe): Test other subclasses of DeclarationMirror. |
| 163 w('$declaration'); |
| 164 } |
| 165 } |
| 166 |
| 167 writeLibrary(LibraryMirror library) { |
| 168 w('library ${n(library.simpleName)};\n\n'); |
| 169 library.members.values.forEach(writeDeclaration); |
| 170 w('\n'); |
| 171 } |
| 172 |
| 173 static StringBuffer stringify(Map<Uri, LibraryMirror> libraries) { |
| 174 StringBuffer buffer = new StringBuffer(); |
| 175 libraries.values.forEach(new MirrorPrinter(buffer).writeLibrary); |
| 176 return buffer; |
| 177 } |
| 178 } |
| 179 |
| 180 main() { |
| 181 print(MirrorPrinter.stringify(currentMirrorSystem().libraries)); |
| 182 } |
| OLD | NEW |