Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirrors.dart

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 dart2js.mirrors;
6
7 import 'dart:collection' show UnmodifiableListView, UnmodifiableMapView;
8
9 import '../constants/expressions.dart';
10 import '../constants/values.dart';
11 import '../elements/elements.dart';
12 import '../scanner/scannerlib.dart';
13 import '../resolution/resolution.dart' show Scope;
14 import '../dart2jslib.dart';
15 import '../dart_types.dart';
16 import '../tree/tree.dart';
17 import '../util/util.dart'
18 show Link,
19 LinkBuilder;
20 import '../util/characters.dart' show $CR, $LF;
21
22 import 'source_mirrors.dart';
23 import 'mirrors_util.dart';
24
25 part 'dart2js_library_mirror.dart';
26 part 'dart2js_type_mirrors.dart';
27 part 'dart2js_member_mirrors.dart';
28 part 'dart2js_instance_mirrors.dart';
29
30 //------------------------------------------------------------------------------
31 // Utility types and functions for the dart2js mirror system
32 //------------------------------------------------------------------------------
33
34 bool _includeLibrary(Dart2JsLibraryMirror mirror) {
35 return const bool.fromEnvironment("list_all_libraries") ||
36 !mirror._element.isInternalLibrary;
37 }
38
39 bool _isPrivate(String name) {
40 return name.startsWith('_');
41 }
42
43 List<ParameterMirror> _parametersFromFunctionSignature(
44 Dart2JsDeclarationMirror owner,
45 FunctionSignature signature) {
46 var parameters = <ParameterMirror>[];
47 Link<Element> link = signature.requiredParameters;
48 while (!link.isEmpty) {
49 parameters.add(new Dart2JsParameterMirror(
50 owner, link.head, isOptional: false, isNamed: false));
51 link = link.tail;
52 }
53 link = signature.optionalParameters;
54 bool isNamed = signature.optionalParametersAreNamed;
55 while (!link.isEmpty) {
56 parameters.add(new Dart2JsParameterMirror(
57 owner, link.head, isOptional: true, isNamed: isNamed));
58 link = link.tail;
59 }
60 return parameters;
61 }
62
63 MethodMirror _convertElementMethodToMethodMirror(
64 Dart2JsDeclarationMirror library, Element element) {
65 if (element is FunctionElement) {
66 return new Dart2JsMethodMirror(library, element);
67 } else {
68 return null;
69 }
70 }
71
72 //------------------------------------------------------------------------------
73 // Dart2Js specific extensions of mirror interfaces
74 //------------------------------------------------------------------------------
75
76 abstract class Dart2JsMirror implements Mirror {
77 Dart2JsMirrorSystem get mirrorSystem;
78 }
79
80 abstract class Dart2JsDeclarationMirror extends Dart2JsMirror
81 implements DeclarationSourceMirror {
82
83 bool get isTopLevel => owner != null && owner is LibraryMirror;
84
85 bool get isPrivate => _isPrivate(_simpleNameString);
86
87 String get _simpleNameString;
88
89 String get _qualifiedNameString {
90 var parent = owner;
91 if (parent is Dart2JsDeclarationMirror) {
92 return '${parent._qualifiedNameString}.${_simpleNameString}';
93 }
94 assert(parent == null);
95 return _simpleNameString;
96 }
97
98 Symbol get simpleName => symbolOf(_simpleNameString, getLibrary(this));
99
100 Symbol get qualifiedName => symbolOf(_qualifiedNameString, getLibrary(this));
101
102 DeclarationMirror lookupInScope(String name) => null;
103
104 bool get isNameSynthetic => false;
105
106 /// Returns the type mirror for [type] in the context of this declaration.
107 TypeMirror _getTypeMirror(DartType type) {
108 return mirrorSystem._convertTypeToTypeMirror(type);
109 }
110
111 /// Returns a list of the declaration mirrorSystem for [element].
112 Iterable<Dart2JsMemberMirror> _getDeclarationMirrors(Element element) {
113 if (element.isSynthesized) {
114 return const <Dart2JsMemberMirror>[];
115 } else if (element is VariableElement) {
116 return <Dart2JsMemberMirror>[new Dart2JsFieldMirror(this, element)];
117 } else if (element is FunctionElement) {
118 return <Dart2JsMemberMirror>[new Dart2JsMethodMirror(this, element)];
119 } else if (element is AbstractFieldElement) {
120 var members = <Dart2JsMemberMirror>[];
121 AbstractFieldElement field = element;
122 if (field.getter != null) {
123 members.add(new Dart2JsMethodMirror(this, field.getter));
124 }
125 if (field.setter != null) {
126 members.add(new Dart2JsMethodMirror(this, field.setter));
127 }
128 return members;
129 }
130 mirrorSystem.compiler.internalError(element,
131 "Unexpected member type $element ${element.kind}.");
132 return null;
133 }
134 }
135
136 abstract class Dart2JsElementMirror extends Dart2JsDeclarationMirror {
137 final Dart2JsMirrorSystem mirrorSystem;
138 final Element _element;
139 List<InstanceMirror> _metadata;
140
141 Dart2JsElementMirror(this.mirrorSystem, this._element) {
142 assert (mirrorSystem != null);
143 assert (_element != null);
144 }
145
146 String get _simpleNameString => _element.name;
147
148 /**
149 * Computes the first token for this declaration using the begin token of the
150 * element node or element position as indicator.
151 */
152 Token getBeginToken() {
153 Element element = _element;
154 if (element is AstElement) {
155 Node node = element.node;
156 if (node != null) {
157 return node.getBeginToken();
158 }
159 }
160 return element.position;
161 }
162
163 /**
164 * Computes the last token for this declaration using the end token of the
165 * element node or element position as indicator.
166 */
167 Token getEndToken() {
168 Element element = _element;
169 if (element is AstElement) {
170 Node node = element.node;
171 if (node != null) {
172 return node.getEndToken();
173 }
174 }
175 return element.position;
176 }
177
178 /**
179 * Returns the first token for the source of this declaration, including
180 * metadata annotations.
181 */
182 Token getFirstToken() {
183 if (!_element.metadata.isEmpty) {
184 for (MetadataAnnotation metadata in _element.metadata) {
185 if (metadata.beginToken != null) {
186 return metadata.beginToken;
187 }
188 }
189 }
190 return getBeginToken();
191 }
192
193 Script getScript() => _element.compilationUnit.script;
194
195 SourceLocation get location {
196 Token beginToken = getFirstToken();
197 Script script = getScript();
198 SourceSpan span;
199 if (beginToken == null) {
200 span = new SourceSpan(script.readableUri, 0, 0);
201 } else {
202 Token endToken = getEndToken();
203 span = mirrorSystem.compiler.spanFromTokens(
204 beginToken, endToken, script.readableUri);
205 }
206 return new Dart2JsSourceLocation(script, span);
207 }
208
209 String toString() => _element.toString();
210
211 void _appendCommentTokens(Token commentToken) {
212 while (commentToken != null && commentToken.kind == COMMENT_TOKEN) {
213 _metadata.add(new Dart2JsCommentInstanceMirror(
214 mirrorSystem, commentToken.value));
215 commentToken = commentToken.next;
216 }
217 }
218
219 List<InstanceMirror> get metadata {
220 if (_metadata == null) {
221 _metadata = <InstanceMirror>[];
222 for (MetadataAnnotation metadata in _element.metadata) {
223 _appendCommentTokens(
224 mirrorSystem.compiler.commentMap[metadata.beginToken]);
225 metadata.ensureResolved(mirrorSystem.compiler);
226 _metadata.add(_convertConstantToInstanceMirror(
227 mirrorSystem, metadata.constant, metadata.constant.value));
228 }
229 _appendCommentTokens(mirrorSystem.compiler.commentMap[getBeginToken()]);
230 }
231 // TODO(johnniwinther): Return an unmodifiable list instead.
232 return new List<InstanceMirror>.from(_metadata);
233 }
234
235 DeclarationMirror lookupInScope(String name) {
236 // TODO(11653): Support lookup of constructors.
237 Scope scope = _element.buildScope();
238 Element result;
239 int index = name.indexOf('.');
240 if (index != -1) {
241 // Lookup [: prefix.id :].
242 String prefix = name.substring(0, index);
243 String id = name.substring(index+1);
244 result = scope.lookup(prefix);
245 if (result != null && result.isPrefix) {
246 PrefixElement prefix = result;
247 result = prefix.lookupLocalMember(id);
248 } else {
249 result = null;
250 }
251 } else {
252 // Lookup [: id :].
253 result = scope.lookup(name);
254 }
255 if (result == null || result.isPrefix) return null;
256 return _convertElementToDeclarationMirror(mirrorSystem, result);
257 }
258
259 bool operator ==(var other) {
260 if (identical(this, other)) return true;
261 if (other == null) return false;
262 if (other is! Dart2JsElementMirror) return false;
263 return _element == other._element &&
264 owner == other.owner;
265 }
266
267 int get hashCode {
268 return 13 * _element.hashCode + 17 * owner.hashCode;
269 }
270 }
271
272 //------------------------------------------------------------------------------
273 // Mirror system implementation.
274 //------------------------------------------------------------------------------
275
276 class Dart2JsMirrorSystem extends MirrorSystem {
277 final Compiler compiler;
278 Map<LibraryElement, Dart2JsLibraryMirror> _libraryMap;
279 UnmodifiableMapView<Uri, LibraryMirror> _filteredLibraries;
280
281 Dart2JsMirrorSystem(this.compiler);
282
283 IsolateMirror get isolate => null;
284
285 void _ensureLibraries() {
286 if (_filteredLibraries == null) {
287 var filteredLibs = new Map<Uri, LibraryMirror>();
288 _libraryMap = new Map<LibraryElement, Dart2JsLibraryMirror>();
289 compiler.libraryLoader.libraries.forEach((LibraryElement v) {
290 var mirror = new Dart2JsLibraryMirror(mirrorSystem, v);
291 if (_includeLibrary(mirror)) {
292 filteredLibs[mirror.uri] = mirror;
293 }
294 _libraryMap[v] = mirror;
295 });
296
297 _filteredLibraries =
298 new UnmodifiableMapView<Uri, LibraryMirror>(filteredLibs);
299 }
300 }
301
302 Map<Uri, LibraryMirror> get libraries {
303 _ensureLibraries();
304 return _filteredLibraries;
305 }
306
307 Dart2JsLibraryMirror _getLibrary(LibraryElement element) =>
308 _libraryMap[element];
309
310 Dart2JsMirrorSystem get mirrorSystem => this;
311
312 TypeMirror get dynamicType =>
313 _convertTypeToTypeMirror(const DynamicType());
314
315 TypeMirror get voidType =>
316 _convertTypeToTypeMirror(const VoidType());
317
318 TypeMirror _convertTypeToTypeMirror(DartType type) {
319 assert(type != null);
320 if (type.treatAsDynamic) {
321 return new Dart2JsDynamicMirror(this, type);
322 } else if (type is InterfaceType) {
323 if (type.typeArguments.isEmpty) {
324 return _getTypeDeclarationMirror(type.element);
325 } else {
326 return new Dart2JsInterfaceTypeMirror(this, type);
327 }
328 } else if (type is TypeVariableType) {
329 return new Dart2JsTypeVariableMirror(this, type);
330 } else if (type is FunctionType) {
331 return new Dart2JsFunctionTypeMirror(this, type);
332 } else if (type is VoidType) {
333 return new Dart2JsVoidMirror(this, type);
334 } else if (type is TypedefType) {
335 if (type.typeArguments.isEmpty) {
336 return _getTypeDeclarationMirror(type.element);
337 } else {
338 return new Dart2JsTypedefMirror(this, type);
339 }
340 }
341 compiler.internalError(type.element,
342 "Unexpected type $type of kind ${type.kind}.");
343 return null;
344 }
345
346 DeclarationMirror _getTypeDeclarationMirror(TypeDeclarationElement element) {
347 if (element.isClass) {
348 return new Dart2JsClassDeclarationMirror(this, element.thisType);
349 } else if (element.isTypedef) {
350 return new Dart2JsTypedefDeclarationMirror(this, element.thisType);
351 }
352 compiler.internalError(element, "Unexpected element $element.");
353 return null;
354 }
355 }
356
357 abstract class ContainerMixin {
358 UnmodifiableMapView<Symbol, DeclarationMirror> _declarations;
359
360 void _ensureDeclarations() {
361 if (_declarations == null) {
362 var declarations = <Symbol, DeclarationMirror>{};
363 _forEachElement((Element element) {
364 for (DeclarationMirror mirror in _getDeclarationMirrors(element)) {
365 assert(invariant(_element,
366 !declarations.containsKey(mirror.simpleName),
367 message: "Declaration name '${nameOf(mirror)}' "
368 "is not unique in $_element."));
369 declarations[mirror.simpleName] = mirror;
370 }
371 });
372 _declarations =
373 new UnmodifiableMapView<Symbol, DeclarationMirror>(declarations);
374 }
375 }
376
377 Element get _element;
378
379 void _forEachElement(f(Element element));
380
381 Iterable<Dart2JsMemberMirror> _getDeclarationMirrors(Element element);
382
383 Map<Symbol, DeclarationMirror> get declarations {
384 _ensureDeclarations();
385 return _declarations;
386 }
387 }
388
389 /**
390 * Converts [element] into its corresponding [DeclarationMirror], if any.
391 *
392 * If [element] is an [AbstractFieldElement] the mirror for its getter is
393 * returned or, if not present, the mirror for its setter.
394 */
395 DeclarationMirror _convertElementToDeclarationMirror(Dart2JsMirrorSystem system,
396 Element element) {
397 if (element.isTypeVariable) {
398 TypeVariableElement typeVariable = element;
399 return new Dart2JsTypeVariableMirror(system, typeVariable.type);
400 }
401
402 Dart2JsLibraryMirror library = system._libraryMap[element.library];
403 if (element.isLibrary) return library;
404 if (element.isTypedef) {
405 TypedefElement typedefElement = element;
406 return new Dart2JsTypedefMirror.fromLibrary(
407 library, typedefElement.thisType);
408 }
409
410 Dart2JsDeclarationMirror container = library;
411 if (element.enclosingClass != null) {
412 container = system._getTypeDeclarationMirror(element.enclosingClass);
413 }
414 if (element.isClass) return container;
415 if (element.isParameter) {
416 Dart2JsMethodMirror method = _convertElementMethodToMethodMirror(
417 container, element.outermostEnclosingMemberOrTopLevel);
418 // TODO(johnniwinther): Find the right info for [isOptional] and [isNamed].
419 return new Dart2JsParameterMirror(
420 method, element, isOptional: false, isNamed: false);
421 }
422 Iterable<DeclarationMirror> members =
423 container._getDeclarationMirrors(element);
424 if (members.isEmpty) return null;
425 return members.first;
426 }
427
428 /**
429 * Experimental API for accessing compilation units defined in a
430 * library.
431 */
432 // TODO(ahe): Superclasses? Is this really a mirror?
433 class Dart2JsCompilationUnitMirror extends Dart2JsMirror with ContainerMixin {
434 final Dart2JsLibraryMirror _library;
435 final CompilationUnitElement _element;
436
437 Dart2JsCompilationUnitMirror(this._element, this._library);
438
439 Dart2JsMirrorSystem get mirrorSystem => _library.mirrorSystem;
440
441 // TODO(johnniwinther): make sure that these are returned in declaration
442 // order.
443 void _forEachElement(f(Element element)) => _element.forEachLocalMember(f);
444
445 Iterable<DeclarationMirror> _getDeclarationMirrors(Element element) =>
446 _library._getDeclarationMirrors(element);
447
448 Uri get uri => _element.script.resourceUri;
449 }
450
451 class ResolvedNode {
452 final node;
453 final _elements;
454 final _mirrorSystem;
455 ResolvedNode(this.node, this._elements, this._mirrorSystem);
456
457 Mirror resolvedMirror(node) {
458 var element = _elements[node];
459 if (element == null) return null;
460 return _convertElementToDeclarationMirror(_mirrorSystem, element);
461 }
462 }
463
464 /**
465 * Transitional class that allows access to features that have not yet
466 * made it to the mirror API.
467 *
468 * All API in this class is experimental.
469 */
470 class BackDoor {
471 /// Return the compilation units comprising [library].
472 static List<Mirror> compilationUnitsOf(Dart2JsLibraryMirror library) {
473 return library._element.compilationUnits.mapToList(
474 (cu) => new Dart2JsCompilationUnitMirror(cu, library));
475 }
476
477 static Iterable metadataSyntaxOf(Dart2JsElementMirror declaration) {
478 Compiler compiler = declaration.mirrorSystem.compiler;
479 return declaration._element.metadata.map((metadata) {
480 var node = metadata.parseNode(compiler);
481 var treeElements = metadata.annotatedElement.treeElements;
482 return new ResolvedNode(
483 node, treeElements, declaration.mirrorSystem);
484 });
485 }
486
487 static ResolvedNode initializerSyntaxOf(Dart2JsFieldMirror variable) {
488 var node = variable._variable.initializer;
489 if (node == null) return null;
490 return new ResolvedNode(
491 node, variable._variable.treeElements, variable.mirrorSystem);
492 }
493
494 static ResolvedNode defaultValueSyntaxOf(Dart2JsParameterMirror parameter) {
495 if (!parameter.hasDefaultValue) return null;
496 ParameterElement parameterElement = parameter._element;
497 var node = parameterElement.initializer;
498 var treeElements = parameterElement.treeElements;
499 return new ResolvedNode(node, treeElements, parameter.mirrorSystem);
500 }
501 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698