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('../../../lib/compiler/compiler.dart', prefix: 'diagnostics'); | |
8 #import('../../../lib/compiler/implementation/elements/elements.dart'); | |
9 #import('../../../lib/compiler/implementation/apiimpl.dart', prefix: 'api'); | |
10 #import('../../../lib/compiler/implementation/scanner/scannerlib.dart'); | |
11 #import('../../../lib/compiler/implementation/leg.dart'); | |
12 #import('../../../lib/compiler/implementation/filenames.dart'); | |
13 #import('../../../lib/compiler/implementation/source_file.dart'); | |
14 #import('../../../lib/compiler/implementation/tree/tree.dart'); | |
15 #import('../../../lib/compiler/implementation/util/util.dart'); | |
16 #import('../../../lib/compiler/implementation/util/uri_extras.dart'); | |
17 #import('../../../lib/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 for the dart2js mirror system | |
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 var parameters = <ParameterMirror>[]; | |
37 Link<Element> link = signature.requiredParameters; | |
38 while (!link.isEmpty()) { | |
39 parameters.add(new Dart2JsParameterMirror( | |
40 system, method, link.head, false)); | |
41 link = link.tail; | |
42 } | |
43 link = signature.optionalParameters; | |
44 while (!link.isEmpty()) { | |
45 parameters.add(new Dart2JsParameterMirror( | |
46 system, method, link.head, true)); | |
47 link = link.tail; | |
48 } | |
49 return parameters; | |
50 } | |
51 | |
52 Dart2JsTypeMirror _convertTypeToTypeMirror( | |
53 Dart2JsMirrorSystem system, | |
54 DartType type, | |
55 InterfaceType defaultType, | |
56 [FunctionSignature functionSignature]) { | |
57 if (type === null) { | |
58 return new Dart2JsInterfaceTypeMirror(system, defaultType); | |
59 } else if (type is InterfaceType) { | |
60 return new Dart2JsInterfaceTypeMirror(system, type); | |
61 } else if (type is TypeVariableType) { | |
62 return new Dart2JsTypeVariableMirror(system, type); | |
63 } else if (type is FunctionType) { | |
64 return new Dart2JsFunctionTypeMirror(system, type, functionSignature); | |
65 } else if (type is VoidType) { | |
66 return new Dart2JsVoidMirror(system, type); | |
67 } else if (type is TypedefType) { | |
68 return new Dart2JsTypedefMirror(system, type); | |
69 } | |
70 throw new IllegalArgumentException("Unexpected interface type $type"); | |
71 } | |
72 | |
73 Collection<Dart2JsMemberMirror> _convertElementMemberToMemberMirrors( | |
74 Dart2JsObjectMirror library, Element element) { | |
75 if (element is SynthesizedConstructorElement) { | |
76 return const <Dart2JsMemberMirror>[]; | |
77 } else if (element is VariableElement) { | |
78 return <Dart2JsMemberMirror>[new Dart2JsFieldMirror(library, element)]; | |
79 } else if (element is FunctionElement) { | |
80 return <Dart2JsMemberMirror>[new Dart2JsMethodMirror(library, element)]; | |
81 } else if (element is AbstractFieldElement) { | |
82 var members = <Dart2JsMemberMirror>[]; | |
83 if (element.getter !== null) { | |
84 members.add(new Dart2JsMethodMirror(library, element.getter)); | |
85 } | |
86 if (element.setter !== null) { | |
87 members.add(new Dart2JsMethodMirror(library, element.setter)); | |
88 } | |
89 return members; | |
90 } | |
91 throw new IllegalArgumentException( | |
92 "Unexpected member type $element ${element.kind}"); | |
93 } | |
94 | |
95 MethodMirror _convertElementMethodToMethodMirror(Dart2JsObjectMirror library, | |
96 Element element) { | |
97 if (element is FunctionElement) { | |
98 return new Dart2JsMethodMirror(library, element); | |
99 } else { | |
100 return null; | |
101 } | |
102 } | |
103 | |
104 class Dart2JsMethodKind { | |
105 static const Dart2JsMethodKind NORMAL = const Dart2JsMethodKind("normal"); | |
106 static const Dart2JsMethodKind CONSTRUCTOR | |
107 = const Dart2JsMethodKind("constructor"); | |
108 static const Dart2JsMethodKind CONST = const Dart2JsMethodKind("const"); | |
109 static const Dart2JsMethodKind FACTORY = const Dart2JsMethodKind("factory"); | |
110 static const Dart2JsMethodKind GETTER = const Dart2JsMethodKind("getter"); | |
111 static const Dart2JsMethodKind SETTER = const Dart2JsMethodKind("setter"); | |
112 static const Dart2JsMethodKind OPERATOR = const Dart2JsMethodKind("operator"); | |
113 | |
114 final String text; | |
115 | |
116 const Dart2JsMethodKind(this.text); | |
117 | |
118 String toString() => text; | |
119 } | |
120 | |
121 | |
122 String _getOperatorFromOperatorName(String name) { | |
123 Map<String, String> mapping = const { | |
124 'eq': '==', | |
125 'not': '~', | |
126 'index': '[]', | |
127 'indexSet': '[]=', | |
128 'mul': '*', | |
129 'div': '/', | |
130 'mod': '%', | |
131 'tdiv': '~/', | |
132 'add': '+', | |
133 'sub': '-', | |
134 'shl': '<<', | |
135 'shr': '>>', | |
136 'ge': '>=', | |
137 'gt': '>', | |
138 'le': '<=', | |
139 'lt': '<', | |
140 'and': '&', | |
141 'xor': '^', | |
142 'or': '|', | |
143 }; | |
144 String newName = mapping[name]; | |
145 if (newName === null) { | |
146 throw new Exception('Unhandled operator name: $name'); | |
147 } | |
148 return newName; | |
149 } | |
150 | |
151 DiagnosticListener get _diagnosticListener { | |
152 return const Dart2JsDiagnosticListener(); | |
153 } | |
154 | |
155 class Dart2JsDiagnosticListener implements DiagnosticListener { | |
156 const Dart2JsDiagnosticListener(); | |
157 | |
158 void cancel([String reason, node, token, instruction, element]) { | |
159 print(reason); | |
160 } | |
161 | |
162 void log(message) { | |
163 print(message); | |
164 } | |
165 | |
166 void internalError(String message, | |
167 [Node node, Token token, HInstruction instruction, | |
168 Element element]) { | |
169 cancel('Internal error: $message', node, token, instruction, element); | |
170 } | |
171 | |
172 void internalErrorOnElement(Element element, String message) { | |
173 internalError(message, element: element); | |
174 } | |
175 } | |
176 | |
177 //------------------------------------------------------------------------------ | |
178 // Compiler extension for apidoc. | |
179 //------------------------------------------------------------------------------ | |
180 | |
181 /** | |
182 * Extension of the compiler that enables the analysis of several libraries with | |
183 * no particular entry point. | |
184 */ | |
185 class LibraryCompiler extends api.Compiler { | |
186 LibraryCompiler(diagnostics.ReadStringFromUri provider, | |
187 diagnostics.DiagnosticHandler handler, | |
188 Uri libraryRoot, Uri packageRoot, | |
189 List<String> options) | |
190 : super(provider, handler, libraryRoot, packageRoot, options) { | |
191 checker = new LibraryTypeCheckerTask(this); | |
192 resolver = new LibraryResolverTask(this); | |
193 } | |
194 | |
195 // TODO(johnniwinther): The following methods are added to enable the analysis | |
196 // of a collection of libraries to be used for apidoc. Most of the methods | |
197 // are based on copies of existing methods and could probably be implemented | |
198 // such that the duplicate code is avoided. Not to affect the correctness and | |
199 // speed of dart2js as is, the redundancy is accepted temporarily. | |
200 | |
201 /** | |
202 * Run the compiler on a list of libraries. No entry point is used. | |
203 */ | |
204 bool runList(List<Uri> uriList) { | |
205 bool success = _runList(uriList); | |
206 for (final task in tasks) { | |
207 log('${task.name} took ${task.timing}msec'); | |
208 } | |
209 return success; | |
210 } | |
211 | |
212 bool _runList(List<Uri> uriList) { | |
213 try { | |
214 runCompilerList(uriList); | |
215 } on CompilerCancelledException catch (exception) { | |
216 log(exception.toString()); | |
217 log('compilation failed'); | |
218 return false; | |
219 } | |
220 tracer.close(); | |
221 log('compilation succeeded'); | |
222 return true; | |
223 } | |
224 | |
225 void runCompilerList(List<Uri> uriList) { | |
226 scanBuiltinLibraries(); | |
227 var elementList = <LibraryElement>[]; | |
228 for (var uri in uriList) { | |
229 elementList.add(scanner.loadLibrary(uri, null, uri)); | |
230 } | |
231 libraries.forEach((_, library) { | |
232 maybeEnableJSHelper(library); | |
233 }); | |
234 | |
235 world.populate(); | |
236 | |
237 log('Resolving...'); | |
238 phase = Compiler.PHASE_RESOLVING; | |
239 backend.enqueueHelpers(enqueuer.resolution); | |
240 processQueueList(enqueuer.resolution, elementList); | |
241 log('Resolved ${enqueuer.resolution.resolvedElements.length} elements.'); | |
242 } | |
243 | |
244 void processQueueList(Enqueuer world, List<LibraryElement> elements) { | |
245 backend.processNativeClasses(world, libraries.getValues()); | |
246 for (var library in elements) { | |
247 library.localMembers.forEach((element) { | |
248 world.addToWorkList(element); | |
249 }); | |
250 } | |
251 progress.reset(); | |
252 world.forEach((WorkItem work) { | |
253 withCurrentElement(work.element, () => work.run(this, world)); | |
254 }); | |
255 } | |
256 | |
257 String codegen(WorkItem work, Enqueuer world) { | |
258 return null; | |
259 } | |
260 } | |
261 | |
262 // TODO(johnniwinther): The source for the apidoc includes calls to methods on | |
263 // for instance [MathPrimitives] which are not resolved by dart2js. Since we | |
264 // do not need to analyse the body of functions to produce the documenation | |
265 // we use a specialized resolver which bypasses method bodies. | |
266 class LibraryResolverTask extends ResolverTask { | |
267 LibraryResolverTask(api.Compiler compiler) : super(compiler); | |
268 | |
269 void visitBody(ResolverVisitor visitor, Statement body) {} | |
270 } | |
271 | |
272 // TODO(johnniwinther): As a side-effect of bypassing method bodies in | |
273 // [LibraryResolveTask] we can not perform the typecheck. | |
274 class LibraryTypeCheckerTask extends TypeCheckerTask { | |
275 LibraryTypeCheckerTask(api.Compiler compiler) : super(compiler); | |
276 | |
277 void check(Node tree, TreeElements elements) {} | |
278 } | |
279 | |
280 //------------------------------------------------------------------------------ | |
281 // Compilation implementation | |
282 //------------------------------------------------------------------------------ | |
283 | |
284 class Dart2JsCompilation implements Compilation { | |
285 bool isWindows = (Platform.operatingSystem == 'windows'); | |
286 api.Compiler _compiler; | |
287 Uri cwd; | |
288 bool isAborting = false; | |
289 Map<String, SourceFile> sourceFiles; | |
290 | |
291 Future<String> provider(Uri uri) { | |
292 if (uri.scheme != 'file') { | |
293 throw new IllegalArgumentException(uri); | |
294 } | |
295 String source; | |
296 try { | |
297 source = readAll(uriPathToNative(uri.path)); | |
298 } on FileIOException catch (ex) { | |
299 throw 'Error: Cannot read "${relativize(cwd, uri, isWindows)}" ' | |
300 '(${ex.osError}).'; | |
301 } | |
302 sourceFiles[uri.toString()] = | |
303 new SourceFile(relativize(cwd, uri, isWindows), source); | |
304 return new Future.immediate(source); | |
305 } | |
306 | |
307 void handler(Uri uri, int begin, int end, | |
308 String message, diagnostics.Diagnostic kind) { | |
309 if (isAborting) return; | |
310 bool fatal = | |
311 kind === diagnostics.Diagnostic.CRASH || | |
312 kind === diagnostics.Diagnostic.ERROR; | |
313 if (uri === null) { | |
314 if (!fatal) { | |
315 return; | |
316 } | |
317 print(message); | |
318 throw message; | |
319 } else if (fatal) { | |
320 SourceFile file = sourceFiles[uri.toString()]; | |
321 print(file.getLocationMessage(message, begin, end, true, (s) => s)); | |
322 throw message; | |
323 } | |
324 } | |
325 | |
326 Dart2JsCompilation(Path script, Path libraryRoot, | |
327 [Path packageRoot, List<String> opts = const <String>[]]) | |
328 : cwd = getCurrentDirectory(), sourceFiles = <String, SourceFile>{} { | |
329 var libraryUri = cwd.resolve(libraryRoot.toString()); | |
330 var packageUri; | |
331 if (packageRoot !== null) { | |
332 packageUri = cwd.resolve(packageRoot.toString()); | |
333 } else { | |
334 packageUri = libraryUri; | |
335 } | |
336 _compiler = new api.Compiler(provider, handler, | |
337 libraryUri, packageUri, <String>[]); | |
338 var scriptUri = cwd.resolve(script.toString()); | |
339 // TODO(johnniwinther): Detect file not found | |
340 _compiler.run(scriptUri); | |
341 } | |
342 | |
343 Dart2JsCompilation.library(List<Path> libraries, Path libraryRoot, | |
344 [Path packageRoot, List<String> opts = const <String>[]]) | |
345 : cwd = getCurrentDirectory(), sourceFiles = <String, SourceFile>{} { | |
346 var libraryUri = cwd.resolve(libraryRoot.toString()); | |
347 var packageUri; | |
348 if (packageRoot !== null) { | |
349 packageUri = cwd.resolve(packageRoot.toString()); | |
350 } else { | |
351 packageUri = libraryUri; | |
352 } | |
353 _compiler = new LibraryCompiler(provider, handler, | |
354 libraryUri, packageUri, <String>[]); | |
355 var librariesUri = <Uri>[]; | |
356 for (Path library in libraries) { | |
357 librariesUri.add(cwd.resolve(library.toString())); | |
358 // TODO(johnniwinther): Detect file not found | |
359 } | |
360 _compiler.runList(librariesUri); | |
361 } | |
362 | |
363 void addLibrary(String path) { | |
364 var uri = cwd.resolve(nativeToUriPath(path)); | |
365 _compiler.scanner.loadLibrary(uri, null); | |
366 } | |
367 | |
368 MirrorSystem get mirrors => new Dart2JsMirrorSystem(_compiler); | |
369 | |
370 Future<String> compileToJavaScript() => | |
371 new Future<String>.immediate(_compiler.assembledCode); | |
372 } | |
373 | |
374 | |
375 //------------------------------------------------------------------------------ | |
376 // Dart2Js specific extensions of mirror interfaces | |
377 //------------------------------------------------------------------------------ | |
378 | |
379 abstract class Dart2JsMirror implements Mirror { | |
380 /** | |
381 * A unique name used as the key in maps. | |
382 */ | |
383 String get canonicalName; | |
384 Dart2JsMirrorSystem get system; | |
385 } | |
386 | |
387 abstract class Dart2JsMemberMirror implements Dart2JsMirror, MemberMirror { | |
388 | |
389 } | |
390 | |
391 abstract class Dart2JsTypeMirror implements Dart2JsMirror, TypeMirror { | |
392 | |
393 } | |
394 | |
395 abstract class Dart2JsElementMirror implements Dart2JsMirror { | |
396 final Dart2JsMirrorSystem system; | |
397 final Element _element; | |
398 | |
399 Dart2JsElementMirror(this.system, this._element) { | |
400 assert (system !== null); | |
401 assert (_element !== null); | |
402 } | |
403 | |
404 String get simpleName => _element.name.slowToString(); | |
405 | |
406 Location get location => new Dart2JsLocation( | |
407 _element.getCompilationUnit().script, | |
408 system.compiler.spanFromElement(_element)); | |
409 | |
410 String toString() => _element.toString(); | |
411 | |
412 int hashCode() => qualifiedName.hashCode(); | |
413 } | |
414 | |
415 abstract class Dart2JsProxyMirror implements Dart2JsMirror { | |
416 final Dart2JsMirrorSystem system; | |
417 | |
418 Dart2JsProxyMirror(this.system); | |
419 | |
420 int hashCode() => qualifiedName.hashCode(); | |
421 } | |
422 | |
423 //------------------------------------------------------------------------------ | |
424 // Mirror system implementation. | |
425 //------------------------------------------------------------------------------ | |
426 | |
427 class Dart2JsMirrorSystem implements MirrorSystem, Dart2JsMirror { | |
428 final api.Compiler compiler; | |
429 Map<String, Dart2JsLibraryMirror> _libraries; | |
430 Map<LibraryElement, Dart2JsLibraryMirror> _libraryMap; | |
431 | |
432 Dart2JsMirrorSystem(this.compiler) | |
433 : _libraryMap = new Map<LibraryElement, Dart2JsLibraryMirror>(); | |
434 | |
435 void _ensureLibraries() { | |
436 if (_libraries == null) { | |
437 _libraries = <String, Dart2JsLibraryMirror>{}; | |
438 compiler.libraries.forEach((_, LibraryElement v) { | |
439 var mirror = new Dart2JsLibraryMirror(system, v); | |
440 _libraries[mirror.canonicalName] = mirror; | |
441 _libraryMap[v] = mirror; | |
442 }); | |
443 } | |
444 } | |
445 | |
446 Map<Object, LibraryMirror> get libraries { | |
447 _ensureLibraries(); | |
448 return new ImmutableMapWrapper<Object, LibraryMirror>(_libraries); | |
449 } | |
450 | |
451 Dart2JsLibraryMirror getLibrary(LibraryElement element) { | |
452 return _libraryMap[element]; | |
453 } | |
454 | |
455 Dart2JsMirrorSystem get system => this; | |
456 | |
457 String get simpleName => "mirror"; | |
458 String get qualifiedName => simpleName; | |
459 | |
460 String get canonicalName => simpleName; | |
461 | |
462 // TODO(johnniwinther): Hack! Dart2JsMirrorSystem need not be a Mirror. | |
463 int hashCode() => qualifiedName.hashCode(); | |
464 } | |
465 | |
466 abstract class Dart2JsObjectMirror extends Dart2JsElementMirror | |
467 implements ObjectMirror { | |
468 Dart2JsObjectMirror(Dart2JsMirrorSystem system, Element element) | |
469 : super(system, element); | |
470 } | |
471 | |
472 class Dart2JsLibraryMirror extends Dart2JsObjectMirror | |
473 implements LibraryMirror { | |
474 Map<String, InterfaceMirror> _types; | |
475 Map<String, MemberMirror> _members; | |
476 | |
477 Dart2JsLibraryMirror(Dart2JsMirrorSystem system, LibraryElement library) | |
478 : super(system, library); | |
479 | |
480 LibraryElement get _library => _element; | |
481 | |
482 LibraryMirror library() => this; | |
483 | |
484 String get canonicalName => simpleName; | |
485 | |
486 /** | |
487 * Returns the library name (for libraries with a #library tag) or the script | |
488 * file name (for scripts without a #library tag). The latter case is used to | |
489 * provide a 'library name' for scripts, to use for instance in dartdoc. | |
490 */ | |
491 String get simpleName { | |
492 if (_library.libraryTag !== null) { | |
493 return _library.libraryTag.argument.dartString.slowToString(); | |
494 } else { | |
495 // Use the file name as script name. | |
496 String path = _library.uri.path; | |
497 return path.substring(path.lastIndexOf('/') + 1); | |
498 } | |
499 } | |
500 | |
501 String get qualifiedName => simpleName; | |
502 | |
503 void _ensureTypes() { | |
504 if (_types == null) { | |
505 _types = <String, InterfaceMirror>{}; | |
506 _library.forEachExport((Element e) { | |
507 if (e.getLibrary() == _library) { | |
508 if (e.isClass()) { | |
509 e.ensureResolved(system.compiler); | |
510 var type = new Dart2JsInterfaceMirror.fromLibrary(this, e); | |
511 _types[type.canonicalName] = type; | |
512 } else if (e.isTypedef()) { | |
513 var type = new Dart2JsTypedefMirror.fromLibrary(this, | |
514 e.computeType(system.compiler)); | |
515 _types[type.canonicalName] = type; | |
516 } | |
517 } | |
518 }); | |
519 } | |
520 } | |
521 | |
522 void _ensureMembers() { | |
523 if (_members == null) { | |
524 _members = <String, MemberMirror>{}; | |
525 _library.forEachExport((Element e) { | |
526 if (!e.isClass() && !e.isTypedef()) { | |
527 for (var member in _convertElementMemberToMemberMirrors(this, e)) { | |
528 _members[member.canonicalName] = member; | |
529 } | |
530 } | |
531 }); | |
532 } | |
533 } | |
534 | |
535 Map<Object, MemberMirror> get declaredMembers { | |
536 _ensureMembers(); | |
537 return new ImmutableMapWrapper<Object, MemberMirror>(_members); | |
538 } | |
539 | |
540 Map<Object, InterfaceMirror> get types { | |
541 _ensureTypes(); | |
542 return new ImmutableMapWrapper<Object, InterfaceMirror>(_types); | |
543 } | |
544 | |
545 Location get location { | |
546 var script = _library.getCompilationUnit().script; | |
547 return new Dart2JsLocation( | |
548 script, | |
549 new SourceSpan(script.uri, 0, script.text.length)); | |
550 } | |
551 } | |
552 | |
553 class Dart2JsLocation implements Location { | |
554 Script _script; | |
555 SourceSpan _span; | |
556 | |
557 Dart2JsLocation(this._script, this._span); | |
558 | |
559 int get start => _span.begin; | |
560 | |
561 int get end => _span.end; | |
562 | |
563 Source get source => new Dart2JsSource(_script); | |
564 | |
565 String get text => _script.text.substring(start, end); | |
566 } | |
567 | |
568 class Dart2JsSource implements Source { | |
569 Script _script; | |
570 | |
571 Dart2JsSource(this._script); | |
572 | |
573 Uri get uri => _script.uri; | |
574 | |
575 String get text => _script.text; | |
576 } | |
577 | |
578 class Dart2JsParameterMirror extends Dart2JsElementMirror | |
579 implements ParameterMirror { | |
580 final MethodMirror _method; | |
581 final bool isOptional; | |
582 | |
583 factory Dart2JsParameterMirror(Dart2JsMirrorSystem system, | |
584 MethodMirror method, | |
585 VariableElement element, | |
586 bool isOptional) { | |
587 if (element is FieldParameterElement) { | |
588 return new Dart2JsFieldParameterMirror(system, | |
589 method, element, isOptional); | |
590 } | |
591 return new Dart2JsParameterMirror._normal(system, | |
592 method, element, isOptional); | |
593 } | |
594 | |
595 Dart2JsParameterMirror._normal(Dart2JsMirrorSystem system, | |
596 this._method, | |
597 VariableElement element, | |
598 this.isOptional) | |
599 : super(system, element); | |
600 | |
601 VariableElement get _variableElement => _element; | |
602 | |
603 String get canonicalName => simpleName; | |
604 | |
605 String get qualifiedName => '${_method.qualifiedName}#${simpleName}'; | |
606 | |
607 TypeMirror get type => _convertTypeToTypeMirror(system, | |
608 _variableElement.computeType(system.compiler), | |
609 system.compiler.types.dynamicType, | |
610 _variableElement.variables.functionSignature); | |
611 | |
612 String get defaultValue { | |
613 if (hasDefaultValue) { | |
614 SendSet expression = _variableElement.cachedNode.asSendSet(); | |
615 return unparse(expression.arguments.head); | |
616 } | |
617 return null; | |
618 } | |
619 bool get hasDefaultValue { | |
620 return _variableElement.cachedNode !== null && | |
621 _variableElement.cachedNode is SendSet; | |
622 } | |
623 | |
624 bool get isInitializingFormal => false; | |
625 | |
626 FieldMirror get initializedField => null; | |
627 } | |
628 | |
629 class Dart2JsFieldParameterMirror extends Dart2JsParameterMirror { | |
630 | |
631 Dart2JsFieldParameterMirror(Dart2JsMirrorSystem system, | |
632 MethodMirror method, | |
633 FieldParameterElement element, | |
634 bool isOptional) | |
635 : super._normal(system, method, element, isOptional); | |
636 | |
637 FieldParameterElement get _fieldParameterElement => _element; | |
638 | |
639 TypeMirror get type { | |
640 if (_fieldParameterElement.variables.cachedNode.type !== null) { | |
641 return super.type; | |
642 } | |
643 return _convertTypeToTypeMirror(system, | |
644 _fieldParameterElement.fieldElement.computeType(system.compiler), | |
645 system.compiler.types.dynamicType, | |
646 _variableElement.variables.functionSignature); | |
647 } | |
648 | |
649 bool get isInitializingFormal => true; | |
650 | |
651 FieldMirror get initializedField => new Dart2JsFieldMirror( | |
652 _method.surroundingDeclaration, _fieldParameterElement.fieldElement); | |
653 } | |
654 | |
655 //------------------------------------------------------------------------------ | |
656 // Declarations | |
657 //------------------------------------------------------------------------------ | |
658 class Dart2JsInterfaceMirror extends Dart2JsObjectMirror | |
659 implements Dart2JsTypeMirror, InterfaceMirror { | |
660 final Dart2JsLibraryMirror library; | |
661 Map<String, Dart2JsMemberMirror> _members; | |
662 List<TypeVariableMirror> _typeVariables; | |
663 | |
664 Dart2JsInterfaceMirror(Dart2JsMirrorSystem system, ClassElement _class) | |
665 : this.library = system.getLibrary(_class.getLibrary()), | |
666 super(system, _class); | |
667 | |
668 ClassElement get _class => _element; | |
669 | |
670 | |
671 Dart2JsInterfaceMirror.fromLibrary(Dart2JsLibraryMirror library, | |
672 ClassElement _class) | |
673 : this.library = library, | |
674 super(library.system, _class); | |
675 | |
676 String get canonicalName => simpleName; | |
677 | |
678 String get qualifiedName => '${library.qualifiedName}.${simpleName}'; | |
679 | |
680 Location get location { | |
681 if (_class is PartialClassElement) { | |
682 var node = _class.parseNode(_diagnosticListener); | |
683 if (node !== null) { | |
684 var script = _class.getCompilationUnit().script; | |
685 var span = system.compiler.spanFromNode(node, script.uri); | |
686 return new Dart2JsLocation(script, span); | |
687 } | |
688 } | |
689 return super.location; | |
690 } | |
691 | |
692 void _ensureMembers() { | |
693 if (_members == null) { | |
694 _members = <String, Dart2JsMemberMirror>{}; | |
695 _class.localMembers.forEach((e) { | |
696 for (var member in _convertElementMemberToMemberMirrors(this, e)) { | |
697 _members[member.canonicalName] = member; | |
698 } | |
699 }); | |
700 } | |
701 } | |
702 | |
703 Map<Object, MemberMirror> get declaredMembers { | |
704 _ensureMembers(); | |
705 return new ImmutableMapWrapper<Object, MemberMirror>(_members); | |
706 } | |
707 | |
708 bool get isObject => _class == system.compiler.objectClass; | |
709 | |
710 bool get isDynamic => _class == system.compiler.dynamicClass; | |
711 | |
712 bool get isVoid => false; | |
713 | |
714 bool get isTypeVariable => false; | |
715 | |
716 bool get isTypedef => false; | |
717 | |
718 bool get isFunction => false; | |
719 | |
720 InterfaceMirror get declaration => this; | |
721 | |
722 InterfaceMirror get superclass { | |
723 if (_class.supertype != null) { | |
724 return new Dart2JsInterfaceTypeMirror(system, _class.supertype); | |
725 } | |
726 return null; | |
727 } | |
728 | |
729 Map<Object, InterfaceMirror> get interfaces { | |
730 var map = new Map<String, InterfaceMirror>(); | |
731 Link<DartType> link = _class.interfaces; | |
732 while (!link.isEmpty()) { | |
733 var type = _convertTypeToTypeMirror(system, link.head, | |
734 system.compiler.types.dynamicType); | |
735 map[type.canonicalName] = type; | |
736 link = link.tail; | |
737 } | |
738 return new ImmutableMapWrapper<Object, InterfaceMirror>(map); | |
739 } | |
740 | |
741 bool get isClass => !_class.isInterface(); | |
742 | |
743 bool get isInterface => _class.isInterface(); | |
744 | |
745 bool get isPrivate => _isPrivate(simpleName); | |
746 | |
747 bool get isDeclaration => true; | |
748 | |
749 List<TypeMirror> get typeArguments { | |
750 throw new UnsupportedOperationException( | |
751 'Declarations do not have type arguments'); | |
752 } | |
753 | |
754 List<TypeVariableMirror> get typeVariables { | |
755 if (_typeVariables == null) { | |
756 _typeVariables = <TypeVariableMirror>[]; | |
757 _class.ensureResolved(system.compiler); | |
758 for (TypeVariableType typeVariable in _class.typeVariables) { | |
759 _typeVariables.add( | |
760 new Dart2JsTypeVariableMirror(system, typeVariable)); | |
761 } | |
762 } | |
763 return _typeVariables; | |
764 } | |
765 | |
766 Map<Object, MethodMirror> get constructors { | |
767 _ensureMembers(); | |
768 return new AsFilteredImmutableMap<Object, MemberMirror, MethodMirror>( | |
769 _members, (m) => m.isConstructor ? m : null); | |
770 } | |
771 | |
772 /** | |
773 * Returns the default type for this interface. | |
774 */ | |
775 InterfaceMirror get defaultType { | |
776 if (_class.defaultClass != null) { | |
777 return new Dart2JsInterfaceTypeMirror(system, _class.defaultClass); | |
778 } | |
779 return null; | |
780 } | |
781 | |
782 bool operator ==(Object other) { | |
783 if (this === other) { | |
784 return true; | |
785 } | |
786 if (other is! InterfaceMirror) { | |
787 return false; | |
788 } | |
789 if (library != other.library) { | |
790 return false; | |
791 } | |
792 if (isDeclaration !== other.isDeclaration) { | |
793 return false; | |
794 } | |
795 return qualifiedName == other.qualifiedName; | |
796 } | |
797 } | |
798 | |
799 class Dart2JsTypedefMirror extends Dart2JsTypeElementMirror | |
800 implements Dart2JsTypeMirror, TypedefMirror { | |
801 final Dart2JsLibraryMirror _library; | |
802 List<TypeVariableMirror> _typeVariables; | |
803 TypeMirror _definition; | |
804 | |
805 Dart2JsTypedefMirror(Dart2JsMirrorSystem system, TypedefType _typedef) | |
806 : this._library = system.getLibrary(_typedef.element.getLibrary()), | |
807 super(system, _typedef); | |
808 | |
809 Dart2JsTypedefMirror.fromLibrary(Dart2JsLibraryMirror library, | |
810 TypedefType _typedef) | |
811 : this._library = library, | |
812 super(library.system, _typedef); | |
813 | |
814 TypedefType get _typedef => _type; | |
815 | |
816 String get canonicalName => simpleName; | |
817 | |
818 String get qualifiedName => '${library.qualifiedName}.${simpleName}'; | |
819 | |
820 Location get location { | |
821 var node = _typedef.element.parseNode(_diagnosticListener); | |
822 if (node !== null) { | |
823 var script = _typedef.element.getCompilationUnit().script; | |
824 var span = system.compiler.spanFromNode(node, script.uri); | |
825 return new Dart2JsLocation(script, span); | |
826 } | |
827 return super.location; | |
828 } | |
829 | |
830 LibraryMirror get library => _library; | |
831 | |
832 bool get isObject => false; | |
833 | |
834 bool get isDynamic => false; | |
835 | |
836 bool get isVoid => false; | |
837 | |
838 bool get isTypeVariable => false; | |
839 | |
840 bool get isTypedef => true; | |
841 | |
842 bool get isFunction => false; | |
843 | |
844 List<TypeMirror> get typeArguments { | |
845 throw new UnsupportedOperationException( | |
846 'Declarations do not have type arguments'); | |
847 } | |
848 | |
849 List<TypeVariableMirror> get typeVariables { | |
850 if (_typeVariables == null) { | |
851 _typeVariables = <TypeVariableMirror>[]; | |
852 for (TypeVariableType typeVariable in _typedef.typeArguments) { | |
853 _typeVariables.add( | |
854 new Dart2JsTypeVariableMirror(system, typeVariable)); | |
855 } | |
856 } | |
857 return _typeVariables; | |
858 } | |
859 | |
860 TypeMirror get definition { | |
861 if (_definition === null) { | |
862 // TODO(johnniwinther): Should be [ensureResolved]. | |
863 system.compiler.resolveTypedef(_typedef.element); | |
864 _definition = _convertTypeToTypeMirror( | |
865 system, | |
866 _typedef.element.alias, | |
867 system.compiler.types.dynamicType, | |
868 _typedef.element.functionSignature); | |
869 } | |
870 return _definition; | |
871 } | |
872 | |
873 Map<Object, MemberMirror> get declaredMembers => | |
874 const <String, MemberMirror>{}; | |
875 | |
876 InterfaceMirror get declaration => this; | |
877 | |
878 // TODO(johnniwinther): How should a typedef respond to these? | |
879 InterfaceMirror get superclass => null; | |
880 | |
881 Map<Object, InterfaceMirror> get interfaces => | |
882 const <String, InterfaceMirror>{}; | |
883 | |
884 bool get isClass => false; | |
885 | |
886 bool get isInterface => false; | |
887 | |
888 bool get isPrivate => _isPrivate(simpleName); | |
889 | |
890 bool get isDeclaration => true; | |
891 | |
892 Map<Object, MethodMirror> get constructors => | |
893 const <String, MethodMirror>{}; | |
894 | |
895 InterfaceMirror get defaultType => null; | |
896 } | |
897 | |
898 class Dart2JsTypeVariableMirror extends Dart2JsTypeElementMirror | |
899 implements TypeVariableMirror { | |
900 final TypeVariableType _typeVariableType; | |
901 InterfaceMirror _declarer; | |
902 | |
903 Dart2JsTypeVariableMirror(Dart2JsMirrorSystem system, | |
904 TypeVariableType typeVariableType) | |
905 : this._typeVariableType = typeVariableType, | |
906 super(system, typeVariableType) { | |
907 assert(_typeVariableType !== null); | |
908 } | |
909 | |
910 | |
911 String get qualifiedName => '${declarer.qualifiedName}.${simpleName}'; | |
912 | |
913 InterfaceMirror get declarer { | |
914 if (_declarer === null) { | |
915 if (_typeVariableType.element.enclosingElement.isClass()) { | |
916 _declarer = new Dart2JsInterfaceMirror(system, | |
917 _typeVariableType.element.enclosingElement); | |
918 } else if (_typeVariableType.element.enclosingElement.isTypedef()) { | |
919 _declarer = new Dart2JsTypedefMirror(system, | |
920 _typeVariableType.element.enclosingElement.computeType( | |
921 system.compiler)); | |
922 } | |
923 } | |
924 return _declarer; | |
925 } | |
926 | |
927 LibraryMirror get library => declarer.library; | |
928 | |
929 bool get isObject => false; | |
930 | |
931 bool get isDynamic => false; | |
932 | |
933 bool get isVoid => false; | |
934 | |
935 bool get isTypeVariable => true; | |
936 | |
937 bool get isTypedef => false; | |
938 | |
939 bool get isFunction => false; | |
940 | |
941 TypeMirror get bound => _convertTypeToTypeMirror( | |
942 system, | |
943 _typeVariableType.element.bound, | |
944 system.compiler.objectClass.computeType(system.compiler)); | |
945 | |
946 bool operator ==(Object other) { | |
947 if (this === other) { | |
948 return true; | |
949 } | |
950 if (other is! TypeVariableMirror) { | |
951 return false; | |
952 } | |
953 if (declarer != other.declarer) { | |
954 return false; | |
955 } | |
956 return qualifiedName == other.qualifiedName; | |
957 } | |
958 } | |
959 | |
960 | |
961 //------------------------------------------------------------------------------ | |
962 // Types | |
963 //------------------------------------------------------------------------------ | |
964 | |
965 abstract class Dart2JsTypeElementMirror extends Dart2JsProxyMirror | |
966 implements Dart2JsTypeMirror { | |
967 final DartType _type; | |
968 | |
969 Dart2JsTypeElementMirror(Dart2JsMirrorSystem system, this._type) | |
970 : super(system); | |
971 | |
972 String get simpleName => _type.name.slowToString(); | |
973 | |
974 String get canonicalName => simpleName; | |
975 | |
976 Location get location { | |
977 var script = _type.element.getCompilationUnit().script; | |
978 return new Dart2JsLocation(script, | |
979 system.compiler.spanFromElement(_type.element)); | |
980 } | |
981 | |
982 LibraryMirror get library { | |
983 return system.getLibrary(_type.element.getLibrary()); | |
984 } | |
985 | |
986 String toString() => _type.element.toString(); | |
987 } | |
988 | |
989 class Dart2JsInterfaceTypeMirror extends Dart2JsTypeElementMirror | |
990 implements InterfaceMirror { | |
991 List<TypeMirror> _typeArguments; | |
992 | |
993 Dart2JsInterfaceTypeMirror(Dart2JsMirrorSystem system, | |
994 InterfaceType interfaceType) | |
995 : super(system, interfaceType); | |
996 | |
997 InterfaceType get _interfaceType => _type; | |
998 | |
999 String get qualifiedName => declaration.qualifiedName; | |
1000 | |
1001 // TODO(johnniwinther): Substitute type arguments for type variables. | |
1002 Map<Object, MemberMirror> get declaredMembers => declaration.declaredMembers; | |
1003 | |
1004 bool get isObject => system.compiler.objectClass == _type.element; | |
1005 | |
1006 bool get isDynamic => system.compiler.dynamicClass == _type.element; | |
1007 | |
1008 bool get isTypeVariable => false; | |
1009 | |
1010 bool get isVoid => false; | |
1011 | |
1012 bool get isTypedef => false; | |
1013 | |
1014 bool get isFunction => false; | |
1015 | |
1016 InterfaceMirror get declaration | |
1017 => new Dart2JsInterfaceMirror(system, _type.element); | |
1018 | |
1019 // TODO(johnniwinther): Substitute type arguments for type variables. | |
1020 InterfaceMirror get superclass => declaration.superclass; | |
1021 | |
1022 // TODO(johnniwinther): Substitute type arguments for type variables. | |
1023 Map<Object, InterfaceMirror> get interfaces => declaration.interfaces; | |
1024 | |
1025 bool get isClass => declaration.isClass; | |
1026 | |
1027 bool get isInterface => declaration.isInterface; | |
1028 | |
1029 bool get isPrivate => declaration.isPrivate; | |
1030 | |
1031 bool get isDeclaration => false; | |
1032 | |
1033 List<TypeMirror> get typeArguments { | |
1034 if (_typeArguments == null) { | |
1035 _typeArguments = <TypeMirror>[]; | |
1036 Link<DartType> type = _interfaceType.arguments; | |
1037 while (type != null && type.head != null) { | |
1038 _typeArguments.add(_convertTypeToTypeMirror(system, type.head, | |
1039 system.compiler.types.dynamicType)); | |
1040 type = type.tail; | |
1041 } | |
1042 } | |
1043 return _typeArguments; | |
1044 } | |
1045 | |
1046 List<TypeVariableMirror> get typeVariables => declaration.typeVariables; | |
1047 | |
1048 // TODO(johnniwinther): Substitute type arguments for type variables. | |
1049 Map<Object, MethodMirror> get constructors => declaration.constructors; | |
1050 | |
1051 // TODO(johnniwinther): Substitute type arguments for type variables? | |
1052 InterfaceMirror get defaultType => declaration.defaultType; | |
1053 | |
1054 bool operator ==(Object other) { | |
1055 if (this === other) { | |
1056 return true; | |
1057 } | |
1058 if (other is! InterfaceMirror) { | |
1059 return false; | |
1060 } | |
1061 if (other.isDeclaration) { | |
1062 return false; | |
1063 } | |
1064 if (declaration != other.declaration) { | |
1065 return false; | |
1066 } | |
1067 var thisTypeArguments = typeArguments.iterator(); | |
1068 var otherTypeArguments = other.typeArguments.iterator(); | |
1069 while (thisTypeArguments.hasNext() && otherTypeArguments.hasNext()) { | |
1070 if (thisTypeArguments.next() != otherTypeArguments.next()) { | |
1071 return false; | |
1072 } | |
1073 } | |
1074 return !thisTypeArguments.hasNext() && !otherTypeArguments.hasNext(); | |
1075 } | |
1076 } | |
1077 | |
1078 | |
1079 class Dart2JsFunctionTypeMirror extends Dart2JsTypeElementMirror | |
1080 implements FunctionTypeMirror { | |
1081 final FunctionSignature _functionSignature; | |
1082 List<ParameterMirror> _parameters; | |
1083 | |
1084 Dart2JsFunctionTypeMirror(Dart2JsMirrorSystem system, | |
1085 FunctionType functionType, this._functionSignature) | |
1086 : super(system, functionType) { | |
1087 assert (_functionSignature !== null); | |
1088 } | |
1089 | |
1090 FunctionType get _functionType => _type; | |
1091 | |
1092 // TODO(johnniwinther): Is this the qualified name of a function type? | |
1093 String get qualifiedName => declaration.qualifiedName; | |
1094 | |
1095 // TODO(johnniwinther): Substitute type arguments for type variables. | |
1096 Map<Object, MemberMirror> get declaredMembers { | |
1097 var method = callMethod; | |
1098 if (method !== null) { | |
1099 var map = new Map<String, MemberMirror>.from( | |
1100 declaration.declaredMembers); | |
1101 var name = method.qualifiedName; | |
1102 map[name] = method; | |
1103 Function func = null; | |
1104 return new ImmutableMapWrapper<Object, MemberMirror>(map); | |
1105 } | |
1106 return declaration.declaredMembers; | |
1107 } | |
1108 | |
1109 bool get isObject => system.compiler.objectClass == _type.element; | |
1110 | |
1111 bool get isDynamic => system.compiler.dynamicClass == _type.element; | |
1112 | |
1113 bool get isVoid => false; | |
1114 | |
1115 bool get isTypeVariable => false; | |
1116 | |
1117 bool get isTypedef => false; | |
1118 | |
1119 bool get isFunction => true; | |
1120 | |
1121 MethodMirror get callMethod => _convertElementMethodToMethodMirror( | |
1122 system.getLibrary(_functionType.element.getLibrary()), | |
1123 _functionType.element); | |
1124 | |
1125 InterfaceMirror get declaration | |
1126 => new Dart2JsInterfaceMirror(system, system.compiler.functionClass); | |
1127 | |
1128 // TODO(johnniwinther): Substitute type arguments for type variables. | |
1129 InterfaceMirror get superclass => declaration.superclass; | |
1130 | |
1131 // TODO(johnniwinther): Substitute type arguments for type variables. | |
1132 Map<Object, InterfaceMirror> get interfaces => declaration.interfaces; | |
1133 | |
1134 bool get isClass => declaration.isClass; | |
1135 | |
1136 bool get isInterface => declaration.isInterface; | |
1137 | |
1138 bool get isPrivate => declaration.isPrivate; | |
1139 | |
1140 bool get isDeclaration => false; | |
1141 | |
1142 List<TypeMirror> get typeArguments => const <TypeMirror>[]; | |
1143 | |
1144 List<TypeVariableMirror> get typeVariables => declaration.typeVariables; | |
1145 | |
1146 Map<Object, MethodMirror> get constructors => | |
1147 <String, MethodMirror>{}; | |
1148 | |
1149 InterfaceMirror get defaultType => null; | |
1150 | |
1151 TypeMirror get returnType { | |
1152 return _convertTypeToTypeMirror(system, _functionType.returnType, | |
1153 system.compiler.types.dynamicType); | |
1154 } | |
1155 | |
1156 List<ParameterMirror> get parameters { | |
1157 if (_parameters === null) { | |
1158 _parameters = _parametersFromFunctionSignature(system, callMethod, | |
1159 _functionSignature); | |
1160 } | |
1161 return _parameters; | |
1162 } | |
1163 } | |
1164 | |
1165 class Dart2JsVoidMirror extends Dart2JsTypeElementMirror { | |
1166 | |
1167 Dart2JsVoidMirror(Dart2JsMirrorSystem system, VoidType voidType) | |
1168 : super(system, voidType); | |
1169 | |
1170 VoidType get _voidType => _type; | |
1171 | |
1172 String get qualifiedName => simpleName; | |
1173 | |
1174 /** | |
1175 * The void type has no location. | |
1176 */ | |
1177 Location get location => null; | |
1178 | |
1179 /** | |
1180 * The void type has no library. | |
1181 */ | |
1182 LibraryMirror get library => null; | |
1183 | |
1184 bool get isObject => false; | |
1185 | |
1186 bool get isVoid => true; | |
1187 | |
1188 bool get isDynamic => false; | |
1189 | |
1190 bool get isTypeVariable => false; | |
1191 | |
1192 bool get isTypedef => false; | |
1193 | |
1194 bool get isFunction => false; | |
1195 | |
1196 bool operator ==(Object other) { | |
1197 if (this === other) { | |
1198 return true; | |
1199 } | |
1200 if (other is! TypeMirror) { | |
1201 return false; | |
1202 } | |
1203 return other.isVoid; | |
1204 } | |
1205 } | |
1206 | |
1207 //------------------------------------------------------------------------------ | |
1208 // Member mirrors implementation. | |
1209 //------------------------------------------------------------------------------ | |
1210 | |
1211 class Dart2JsMethodMirror extends Dart2JsElementMirror | |
1212 implements Dart2JsMemberMirror, MethodMirror { | |
1213 final Dart2JsObjectMirror _objectMirror; | |
1214 String _name; | |
1215 String _constructorName; | |
1216 String _operatorName; | |
1217 Dart2JsMethodKind _kind; | |
1218 String _canonicalName; | |
1219 | |
1220 Dart2JsMethodMirror(Dart2JsObjectMirror objectMirror, | |
1221 FunctionElement function) | |
1222 : this._objectMirror = objectMirror, | |
1223 super(objectMirror.system, function) { | |
1224 _name = _element.name.slowToString(); | |
1225 if (_function.kind == ElementKind.GETTER) { | |
1226 _kind = Dart2JsMethodKind.GETTER; | |
1227 _canonicalName = _name; | |
1228 } else if (_function.kind == ElementKind.SETTER) { | |
1229 _kind = Dart2JsMethodKind.SETTER; | |
1230 _canonicalName = '$_name='; | |
1231 } else if (_function.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { | |
1232 _constructorName = ''; | |
1233 int dollarPos = _name.indexOf('\$'); | |
1234 if (dollarPos != -1) { | |
1235 _constructorName = _name.substring(dollarPos + 1); | |
1236 _name = _name.substring(0, dollarPos); | |
1237 // canonical name is TypeName.constructorName | |
1238 _canonicalName = '$_name.$_constructorName'; | |
1239 } else { | |
1240 // canonical name is TypeName | |
1241 _canonicalName = _name; | |
1242 } | |
1243 if (_function.modifiers !== null && _function.modifiers.isConst()) { | |
1244 _kind = Dart2JsMethodKind.CONST; | |
1245 } else { | |
1246 _kind = Dart2JsMethodKind.CONSTRUCTOR; | |
1247 } | |
1248 } else if (_function.modifiers !== null && | |
1249 _function.modifiers.isFactory()) { | |
1250 _kind = Dart2JsMethodKind.FACTORY; | |
1251 _constructorName = ''; | |
1252 int dollarPos = _name.indexOf('\$'); | |
1253 if (dollarPos != -1) { | |
1254 _constructorName = _name.substring(dollarPos+1); | |
1255 _name = _name.substring(0, dollarPos); | |
1256 } | |
1257 // canonical name is TypeName.constructorName | |
1258 _canonicalName = '$_name.$_constructorName'; | |
1259 } else if (_name == 'negate') { | |
1260 _operatorName = _name; | |
1261 _name = 'operator'; | |
1262 _kind = Dart2JsMethodKind.OPERATOR; | |
1263 // canonical name is 'operator operatorName' | |
1264 _canonicalName = 'operator $_operatorName'; | |
1265 } else if (_name.startsWith('operator\$')) { | |
1266 String str = _name.substring(9); | |
1267 _name = 'operator'; | |
1268 _kind = Dart2JsMethodKind.OPERATOR; | |
1269 _operatorName = _getOperatorFromOperatorName(str); | |
1270 // canonical name is 'operator operatorName' | |
1271 _canonicalName = 'operator $_operatorName'; | |
1272 } else { | |
1273 _kind = Dart2JsMethodKind.NORMAL; | |
1274 _canonicalName = _name; | |
1275 } | |
1276 } | |
1277 | |
1278 FunctionElement get _function => _element; | |
1279 | |
1280 String get simpleName => _name; | |
1281 | |
1282 String get qualifiedName | |
1283 => '${surroundingDeclaration.qualifiedName}.$canonicalName'; | |
1284 | |
1285 String get canonicalName => _canonicalName; | |
1286 | |
1287 ObjectMirror get surroundingDeclaration => _objectMirror; | |
1288 | |
1289 bool get isTopLevel => _objectMirror is LibraryMirror; | |
1290 | |
1291 bool get isConstructor | |
1292 => _kind == Dart2JsMethodKind.CONSTRUCTOR || isConst || isFactory; | |
1293 | |
1294 bool get isField => false; | |
1295 | |
1296 bool get isMethod => !isConstructor; | |
1297 | |
1298 bool get isPrivate => _isPrivate(simpleName); | |
1299 | |
1300 bool get isStatic => | |
1301 _function.modifiers !== null && _function.modifiers.isStatic(); | |
1302 | |
1303 List<ParameterMirror> get parameters { | |
1304 return _parametersFromFunctionSignature(system, this, | |
1305 _function.computeSignature(system.compiler)); | |
1306 } | |
1307 | |
1308 TypeMirror get returnType => _convertTypeToTypeMirror( | |
1309 system, _function.computeSignature(system.compiler).returnType, | |
1310 system.compiler.types.dynamicType); | |
1311 | |
1312 bool get isConst => _kind == Dart2JsMethodKind.CONST; | |
1313 | |
1314 bool get isFactory => _kind == Dart2JsMethodKind.FACTORY; | |
1315 | |
1316 String get constructorName => _constructorName; | |
1317 | |
1318 bool get isGetter => _kind == Dart2JsMethodKind.GETTER; | |
1319 | |
1320 bool get isSetter => _kind == Dart2JsMethodKind.SETTER; | |
1321 | |
1322 bool get isOperator => _kind == Dart2JsMethodKind.OPERATOR; | |
1323 | |
1324 String get operatorName => _operatorName; | |
1325 | |
1326 Location get location { | |
1327 var node = _function.parseNode(_diagnosticListener); | |
1328 if (node !== null) { | |
1329 var script = _function.getCompilationUnit().script; | |
1330 if (_function.isPatched) { | |
1331 // TODO(ager): This should not be necessary when patch | |
1332 // support has been reworked. | |
1333 script = _function.patch.getCompilationUnit().script; | |
1334 } | |
1335 var span = system.compiler.spanFromNode(node, script.uri); | |
1336 return new Dart2JsLocation(script, span); | |
1337 } | |
1338 return super.location; | |
1339 } | |
1340 | |
1341 } | |
1342 | |
1343 class Dart2JsFieldMirror extends Dart2JsElementMirror | |
1344 implements Dart2JsMemberMirror, FieldMirror { | |
1345 Dart2JsObjectMirror _objectMirror; | |
1346 VariableElement _variable; | |
1347 | |
1348 Dart2JsFieldMirror(Dart2JsObjectMirror objectMirror, | |
1349 VariableElement variable) | |
1350 : this._objectMirror = objectMirror, | |
1351 this._variable = variable, | |
1352 super(objectMirror.system, variable); | |
1353 | |
1354 String get qualifiedName | |
1355 => '${surroundingDeclaration.qualifiedName}.$canonicalName'; | |
1356 | |
1357 String get canonicalName => simpleName; | |
1358 | |
1359 ObjectMirror get surroundingDeclaration => _objectMirror; | |
1360 | |
1361 bool get isTopLevel => _objectMirror is LibraryMirror; | |
1362 | |
1363 bool get isConstructor => false; | |
1364 | |
1365 bool get isField => true; | |
1366 | |
1367 bool get isMethod => false; | |
1368 | |
1369 bool get isPrivate => _isPrivate(simpleName); | |
1370 | |
1371 bool get isStatic => _variable.modifiers.isStatic(); | |
1372 | |
1373 // TODO(johnniwinther): Should this return true on const as well? | |
1374 bool get isFinal => _variable.modifiers.isFinal(); | |
1375 | |
1376 TypeMirror get type => _convertTypeToTypeMirror(system, | |
1377 _variable.computeType(system.compiler), | |
1378 system.compiler.types.dynamicType); | |
1379 | |
1380 Location get location { | |
1381 var script = _variable.getCompilationUnit().script; | |
1382 var node = _variable.variables.parseNode(_diagnosticListener); | |
1383 if (node !== null) { | |
1384 var span = system.compiler.spanFromNode(node, script.uri); | |
1385 return new Dart2JsLocation(script, span); | |
1386 } else { | |
1387 var span = system.compiler.spanFromElement(_variable); | |
1388 return new Dart2JsLocation(script, span); | |
1389 } | |
1390 } | |
1391 } | |
1392 | |
OLD | NEW |