Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // VM-specific implementation of the dart:mirrors library. | 5 // VM-specific implementation of the dart:mirrors library. |
| 6 | 6 |
| 7 // These values are allowed to be passed directly over the wire. | 7 // These values are allowed to be passed directly over the wire. |
| 8 bool isSimpleValue(var value) { | 8 bool isSimpleValue(var value) { |
| 9 return (value === null || value is num || value is String || value is bool); | 9 return (value === null || value is num || value is String || value is bool); |
| 10 } | 10 } |
| 11 | 11 |
| 12 abstract class _LocalMirrorImpl implements Mirror { | 12 abstract class _LocalMirrorImpl implements Mirror { |
| 13 // Local mirrors always return the same IsolateMirror. This field | 13 // Local mirrors always return the same IsolateMirror. This field |
| 14 // is more interesting once we implement remote mirrors. | 14 // is more interesting once we implement remote mirrors. |
| 15 IsolateMirror get isolate() { return Mirrors.localIsolateMirror(); } | 15 IsolateMirror get isolate() { return _Mirrors.currentIsolateMirror(); } |
| 16 } | 16 } |
| 17 | 17 |
| 18 class _LocalIsolateMirrorImpl extends _LocalMirrorImpl | 18 class _LocalIsolateMirrorImpl extends _LocalMirrorImpl |
| 19 implements IsolateMirror { | 19 implements IsolateMirror { |
| 20 _LocalIsolateMirrorImpl(this.debugName, this.rootLibrary, this.libraries) {} | 20 _LocalIsolateMirrorImpl(this.debugName, this.rootLibrary, this._libraries) {} |
| 21 | 21 |
| 22 final String debugName; | 22 final String debugName; |
| 23 final LibraryMirror rootLibrary; | 23 final LibraryMirror rootLibrary; |
| 24 final Map<String, LibraryMirror> libraries; | 24 final Map<String, LibraryMirror> _libraries; |
| 25 | |
| 26 Map<String, LibraryMirror> libraries() { return _libraries; } | |
| 27 | |
| 28 String toString() { | |
| 29 return "IsolateMirror on '$debugName'"; | |
| 30 } | |
| 25 } | 31 } |
| 26 | 32 |
| 27 // A VMReference is used to hold a reference to a VM-internal object, | 33 // A VMReference is used to hold a reference to a VM-internal object, |
| 28 // which can include things like libraries, classes, etc. | 34 // which can include things like libraries, classes, etc. |
| 29 class VMReference extends NativeFieldWrapperClass1 { | 35 class VMReference extends NativeFieldWrapperClass1 { |
| 30 } | 36 } |
| 31 | 37 |
| 32 abstract class _LocalVMObjectMirrorImpl extends _LocalMirrorImpl { | 38 abstract class _LocalVMObjectMirrorImpl extends _LocalMirrorImpl { |
| 33 _LocalVMObjectMirrorImpl(this._reference) {} | 39 _LocalVMObjectMirrorImpl(this._reference) {} |
| 34 | 40 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 46 Future<InstanceMirror> invoke(String memberName, | 52 Future<InstanceMirror> invoke(String memberName, |
| 47 List<Object> positionalArguments, | 53 List<Object> positionalArguments, |
| 48 [Map<String,Object> namedArguments]) { | 54 [Map<String,Object> namedArguments]) { |
| 49 if (namedArguments !== null) { | 55 if (namedArguments !== null) { |
| 50 throw new NotImplementedException('named arguments not implemented'); | 56 throw new NotImplementedException('named arguments not implemented'); |
| 51 } | 57 } |
| 52 // Walk the arguments and make sure they are legal. | 58 // Walk the arguments and make sure they are legal. |
| 53 for (int i = 0; i < positionalArguments.length; i++) { | 59 for (int i = 0; i < positionalArguments.length; i++) { |
| 54 var arg = positionalArguments[i]; | 60 var arg = positionalArguments[i]; |
| 55 if (arg is Mirror) { | 61 if (arg is Mirror) { |
| 56 throw new MirrorException( | 62 if (arg is! InstanceMirror) { |
| 57 'positional argument $i ($arg) was not an InstanceMirror'); | 63 throw new MirrorException( |
| 58 } | 64 'positional argument $i ($arg) was not an InstanceMirror'); |
| 59 if (!isSimpleValue(arg)) { | 65 } |
| 66 } else if (!isSimpleValue(arg)) { | |
| 60 throw new MirrorException( | 67 throw new MirrorException( |
| 61 'positional argument $i ($arg) was not a simple value'); | 68 'positional argument $i ($arg) was not a simple value'); |
| 62 } | 69 } |
| 63 } | 70 } |
| 64 Completer<InstanceMirror> completer = new Completer<InstanceMirror>(); | 71 Completer<InstanceMirror> completer = new Completer<InstanceMirror>(); |
| 65 completer.complete( | 72 try { |
| 66 _invoke(this, memberName, positionalArguments)); | 73 completer.complete( |
| 74 _invoke(this, memberName, positionalArguments)); | |
| 75 } catch (var exception) { | |
| 76 completer.completeException(exception); | |
| 77 } | |
| 67 return completer.future; | 78 return completer.future; |
| 68 } | 79 } |
| 69 | 80 |
| 70 static _invoke(ref, memberName, positionalArguments) | 81 static _invoke(ref, memberName, positionalArguments) |
| 71 native 'LocalObjectMirrorImpl_invoke'; | 82 native 'LocalObjectMirrorImpl_invoke'; |
| 72 } | 83 } |
| 73 | 84 |
| 85 // Prints a string as it might appear in dart program text. | |
| 86 // TODO(turnidge): Consider truncating. | |
| 87 String _dartEscape(String str) { | |
| 88 bool isNice(int code) { | |
| 89 return (code >= 32 && code <= 126); | |
| 90 } | |
| 91 | |
| 92 StringBuffer buf = new StringBuffer(); | |
| 93 for (int i = 0; i < str.length; i++) { | |
| 94 var input = str[i]; | |
| 95 String output; | |
| 96 switch (input) { | |
| 97 case "\\" : | |
| 98 output = "\\\\"; | |
|
Ivan Posva
2012/06/11 16:45:02
You could also use raw strings here. Then the inpu
turnidge
2012/06/12 20:51:46
Oh, forgot about raw strings. Thanks.
| |
| 99 break; | |
| 100 case "\'" : | |
| 101 output = "\\'"; | |
| 102 break; | |
| 103 case '\n' : | |
| 104 output = '\\n'; | |
| 105 break; | |
| 106 case '\r' : | |
| 107 output = '\\r'; | |
| 108 break; | |
| 109 case '\f' : | |
| 110 output = '\\f'; | |
| 111 break; | |
| 112 case '\b' : | |
| 113 output = '\\b'; | |
| 114 break; | |
| 115 case '\t' : | |
| 116 output = '\\t'; | |
| 117 break; | |
| 118 case '\v' : | |
| 119 output = '\\v'; | |
| 120 break; | |
| 121 default: | |
| 122 int code = input.charCodeAt(0); | |
| 123 if (isNice(code)) { | |
| 124 output = input; | |
| 125 } else { | |
| 126 output = '\\u{${code.toRadixString(16)}}'; | |
| 127 } | |
| 128 break; | |
| 129 } | |
| 130 buf.add(output); | |
| 131 } | |
| 132 return buf.toString(); | |
| 133 } | |
| 134 | |
| 74 class _LocalInstanceMirrorImpl extends _LocalObjectMirrorImpl | 135 class _LocalInstanceMirrorImpl extends _LocalObjectMirrorImpl |
| 75 implements InstanceMirror { | 136 implements InstanceMirror { |
| 76 _LocalInstanceMirrorImpl(ref, this.simpleValue) : super(ref) {} | 137 _LocalInstanceMirrorImpl(ref, |
| 77 | 138 this._class, |
| 78 final simpleValue; | 139 this.hasSimpleValue, |
| 140 this._simpleValue) : super(ref) {} | |
| 141 | |
| 142 var _class; | |
| 143 InterfaceMirror getClass() { | |
| 144 if (_class is _LazyInterfaceMirror) { | |
| 145 _class = _class.resolve(isolate); | |
| 146 } | |
| 147 return _class; | |
| 148 } | |
| 149 | |
| 150 bool hasSimpleValue; | |
| 151 | |
| 152 var _simpleValue; | |
| 153 get simpleValue() { | |
| 154 if (!hasSimpleValue) { | |
| 155 throw new MirrorException( | |
| 156 "Before accesing simpleValue you must check that hasSimpleValue " | |
| 157 "is true"); | |
| 158 } | |
| 159 return _simpleValue; | |
| 160 } | |
| 161 | |
| 162 String toString() { | |
| 163 if (hasSimpleValue) { | |
| 164 if (simpleValue is String) { | |
| 165 return "InstanceMirror on <'${_dartEscape(simpleValue)}'>"; | |
| 166 } else { | |
| 167 return "InstanceMirror on <$simpleValue>"; | |
| 168 } | |
| 169 } else { | |
| 170 return "InstanceMirror on instance of '${getClass().simpleName}'"; | |
| 171 } | |
| 172 } | |
| 173 } | |
| 174 | |
| 175 class _LazyInterfaceMirror { | |
| 176 _LazyInterfaceMirror(this.libraryName, this.interfaceName) {} | |
| 177 | |
| 178 InterfaceMirror resolve(IsolateMirror isolate) { | |
| 179 return isolate.libraries()[libraryName].members()[interfaceName]; | |
| 180 } | |
| 181 | |
| 182 final String libraryName; | |
| 183 final String interfaceName; | |
| 184 } | |
| 185 | |
| 186 class _LocalInterfaceMirrorImpl extends _LocalObjectMirrorImpl | |
| 187 implements InterfaceMirror { | |
| 188 _LocalInterfaceMirrorImpl(ref, | |
| 189 this.simpleName, | |
| 190 this.isClass, | |
| 191 this._library, | |
| 192 this._superclass, | |
| 193 this._superinterfaces, | |
| 194 this._defaultFactory) : super(ref) {} | |
| 195 | |
| 196 final String simpleName; | |
| 197 final bool isClass; | |
| 198 | |
| 199 var _library; | |
| 200 LibraryMirror get library() { | |
| 201 if (_library is _LazyLibraryMirror) { | |
| 202 _library = _library.resolve(isolate); | |
| 203 } | |
| 204 return _library; | |
| 205 } | |
| 206 | |
| 207 var _superclass; | |
| 208 InterfaceMirror superclass() { | |
|
Ivan Posva
2012/06/11 16:45:02
There seems to a mismatch between getters and meth
turnidge
2012/06/12 20:51:46
I agree that there is a mismatch between getters a
| |
| 209 if (_superclass is _LazyInterfaceMirror) { | |
| 210 _superclass = _superclass.resolve(isolate); | |
| 211 } | |
| 212 return _superclass; | |
| 213 } | |
| 214 | |
| 215 var _superinterfaces; | |
| 216 List<InterfaceMirror> superinterfaces() { | |
|
Ivan Posva
2012/06/11 16:45:02
ditto
| |
| 217 if (_superinterfaces.length > 0 && | |
| 218 _superinterfaces[0] is _LazyInterfaceMirror) { | |
| 219 List<InterfaceMirror> resolved = new List<InterfaceMirror>(); | |
| 220 for (int i = 0; i < _superinterfaces.length; i++) { | |
| 221 resolved.add(_superinterfaces[i].resolve(isolate)); | |
| 222 } | |
| 223 _superinterfaces = resolved; | |
| 224 } | |
| 225 return _superinterfaces; | |
| 226 } | |
| 227 | |
| 228 var _defaultFactory; | |
| 229 InterfaceMirror defaultFactory() { | |
|
Ivan Posva
2012/06/11 16:45:02
ditto.
| |
| 230 if (_defaultFactory is _LazyInterfaceMirror) { | |
| 231 _defaultFactory = _defaultFactory.resolve(isolate); | |
| 232 } | |
| 233 return _defaultFactory; | |
| 234 } | |
| 235 | |
| 236 String toString() { | |
| 237 return "InterfaceMirror on '$simpleName'"; | |
| 238 } | |
| 239 } | |
| 240 | |
| 241 class _LazyLibraryMirror { | |
| 242 _LazyLibraryMirror(this.libraryName) {} | |
| 243 | |
| 244 LibraryMirror resolve(IsolateMirror isolate) { | |
| 245 return isolate.libraries()[libraryName]; | |
| 246 } | |
| 247 | |
| 248 final String libraryName; | |
| 79 } | 249 } |
| 80 | 250 |
| 81 class _LocalLibraryMirrorImpl extends _LocalObjectMirrorImpl | 251 class _LocalLibraryMirrorImpl extends _LocalObjectMirrorImpl |
| 82 implements LibraryMirror { | 252 implements LibraryMirror { |
| 83 _LocalLibraryMirrorImpl(ref, this.simpleName, this.url) : super(ref) {} | 253 _LocalLibraryMirrorImpl(ref, |
| 254 this.simpleName, | |
| 255 this.url, | |
| 256 this._members) : super(ref) {} | |
| 84 | 257 |
| 85 final String simpleName; | 258 final String simpleName; |
| 86 final String url; | 259 final String url; |
| 260 Map<String, InterfaceMirror> _members; | |
| 261 | |
| 262 Map<String, Mirror> members() { return _members; } | |
| 263 | |
| 264 String toString() { | |
| 265 return "LibraryMirror on '$simpleName'"; | |
| 266 } | |
| 87 } | 267 } |
| 88 | 268 |
| 89 class _Mirrors { | 269 class _Mirrors { |
| 90 // Does a port refer to our local isolate? | 270 // Does a port refer to our local isolate? |
| 91 static bool isLocalPort(SendPort port) native 'Mirrors_isLocalPort'; | 271 static bool isLocalPort(SendPort port) native 'Mirrors_isLocalPort'; |
| 92 | 272 |
| 93 static IsolateMirror _localIsolateMirror; | 273 static IsolateMirror _currentIsolateMirror = null; |
| 94 | |
| 95 // The IsolateMirror for the current isolate. | |
| 96 static IsolateMirror localIsolateMirror() { | |
| 97 if (_localIsolateMirror === null) { | |
| 98 _localIsolateMirror = makeLocalIsolateMirror(); | |
| 99 } | |
| 100 return _localIsolateMirror; | |
| 101 } | |
| 102 | 274 |
| 103 // Creates a new local IsolateMirror. | 275 // Creates a new local IsolateMirror. |
| 104 static IsolateMirror makeLocalIsolateMirror() | 276 static IsolateMirror makeLocalIsolateMirror() |
| 105 native 'Mirrors_makeLocalIsolateMirror'; | 277 native 'Mirrors_makeLocalIsolateMirror'; |
| 106 | 278 |
| 279 // The IsolateMirror for the current isolate. | |
| 280 static IsolateMirror currentIsolateMirror() { | |
| 281 if (_currentIsolateMirror === null) { | |
| 282 _currentIsolateMirror = makeLocalIsolateMirror(); | |
| 283 } | |
| 284 return _currentIsolateMirror; | |
| 285 } | |
| 286 | |
| 107 static Future<IsolateMirror> isolateMirrorOf(SendPort port) { | 287 static Future<IsolateMirror> isolateMirrorOf(SendPort port) { |
| 108 Completer<IsolateMirror> completer = new Completer<IsolateMirror>(); | 288 Completer<IsolateMirror> completer = new Completer<IsolateMirror>(); |
| 109 if (isLocalPort(port)) { | 289 if (isLocalPort(port)) { |
| 110 // Make a local isolate mirror. | 290 // Make a local isolate mirror. |
| 111 completer.complete(localIsolateMirror()); | 291 try { |
| 292 completer.complete(currentIsolateMirror()); | |
| 293 } catch (var exception) { | |
| 294 completer.completeException(exception); | |
| 295 } | |
| 112 } else { | 296 } else { |
| 113 // Make a remote isolate mirror. | 297 // Make a remote isolate mirror. |
| 114 throw new NotImplementedException('Remote mirrors not yet implemented'); | 298 throw new NotImplementedException('Remote mirrors not yet implemented'); |
| 115 } | 299 } |
| 116 return completer.future; | 300 return completer.future; |
| 117 } | 301 } |
| 118 } | 302 |
| 303 // Creates a new local InstanceMirror | |
| 304 static InstanceMirror makeLocalInstanceMirror(Object reflectee) | |
| 305 native 'Mirrors_makeLocalInstanceMirror'; | |
| 306 | |
| 307 // The IsolateMirror for the current isolate. | |
| 308 static InstanceMirror mirrorOf(Object reflectee) { | |
| 309 return makeLocalInstanceMirror(reflectee); | |
| 310 } | |
| 311 } | |
| OLD | NEW |