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

Side by Side Diff: lib/compiler/implementation/elements/elements.dart

Issue 10832203: Refactor Library/CompilationUnit and how we define local Scope. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #library('elements'); 5 #library('elements');
6 6
7 #import('dart:uri');
8
7 #import('../tree/tree.dart'); 9 #import('../tree/tree.dart');
8 #import('../scanner/scannerlib.dart'); 10 #import('../scanner/scannerlib.dart');
9 #import('../leg.dart'); // TODO(karlklose): we only need type. 11 #import('../leg.dart'); // TODO(karlklose): we only need type.
10 #import('../util/util.dart'); 12 #import('../util/util.dart');
11 13
12 class ElementCategory { 14 class ElementCategory {
13 /** 15 /**
14 * Represents things that we don't expect to find when looking in a 16 * Represents things that we don't expect to find when looking in a
15 * scope. 17 * scope.
16 */ 18 */
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 117
116 void addMetadata(Node node) { 118 void addMetadata(Node node) {
117 metadata = metadata.prepend(node); 119 metadata = metadata.prepend(node);
118 } 120 }
119 121
120 bool isFunction() => kind === ElementKind.FUNCTION; 122 bool isFunction() => kind === ElementKind.FUNCTION;
121 bool isClosure() => false; 123 bool isClosure() => false;
122 bool isMember() => 124 bool isMember() =>
123 enclosingElement !== null && enclosingElement.kind === ElementKind.CLASS; 125 enclosingElement !== null && enclosingElement.kind === ElementKind.CLASS;
124 bool isInstanceMember() => false; 126 bool isInstanceMember() => false;
127 bool isConstructor() => isFactoryConstructor() || isGenerativeConstructor();
125 bool isFactoryConstructor() => modifiers !== null && modifiers.isFactory(); 128 bool isFactoryConstructor() => modifiers !== null && modifiers.isFactory();
126 bool isGenerativeConstructor() => kind === ElementKind.GENERATIVE_CONSTRUCTOR; 129 bool isGenerativeConstructor() => kind === ElementKind.GENERATIVE_CONSTRUCTOR;
127 bool isGenerativeConstructorBody() => 130 bool isGenerativeConstructorBody() =>
128 kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY; 131 kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY;
129 bool isCompilationUnit() { 132 bool isCompilationUnit() {
130 return kind === ElementKind.COMPILATION_UNIT || 133 return kind === ElementKind.COMPILATION_UNIT ||
131 kind === ElementKind.LIBRARY; 134 kind === ElementKind.LIBRARY;
132 } 135 }
133 bool isClass() => kind === ElementKind.CLASS; 136 bool isClass() => kind === ElementKind.CLASS;
134 bool isPrefix() => kind === ElementKind.PREFIX; 137 bool isPrefix() => kind === ElementKind.PREFIX;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 } 243 }
241 244
242 bool _isNative = false; 245 bool _isNative = false;
243 void setNative() { _isNative = true; } 246 void setNative() { _isNative = true; }
244 bool isNative() => _isNative; 247 bool isNative() => _isNative;
245 248
246 FunctionElement asFunctionElement() => null; 249 FunctionElement asFunctionElement() => null;
247 } 250 }
248 251
249 class ContainerElement extends Element { 252 class ContainerElement extends Element {
250 ContainerElement(name, kind, enclosingElement) : 253 Link<Element> localMembers = const EmptyLink<Element>();
251 super(name, kind, enclosingElement);
252 254
253 abstract void addMember(Element element, DiagnosticListener listener); 255 ContainerElement(name, kind, enclosingElement)
256 : super(name, kind, enclosingElement);
257
258 void addMember(Element element, DiagnosticListener listener) {
259 localMembers = localMembers.prepend(element);
260 }
261 }
262
263 class ScopeContainerElement extends ContainerElement {
264 final Map<SourceString, Element> localScope;
265
266 ScopeContainerElement(name, kind, enclosingElement)
267 : super(name, kind, enclosingElement),
268 localScope = new Map<SourceString, Element>();
269
270 void addMember(Element element, DiagnosticListener listener) {
271 super.addMember(element, listener);
272 addToScope(element, listener);
273 }
274
275 void addToScope(Element element, DiagnosticListener listener) {
276 if (element.isAccessor()) {
277 addGetterOrSetter(element, localScope[element.name], listener);
278 } else {
279 Element existing = localScope.putIfAbsent(element.name, () => element);
280 if (existing !== element) {
281 listener.cancel('duplicate definition', token: element.position());
282 listener.cancel('existing definition', token: existing.position());
283 }
284 }
285 }
286
287 Element localLookup(SourceString elementName) {
288 return localScope[elementName];
289 }
254 290
255 void addGetterOrSetter(Element element, 291 void addGetterOrSetter(Element element,
256 Element existing, 292 Element existing,
257 DiagnosticListener listener) { 293 DiagnosticListener listener) {
258 void reportError(Element other) { 294 void reportError(Element other) {
259 listener.cancel('duplicate definition of ${element.name.slowToString()}', 295 listener.cancel('duplicate definition of ${element.name.slowToString()}',
260 element: element); 296 element: element);
261 listener.cancel('existing definition', element: other); 297 listener.cancel('existing definition', element: other);
262 } 298 }
263 299
(...skipping 19 matching lines...) Expand all
283 if (element.kind == ElementKind.GETTER) { 319 if (element.kind == ElementKind.GETTER) {
284 field.getter = element; 320 field.getter = element;
285 } else { 321 } else {
286 field.setter = element; 322 field.setter = element;
287 } 323 }
288 addMember(field, listener); 324 addMember(field, listener);
289 } 325 }
290 } 326 }
291 } 327 }
292 328
329
ahe 2012/08/08 17:39:05 extra lines
330
293 class CompilationUnitElement extends ContainerElement { 331 class CompilationUnitElement extends ContainerElement {
294 final Script script; 332 final Script script;
295 Link<Element> topLevelElements = const EmptyLink<Element>();
296 333
297 CompilationUnitElement(Script script, Element enclosing) 334 CompilationUnitElement(Script script, Element enclosing)
298 : this.script = script, 335 : this.script = script,
299 super(new SourceString(script.name), 336 super(new SourceString(script.name),
300 ElementKind.COMPILATION_UNIT, 337 ElementKind.COMPILATION_UNIT,
301 enclosing); 338 enclosing);
302 339
303 CompilationUnitElement.library(Script script)
304 : this.script = script,
305 super(new SourceString(script.name), ElementKind.LIBRARY, null);
306
307 void addMember(Element element, DiagnosticListener listener) { 340 void addMember(Element element, DiagnosticListener listener) {
308 LibraryElement library = enclosingElement; 341 // Keep a list of top level members.
309 library.addMember(element, listener); 342 super.addMember(element, listener);
310 topLevelElements = topLevelElements.prepend(element); 343 // Provide the member to the library to build scope.
311 } 344 getLibrary().addMember(element, listener);
312
313 void define(Element element, DiagnosticListener listener) {
314 LibraryElement library = enclosingElement;
315 library.define(element, listener);
316 }
317
318 void addTag(ScriptTag tag, DiagnosticListener listener) {
319 listener.cancel("script tags not allowed here", node: tag);
320 } 345 }
321 } 346 }
322 347
323 class LibraryElement extends CompilationUnitElement { 348 class LibraryElement extends ScopeContainerElement {
324 // TODO(ahe): Library element should not be a subclass of 349 CompilationUnitElement entryCompilationUnit;
325 // CompilationUnitElement. 350 Link<CompilationUnitElement> compilationUnits =
351 const EmptyLink<CompilationUnitElement>();
326 352
327 Link<CompilationUnitElement> compilationUnits =
328 const EmptyLink<CompilationUnitElement>();
329 Link<ScriptTag> tags = const EmptyLink<ScriptTag>(); 353 Link<ScriptTag> tags = const EmptyLink<ScriptTag>();
330 ScriptTag libraryTag; 354 ScriptTag libraryTag;
331 Map<SourceString, Element> elements;
332 bool canUseNative = false; 355 bool canUseNative = false;
333 LibraryElement patch = null; 356 LibraryElement patch = null;
334 357
335 LibraryElement(Script script) 358 LibraryElement(Script script)
336 : elements = new Map<SourceString, Element>(), 359 : super(new SourceString(script.name), ElementKind.LIBRARY, null) {
337 super.library(script); 360 entryCompilationUnit = new CompilationUnitElement(script, this);
Lasse Reichstein Nielsen 2012/08/08 14:22:12 In the longer run, maybe we should add entryCompil
Anders Johnsen 2012/08/08 17:30:37 I partly agree. It would be nice memory-wise, but
361 }
362
363 Uri get uri() => entryCompilationUnit.script.uri;
338 364
339 bool get isPatched() => patch !== null; 365 bool get isPatched() => patch !== null;
340 366
341 void addCompilationUnit(CompilationUnitElement element) { 367 void addCompilationUnit(CompilationUnitElement element) {
342 compilationUnits = compilationUnits.prepend(element); 368 compilationUnits = compilationUnits.prepend(element);
343 } 369 }
344 370
345 void addTag(ScriptTag tag, DiagnosticListener listener) { 371 void addTag(ScriptTag tag, DiagnosticListener listener) {
346 tags = tags.prepend(tag); 372 tags = tags.prepend(tag);
347 } 373 }
348 374
349 void addMember(Element element, DiagnosticListener listener) {
350 topLevelElements = topLevelElements.prepend(element);
351 define(element, listener);
352 }
353
354 void define(Element element, DiagnosticListener listener) {
355 if (element.kind == ElementKind.GETTER
356 || element.kind == ElementKind.SETTER) {
357 addGetterOrSetter(element, elements[element.name], listener);
358 } else {
359 Element existing = elements.putIfAbsent(element.name, () => element);
360 if (existing !== element) {
361 listener.cancel('duplicate definition', token: element.position());
362 listener.cancel('existing definition', token: existing.position());
363 }
364 }
365 }
366
367 /** Look up a top-level element in this library. The element could 375 /** Look up a top-level element in this library. The element could
368 * potentially have been imported from another library. Returns 376 * potentially have been imported from another library. Returns
369 * null if no such element exist. */ 377 * null if no such element exist. */
370 Element find(SourceString elementName) { 378 Element find(SourceString elementName) {
371 return elements[elementName]; 379 return localScope[elementName];
372 } 380 }
373 381
374 /** Look up a top-level element in this library, but only look for 382 /** Look up a top-level element in this library, but only look for
375 * non-imported elements. Returns null if no such element exist. */ 383 * non-imported elements. Returns null if no such element exist. */
376 Element findLocal(SourceString elementName) { 384 Element findLocal(SourceString elementName) {
377 Element result = elements[elementName]; 385 Element result = localScope[elementName];
378 if (result === null || result.getLibrary() != this) return null; 386 if (result === null || result.getLibrary() != this) return null;
379 return result; 387 return result;
380 } 388 }
381 389
382 void forEachExport(f(Element element)) { 390 void forEachExport(f(Element element)) {
383 elements.forEach((SourceString _, Element e) { 391 localMembers.forEach((Element e) {
384 if (this === e.getLibrary() 392 if (this === e.getLibrary()
Lasse Reichstein Nielsen 2012/08/08 14:22:12 The library test should be unnecessary when you on
Anders Johnsen 2012/08/08 17:30:37 Done.
385 && e.kind !== ElementKind.PREFIX 393 && e.kind !== ElementKind.PREFIX
386 && e.kind !== ElementKind.FOREIGN) { 394 && e.kind !== ElementKind.FOREIGN) {
387 if (!e.name.isPrivate()) f(e); 395 if (!e.name.isPrivate()) f(e);
Lasse Reichstein Nielsen 2012/08/08 14:22:12 Put the !e.name.isPrivate() into the first if too.
Anders Johnsen 2012/08/08 17:30:37 Done.
388 } 396 }
389 }); 397 });
390 } 398 }
391 399
392 bool hasLibraryName() => libraryTag !== null; 400 bool hasLibraryName() => libraryTag !== null;
393 401
394 /** 402 /**
395 * Returns the library name (as defined by the #library tag) or for script 403 * Returns the library name (as defined by the #library tag) or for script
396 * (which have no #library tag) the script file name. The latter case is used 404 * (which have no #library tag) the script file name. The latter case is used
397 * to private 'library name' for scripts to use for instance in dartdoc. 405 * to private 'library name' for scripts to use for instance in dartdoc.
398 */ 406 */
399 String getLibraryOrScriptName() { 407 String getLibraryOrScriptName() {
400 if (libraryTag !== null) { 408 if (libraryTag !== null) {
401 return libraryTag.argument.dartString.slowToString(); 409 return libraryTag.argument.dartString.slowToString();
402 } else { 410 } else {
403 // Use the file name as script name. 411 // Use the file name as script name.
404 var path = script.uri.path; 412 var path = uri.path;
Lasse Reichstein Nielsen 2012/08/08 14:22:12 var -> String.
Anders Johnsen 2012/08/08 17:30:37 While I believe we are moving away from this style
405 return path.substring(path.lastIndexOf('/') + 1); 413 return path.substring(path.lastIndexOf('/') + 1);
406 } 414 }
407 } 415 }
408 416
417 CompilationUnitElement getCompilationUnit() => entryCompilationUnit;
418
409 Scope buildEnclosingScope() => new TopScope(this); 419 Scope buildEnclosingScope() => new TopScope(this);
410 } 420 }
411 421
412 class PrefixElement extends Element { 422 class PrefixElement extends Element {
413 Map<SourceString, Element> imported; 423 Map<SourceString, Element> imported;
414 Token firstPosition; 424 Token firstPosition;
415 final CompilationUnitElement patchSource; 425 final LibraryElement patchLibrary;
Lasse Reichstein Nielsen 2012/08/08 14:22:12 Why not store the CompilationUnitElement of patchL
Anders Johnsen 2012/08/08 17:30:37 Done.
416 426
417 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition, 427 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition,
418 [this.patchSource]) 428 [this.patchLibrary])
419 : imported = new Map<SourceString, Element>(), 429 : imported = new Map<SourceString, Element>(),
420 super(prefix, ElementKind.PREFIX, enclosing); 430 super(prefix, ElementKind.PREFIX, enclosing);
421 431
422 CompilationUnitElement getCompilationUnit() { 432 CompilationUnitElement getCompilationUnit() {
423 if (patchSource !== null) return patchSource; 433 if (patchLibrary !== null) return patchLibrary.entryCompilationUnit;
424 return super.getCompilationUnit(); 434 return super.getCompilationUnit();
425 } 435 }
426 436
427 lookupLocalMember(SourceString memberName) => imported[memberName]; 437 lookupLocalMember(SourceString memberName) => imported[memberName];
428 438
429 Type computeType(Compiler compiler) => compiler.types.dynamicType; 439 Type computeType(Compiler compiler) => compiler.types.dynamicType;
430 440
431 Token position() => firstPosition; 441 Token position() => firstPosition;
432 } 442 }
433 443
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 TypeVariableElement variableElement = 874 TypeVariableElement variableElement =
865 new TypeVariableElement(variableName, element, node); 875 new TypeVariableElement(variableName, element, node);
866 TypeVariableType variableType = new TypeVariableType(variableElement); 876 TypeVariableType variableType = new TypeVariableType(variableElement);
867 variableElement.type = variableType; 877 variableElement.type = variableType;
868 arguments.addLast(variableType); 878 arguments.addLast(variableType);
869 } 879 }
870 return arguments.toLink(); 880 return arguments.toLink();
871 } 881 }
872 } 882 }
873 883
874 class ClassElement extends ContainerElement 884 class ClassElement extends ScopeContainerElement
875 implements TypeDeclarationElement { 885 implements TypeDeclarationElement {
876 final int id; 886 final int id;
877 InterfaceType type; 887 InterfaceType type;
878 Type supertype; 888 Type supertype;
879 Type defaultClass; 889 Type defaultClass;
880 Link<Element> members = const EmptyLink<Element>();
881 Map<SourceString, Element> localMembers;
882 Map<SourceString, Element> constructors;
883 Link<Type> interfaces = const EmptyLink<Type>(); 890 Link<Type> interfaces = const EmptyLink<Type>();
884 bool isResolved = false; 891 bool isResolved = false;
885 bool isBeingResolved = false; 892 bool isBeingResolved = false;
886 // backendMembers are members that have been added by the backend to simplify 893 // backendMembers are members that have been added by the backend to simplify
887 // compilation. They don't have any user-side counter-part. 894 // compilation. They don't have any user-side counter-part.
888 Link<Element> backendMembers = const EmptyLink<Element>(); 895 Link<Element> backendMembers = const EmptyLink<Element>();
889 896
890 Link<Type> allSupertypes; 897 Link<Type> allSupertypes;
891 ClassElement patch = null; 898 ClassElement patch = null;
892 899
893 ClassElement(SourceString name, CompilationUnitElement enclosing, this.id) 900 ClassElement(SourceString name, CompilationUnitElement enclosing, this.id)
894 : localMembers = new Map<SourceString, Element>(), 901 : super(name, ElementKind.CLASS, enclosing);
895 constructors = new Map<SourceString, Element>(),
896 super(name, ElementKind.CLASS, enclosing);
897
898 void addMember(Element element, DiagnosticListener listener) {
899 members = members.prepend(element);
900 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR ||
901 element.modifiers.isFactory()) {
902 constructors[element.name] = element;
903 } else if (element.kind == ElementKind.GETTER
904 || element.kind == ElementKind.SETTER) {
905 addGetterOrSetter(element, localMembers[element.name], listener);
906 } else {
907 localMembers[element.name] = element;
908 }
909 }
910 902
911 InterfaceType computeType(compiler) { 903 InterfaceType computeType(compiler) {
912 if (type == null) { 904 if (type == null) {
913 ClassNode node = parseNode(compiler); 905 ClassNode node = parseNode(compiler);
914 Link<Type> parameters = 906 Link<Type> parameters =
915 TypeDeclarationElement.createTypeVariables(this, node.typeParameters); 907 TypeDeclarationElement.createTypeVariables(this, node.typeParameters);
916 type = new InterfaceType(this, parameters); 908 type = new InterfaceType(this, parameters);
917 } 909 }
918 return type; 910 return type;
919 } 911 }
920 912
921 Link<Type> get typeVariables() => type.arguments; 913 Link<Type> get typeVariables() => type.arguments;
922 914
923 ClassElement ensureResolved(Compiler compiler) { 915 ClassElement ensureResolved(Compiler compiler) {
924 compiler.resolveClass(this); 916 compiler.resolveClass(this);
925 return this; 917 return this;
926 } 918 }
927 919
920 /**
921 * Lookup local members in the class. This will ignore constructors.
922 */
928 Element lookupLocalMember(SourceString memberName) { 923 Element lookupLocalMember(SourceString memberName) {
929 return localMembers[memberName]; 924 var result = localLookup(memberName);
925 if (result !== null && result.isConstructor()) return null;
926 return result;
930 } 927 }
931 928
929 /**
930 * Lookup super members for the class. This will ignore constructors.
931 */
932 Element lookupSuperMember(SourceString memberName) { 932 Element lookupSuperMember(SourceString memberName) {
933 bool isPrivate = memberName.isPrivate(); 933 bool isPrivate = memberName.isPrivate();
934 for (ClassElement s = superclass; s != null; s = s.superclass) { 934 for (ClassElement s = superclass; s != null; s = s.superclass) {
935 // Private members from a different library are not visible. 935 // Private members from a different library are not visible.
936 if (isPrivate && getLibrary() !== s.getLibrary()) continue; 936 if (isPrivate && getLibrary() !== s.getLibrary()) continue;
937 Element e = s.lookupLocalMember(memberName); 937 Element e = s.lookupLocalMember(memberName);
938 if (e === null) continue; 938 if (e === null) continue;
939 // Static members are not inherited. 939 // Static members are not inherited.
940 if (e.modifiers.isStatic()) continue; 940 if (e.modifiers.isStatic()) continue;
941 return e; 941 return e;
942 } 942 }
943 return null; 943 return null;
944 } 944 }
945 945
946 /** 946 /**
947 * Find the first member in the class chain with the given 947 * Find the first member in the class chain with the given
948 * [memberName]. This method is NOT to be used for resolving 948 * [memberName]. This method is NOT to be used for resolving
949 * unqualified sends because it does not implement the scoping 949 * unqualified sends because it does not implement the scoping
950 * rules, where library scope comes before superclass scope. 950 * rules, where library scope comes before superclass scope.
951 */ 951 */
952 Element lookupMember(SourceString memberName) { 952 Element lookupMember(SourceString memberName) {
953 Element localMember = localMembers[memberName]; 953 Element localMember = lookupLocalMember(memberName);
954 return localMember === null ? lookupSuperMember(memberName) : localMember; 954 return localMember === null ? lookupSuperMember(memberName) : localMember;
955 } 955 }
956 956
957 /** 957 /**
958 * Returns true if the [fieldMember] is shadowed by another field. The given 958 * Returns true if the [fieldMember] is shadowed by another field. The given
959 * [fieldMember] must be a member of this class. 959 * [fieldMember] must be a member of this class.
960 * 960 *
961 * This method also works if the [fieldMember] is private. 961 * This method also works if the [fieldMember] is private.
962 */ 962 */
963 bool isShadowedByField(Element fieldMember) { 963 bool isShadowedByField(Element fieldMember) {
(...skipping 24 matching lines...) Expand all
988 Element noMatch(Element)]) { 988 Element noMatch(Element)]) {
989 // TODO(karlklose): have a map from class names to a map of constructors 989 // TODO(karlklose): have a map from class names to a map of constructors
990 // instead of creating the name here? 990 // instead of creating the name here?
991 SourceString normalizedName; 991 SourceString normalizedName;
992 if (constructorName !== const SourceString('')) { 992 if (constructorName !== const SourceString('')) {
993 normalizedName = Elements.constructConstructorName(className, 993 normalizedName = Elements.constructConstructorName(className,
994 constructorName); 994 constructorName);
995 } else { 995 } else {
996 normalizedName = className; 996 normalizedName = className;
997 } 997 }
998 Element result = constructors[normalizedName]; 998 return localLookup(normalizedName);
999 if (result === null && noMatch !== null) { 999 }
1000 result = noMatch(lookupLocalMember(constructorName)); 1000
1001 bool get hasConstructor() {
1002 // Search in scope to be sure we search patched constructors.
Lasse Reichstein Nielsen 2012/08/08 14:22:12 Huh? Patched constructors are also members, as are
Anders Johnsen 2012/08/08 17:30:37 Yes, but they are going to be hidden under a Patch
1003 for (var element in localScope.getValues()) {
1004 if (element.isConstructor()) return true;
1001 } 1005 }
1002 return result; 1006 return false;
1007 }
1008
1009 Collection<Element> get constructors() {
1010 // TODO(ajohnsen): See if we can avoid this method at some point.
1011 var result = <Element>[];
1012 // Search in scope to be sure we search patched constructors.
1013 return localScope.getValues().filter((element) => element.isConstructor());
1003 } 1014 }
1004 1015
1005 /** 1016 /**
1006 * Returns the super class, if any. 1017 * Returns the super class, if any.
1007 * 1018 *
1008 * The returned element may not be resolved yet. 1019 * The returned element may not be resolved yet.
1009 */ 1020 */
1010 ClassElement get superclass() { 1021 ClassElement get superclass() {
1011 assert(isResolved); 1022 assert(isResolved);
1012 return supertype === null ? null : supertype.element; 1023 return supertype === null ? null : supertype.element;
1013 } 1024 }
1014 1025
1015 /** 1026 /**
1016 * Runs through all members of this class. 1027 * Runs through all members of this class.
1017 * 1028 *
1018 * The enclosing class is passed to the callback. This is useful when 1029 * The enclosing class is passed to the callback. This is useful when
1019 * [includeSuperMembers] is [:true:]. 1030 * [includeSuperMembers] is [:true:].
1020 */ 1031 */
1021 void forEachMember([void f(ClassElement enclosingClass, Element member), 1032 void forEachMember([void f(ClassElement enclosingClass, Element member),
1022 includeBackendMembers = false, 1033 includeBackendMembers = false,
1023 includeSuperMembers = false]) { 1034 includeSuperMembers = false]) {
1024 Set<ClassElement> seen = new Set<ClassElement>(); 1035 Set<ClassElement> seen = new Set<ClassElement>();
1025 ClassElement classElement = this; 1036 ClassElement classElement = this;
1026 do { 1037 do {
1027 if (seen.contains(classElement)) return; 1038 if (seen.contains(classElement)) return;
1028 seen.add(classElement); 1039 seen.add(classElement);
1029 for (Element element in classElement.members) { 1040 for (Element element in classElement.localMembers) {
1030 f(classElement, element); 1041 f(classElement, element);
1031 } 1042 }
1032 if (includeBackendMembers) { 1043 if (includeBackendMembers) {
1033 for (Element element in classElement.backendMembers) { 1044 for (Element element in classElement.backendMembers) {
1034 f(classElement, element); 1045 f(classElement, element);
1035 } 1046 }
1036 } 1047 }
1037 classElement = includeSuperMembers ? classElement.superclass : null; 1048 classElement = includeSuperMembers ? classElement.superclass : null;
1038 } while(classElement !== null); 1049 } while(classElement !== null);
1039 } 1050 }
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 TypeVariableElement(name, Element enclosing, this.cachedNode, 1288 TypeVariableElement(name, Element enclosing, this.cachedNode,
1278 [this.type, this.bound]) 1289 [this.type, this.bound])
1279 : super(name, ElementKind.TYPE_VARIABLE, enclosing); 1290 : super(name, ElementKind.TYPE_VARIABLE, enclosing);
1280 1291
1281 TypeVariableType computeType(compiler) => type; 1292 TypeVariableType computeType(compiler) => type;
1282 1293
1283 Node parseNode(compiler) => cachedNode; 1294 Node parseNode(compiler) => cachedNode;
1284 1295
1285 String toString() => "${enclosingElement.toString()}.${name.slowToString()}"; 1296 String toString() => "${enclosingElement.toString()}.${name.slowToString()}";
1286 } 1297 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698