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

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

Issue 1799283002: Delete support for source mirrors (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: new attempt Created 4 years, 7 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 mirrors_util;
6
7 import 'dart:collection' show Queue, IterableBase;
8
9 import 'source_mirrors.dart';
10
11 //------------------------------------------------------------------------------
12 // Utility functions for using the Mirror API
13 //------------------------------------------------------------------------------
14
15 String nameOf(DeclarationMirror mirror) =>
16 MirrorSystem.getName(mirror.simpleName);
17
18 String qualifiedNameOf(DeclarationMirror mirror) =>
19 MirrorSystem.getName(mirror.qualifiedName);
20
21 // TODO(johnniwinther): Handle private names.
22 Symbol symbolOf(String name, [LibraryMirror library]) => new Symbol(name);
23
24 /**
25 * Return the display name for [mirror].
26 *
27 * The display name is the normal representation of the entity name. In most
28 * cases the display name is the simple name, but for a setter 'foo=' the
29 * display name is simply 'foo' and for the unary minus operator the display
30 * name is 'operator -'. For 'dart:' libraries the display name is the URI and
31 * not the library name, for instance 'dart:core' instead of 'dart.core'.
32 *
33 * The display name is not unique.
34 */
35 String displayName(DeclarationMirror mirror) {
36 if (mirror is LibraryMirror) {
37 LibraryMirror library = mirror;
38 if (library.uri.scheme == 'dart') {
39 return library.uri.toString();
40 }
41 } else if (mirror is MethodMirror) {
42 String simpleName = nameOf(mirror);
43 if (mirror.isSetter) {
44 // Remove trailing '='.
45 return simpleName.substring(0, simpleName.length - 1);
46 } else if (mirror.isOperator) {
47 return 'operator ${operatorName(mirror)}';
48 } else if (mirror.isConstructor) {
49 String className = displayName(mirror.owner);
50 if (simpleName == '') {
51 return className;
52 } else {
53 return '$className.$simpleName';
54 }
55 }
56 }
57 return MirrorSystem.getName(mirror.simpleName);
58 }
59
60 /**
61 * Returns the operator name if [methodMirror] is an operator method,
62 * for instance [:'<':] for [:operator <:] and [:'-':] for the unary minus
63 * operator. Return [:null:] if [methodMirror] is not an operator method.
64 */
65 String operatorName(MethodMirror methodMirror) {
66 if (methodMirror.isOperator) {
67 if (methodMirror.simpleName == const Symbol('unary-')) {
68 return '-';
69 } else {
70 return nameOf(methodMirror);
71 }
72 }
73 return null;
74 }
75
76 /**
77 * Returns an iterable over the type declarations directly inheriting from
78 * the declaration of [type] within [mirrors].
79 */
80 Iterable<ClassMirror> computeSubdeclarations(
81 MirrorSystem mirrors, ClassMirror type) {
82 type = type.originalDeclaration;
83 var subtypes = <ClassMirror>[];
84 mirrors.libraries.forEach((_, library) {
85 library.declarations.values
86 .where((mirror) => mirror is ClassMirror)
87 .forEach((ClassMirror otherType) {
88 var superClass = otherType.superclass;
89 if (superClass != null) {
90 superClass = superClass.originalDeclaration;
91 if (superClass == type) {
92 subtypes.add(otherType);
93 }
94 }
95 final superInterfaces = otherType.superinterfaces;
96 for (ClassMirror superInterface in superInterfaces) {
97 superInterface = superInterface.originalDeclaration;
98 if (superInterface == type) {
99 subtypes.add(otherType);
100 }
101 }
102 });
103 });
104 return subtypes;
105 }
106
107 class HierarchyIterable extends IterableBase<ClassMirror> {
108 final bool includeType;
109 final ClassMirror type;
110
111 HierarchyIterable(this.type, {bool includeType})
112 : this.includeType = includeType;
113
114 Iterator<ClassMirror> get iterator =>
115 new HierarchyIterator(type, includeType: includeType);
116 }
117
118 /**
119 * [HierarchyIterator] iterates through the class hierarchy of the provided
120 * type.
121 *
122 * First the superclass relation is traversed, skipping [Object], next the
123 * superinterface relation and finally is [Object] visited. The supertypes are
124 * visited in breadth first order and a superinterface is visited more than once
125 * if implemented through multiple supertypes.
126 */
127 class HierarchyIterator implements Iterator<ClassMirror> {
128 final Queue<ClassMirror> queue = new Queue<ClassMirror>();
129 ClassMirror object;
130 ClassMirror _current;
131
132 HierarchyIterator(ClassMirror type, {bool includeType}) {
133 if (includeType) {
134 queue.add(type);
135 } else {
136 push(type);
137 }
138 }
139
140 ClassMirror push(ClassMirror type) {
141 if (type.superclass != null) {
142 if (isObject(type.superclass)) {
143 object = type.superclass;
144 } else {
145 queue.addFirst(type.superclass);
146 }
147 }
148 queue.addAll(type.superinterfaces);
149 return type;
150 }
151
152 ClassMirror get current => _current;
153
154 bool moveNext() {
155 _current = null;
156 if (queue.isEmpty) {
157 if (object == null) return false;
158 _current = object;
159 object = null;
160 return true;
161 } else {
162 _current = push(queue.removeFirst());
163 return true;
164 }
165 }
166 }
167
168 LibraryMirror getLibrary(DeclarationMirror declaration) {
169 while (declaration != null && declaration is! LibraryMirror) {
170 declaration = declaration.owner;
171 }
172 return declaration;
173 }
174
175 Iterable<DeclarationMirror> membersOf(
176 Map<Symbol, DeclarationMirror> declarations) {
177 return declarations.values
178 .where((mirror) => mirror is MethodMirror || mirror is VariableMirror);
179 }
180
181 Iterable<TypeMirror> classesOf(Map<Symbol, DeclarationMirror> declarations) {
182 return new _TypeOfIterable<ClassMirror>(declarations.values);
183 }
184
185 Iterable<TypeMirror> typesOf(Map<Symbol, DeclarationMirror> declarations) {
186 return new _TypeOfIterable<TypeMirror>(declarations.values);
187 }
188
189 Iterable<MethodMirror> methodsOf(Map<Symbol, DeclarationMirror> declarations) {
190 return anyMethodOf(declarations).where((mirror) => mirror.isRegularMethod);
191 }
192
193 Iterable<MethodMirror> constructorsOf(
194 Map<Symbol, DeclarationMirror> declarations) {
195 return anyMethodOf(declarations).where((mirror) => mirror.isConstructor);
196 }
197
198 Iterable<MethodMirror> settersOf(Map<Symbol, DeclarationMirror> declarations) {
199 return anyMethodOf(declarations).where((mirror) => mirror.isSetter);
200 }
201
202 Iterable<MethodMirror> gettersOf(Map<Symbol, DeclarationMirror> declarations) {
203 return anyMethodOf(declarations).where((mirror) => mirror.isGetter);
204 }
205
206 Iterable<MethodMirror> anyMethodOf(
207 Map<Symbol, DeclarationMirror> declarations) {
208 return new _TypeOfIterable<MethodMirror>(declarations.values);
209 }
210
211 Iterable<VariableMirror> variablesOf(
212 Map<Symbol, DeclarationMirror> declarations) {
213 return new _TypeOfIterable<VariableMirror>(declarations.values);
214 }
215
216 class _TypeOfIterable<T> extends IterableBase<T> {
217 final Iterable _source;
218
219 _TypeOfIterable(this._source);
220
221 Iterator<T> get iterator => new _TypeOfIterator<T>(_source.iterator);
222 }
223
224 class _TypeOfIterator<T> implements Iterator<T> {
225 final Iterator _source;
226
227 T get current => _source.current;
228
229 _TypeOfIterator(this._source);
230
231 bool moveNext() {
232 while (_source.moveNext()) {
233 if (_source.current is T) {
234 return true;
235 }
236 }
237 return false;
238 }
239 }
240
241 bool isObject(TypeMirror mirror) =>
242 mirror is ClassMirror && mirror.superclass == null;
243
244 /// Returns `true` if [cls] is declared in a private dart library.
245 bool isFromPrivateDartLibrary(ClassMirror cls) {
246 if (isMixinApplication(cls)) cls = cls.mixin;
247 var uri = getLibrary(cls).uri;
248 return uri.scheme == 'dart' && uri.path.startsWith('_');
249 }
250
251 /// Returns `true` if [mirror] reflects a mixin application.
252 bool isMixinApplication(Mirror mirror) {
253 return mirror is ClassMirror && mirror.mixin != mirror;
254 }
255
256 /**
257 * Returns the superclass of [cls] skipping unnamed mixin applications.
258 *
259 * For instance, for all of the following definitions this method returns [:B:].
260 *
261 * class A extends B {}
262 * class A extends B with C1, C2 {}
263 * class A extends B implements D1, D2 {}
264 * class A extends B with C1, C2 implements D1, D2 {}
265 * class A = B with C1, C2;
266 * abstract class A = B with C1, C2 implements D1, D2;
267 */
268 ClassSourceMirror getSuperclass(ClassSourceMirror cls) {
269 ClassSourceMirror superclass = cls.superclass;
270 while (isMixinApplication(superclass) && superclass.isNameSynthetic) {
271 superclass = superclass.superclass;
272 }
273 return superclass;
274 }
275
276 /**
277 * Returns the mixins directly applied to [cls].
278 *
279 * For instance, for all of the following definitions this method returns
280 * [:C1, C2:].
281 *
282 * class A extends B with C1, C2 {}
283 * class A extends B with C1, C2 implements D1, D2 {}
284 * class A = B with C1, C2;
285 * abstract class A = B with C1, C2 implements D1, D2;
286 */
287 Iterable<ClassSourceMirror> getAppliedMixins(ClassSourceMirror cls) {
288 List<ClassSourceMirror> mixins = <ClassSourceMirror>[];
289 ClassSourceMirror superclass = cls.superclass;
290 while (isMixinApplication(superclass) && superclass.isNameSynthetic) {
291 mixins.add(superclass.mixin);
292 superclass = superclass.superclass;
293 }
294 if (mixins.length > 1) {
295 mixins = new List<ClassSourceMirror>.from(mixins.reversed);
296 }
297 if (isMixinApplication(cls)) {
298 mixins.add(cls.mixin);
299 }
300 return mixins;
301 }
302
303 /**
304 * Returns the superinterfaces directly and explicitly implemented by [cls].
305 *
306 * For instance, for all of the following definitions this method returns
307 * [:D1, D2:].
308 *
309 * class A extends B implements D1, D2 {}
310 * class A extends B with C1, C2 implements D1, D2 {}
311 * abstract class A = B with C1, C2 implements D1, D2;
312 */
313 Iterable<ClassMirror> getExplicitInterfaces(ClassMirror cls) {
314 if (isMixinApplication(cls)) {
315 bool first = true;
316 ClassMirror mixin = cls.mixin;
317 bool filter(ClassMirror superinterface) {
318 if (first && superinterface == mixin) {
319 first = false;
320 return false;
321 }
322 return true;
323 }
324 return cls.superinterfaces.where(filter);
325 }
326 return cls.superinterfaces;
327 }
328
329 final RegExp _singleLineCommentStart = new RegExp(r'^///? ?(.*)');
330 final RegExp _multiLineCommentStartEnd =
331 new RegExp(r'^/\*\*? ?([\s\S]*)\*/$', multiLine: true);
332 final RegExp _multiLineCommentLineStart = new RegExp(r'^[ \t]*\* ?(.*)');
333
334 /**
335 * Pulls the raw text out of a comment (i.e. removes the comment
336 * characters).
337 */
338 String stripComment(String comment) {
339 Match match = _singleLineCommentStart.firstMatch(comment);
340 if (match != null) {
341 return match[1];
342 }
343 match = _multiLineCommentStartEnd.firstMatch(comment);
344 if (match != null) {
345 comment = match[1];
346 var sb = new StringBuffer();
347 List<String> lines = comment.split('\n');
348 for (int index = 0; index < lines.length; index++) {
349 String line = lines[index];
350 if (index == 0) {
351 sb.write(line); // Add the first line unprocessed.
352 continue;
353 }
354 sb.write('\n');
355 match = _multiLineCommentLineStart.firstMatch(line);
356 if (match != null) {
357 sb.write(match[1]);
358 } else if (index < lines.length - 1 || !line.trim().isEmpty) {
359 // Do not add the last line if it only contains white space.
360 // This interprets cases like
361 // /*
362 // * Foo
363 // */
364 // as "\nFoo\n" and not as "\nFoo\n ".
365 sb.write(line);
366 }
367 }
368 return sb.toString();
369 }
370 throw new ArgumentError('Invalid comment $comment');
371 }
372
373 /**
374 * Looks up [name] in the scope [declaration].
375 *
376 * If [name] is of the form 'a.b.c', 'a' is looked up in the scope of
377 * [declaration] and if unresolved 'a.b' is looked in the scope of
378 * [declaration]. Each identifier of the remaining suffix, 'c' or 'b.c', is
379 * then looked up in the local scope of the previous result.
380 *
381 * For instance, assumming that [:Iterable:] is imported into the scope of
382 * [declaration] via the prefix 'col', 'col.Iterable.E' finds the type
383 * variable of [:Iterable:] and 'col.Iterable.contains.element' finds the
384 * [:element:] parameter of the [:contains:] method on [:Iterable:].
385 */
386 DeclarationMirror lookupQualifiedInScope(
387 DeclarationSourceMirror declaration, String name) {
388 // TODO(11653): Support lookup of constructors using the [:new Foo:]
389 // syntax.
390 int offset = 1;
391 List<String> parts = name.split('.');
392 DeclarationMirror result = declaration.lookupInScope(parts[0]);
393 if (result == null && parts.length > 1) {
394 // Try lookup of `prefix.id`.
395 result = declaration.lookupInScope('${parts[0]}.${parts[1]}');
396 offset = 2;
397 }
398 if (result == null) return null;
399 LibraryMirror library = getLibrary(result);
400 while (result != null && offset < parts.length) {
401 result = _lookupLocal(result, symbolOf(parts[offset++], library));
402 }
403 return result;
404 }
405
406 DeclarationMirror _lookupLocal(Mirror mirror, Symbol id) {
407 DeclarationMirror result;
408 if (mirror is LibraryMirror) {
409 // Try member lookup.
410 result = mirror.declarations[id];
411 } else if (mirror is ClassMirror) {
412 // Try member lookup.
413 result = mirror.declarations[id];
414 if (result != null) return result;
415 // Try type variables.
416 result = mirror.typeVariables.firstWhere(
417 (TypeVariableMirror v) => v.simpleName == id,
418 orElse: () => null);
419 } else if (mirror is MethodMirror) {
420 result = mirror.parameters.firstWhere(
421 (ParameterMirror p) => p.simpleName == id,
422 orElse: () => null);
423 }
424 return result;
425 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/mirrors/dart2js_type_mirrors.dart ('k') | pkg/compiler/lib/src/mirrors/source_mirrors.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698