Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 #library('mirrors.dart2js'); | |
| 6 | |
| 7 #import('../../compiler/compiler.dart', prefix: 'diagnostics'); | |
| 8 #import('../../compiler/implementation/elements/elements.dart'); | |
| 9 #import('../../compiler/implementation/apiimpl.dart', prefix: 'api'); | |
| 10 #import('../../compiler/implementation/scanner/scannerlib.dart'); | |
| 11 #import('../../compiler/implementation/leg.dart'); | |
| 12 #import('../../compiler/implementation/filenames.dart'); | |
| 13 #import('../../compiler/implementation/source_file.dart'); | |
| 14 #import('../../compiler/implementation/tree/tree.dart'); | |
| 15 #import('../../compiler/implementation/util/util.dart'); | |
| 16 #import('../../compiler/implementation/util/uri_extras.dart'); | |
| 17 #import('../../compiler/implementation/dart2js.dart'); | |
| 18 #import('mirrors.dart'); | |
| 19 #import('util.dart'); | |
| 20 #import('dart:io'); | |
| 21 #import('dart:uri'); | |
| 22 | |
| 23 | |
| 24 /////////////////////////////////////////////////////// | |
| 25 // utility types and functions | |
| 26 /////////////////////////////////////////////////////// | |
| 27 | |
| 28 bool _isPrivate(String name) { | |
| 29 return name.startsWith('_'); | |
| 30 } | |
| 31 | |
| 32 List<ParameterMirror> _parametersFromFunctionSignature( | |
| 33 Dart2jsMirrorSystem system, | |
| 34 Dart2jsMethodMirror method, | |
| 35 FunctionSignature signature) | |
| 36 { | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Brace on previous line.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 37 var parameters = <ParameterMirror>[]; | |
| 38 var link = signature.requiredParameters; | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Write the type of the variable.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 39 while (!link.isEmpty()) { | |
| 40 parameters.add(new Dart2jsParameterMirror(system, method, | |
| 41 link.head, false)); | |
| 42 link = link.tail; | |
| 43 } | |
| 44 link = signature.optionalParameters; | |
| 45 while (!link.isEmpty()) { | |
| 46 parameters.add(new Dart2jsParameterMirror(system, method, | |
| 47 link.head, true)); | |
| 48 link = link.tail; | |
| 49 } | |
| 50 return parameters; | |
| 51 } | |
| 52 | |
| 53 Dart2jsTypeMirror _typeConverter(Dart2jsMirrorSystem system, | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Seems like it should be called _convertType? I.e.,
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 54 Type type, | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
indentation.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 55 InterfaceType defaultType, | |
| 56 [FunctionSignature functionSignature]) | |
| 57 { | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Brace on previous line.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 58 if (type === null) { | |
| 59 return new Dart2jsInterfaceTypeMirror(system, defaultType); | |
| 60 } else if (type is InterfaceType) { | |
| 61 return new Dart2jsInterfaceTypeMirror(system, type); | |
| 62 } else if (type is TypeVariableType) { | |
| 63 return new Dart2jsTypeVariableMirror(system, type); | |
| 64 } else if (type is FunctionType) { | |
| 65 if (type.element is TypedefElement) { | |
| 66 return new Dart2jsTypedefMirror(system, type.element); | |
| 67 } else { | |
| 68 return new Dart2jsFunctionTypeMirror(system, type, functionSignature); | |
| 69 } | |
| 70 } else if (type is VoidType) { | |
| 71 return new Dart2jsVoidMirror(system, type); | |
| 72 } | |
| 73 throw new IllegalArgumentException("Unexpected interface type $type"); | |
| 74 } | |
| 75 | |
| 76 Collection<Dart2jsMemberMirror> _memberConverter(Dart2jsObjectMirror library, | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
_convertMember?
Or even better, say something abou
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 77 Element element) | |
| 78 { | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Brace on previous line.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 79 if (element is SynthesizedConstructorElement) { | |
| 80 return const <Dart2jsMemberMirror>[]; | |
| 81 } else if (element is VariableElement) { | |
| 82 return [new Dart2jsFieldMirror(library, element)]; | |
| 83 } else if (element is FunctionElement) { | |
| 84 return [new Dart2jsMethodMirror(library, element)]; | |
| 85 } else if (element is AbstractFieldElement) { | |
| 86 var members = <Dart2jsMemberMirror>[]; | |
| 87 if (element.getter !== null) { | |
| 88 members.add(new Dart2jsMethodMirror(library, element.getter, | |
| 89 Dart2jsMethodKind.GETTER)); | |
| 90 } | |
| 91 if (element.setter !== null) { | |
| 92 members.add(new Dart2jsMethodMirror(library, element.setter, | |
| 93 Dart2jsMethodKind.SETTER)); | |
| 94 } | |
| 95 return members; | |
| 96 } | |
| 97 throw new IllegalArgumentException( | |
| 98 "Unexpected member type $element ${element.kind}"); | |
| 99 } | |
| 100 | |
| 101 MethodMirror _methodConverter(Dart2jsObjectMirror library, Element element) { | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
_convertMethod?
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 102 if (element is FunctionElement) { | |
| 103 return new Dart2jsMethodMirror(library, element); | |
| 104 } else if (element is TypedefElement) { | |
| 105 // TODO(johnniwinther): How to wrap typedefs? | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
How is a typedef a method?
Johnni Winther
2012/07/03 07:38:50
They don't seem to be. Case removed.
| |
| 106 return null; | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 class Dart2jsMethodKind { | |
| 111 static final Dart2jsMethodKind NORMAL = const Dart2jsMethodKind("normal"); | |
| 112 static final Dart2jsMethodKind CONSTRUCTOR | |
| 113 = const Dart2jsMethodKind("constructor"); | |
| 114 static final Dart2jsMethodKind CONST = const Dart2jsMethodKind("const"); | |
| 115 static final Dart2jsMethodKind FACTORY = const Dart2jsMethodKind("factory"); | |
| 116 static final Dart2jsMethodKind GETTER = const Dart2jsMethodKind("getter"); | |
| 117 static final Dart2jsMethodKind SETTER = const Dart2jsMethodKind("setter"); | |
| 118 static final Dart2jsMethodKind OPERATOR = const Dart2jsMethodKind("operator"); | |
| 119 | |
| 120 final String text; | |
| 121 | |
| 122 const Dart2jsMethodKind(this.text); | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Make a toString() for debugging. Otherwise someone
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 123 } | |
| 124 | |
| 125 String _getOperatorFromOperatorName(String str) { | |
| 126 if (str == 'eq') return '=='; | |
| 127 else if (str == 'not') return '~'; | |
| 128 else if (str == 'negate') return 'negate'; | |
| 129 else if (str == 'index') return '[]'; | |
| 130 else if (str == 'indexSet') return '[]='; | |
| 131 else if (str == 'mul') return '*'; | |
| 132 else if (str == 'div') return '/'; | |
| 133 else if (str == 'mod') return '%'; | |
| 134 else if (str == 'tdiv') return '~/'; | |
| 135 else if (str == 'add') return '+'; | |
| 136 else if (str == 'sub') return '-'; | |
| 137 else if (str == 'shl') return '<<'; | |
| 138 else if (str == 'shr') return '>>'; | |
| 139 else if (str == 'ge') return '>='; | |
| 140 else if (str == 'gt') return '>'; | |
| 141 else if (str == 'le') return '<='; | |
| 142 else if (str == 'lt') return '<'; | |
| 143 else if (str == 'and') return '&'; | |
| 144 else if (str == 'xor') return '^'; | |
| 145 else if (str == 'or') return '|'; | |
| 146 else { | |
| 147 throw new Exception('Unhandled operator name: $str'); | |
| 148 } | |
| 149 } | |
| 150 | |
| 151 class Dart2jsDiagnosticListener implements DiagnosticListener { | |
| 152 const Dart2jsDiagnosticListener(); | |
| 153 | |
| 154 void cancel([String reason, node, token, instruction, element]) { | |
| 155 print(reason); | |
| 156 } | |
| 157 | |
| 158 void log(message) { | |
| 159 print(message); | |
| 160 } | |
| 161 } | |
| 162 | |
| 163 class LinkIterableAdapter<A,B> implements Iterable<B> { | |
| 164 final Link<A> _link; | |
| 165 final Converter<A,B> _converter; | |
| 166 | |
| 167 LinkIterableAdapter(this._link, this._converter); | |
| 168 | |
| 169 Iterator<B> iterator() { | |
| 170 return new LinkIteratorAdapter<A,B>(_link, _converter); | |
| 171 } | |
| 172 } | |
| 173 | |
| 174 class LinkIteratorAdapter<A,B> implements Iterator<B> { | |
| 175 Link<A> _link; | |
| 176 final Converter<A,B> _converter; | |
| 177 | |
| 178 LinkIteratorAdapter(this._link, this._converter); | |
| 179 | |
| 180 bool hasNext() => _link != null && _link.head != null; | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
An empty linked list is "const EmptyLink<A>()". It
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 181 | |
| 182 B next() { | |
| 183 if (hasNext()) { | |
| 184 var val = _converter(_link.head); | |
| 185 _link = _link.tail; | |
| 186 return val; | |
| 187 } | |
| 188 throw new NoMoreElementsException(); | |
| 189 } | |
| 190 } | |
| 191 | |
| 192 /////////////////////////////////////////////////////// | |
| 193 // compilation | |
| 194 /////////////////////////////////////////////////////// | |
| 195 | |
| 196 class Dart2jsCompilation implements Compilation { | |
| 197 api.Compiler _compiler; | |
| 198 Uri cwd; | |
| 199 bool isAborting = false; | |
| 200 Map<String, SourceFile> sourceFiles; | |
| 201 | |
| 202 Future<String> provider(Uri uri) { | |
| 203 if (uri.scheme != 'file') { | |
| 204 throw new IllegalArgumentException(uri); | |
| 205 } | |
| 206 String source; | |
| 207 try { | |
| 208 source = readAll(uriPathToNative(uri.path)); | |
| 209 } catch (FileIOException ex) { | |
| 210 throw 'Error: Cannot read "${relativize(cwd, uri)}" (${ex.osError}).'; | |
| 211 } | |
| 212 sourceFiles[uri.toString()] = | |
| 213 new SourceFile(relativize(cwd, uri), source); | |
| 214 return new Future.immediate(source); | |
| 215 } | |
| 216 | |
| 217 void handler(Uri uri, int begin, int end, | |
| 218 String message, diagnostics.Diagnostic kind) | |
| 219 { | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Brace on previous line (and ditto for all later in
| |
| 220 bool fatal = | |
| 221 kind === diagnostics.Diagnostic.CRASH || | |
| 222 kind === diagnostics.Diagnostic.ERROR; | |
| 223 if (isAborting) return; | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Move this above "fatal" declaration.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 224 if (uri === null && !fatal) { | |
| 225 return; | |
| 226 } | |
| 227 if (uri === null) { | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
move "if (!fatal) return" in here. I recommend kee
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 228 assert(fatal); | |
| 229 print(message); | |
| 230 } else if (fatal) { | |
| 231 SourceFile file = sourceFiles[uri.toString()]; | |
| 232 print(file.getLocationMessage(message, begin, end, true, (s) => s)); | |
| 233 } | |
| 234 if (fatal) { | |
| 235 throw message; | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Put "throw message" at the end of both of the prio
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 236 } | |
| 237 } | |
| 238 | |
| 239 Dart2jsCompilation(String script, String libraryRoot, | |
| 240 [String packageRoot, List<String> opts = const []]) | |
| 241 : cwd = getCurrentDirectory(), | |
| 242 sourceFiles = <SourceFile>{} | |
| 243 { | |
| 244 var libraryUri = cwd.resolve(nativeToUriPath(libraryRoot)); | |
| 245 var packageUri; | |
| 246 if (packageRoot !== null) { | |
| 247 packageUri = cwd.resolve(nativeToUriPath(packageRoot)); | |
| 248 } else { | |
| 249 packageUri = libraryUri; | |
| 250 } | |
| 251 _compiler = new api.Compiler(provider, handler, | |
| 252 libraryUri, packageUri, <String>[]); | |
| 253 var scriptUri = cwd.resolve(nativeToUriPath(script)); | |
| 254 // TODO(johnniwinther): Detect file not found | |
| 255 _compiler.run(scriptUri); | |
| 256 } | |
| 257 | |
| 258 void addLibrary(String path) { | |
| 259 var uri = cwd.resolve(nativeToUriPath(path)); | |
| 260 _compiler.scanner.loadLibrary(uri, null); | |
| 261 } | |
| 262 | |
| 263 MirrorSystem mirrors() => new Dart2jsMirrorSystem(_compiler); | |
| 264 } | |
| 265 | |
| 266 /////////////////////////////////////////////////////// | |
| 267 // interface extensions | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
What does that mean?
Capitalize/Title-case the hea
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 268 /////////////////////////////////////////////////////// | |
| 269 | |
| 270 interface Dart2jsMirror extends Mirror { | |
| 271 /** | |
| 272 * A unique name used as the key in maps. | |
| 273 */ | |
| 274 final String canonicalName; | |
| 275 final Dart2jsMirrorSystem system; | |
| 276 } | |
| 277 | |
| 278 interface Dart2jsMemberMirror extends Dart2jsMirror, MemberMirror { | |
| 279 | |
| 280 } | |
| 281 | |
| 282 interface Dart2jsTypeMirror extends Dart2jsMirror, TypeMirror { | |
| 283 | |
| 284 } | |
| 285 | |
| 286 abstract class Dart2jsElementMirror implements Dart2jsMirror { | |
| 287 final Dart2jsMirrorSystem system; | |
| 288 final Element _element; | |
| 289 | |
| 290 Dart2jsElementMirror(this.system, this._element) { | |
| 291 assert (system !== null); | |
| 292 assert (_element !== null); | |
| 293 } | |
| 294 | |
| 295 String simpleName() => _element.name.slowToString(); | |
| 296 | |
| 297 Location location() => new Dart2jsLocation( | |
| 298 _element.getCompilationUnit().script, | |
| 299 system.compiler.spanFromElement(_element)); | |
| 300 | |
| 301 String toString() => _element.toString(); | |
| 302 } | |
| 303 | |
| 304 abstract class Dart2jsProxyMirror implements Dart2jsMirror { | |
| 305 final Dart2jsMirrorSystem system; | |
| 306 | |
| 307 Dart2jsProxyMirror(this.system); | |
| 308 } | |
| 309 | |
| 310 /////////////////////////////////////////////////////// | |
| 311 // implementation | |
| 312 /////////////////////////////////////////////////////// | |
| 313 | |
| 314 class Dart2jsMirrorSystem implements MirrorSystem, Dart2jsMirror { | |
| 315 final api.Compiler compiler; | |
| 316 final DiagnosticListener diagnosticListener | |
| 317 = const Dart2jsDiagnosticListener(); | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Why not make this static? Seems like a waste of sp
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 318 Map<String,Dart2jsLibraryMirror> _libraries; | |
| 319 Map<Object,LibraryMirror> _immutableLibraryMap; | |
| 320 Map<LibraryElement,Dart2jsLibraryMirror> _libraryMap; | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Space after comma. Ditto all other cases of this.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 321 | |
| 322 Dart2jsMirrorSystem(this.compiler) | |
| 323 : _libraryMap = new Map<LibraryElement,Dart2jsLibraryMirror>(); | |
| 324 | |
| 325 void _ensureLibraries() { | |
| 326 if (_libraries == null) { | |
| 327 _libraries = <Dart2jsLibraryMirror>{}; | |
| 328 compiler.libraries.forEach((_, LibraryElement v) { | |
| 329 var mirror = new Dart2jsLibraryMirror(system, v); | |
| 330 _libraries[mirror.canonicalName] = mirror; | |
| 331 _libraryMap[v] = mirror; | |
| 332 }); | |
| 333 _immutableLibraryMap | |
| 334 = new ImmutableMapWrapper<Object,LibraryMirror>(_libraries); | |
| 335 } | |
| 336 } | |
| 337 | |
| 338 Map<Object,LibraryMirror> libraries() { | |
| 339 _ensureLibraries(); | |
| 340 return _immutableLibraryMap; | |
| 341 } | |
| 342 | |
| 343 Dart2jsLibraryMirror getLibrary(LibraryElement element) { | |
| 344 return _libraryMap[element]; | |
| 345 } | |
| 346 | |
| 347 Dart2jsMirrorSystem get system() => this; | |
| 348 | |
| 349 String simpleName() => "mirror"; | |
| 350 String qualifiedName() => simpleName(); | |
| 351 | |
| 352 String get canonicalName() => simpleName(); | |
| 353 | |
| 354 Iterable<InterfaceMirror> computeSubdeclarations(InterfaceMirror type) { | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
I'm not absolutely convinced that we should have t
Johnni Winther
2012/07/03 07:38:50
I agree, I don't think it fits in the mirror syste
| |
| 355 _ensureLibraries(); | |
| 356 type = type.declaration; | |
| 357 var subtypes = <InterfaceMirror>[]; | |
| 358 _libraries.forEach((_,library) { | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Space after comma here too.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 359 for (InterfaceMirror otherType in library.types().getValues()) { | |
| 360 var superClass = otherType.superclass(); | |
| 361 if (superClass !== null) { | |
| 362 superClass = superClass.declaration; | |
| 363 if (type.library() === superClass.library()) { | |
| 364 if (superClass == type) { | |
| 365 subtypes.add(otherType); | |
| 366 } | |
| 367 } | |
| 368 } | |
| 369 for (InterfaceMirror superInterface | |
| 370 in otherType.interfaces().getValues()) | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Interesting indentation. Consider using a helper v
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 371 { | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Brace on precious line.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 372 superInterface = superInterface.declaration; | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
What is the difference between an interface and it
Johnni Winther
2012/07/03 07:38:50
[:interface List<E> ...:] is the declaration where
| |
| 373 if (type.library() === superInterface.library()) { | |
| 374 if (superInterface == type) { | |
| 375 subtypes.add(otherType); | |
| 376 } | |
| 377 } | |
| 378 } | |
| 379 } | |
| 380 }); | |
| 381 return subtypes; | |
| 382 } | |
| 383 } | |
| 384 | |
| 385 abstract class Dart2jsObjectMirror extends Dart2jsElementMirror | |
| 386 implements ObjectMirror | |
| 387 { | |
| 388 Dart2jsObjectMirror(Dart2jsMirrorSystem system, Element element) | |
| 389 : super(system, element); | |
| 390 } | |
| 391 | |
| 392 class Dart2jsLibraryMirror extends Dart2jsObjectMirror | |
| 393 implements LibraryMirror | |
| 394 { | |
| 395 final LibraryElement _library; | |
| 396 Map<String,InterfaceMirror> _types; | |
| 397 Map<Object,InterfaceMirror> _immutableTypesMap; | |
| 398 Map<String,MemberMirror> _members; | |
| 399 Map<Object,MemberMirror> _immutableMembersMap; | |
| 400 | |
| 401 Dart2jsLibraryMirror(Dart2jsMirrorSystem system, LibraryElement library) : | |
| 402 this._library = library, | |
| 403 super(system, library); | |
| 404 | |
| 405 String get canonicalName() => simpleName(); | |
| 406 | |
| 407 | |
| 408 /** | |
| 409 * Returns the library name (as defined by the #library tag) or for script | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Parenthesized comments are different in nature, wh
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 410 * (which have no #library tag) the script file name. The latter case is used | |
| 411 * to private 'library name' for scripts to use for instance in dartdoc. | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
"to private"? Something missing?
Johnni Winther
2012/07/03 07:38:50
Done.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 412 */ | |
| 413 String simpleName() { | |
| 414 if (_library.libraryTag !== null) { | |
| 415 return _library.libraryTag.argument.dartString.slowToString(); | |
| 416 } else { | |
| 417 // Use the file name as script name. | |
| 418 var path = _library.script.uri.path; | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Add typename for "path". I'm guessing "String", bu
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 419 return path.substring(path.lastIndexOf('/') + 1); | |
| 420 } | |
| 421 } | |
| 422 | |
| 423 String qualifiedName() => simpleName(); | |
| 424 | |
| 425 | |
| 426 void _ensureTypes() { | |
| 427 if (_types == null) { | |
| 428 _types = <InterfaceMirror>{}; | |
| 429 _library.forEachExport((Element e) { | |
| 430 if (e.getLibrary() == _library) { | |
| 431 if (e.isClass()) { | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Isn't isClass a getter? And isTypedef below?
(And
Johnni Winther
2012/07/03 07:38:50
They are methods (defined on Element). I don't kno
| |
| 432 var type = new Dart2jsInterfaceMirror.fromLibrary(this, e); | |
| 433 _types[type.canonicalName] = type; | |
| 434 } else if (e.isTypedef()) { | |
| 435 var type = new Dart2jsTypedefMirror.fromLibrary(this, e); | |
| 436 _types[type.canonicalName] = type; | |
| 437 } | |
| 438 } | |
| 439 }); | |
| 440 _immutableTypesMap | |
| 441 = new ImmutableMapWrapper<Object,InterfaceMirror>(_types); | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
'=' on previous line. Ditto in other places.
Johnni Winther
2012/07/03 07:38:50
The immutable map is no longer cached.
| |
| 442 } | |
| 443 } | |
| 444 | |
| 445 void _ensureMembers() { | |
| 446 if (_members == null) { | |
| 447 _members = <MemberMirror>{}; | |
| 448 _library.forEachExport((Element e) { | |
| 449 if (!(e.isClass() || e.isTypedef())) { | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
A little hard to read. Consider whether
if (!e.is
Johnni Winther
2012/07/03 07:38:50
Again, methods defined in Element.
| |
| 450 for (var member in _memberConverter(this, e)) { | |
| 451 _members[member.canonicalName] = member; | |
| 452 } | |
| 453 } | |
| 454 }); | |
| 455 _immutableMembersMap | |
| 456 = new ImmutableMapWrapper<Object,MemberMirror>(_members); | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Are you sure we want to cache the wrapper, and not
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 457 } | |
| 458 } | |
| 459 | |
| 460 Map<Object,MemberMirror> declaredMembers() { | |
| 461 _ensureMembers(); | |
| 462 return _immutableMembersMap; | |
| 463 } | |
| 464 | |
| 465 Map<Object,InterfaceMirror> types() { | |
| 466 _ensureTypes(); | |
| 467 return _immutableTypesMap; | |
| 468 } | |
| 469 | |
| 470 Location location() { | |
| 471 var script = _library.getCompilationUnit().script; | |
| 472 return new Dart2jsLocation( | |
| 473 script, | |
| 474 new SourceSpan(script.uri, 0, script.text.length)); | |
| 475 } | |
| 476 } | |
| 477 | |
| 478 class Dart2jsLocation implements Location { | |
| 479 Script _script; | |
| 480 SourceSpan _span; | |
| 481 | |
| 482 Dart2jsLocation(this._script, this._span); | |
| 483 | |
| 484 int start() => _span.begin; | |
| 485 int end() => _span.end; | |
| 486 Source source() => new Dart2jsSource(_script); | |
| 487 | |
| 488 String text() => _script.text.substring(start(), end()); | |
| 489 } | |
| 490 | |
| 491 class Dart2jsSource implements Source { | |
| 492 Script _script; | |
| 493 | |
| 494 Dart2jsSource(this._script); | |
| 495 | |
| 496 Uri uri() => _script.uri; | |
| 497 String text() => _script.text; | |
| 498 } | |
| 499 | |
| 500 class Dart2jsParameterMirror extends Dart2jsElementMirror | |
| 501 implements ParameterMirror { | |
| 502 final MethodMirror _method; | |
| 503 final VariableElement _variableElement; | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Don't store this twice, just make a getter for _el
| |
| 504 final bool _isOptional; | |
| 505 | |
| 506 Dart2jsParameterMirror(Dart2jsMirrorSystem system, | |
| 507 this._method, | |
| 508 VariableElement element, | |
| 509 this._isOptional) | |
| 510 : this._variableElement = element, | |
| 511 super(system, element); | |
| 512 | |
| 513 String get canonicalName() => simpleName(); | |
| 514 | |
| 515 String qualifiedName() => '${_method.qualifiedName()}#${simpleName()}'; | |
| 516 | |
| 517 // TODO(johnniwinther): Provide | |
| 518 // [:_variableElement.variables.functionSignature:] instead of [:null:]. | |
| 519 TypeMirror type() => _typeConverter(system, | |
| 520 _variableElement.computeType(system.compiler), | |
| 521 system.compiler.dynamicClass.computeType(system.compiler), | |
| 522 null); | |
| 523 | |
| 524 String defaultValue() => null; // TODO(johnniwinther): How to compute this? | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
The return type seems odd. Shouldn't this return a
Johnni Winther
2012/07/03 07:38:50
Yes, it's on the general TODO for the mirror syste
| |
| 525 | |
| 526 bool hasDefaultValue() => false; // TODO(johnniwinther): How to compute this? | |
| 527 | |
| 528 bool isOptional() => _isOptional; | |
| 529 } | |
| 530 | |
| 531 /////////////////////////////////////////////////////// | |
| 532 // declarations | |
| 533 /////////////////////////////////////////////////////// | |
| 534 | |
| 535 class Dart2jsInterfaceMirror extends Dart2jsObjectMirror | |
| 536 implements Dart2jsTypeMirror, InterfaceMirror | |
| 537 { | |
| 538 final Dart2jsLibraryMirror _library; | |
| 539 final ClassElement _class; | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Again, don't duplicate the superclass field, just
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 540 Map<String,Dart2jsMemberMirror> _members; | |
| 541 Map<Object,MemberMirror> _immutableMembersMap; | |
| 542 List<TypeVariableMirror> _typeVariables; | |
| 543 | |
| 544 Dart2jsInterfaceMirror(Dart2jsMirrorSystem system, ClassElement _class) | |
| 545 : this._library = system.getLibrary(_class.getLibrary()), | |
| 546 this._class = _class, | |
| 547 super(system, _class); | |
| 548 | |
| 549 Dart2jsInterfaceMirror.fromLibrary(Dart2jsLibraryMirror library, | |
| 550 ClassElement _class) | |
| 551 : this._library = library, | |
| 552 this._class = _class, | |
| 553 super(library.system, _class); | |
| 554 | |
| 555 String get canonicalName() => simpleName(); | |
| 556 | |
| 557 String qualifiedName() => '${library().qualifiedName()}.${simpleName()}'; | |
| 558 | |
| 559 Location location() { | |
| 560 if (_class is PartialClassElement) { | |
| 561 var node = _class.parseNode(system.diagnosticListener); | |
| 562 if (node !== null) { | |
| 563 var script = _class.getCompilationUnit().script; | |
| 564 var span = system.compiler.spanFromNode(node, script.uri); | |
| 565 return new Dart2jsLocation(script, span); | |
| 566 } | |
| 567 } | |
| 568 return super.location(); | |
| 569 } | |
| 570 | |
| 571 void _ensureMembers() { | |
| 572 if (_members == null) { | |
| 573 _members = <Dart2jsMemberMirror>{}; | |
| 574 _class.constructors.forEach((_, e) { | |
| 575 for (var member in _memberConverter(this, e)) { | |
| 576 _members[member.canonicalName] = member; | |
| 577 } | |
| 578 }); | |
| 579 _class.localMembers.forEach((_, e) { | |
| 580 for (var member in _memberConverter(this, e)) { | |
| 581 _members[member.canonicalName] = member; | |
| 582 } | |
| 583 }); | |
| 584 _immutableMembersMap | |
| 585 = new ImmutableMapWrapper<Object,MemberMirror>(_members); | |
| 586 } | |
| 587 } | |
| 588 | |
| 589 Map<Object,MemberMirror> declaredMembers() { | |
| 590 _ensureMembers(); | |
| 591 return _immutableMembersMap; | |
| 592 } | |
| 593 | |
| 594 LibraryMirror library() { | |
| 595 return _library; | |
| 596 } | |
| 597 | |
| 598 bool get isObject() => _class == system.compiler.objectClass; | |
| 599 | |
| 600 bool get isDynamic() => _class == system.compiler.dynamicClass; | |
| 601 | |
| 602 bool get isVoid() => false; | |
| 603 | |
| 604 bool get isTypeVariable() => false; | |
| 605 | |
| 606 bool get isTypedef() => false; | |
| 607 | |
| 608 bool get isFunction() => false; | |
| 609 | |
| 610 InterfaceMirror get declaration() => this; | |
| 611 | |
| 612 InterfaceMirror superclass() { | |
| 613 if (_class.supertype != null) { | |
| 614 return new Dart2jsInterfaceTypeMirror(system, _class.supertype); | |
| 615 } | |
| 616 return null; | |
| 617 } | |
| 618 | |
| 619 Map<Object,InterfaceMirror> interfaces() { | |
| 620 var map = new Map<String,InterfaceMirror>(); | |
| 621 var link = _class.interfaces; | |
| 622 while (!link.isEmpty()) { | |
| 623 var type = _typeConverter(system, link.head, | |
| 624 system.compiler.dynamicClass.computeType(system.compiler)); | |
| 625 map[type.canonicalName] = type; | |
| 626 link = link.tail; | |
| 627 } | |
| 628 return new ImmutableMapWrapper<Object,InterfaceMirror>(map); | |
| 629 } | |
| 630 | |
| 631 Iterable<InterfaceMirror> computeSubdeclarations() { | |
| 632 return system.computeSubdeclarations(this); | |
| 633 } | |
| 634 | |
| 635 bool get isClass() => !_class.isInterface(); | |
| 636 | |
| 637 bool get isInterface() => _class.isInterface(); | |
| 638 | |
| 639 bool get isPrivate() => _isPrivate(simpleName()); | |
| 640 | |
| 641 bool get isDeclaration() => true; | |
| 642 | |
| 643 List<TypeMirror> typeArguments() { | |
| 644 throw new UnsupportedOperationException( | |
| 645 'Declarations do not have type arguments'); | |
| 646 } | |
| 647 | |
| 648 List<TypeVariableMirror> typeVariables() { | |
| 649 if (_typeVariables == null) { | |
| 650 _typeVariables = <TypeVariableMirror>[]; | |
| 651 _class.typeParameters.forEach((_,parameter) { | |
| 652 _typeVariables.add( | |
| 653 new Dart2jsTypeVariableMirror(system, | |
| 654 parameter.computeType(system.compiler))); | |
| 655 }); | |
| 656 } | |
| 657 return _typeVariables; | |
| 658 } | |
| 659 | |
| 660 Map<Object,MethodMirror> constructors() { | |
| 661 _ensureMembers(); | |
| 662 return new AsFilteredImmutableMapWrapper<Object,MemberMirror,MethodMirror>( | |
| 663 _members, (m) => m.isConstructor ? m : null); | |
| 664 } | |
| 665 | |
| 666 /** | |
| 667 * Returns the default type for this interface. | |
| 668 */ | |
| 669 InterfaceMirror defaultType() { | |
| 670 if (_class.defaultClass != null) { | |
| 671 return new Dart2jsInterfaceTypeMirror(system, _class.defaultClass); | |
| 672 } | |
| 673 return null; | |
| 674 } | |
| 675 | |
| 676 bool operator ==(Object other) { | |
| 677 //print('$this == $other'); | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Remove debug codem here and below.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 678 if (this === other) { | |
| 679 return true; | |
| 680 } | |
| 681 //print('- this != other'); | |
| 682 if (other is! InterfaceMirror) { | |
| 683 return false; | |
| 684 } | |
| 685 //print('- other is InterfaceMirror'); | |
| 686 if (library() != other.library()) { | |
| 687 return false; | |
| 688 } | |
| 689 //print('- library() == other.library()'); | |
| 690 if (isDeclaration !== other.isDeclaration) { | |
| 691 return false; | |
| 692 } | |
| 693 //print('- isDeclaration == other.isDeclaration'); | |
| 694 return qualifiedName() == other.qualifiedName(); | |
| 695 } | |
| 696 } | |
| 697 | |
| 698 class Dart2jsTypedefMirror extends Dart2jsElementMirror | |
| 699 implements Dart2jsTypeMirror, TypedefMirror | |
| 700 { | |
| 701 final Dart2jsLibraryMirror _library; | |
| 702 final TypedefElement _typedef; | |
| 703 List<TypeVariableMirror> _typeVariables; | |
| 704 TypeMirror _definition; | |
| 705 | |
| 706 Dart2jsTypedefMirror(Dart2jsMirrorSystem system, TypedefElement _typedef) | |
| 707 : this._library = system.getLibrary(_typedef.getLibrary()), | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
indent by 4.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 708 this._typedef = _typedef, | |
| 709 super(system, _typedef); | |
| 710 | |
| 711 Dart2jsTypedefMirror.fromLibrary(Dart2jsLibraryMirror library, | |
| 712 TypedefElement _typedef) | |
| 713 : this._library = library, | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
By 4.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 714 this._typedef = _typedef, | |
| 715 super(library.system, _typedef); | |
| 716 | |
| 717 String get canonicalName() => simpleName(); | |
| 718 | |
| 719 String qualifiedName() => '${library().qualifiedName()}.${simpleName()}'; | |
| 720 | |
| 721 Location location() { | |
| 722 var node = _typedef.parseNode(system.diagnosticListener); | |
| 723 if (node !== null) { | |
| 724 var script = _typedef.getCompilationUnit().script; | |
| 725 var span = system.compiler.spanFromNode(node, script.uri); | |
| 726 return new Dart2jsLocation(script, span); | |
| 727 } | |
| 728 return super.location(); | |
| 729 } | |
| 730 | |
| 731 LibraryMirror library() { | |
| 732 return _library; | |
| 733 } | |
| 734 | |
| 735 bool get isObject() => false; | |
| 736 | |
| 737 bool get isDynamic() => false; | |
| 738 | |
| 739 bool get isVoid() => false; | |
| 740 | |
| 741 bool get isTypeVariable() => false; | |
| 742 | |
| 743 bool get isTypedef() => true; | |
| 744 | |
| 745 bool get isFunction() => false; | |
| 746 | |
| 747 List<TypeMirror> typeArguments() { | |
| 748 throw new UnsupportedOperationException( | |
| 749 'Declarations do not have type arguments'); | |
| 750 } | |
| 751 | |
| 752 List<TypeVariableMirror> typeVariables() { | |
| 753 if (_typeVariables == null) { | |
| 754 _typeVariables = <TypeVariableMirror>[]; | |
| 755 // TODO(johnniwinther): Equip [Typedef] with a [typeParameters] map, just | |
| 756 // like [ClassElement]: | |
| 757 /*// Ensure that typeParameters have been calculated. | |
| 758 _typedef.computeType(system.compiler); | |
| 759 _typedef.typeParameters.forEach((_,parameter) { | |
| 760 _typeVariables.add( | |
| 761 new Dart2jsTypeVariableMirror(system, | |
| 762 parameter.computeType(system.compiler))); | |
| 763 });*/ | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Don't include commented-out code in CL.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 764 } | |
| 765 return _typeVariables; | |
| 766 } | |
| 767 | |
| 768 TypeMirror definition() { | |
| 769 if (_definition === null) { | |
| 770 // TODO(johnniwinther): Provide access to the functionSignature of the | |
| 771 // aliased function definition: | |
| 772 /*_definition = new Dart2jsFunctionTypeMirror( | |
| 773 system, _typedef.computeType(system.compiler));*/ | |
| 774 } | |
| 775 return _definition; | |
| 776 } | |
| 777 | |
| 778 Map<Object,MemberMirror> declaredMembers() => const <MemberMirror>{}; | |
| 779 | |
| 780 InterfaceMirror get declaration() => this; | |
| 781 | |
| 782 // TODO(johnniwinther): How should a typedef respond to these? | |
| 783 InterfaceMirror superclass() => null; | |
| 784 | |
| 785 Map<Object,InterfaceMirror> interfaces() => const <InterfaceMirror>{}; | |
| 786 | |
| 787 // TODO(johnniwinther): How should a typedef respond to this? | |
| 788 Iterable<InterfaceMirror> computeSubdeclarations() | |
| 789 => const <InterfaceMirror>[]; | |
| 790 | |
| 791 bool get isClass() => false; | |
| 792 | |
| 793 bool get isInterface() => false; | |
| 794 | |
| 795 bool get isPrivate() => _isPrivate(simpleName()); | |
| 796 | |
| 797 bool get isDeclaration() => true; | |
| 798 | |
| 799 Map<Object,MethodMirror> constructors() => const <MethodMirror>{}; | |
| 800 | |
| 801 InterfaceMirror defaultType() => null; | |
| 802 } | |
| 803 | |
| 804 class Dart2jsTypeVariableMirror extends Dart2jsTypeElementMirror | |
| 805 implements TypeVariableMirror | |
| 806 { | |
| 807 final TypeVariableType _typeVariableType; | |
| 808 InterfaceMirror _declarer; | |
| 809 | |
| 810 Dart2jsTypeVariableMirror(Dart2jsMirrorSystem system, | |
| 811 TypeVariableType typeVariableType) | |
| 812 : this._typeVariableType = typeVariableType, | |
| 813 super(system, typeVariableType) | |
| 814 { | |
| 815 assert (_typeVariableType !== null); | |
| 816 } | |
| 817 | |
| 818 | |
| 819 String qualifiedName() => '${declarer().qualifiedName()}.${simpleName()}'; | |
| 820 | |
| 821 InterfaceMirror declarer() { | |
| 822 if (_declarer === null) { | |
| 823 if (_typeVariableType.element.enclosingElement.isClass()) { | |
| 824 _declarer = new Dart2jsInterfaceMirror(system, | |
| 825 _typeVariableType.element.enclosingElement); | |
| 826 } else if (_typeVariableType.element.enclosingElement.isTypedef()) { | |
| 827 _declarer = new Dart2jsTypedefMirror(system, | |
| 828 _typeVariableType.element.enclosingElement); | |
| 829 } | |
| 830 } | |
| 831 return _declarer; | |
| 832 } | |
| 833 | |
| 834 LibraryMirror library() => declarer().library(); | |
| 835 | |
| 836 bool get isObject() => false; | |
| 837 | |
| 838 bool get isDynamic() => false; | |
| 839 | |
| 840 bool get isVoid() => false; | |
| 841 | |
| 842 bool get isTypeVariable() => true; | |
| 843 | |
| 844 bool get isTypedef() => false; | |
| 845 | |
| 846 bool get isFunction() => false; | |
| 847 | |
| 848 TypeMirror bound() | |
| 849 => _typeConverter(system, | |
| 850 _typeVariableType.element.bound, | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
indentation.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 851 system.compiler.objectClass.computeType(system.compiler)); | |
| 852 | |
| 853 bool operator ==(Object other) { | |
| 854 if (this === other) { | |
| 855 return true; | |
| 856 } | |
| 857 if (other is! TypeVariableMirror) { | |
| 858 return false; | |
| 859 } | |
| 860 if (declarer() != other.declarer()) { | |
| 861 print('${declarer()} != ${other.declarer()}'); | |
| 862 return false; | |
| 863 } | |
| 864 return qualifiedName() == other.qualifiedName(); | |
| 865 } | |
| 866 } | |
| 867 | |
| 868 | |
| 869 /////////////////////////////////////////////////////// | |
| 870 // types | |
| 871 /////////////////////////////////////////////////////// | |
| 872 | |
| 873 abstract class Dart2jsTypeElementMirror extends Dart2jsProxyMirror | |
| 874 implements Dart2jsTypeMirror | |
| 875 { | |
| 876 final Type _type; | |
| 877 | |
| 878 Dart2jsTypeElementMirror(Dart2jsMirrorSystem system, this._type) | |
| 879 : super(system); | |
| 880 | |
| 881 String simpleName() => _type.name.slowToString(); | |
| 882 | |
| 883 String get canonicalName() => simpleName(); | |
| 884 | |
| 885 Location location() { | |
| 886 var script = _type.element.getCompilationUnit().script; | |
| 887 return new Dart2jsLocation(script, | |
| 888 system.compiler.spanFromElement(_type.element)); | |
| 889 } | |
| 890 | |
| 891 LibraryMirror library() { | |
| 892 return system.getLibrary(_type.element.getLibrary()); | |
| 893 } | |
| 894 | |
| 895 String toString() => _type.element.toString(); | |
| 896 } | |
| 897 | |
| 898 class Dart2jsInterfaceTypeMirror extends Dart2jsTypeElementMirror | |
| 899 implements InterfaceMirror | |
| 900 { | |
| 901 final InterfaceType _interfaceType; | |
| 902 List<TypeMirror> _typeArguments; | |
| 903 | |
| 904 Dart2jsInterfaceTypeMirror(Dart2jsMirrorSystem system, | |
| 905 InterfaceType interfaceType) | |
| 906 : this._interfaceType = interfaceType, | |
| 907 super(system, interfaceType); | |
| 908 | |
| 909 String qualifiedName() => declaration.qualifiedName(); | |
| 910 | |
| 911 // TODO(johnniwinther): Substitute type arguments for type variables. | |
| 912 Map<Object,MemberMirror> declaredMembers() => declaration.declaredMembers(); | |
| 913 | |
| 914 bool get isObject() => system.compiler.objectClass == _type.element; | |
| 915 | |
| 916 bool get isDynamic() => system.compiler.dynamicClass == _type.element; | |
| 917 | |
| 918 bool get isTypeVariable() => false; | |
| 919 | |
| 920 bool get isVoid() => false; | |
| 921 | |
| 922 bool get isTypedef() => false; | |
| 923 | |
| 924 bool get isFunction() => false; | |
| 925 | |
| 926 InterfaceMirror get declaration() | |
| 927 => new Dart2jsInterfaceMirror(system, _type.element); | |
| 928 | |
| 929 // TODO(johnniwinther): Substitute type arguments for type variables. | |
| 930 InterfaceMirror superclass() => declaration.superclass(); | |
| 931 | |
| 932 // TODO(johnniwinther): Substitute type arguments for type variables. | |
| 933 Map<Object, InterfaceMirror> interfaces() => declaration.interfaces(); | |
| 934 | |
| 935 // TODO(johnniwinther): Substitute type arguments for type variables? and how? | |
| 936 Iterable<InterfaceMirror> computeSubdeclarations() | |
| 937 => declaration.computeSubdeclarations(); | |
| 938 | |
| 939 bool get isClass() => declaration.isClass; | |
| 940 | |
| 941 bool get isInterface() => declaration.isInterface; | |
| 942 | |
| 943 bool get isPrivate() => declaration.isPrivate; | |
| 944 | |
| 945 bool get isDeclaration() => false; | |
| 946 | |
| 947 List<TypeMirror> typeArguments() { | |
| 948 if (_typeArguments == null) { | |
| 949 _typeArguments = <TypeMirror>[]; | |
| 950 Link<Type> type = _interfaceType.arguments; | |
| 951 while (type != null && type.head != null) { | |
| 952 _typeArguments.add(_typeConverter(system, type.head, | |
| 953 system.compiler.dynamicClass.computeType(system.compiler))); | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
indentation.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 954 type = type.tail; | |
| 955 } | |
| 956 } | |
| 957 return _typeArguments; | |
| 958 } | |
| 959 | |
| 960 | |
| 961 List<TypeVariableMirror> typeVariables() => declaration.typeVariables(); | |
| 962 | |
| 963 // TODO(johnniwinther): Substitute type arguments for type variables. | |
| 964 Map<Object,MethodMirror> constructors() => declaration.constructors(); | |
| 965 | |
| 966 // TODO(johnniwinther): Substitute type arguments for type variables? | |
| 967 InterfaceMirror defaultType() => declaration.defaultType(); | |
| 968 | |
| 969 bool operator ==(Object other) { | |
| 970 if (this === other) { | |
| 971 return true; | |
| 972 } | |
| 973 if (other is! InterfaceMirror) { | |
| 974 return false; | |
| 975 } | |
| 976 if (other.isDeclaration) { | |
| 977 return false; | |
| 978 } | |
| 979 if (declaration != other.declaration) { | |
| 980 return false; | |
| 981 } | |
| 982 var thisTypeArguments = typeArguments().iterator(); | |
| 983 var otherTypeArguments = other.typeArguments().iterator(); | |
| 984 while (thisTypeArguments.hasNext() && otherTypeArguments.hasNext()) { | |
| 985 if (thisTypeArguments.next() != otherTypeArguments.next()) { | |
| 986 return false; | |
| 987 } | |
| 988 } | |
| 989 return !thisTypeArguments.hasNext() && !otherTypeArguments.hasNext(); | |
| 990 } | |
| 991 } | |
| 992 | |
| 993 | |
| 994 class Dart2jsFunctionTypeMirror extends Dart2jsTypeElementMirror | |
| 995 implements FunctionTypeMirror | |
| 996 { | |
| 997 final FunctionType _functionType; | |
| 998 final FunctionSignature _functionSignature; | |
| 999 List<ParameterMirror> _parameters; | |
| 1000 | |
| 1001 Dart2jsFunctionTypeMirror(Dart2jsMirrorSystem system, | |
| 1002 FunctionType functionType, this._functionSignature) | |
| 1003 : this._functionType = functionType, | |
| 1004 super(system, functionType) | |
| 1005 { | |
| 1006 assert (_functionSignature !== null); | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
indent by 2.
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 1007 } | |
| 1008 | |
| 1009 // TODO(johnniwinther): Is this the qualified name of a function type? | |
| 1010 String qualifiedName() => declaration.qualifiedName(); | |
| 1011 | |
| 1012 // TODO(johnniwinther): Substitute type arguments for type variables. | |
| 1013 Map<Object,MemberMirror> declaredMembers() { | |
| 1014 var method = callMethod(); | |
| 1015 if (method !== null) { | |
| 1016 var map = new Map<String,MemberMirror>.from( | |
| 1017 declaration.declaredMembers()); | |
| 1018 var name = method.qualifiedName(); | |
| 1019 map[name] = method; | |
| 1020 Function func = null; | |
| 1021 return new ImmutableMapWrapper<Object,MemberMirror>(map); | |
| 1022 } | |
| 1023 return declaration.declaredMembers(); | |
| 1024 } | |
| 1025 | |
| 1026 bool get isObject() => system.compiler.objectClass == _type.element; | |
| 1027 | |
| 1028 bool get isDynamic() => system.compiler.dynamicClass == _type.element; | |
| 1029 | |
| 1030 bool get isVoid() => false; | |
| 1031 | |
| 1032 bool get isTypeVariable() => false; | |
| 1033 | |
| 1034 bool get isTypedef() => false; | |
| 1035 | |
| 1036 bool get isFunction() => true; | |
| 1037 | |
| 1038 MethodMirror callMethod() => _methodConverter( | |
| 1039 system.getLibrary(_functionType.element.getLibrary()), | |
| 1040 _functionType.element); | |
| 1041 | |
| 1042 InterfaceMirror get declaration() | |
| 1043 => new Dart2jsInterfaceMirror(system, system.compiler.functionClass); | |
| 1044 | |
| 1045 // TODO(johnniwinther): Substitute type arguments for type variables. | |
| 1046 InterfaceMirror superclass() => declaration.superclass(); | |
| 1047 | |
| 1048 // TODO(johnniwinther): Substitute type arguments for type variables. | |
| 1049 Map<Object,InterfaceMirror> interfaces() => declaration.interfaces(); | |
| 1050 | |
| 1051 // TODO(johnniwinther): Substitute type arguments for type variables? and how? | |
| 1052 Iterable<InterfaceMirror> computeSubdeclarations() | |
| 1053 => declaration.computeSubdeclarations(); | |
| 1054 | |
| 1055 bool get isClass() => declaration.isClass; | |
| 1056 | |
| 1057 bool get isInterface() => declaration.isInterface; | |
| 1058 | |
| 1059 bool get isPrivate() => declaration.isPrivate; | |
| 1060 | |
| 1061 bool get isDeclaration() => false; | |
| 1062 | |
| 1063 List<TypeMirror> typeArguments() => const <TypeMirror>[]; | |
| 1064 | |
| 1065 List<TypeVariableMirror> typeVariables() => declaration.typeVariables(); | |
| 1066 | |
| 1067 Map<Object,MethodMirror> constructors() => <MethodMirror>{}; | |
| 1068 | |
| 1069 InterfaceMirror defaultType() => null; | |
| 1070 | |
| 1071 TypeMirror returnType() { | |
| 1072 return _typeConverter(system, _functionType.returnType, | |
| 1073 system.compiler.dynamicClass.computeType(system.compiler)); | |
| 1074 } | |
| 1075 | |
| 1076 List<ParameterMirror> parameters() { | |
| 1077 if (_parameters === null) { | |
| 1078 _parameters = _parametersFromFunctionSignature(system, callMethod(), | |
| 1079 _functionSignature); | |
| 1080 } | |
| 1081 return _parameters; | |
| 1082 } | |
| 1083 } | |
| 1084 | |
| 1085 class Dart2jsVoidMirror extends Dart2jsTypeElementMirror { | |
| 1086 VoidType _voidType; | |
| 1087 | |
| 1088 Dart2jsVoidMirror(Dart2jsMirrorSystem system, VoidType voidType) | |
| 1089 : _voidType = voidType, | |
|
Lasse Reichstein Nielsen
2012/07/02 11:48:53
Indent by 4 (ditto in more places below, and proba
Johnni Winther
2012/07/03 07:38:50
Done.
| |
| 1090 super(system, voidType); | |
| 1091 | |
| 1092 String qualifiedName() => simpleName(); | |
| 1093 | |
| 1094 /** | |
| 1095 * The void type has no location. | |
| 1096 */ | |
| 1097 Location location() => null; | |
| 1098 | |
| 1099 /** | |
| 1100 * The void type has no library. | |
| 1101 */ | |
| 1102 LibraryMirror getLibrary() => null; | |
| 1103 | |
| 1104 bool get isObject() => false; | |
| 1105 | |
| 1106 bool get isVoid() => true; | |
| 1107 | |
| 1108 bool get isDynamic() => false; | |
| 1109 | |
| 1110 bool get isTypeVariable() => false; | |
| 1111 | |
| 1112 bool get isTypedef() => false; | |
| 1113 | |
| 1114 bool get isFunction() => false; | |
| 1115 | |
| 1116 bool operator ==(Object other) { | |
| 1117 if (this === other) { | |
| 1118 return true; | |
| 1119 } | |
| 1120 if (other is! TypeMirror) { | |
| 1121 return false; | |
| 1122 } | |
| 1123 return other.isVoid; | |
| 1124 } | |
| 1125 } | |
| 1126 | |
| 1127 /////////////////////////////////////////////////////// | |
| 1128 // members | |
| 1129 /////////////////////////////////////////////////////// | |
| 1130 | |
| 1131 class Dart2jsMethodMirror extends Dart2jsElementMirror | |
| 1132 implements Dart2jsMemberMirror, MethodMirror | |
| 1133 { | |
| 1134 final Dart2jsObjectMirror _objectMirror; | |
| 1135 final FunctionElement _function; | |
| 1136 String _name; | |
| 1137 String _constructorName; | |
| 1138 String _operatorName; | |
| 1139 Dart2jsMethodKind _kind; | |
| 1140 String _canonicalName; | |
| 1141 | |
| 1142 Dart2jsMethodMirror(Dart2jsObjectMirror objectMirror, | |
| 1143 FunctionElement function, | |
| 1144 [Dart2jsMethodKind kind = null]) | |
| 1145 : this._objectMirror = objectMirror, | |
| 1146 this._function = function, | |
| 1147 this._kind = kind, | |
| 1148 super(objectMirror.system, function) | |
| 1149 { | |
| 1150 _name = _element.name.slowToString(); | |
| 1151 if (kind == null) { | |
| 1152 if (_function.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { | |
| 1153 _constructorName = ''; | |
| 1154 var dollarPos = _name.indexOf('\$'); | |
| 1155 if (dollarPos != -1) { | |
| 1156 _constructorName = _name.substring(dollarPos+1); | |
| 1157 _name = _name.substring(0, dollarPos); | |
| 1158 // canonical name is TypeName.constructorName | |
| 1159 _canonicalName = '$_name.$_constructorName'; | |
| 1160 } else { | |
| 1161 // canonical name is TypeName | |
| 1162 _canonicalName = _name; | |
| 1163 } | |
| 1164 if (_function.modifiers !== null && _function.modifiers.isConst()) { | |
| 1165 _kind = Dart2jsMethodKind.CONST; | |
| 1166 } else { | |
| 1167 _kind = Dart2jsMethodKind.CONSTRUCTOR; | |
| 1168 } | |
| 1169 } else if (_function.modifiers !== null | |
| 1170 && _function.modifiers.isFactory()) | |
| 1171 { | |
| 1172 _constructorName = ''; | |
| 1173 var dollarPos = _name.indexOf('\$'); | |
| 1174 if (dollarPos != -1) { | |
| 1175 _constructorName = _name.substring(dollarPos+1); | |
| 1176 _name = _name.substring(0, dollarPos); | |
| 1177 } | |
| 1178 _kind = Dart2jsMethodKind.FACTORY; | |
| 1179 // canonical name is TypeName.constructorName | |
| 1180 _canonicalName = '$_name.$_constructorName'; | |
| 1181 } else if (_name.startsWith('operator\$')) { | |
| 1182 var str = _name.substring(9); | |
| 1183 _name = 'operator'; | |
| 1184 _kind = Dart2jsMethodKind.OPERATOR; | |
| 1185 _operatorName = _getOperatorFromOperatorName(str); | |
| 1186 // canonical name is 'operator operatorName' | |
| 1187 _canonicalName = 'operator $_operatorName'; | |
| 1188 } else { | |
| 1189 _kind = Dart2jsMethodKind.NORMAL; | |
| 1190 _canonicalName = _name; | |
| 1191 } | |
| 1192 } else if (kind == Dart2jsMethodKind.GETTER) { | |
| 1193 _canonicalName = _name; | |
| 1194 } else if (kind == Dart2jsMethodKind.SETTER) { | |
| 1195 _canonicalName = '$_name='; | |
| 1196 } else { | |
| 1197 assert(false); | |
| 1198 } | |
| 1199 } | |
| 1200 | |
| 1201 String simpleName() => _name; | |
| 1202 | |
| 1203 String qualifiedName() | |
| 1204 => '${surroundingDeclaration().qualifiedName()}.$canonicalName'; | |
| 1205 | |
| 1206 String get canonicalName() => _canonicalName; | |
| 1207 | |
| 1208 ObjectMirror surroundingDeclaration() => _objectMirror; | |
| 1209 | |
| 1210 bool get isTopLevel() => _objectMirror is LibraryMirror; | |
| 1211 | |
| 1212 bool get isConstructor() | |
| 1213 => _kind == Dart2jsMethodKind.CONSTRUCTOR || isConst || isFactory; | |
| 1214 | |
| 1215 bool get isField() => false; | |
| 1216 | |
| 1217 bool get isMethod() => !isConstructor; | |
| 1218 | |
| 1219 bool get isPrivate() => _isPrivate(simpleName()); | |
| 1220 | |
| 1221 bool get isStatic() => | |
| 1222 _function.modifiers !== null && _function.modifiers.isStatic(); | |
| 1223 | |
| 1224 List<ParameterMirror> parameters() { | |
| 1225 return _parametersFromFunctionSignature(system, this, | |
| 1226 _function.computeSignature(system.compiler)); | |
| 1227 } | |
| 1228 | |
| 1229 | |
| 1230 TypeMirror returnType() => _typeConverter( | |
| 1231 system, _function.computeSignature(system.compiler).returnType, | |
| 1232 system.compiler.dynamicClass.computeType(system.compiler)); | |
| 1233 | |
| 1234 bool get isConst() => _kind == Dart2jsMethodKind.CONST; | |
| 1235 | |
| 1236 bool get isFactory() => _kind == Dart2jsMethodKind.FACTORY; | |
| 1237 | |
| 1238 String get constructorName() => _constructorName; | |
| 1239 | |
| 1240 bool get isGetter() => _kind == Dart2jsMethodKind.GETTER; | |
| 1241 | |
| 1242 bool get isSetter() => _kind == Dart2jsMethodKind.SETTER; | |
| 1243 | |
| 1244 bool get isOperator() => _kind == Dart2jsMethodKind.OPERATOR; | |
| 1245 | |
| 1246 String get operatorName() => _operatorName; | |
| 1247 | |
| 1248 Location location() { | |
| 1249 var node = _function.parseNode(system.diagnosticListener); | |
| 1250 if (node !== null) { | |
| 1251 var script = _function.getCompilationUnit().script; | |
| 1252 var span = system.compiler.spanFromNode(node, script.uri); | |
| 1253 return new Dart2jsLocation(script, span); | |
| 1254 } | |
| 1255 return super.location(); | |
| 1256 } | |
| 1257 | |
| 1258 } | |
| 1259 | |
| 1260 class Dart2jsFieldMirror extends Dart2jsElementMirror | |
| 1261 implements Dart2jsMemberMirror, FieldMirror | |
| 1262 { | |
| 1263 Dart2jsObjectMirror _objectMirror; | |
| 1264 VariableElement _variable; | |
| 1265 | |
| 1266 Dart2jsFieldMirror(Dart2jsObjectMirror objectMirror, | |
| 1267 VariableElement variable) | |
| 1268 : this._objectMirror = objectMirror, | |
| 1269 this._variable = variable, | |
| 1270 super(objectMirror.system, variable); | |
| 1271 | |
| 1272 String qualifiedName() | |
| 1273 => '${surroundingDeclaration().qualifiedName()}.$canonicalName'; | |
| 1274 | |
| 1275 String get canonicalName() => simpleName(); | |
| 1276 | |
| 1277 ObjectMirror surroundingDeclaration() => _objectMirror; | |
| 1278 | |
| 1279 bool get isTopLevel() => _objectMirror is LibraryMirror; | |
| 1280 | |
| 1281 bool get isConstructor() => false; | |
| 1282 | |
| 1283 bool get isField() => true; | |
| 1284 | |
| 1285 bool get isMethod() => false; | |
| 1286 | |
| 1287 bool get isPrivate() => _isPrivate(simpleName()); | |
| 1288 | |
| 1289 bool get isStatic() => _variable.modifiers.isStatic(); | |
| 1290 | |
| 1291 bool get isFinal() => _variable.modifiers.isFinal(); | |
| 1292 | |
| 1293 TypeMirror type() => _typeConverter(system, | |
| 1294 _variable.computeType(system.compiler), | |
| 1295 system.compiler.dynamicClass.computeType(system.compiler)); | |
| 1296 | |
| 1297 Location location() { | |
| 1298 var script = _variable.getCompilationUnit().script; | |
| 1299 var node = _variable.variables.parseNode(system.diagnosticListener); | |
| 1300 if (node !== null) { | |
| 1301 var span = system.compiler.spanFromNode(node, script.uri); | |
| 1302 return new Dart2jsLocation(script, span); | |
| 1303 } else { | |
| 1304 var span = system.compiler.spanFromElement(_variable); | |
| 1305 return new Dart2jsLocation(script, span); | |
| 1306 } | |
| 1307 } | |
| 1308 } | |
| 1309 | |
| OLD | NEW |