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

Side by Side Diff: pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart

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

Powered by Google App Engine
This is Rietveld 408576698