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

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

Issue 10905305: Patch refactoring. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Replaced includeInjectedMembers by implementation Created 8 years, 2 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'); 7 #import('dart:uri');
8 8
9 #import('../tree/tree.dart'); 9 #import('../tree/tree.dart');
10 #import('../scanner/scannerlib.dart'); 10 #import('../scanner/scannerlib.dart');
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 toString() => id; 107 toString() => id;
108 } 108 }
109 109
110 class Element implements Hashable, Spannable { 110 class Element implements Hashable, Spannable {
111 final SourceString name; 111 final SourceString name;
112 final ElementKind kind; 112 final ElementKind kind;
113 final Element enclosingElement; 113 final Element enclosingElement;
114 Link<MetadataAnnotation> metadata = const EmptyLink<MetadataAnnotation>(); 114 Link<MetadataAnnotation> metadata = const EmptyLink<MetadataAnnotation>();
115 115
116 Element(this.name, this.kind, this.enclosingElement) { 116 Element(this.name, this.kind, this.enclosingElement) {
117 assert(getLibrary() !== null); 117 assert(isErroneous() || getImplementationLibrary() !== null);
118 } 118 }
119 119
120 Modifiers get modifiers => null; 120 Modifiers get modifiers => null;
121 121
122 Node parseNode(DiagnosticListener listener) { 122 Node parseNode(DiagnosticListener listener) {
123 listener.cancel("Internal Error: $this.parseNode", token: position()); 123 listener.cancel("Internal Error: $this.parseNode not "
ahe 2012/10/02 13:27:04 listener.internalErrorOnElement('not implemented',
Johnni Winther 2012/10/03 09:22:59 Done.
124 "implemented on ${super.toString()}", token: position());
124 } 125 }
125 126
126 DartType computeType(Compiler compiler) { 127 DartType computeType(Compiler compiler) {
127 compiler.internalError("$this.computeType.", token: position()); 128 compiler.internalError("$this.computeType.", token: position());
128 } 129 }
129 130
130 void addMetadata(MetadataAnnotation annotation) { 131 void addMetadata(MetadataAnnotation annotation) {
131 assert(annotation.annotatedElement === null); 132 assert(annotation.annotatedElement === null);
132 annotation.annotatedElement = this; 133 annotation.annotatedElement = this;
133 metadata = metadata.prepend(annotation); 134 metadata = metadata.prepend(annotation);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 183
183 /** 184 /**
184 * Is [:true:] if this element is a patch. 185 * Is [:true:] if this element is a patch.
185 * 186 *
186 * If [:true:] this element has a non-null [origin] field. 187 * If [:true:] this element has a non-null [origin] field.
187 * 188 *
188 * See [:patch_parser.dart:] for a description of the terminology. 189 * See [:patch_parser.dart:] for a description of the terminology.
189 */ 190 */
190 bool get isPatch => false; 191 bool get isPatch => false;
191 192
192
193 /** 193 /**
194 * Is [:true:] if this element defines the implementation for the entity of 194 * Is [:true:] if this element defines the implementation for the entity of
195 * this element. 195 * this element.
196 * 196 *
197 * See [:patch_parser.dart:] for a description of the terminology. 197 * See [:patch_parser.dart:] for a description of the terminology.
198 */ 198 */
199 bool get isImplementation => implementation === this; 199 bool get isImplementation => !isPatched;
200 200
201 /** 201 /**
202 * Is [:true:] if this element introduces the entity of this element. 202 * Is [:true:] if this element introduces the entity of this element.
203 * 203 *
204 * See [:patch_parser.dart:] for a description of the terminology. 204 * See [:patch_parser.dart:] for a description of the terminology.
205 */ 205 */
206 bool get isDeclaration => declaration === this; 206 bool get isDeclaration => !isPatch;
207 207
208 /** 208 /**
209 * Returns the element which defines the implementation for the entity of this 209 * Returns the element which defines the implementation for the entity of this
210 * element. 210 * element.
211 * 211 *
212 * See [:patch_parser.dart:] for a description of the terminology. 212 * See [:patch_parser.dart:] for a description of the terminology.
213 */ 213 */
214 Element get implementation => this; 214 Element get implementation => isPatched ? patch : this;
215 215
216 /** 216 /**
217 * Returns the element which introduces the entity of this element. 217 * Returns the element which introduces the entity of this element.
218 * 218 *
219 * See [:patch_parser.dart:] for a description of the terminology. 219 * See [:patch_parser.dart:] for a description of the terminology.
220 */ 220 */
221 Element get declaration => this; 221 Element get declaration => isPatch ? origin : this;
222 222
223 // TODO(johnniwinther): This breaks for libraries (for which enclosing 223 // TODO(johnniwinther): This breaks for libraries (for which enclosing
224 // elements are null) and is invalid for top level variable declarations for 224 // elements are null) and is invalid for top level variable declarations for
225 // which the enclosing element is a VariableDeclarations and not a compilation 225 // which the enclosing element is a VariableDeclarations and not a compilation
226 // unit. 226 // unit.
227 bool isTopLevel() { 227 bool isTopLevel() {
228 return enclosingElement !== null && enclosingElement.isCompilationUnit(); 228 return enclosingElement !== null && enclosingElement.isCompilationUnit();
229 } 229 }
230 230
231 bool isAssignable() { 231 bool isAssignable() {
(...skipping 12 matching lines...) Expand all
244 } 244 }
245 245
246 // TODO(kasperl): This is a very bad hash code for the element and 246 // TODO(kasperl): This is a very bad hash code for the element and
247 // there's no reason why two elements with the same name should have 247 // there's no reason why two elements with the same name should have
248 // the same hash code. Replace this with a simple id in the element? 248 // the same hash code. Replace this with a simple id in the element?
249 int hashCode() => name === null ? 0 : name.hashCode(); 249 int hashCode() => name === null ? 0 : name.hashCode();
250 250
251 CompilationUnitElement getCompilationUnit() { 251 CompilationUnitElement getCompilationUnit() {
252 Element element = this; 252 Element element = this;
253 while (element !== null && !element.isCompilationUnit()) { 253 while (element !== null && !element.isCompilationUnit()) {
254 if (element is CompilationUnitOverrideElement) { 254 if (element is CompilationUnitOverrideElement) {
ahe 2012/10/02 13:27:04 Why do we still have this?
Johnni Winther 2012/10/03 09:22:59 It'll be removed in an after-patch-refactoring cle
255 CompilationUnitOverrideElement override = element; 255 CompilationUnitOverrideElement override = element;
256 return override.compilationUnit; 256 return override.compilationUnit;
257 } 257 }
258 if (element.isLibrary()) { 258 if (element.isLibrary()) {
259 LibraryElement library = element; 259 LibraryElement library = element;
260 return library.entryCompilationUnit; 260 return library.entryCompilationUnit;
261 } 261 }
262 element = element.enclosingElement; 262 element = element.enclosingElement;
263 if (element is FunctionElement) {
264 FunctionElement function = element;
265 if (function.isPatched) {
266 element = function.patch;
267 }
268 }
269 } 263 }
270 return element; 264 return element;
271 } 265 }
272 266
273 LibraryElement getLibrary() { 267 LibraryElement getLibrary() => enclosingElement.getLibrary();
268
269 LibraryElement getImplementationLibrary() {
274 Element element = this; 270 Element element = this;
275 while (element.kind !== ElementKind.LIBRARY) { 271 while (element.kind !== ElementKind.LIBRARY) {
276 element = element.enclosingElement; 272 element = element.enclosingElement;
277 } 273 }
278 return element; 274 return element;
279 } 275 }
280 276
281 LibraryElement getImplementationLibrary() => getLibrary();
282
283 ClassElement getEnclosingClass() { 277 ClassElement getEnclosingClass() {
284 for (Element e = this; e !== null; e = e.enclosingElement) { 278 for (Element e = this; e !== null; e = e.enclosingElement) {
285 if (e.isClass()) return e; 279 if (e.isClass()) return e;
286 } 280 }
287 return null; 281 return null;
288 } 282 }
289 283
290 Element getEnclosingClassOrCompilationUnit() { 284 Element getEnclosingClassOrCompilationUnit() {
291 for (Element e = this; e !== null; e = e.enclosingElement) { 285 for (Element e = this; e !== null; e = e.enclosingElement) {
292 if (e.isClass() || e.isCompilationUnit()) return e; 286 if (e.isClass() || e.isCompilationUnit()) return e;
(...skipping 15 matching lines...) Expand all
308 return e; 302 return e;
309 } 303 }
310 } 304 }
311 return null; 305 return null;
312 } 306 }
313 307
314 /** 308 /**
315 * Creates the scope for this element. The scope of the 309 * Creates the scope for this element. The scope of the
316 * enclosing element will be the parent scope. 310 * enclosing element will be the parent scope.
317 */ 311 */
318 Scope buildScope() => buildEnclosingScope(); 312 // TODO(johnniwinther): Clean up scope generation. Possibly generation scopes
313 // externally.
314 Scope buildScope({bool patchScope: false}) =>
315 buildEnclosingScope(patchScope: patchScope);
319 316
320 /** 317 /**
321 * Creates the scope for the enclosing element. 318 * Creates the scope for the enclosing element.
322 */ 319 */
323 Scope buildEnclosingScope() => enclosingElement.buildScope(); 320 // TODO(johnniwinther): Remove buildEnclosingScope as part of scope clean-up.
321 Scope buildEnclosingScope({bool patchScope: false}) =>
322 enclosingElement.buildScope(patchScope: patchScope);
324 323
325 String toString() { 324 String toString() {
326 // TODO(johnniwinther): Test for nullness of name, or make non-nullness an 325 // TODO(johnniwinther): Test for nullness of name, or make non-nullness an
327 // invariant for all element types? 326 // invariant for all element types?
328 var nameText = name !== null ? name.slowToString() : '?'; 327 var nameText = name !== null ? name.slowToString() : '?';
329 if (enclosingElement !== null && !isTopLevel()) { 328 if (enclosingElement !== null && !isTopLevel()) {
330 String holderName = enclosingElement.name !== null 329 String holderName = enclosingElement.name !== null
331 ? enclosingElement.name.slowToString() 330 ? enclosingElement.name.slowToString()
332 : '${enclosingElement.kind}?'; 331 : '${enclosingElement.kind}?';
333 return '$kind($holderName#${nameText})'; 332 return '$kind($holderName#${nameText})';
334 } else { 333 } else {
335 return '$kind(${nameText})'; 334 return '$kind(${nameText})';
336 } 335 }
337 } 336 }
338 337
339 bool _isNative = false; 338 bool _isNative = false;
340 void setNative() { _isNative = true; } 339 void setNative() { _isNative = true; }
341 bool isNative() => _isNative; 340 bool isNative() => _isNative;
342 341
343 FunctionElement asFunctionElement() => null; 342 FunctionElement asFunctionElement() => null;
344 343
344 static bool isInvalid(Element e) => e == null || e.isErroneous();
345 Element cloneTo(Element enclosing, DiagnosticListener listener) { 345 Element cloneTo(Element enclosing, DiagnosticListener listener) {
346 listener.cancel("Unimplemented cloneTo", element: this); 346 listener.cancel("Unimplemented cloneTo", element: this);
347 } 347 }
348 } 348 }
349 349
350 /** 350 /**
351 * Represents an unresolvable or duplicated element. 351 * Represents an unresolvable or duplicated element.
352 * 352 *
353 * An [ErroneousElement] is used instead of [null] to provide additional 353 * An [ErroneousElement] is used instead of [null] to provide additional
354 * information about the error that caused the element to be unresolvable 354 * information about the error that caused the element to be unresolvable
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 Element existing = localScope.putIfAbsent(element.name, () => element); 437 Element existing = localScope.putIfAbsent(element.name, () => element);
438 if (existing !== element) { 438 if (existing !== element) {
439 // TODO(ahe): Do something similar to Resolver.reportErrorWithContext. 439 // TODO(ahe): Do something similar to Resolver.reportErrorWithContext.
440 listener.cancel('duplicate definition', token: element.position()); 440 listener.cancel('duplicate definition', token: element.position());
441 listener.cancel('existing definition', token: existing.position()); 441 listener.cancel('existing definition', token: existing.position());
442 } 442 }
443 } 443 }
444 } 444 }
445 445
446 Element localLookup(SourceString elementName) { 446 Element localLookup(SourceString elementName) {
447 return localScope[elementName]; 447 Element result = localScope[elementName];
448 if (result == null && isPatch) {
449 result = origin.localScope[elementName];
450 }
451 return result;
448 } 452 }
449 453
450 /** 454 /**
451 * Adds a definition for an [accessor] (getter or setter) to a container. 455 * Adds a definition for an [accessor] (getter or setter) to a container.
452 * The definition binds to an abstract field that can hold both a getter 456 * The definition binds to an abstract field that can hold both a getter
453 * and a setter. 457 * and a setter.
454 * 458 *
455 * The abstract field is added once, for the first getter or setter, and 459 * The abstract field is added once, for the first getter or setter, and
456 * reused if the other one is also added. 460 * reused if the other one is also added.
457 * The abstract field should not be treated as a proper member of the 461 * The abstract field should not be treated as a proper member of the
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 CompilationUnitElement(Script script, Element enclosing) 512 CompilationUnitElement(Script script, Element enclosing)
509 : this.script = script, 513 : this.script = script,
510 super(new SourceString(script.name), 514 super(new SourceString(script.name),
511 ElementKind.COMPILATION_UNIT, 515 ElementKind.COMPILATION_UNIT,
512 enclosing); 516 enclosing);
513 517
514 void addMember(Element element, DiagnosticListener listener) { 518 void addMember(Element element, DiagnosticListener listener) {
515 // Keep a list of top level members. 519 // Keep a list of top level members.
516 super.addMember(element, listener); 520 super.addMember(element, listener);
517 // Provide the member to the library to build scope. 521 // Provide the member to the library to build scope.
518 getLibrary().addMember(element, listener); 522 if (enclosingElement.isPatch) {
523 getImplementationLibrary().addMember(element, listener);
524 } else {
525 getLibrary().addMember(element, listener);
526 }
519 } 527 }
520 } 528 }
521 529
522 class CompilationUnitOverrideElement extends Element { 530 class CompilationUnitOverrideElement extends Element {
523 final CompilationUnitElement compilationUnit; 531 final CompilationUnitElement compilationUnit;
524 532
525 CompilationUnitOverrideElement(CompilationUnitElement compilationUnit, 533 CompilationUnitOverrideElement(CompilationUnitElement compilationUnit,
526 Element enclosing) 534 Element enclosing)
527 : this.compilationUnit = compilationUnit, 535 : this.compilationUnit = compilationUnit,
528 super(compilationUnit.name, 536 super(compilationUnit.name,
529 ElementKind.COMPILATION_UNIT_OVERRIDE, 537 ElementKind.COMPILATION_UNIT_OVERRIDE,
530 enclosing); 538 enclosing);
531 } 539 }
532 540
533 class LibraryElement extends ScopeContainerElement { 541 class LibraryElement extends ScopeContainerElement {
534 final Uri uri; 542 final Uri uri;
535 CompilationUnitElement entryCompilationUnit; 543 CompilationUnitElement entryCompilationUnit;
536 Link<CompilationUnitElement> compilationUnits = 544 Link<CompilationUnitElement> compilationUnits =
537 const EmptyLink<CompilationUnitElement>(); 545 const EmptyLink<CompilationUnitElement>();
538 Link<LibraryTag> tags = const EmptyLink<LibraryTag>(); 546 Link<LibraryTag> tags = const EmptyLink<LibraryTag>();
539 LibraryTag libraryTag; 547 LibraryTag libraryTag;
540 bool canUseNative = false; 548 bool canUseNative = false;
541 LibraryElement patch = null; 549 LibraryElement patch = null;
550 final LibraryElement origin;
ahe 2012/10/02 13:27:04 Document this.
Johnni Winther 2012/10/03 09:22:59 Done.
542 551
543 /** 552 /**
544 * Map for elements imported through import declarations. 553 * Map for elements imported through import declarations.
545 * 554 *
546 * Addition to the map is performed by [addImport]. Lookup is done trough 555 * Addition to the map is performed by [addImport]. Lookup is done trough
547 * [find]. 556 * [find].
548 */ 557 */
549 final Map<SourceString, Element> importScope; 558 final Map<SourceString, Element> importScope;
550 559
551 LibraryElement(Script script, [Uri uri]) 560 LibraryElement(Script script, [Uri uri, LibraryElement this.origin])
552 : this.uri = ((uri === null) ? script.uri : uri), 561 : this.uri = ((uri === null) ? script.uri : uri),
553 importScope = new Map<SourceString, Element>(), 562 importScope = new Map<SourceString, Element>(),
554 super(new SourceString(script.name), ElementKind.LIBRARY, null) { 563 super(new SourceString(script.name), ElementKind.LIBRARY, null) {
555 entryCompilationUnit = new CompilationUnitElement(script, this); 564 entryCompilationUnit = new CompilationUnitElement(script, this);
565 if (isPatch) {
566 origin.patch = this;
567 }
556 } 568 }
557 569
570 bool get isPatched => patch !== null;
571 bool get isPatch => origin !== null;
558 572
559 bool get isPatched => patch !== null; 573 LibraryElement get declaration => super.declaration;
ahe 2012/10/02 13:27:04 Why?
Johnni Winther 2012/10/03 09:22:59 To let the editor know that declaration is a Libra
574 LibraryElement get implementation => super.implementation;
ahe 2012/10/02 13:27:04 Why?
Johnni Winther 2012/10/03 09:22:59 Ditto.
560 575
561 void addCompilationUnit(CompilationUnitElement element) { 576 void addCompilationUnit(CompilationUnitElement element) {
562 compilationUnits = compilationUnits.prepend(element); 577 compilationUnits = compilationUnits.prepend(element);
563 } 578 }
564 579
565 void addTag(LibraryTag tag, DiagnosticListener listener) { 580 void addTag(LibraryTag tag, DiagnosticListener listener) {
566 tags = tags.prepend(tag); 581 tags = tags.prepend(tag);
567 } 582 }
568 583
569 /** 584 /**
570 * Adds [element] to the import scope of this library. 585 * Adds [element] to the import scope of this library.
571 * 586 *
572 * If an element by the same name is already in the imported scope, an 587 * If an element by the same name is already in the imported scope, an
573 * [ErroneousElement] will be put in the imported scope, allowing for the 588 * [ErroneousElement] will be put in the imported scope, allowing for the
574 * detection of ambiguous uses of imported names. 589 * detection of ambiguous uses of imported names.
575 */ 590 */
576 void addImport(Element element, DiagnosticListener listener) { 591 void addImport(Element element, DiagnosticListener listener) {
577 Element existing = importScope.putIfAbsent(element.name, () => element); 592 Element existing = importScope.putIfAbsent(element.name, () => element);
578 if (existing !== element && existing !== null) { 593 if (existing !== element && existing !== null) {
579 if (!existing.isErroneous()) { 594 if (!existing.isErroneous()) {
580 // TODO(johnniwinther): Provide access to both the new and existing 595 // TODO(johnniwinther): Provide access to both the new and existing
581 // elements. 596 // elements.
582 importScope[element.name] = new ErroneousElement( 597 importScope[element.name] = new ErroneousElement(
583 MessageKind.DUPLICATE_IMPORT, 598 MessageKind.DUPLICATE_IMPORT,
584 [element.name], element.name, this); 599 [element.name], element.name, this);
585 } 600 }
586 } 601 }
587 } 602 }
588 603
604 LibraryElement getLibrary() => isPatch ? origin : this;
589 605
590 /** 606 /**
591 * Look up a top-level element in this library. The element could 607 * Look up a top-level element in this library. The element could
592 * potentially have been imported from another library. Returns 608 * potentially have been imported from another library. Returns
593 * null if no such element exist and an [ErroneousElement] if multiple 609 * null if no such element exist and an [ErroneousElement] if multiple
594 * elements have been imported. 610 * elements have been imported.
595 */ 611 */
596 Element find(SourceString elementName) { 612 Element find(SourceString elementName) {
597 Element result = localScope[elementName]; 613 Element result = localScope[elementName];
598 if (result === null) { 614 if (result === null) {
599 result = importScope[elementName]; 615 result = importScope[elementName];
600 } 616 }
601 return result; 617 return result;
602 } 618 }
603 619
604 /** Look up a top-level element in this library, but only look for 620 /** Look up a top-level element in this library, but only look for
605 * non-imported elements. Returns null if no such element exist. */ 621 * non-imported elements. Returns null if no such element exist. */
606 Element findLocal(SourceString elementName) { 622 Element findLocal(SourceString elementName) {
623 // TODO(johnniwinther): How to handle injected elements in the patch
624 // library?
607 Element result = localScope[elementName]; 625 Element result = localScope[elementName];
608 if (result === null || result.getLibrary() != this) return null; 626 if (result === null || result.getLibrary() != this) return null;
609 return result; 627 return result;
610 } 628 }
611 629
612 void forEachExport(f(Element element)) { 630 void forEachExport(f(Element element)) {
613 localScope.forEach((_, Element e) { 631 localScope.forEach((_, Element e) {
614 if (this === e.getLibrary() 632 if (this === e.getLibrary()
615 && e.kind !== ElementKind.PREFIX 633 && e.kind !== ElementKind.PREFIX
616 && e.kind !== ElementKind.FOREIGN 634 && e.kind !== ElementKind.FOREIGN
617 && !e.name.isPrivate()) { 635 && !e.name.isPrivate()) {
618 f(e); 636 f(e);
619 } 637 }
620 }); 638 });
621 } 639 }
622 640
641 void forEachLocalMember(f(Element element)) {
642 if (isPatch) {
643 // Patch libraries return both origin and patch members.
ahe 2012/10/02 13:27:04 What does "return" mean in this context?
Johnni Winther 2012/10/03 09:22:59 Done.
644 origin.localMembers.forEach(f);
645
646 void filterPatch(Element element) {
647 if (!element.isPatch) {
648 // Return only the origin element.
ahe 2012/10/02 13:27:04 What does this comment mean?
Johnni Winther 2012/10/03 09:22:59 Done.
649 f(element);
650 }
651 }
652 localMembers.forEach(filterPatch);
653 } else {
654 localMembers.forEach(f);
655 }
656 }
657
623 bool hasLibraryName() => libraryTag !== null; 658 bool hasLibraryName() => libraryTag !== null;
624 659
625 /** 660 /**
626 * Returns the library name (as defined by the #library tag) or for script 661 * Returns the library name (as defined by the #library tag) or for script
627 * (which have no #library tag) the script file name. The latter case is used 662 * (which have no #library tag) the script file name. The latter case is used
628 * to private 'library name' for scripts to use for instance in dartdoc. 663 * to private 'library name' for scripts to use for instance in dartdoc.
629 */ 664 */
630 String getLibraryOrScriptName() { 665 String getLibraryOrScriptName() {
631 if (libraryTag !== null) { 666 if (libraryTag !== null) {
632 return libraryTag.argument.dartString.slowToString(); 667 return libraryTag.argument.dartString.slowToString();
633 } else { 668 } else {
634 // Use the file name as script name. 669 // Use the file name as script name.
635 String path = uri.path; 670 String path = uri.path;
636 return path.substring(path.lastIndexOf('/') + 1); 671 return path.substring(path.lastIndexOf('/') + 1);
637 } 672 }
638 } 673 }
639 674
640 Scope buildEnclosingScope() => new TopScope(this); 675 Scope buildEnclosingScope({bool patchScope: false}) {
ahe 2012/10/02 13:27:04 I would prefer to avoid optional arguments here.
Johnni Winther 2012/10/03 09:22:59 Added a TODO.
676 if (origin !== null) {
677 return new PatchLibraryScope(origin, this);
678 } if (patchScope && patch !== null) {
679 return new PatchLibraryScope(this, patch);
680 } else {
681 return new TopScope(this);
682 }
683 }
641 684
642 bool get isPlatformLibrary => uri.scheme == "dart"; 685 bool get isPlatformLibrary => uri.scheme == "dart";
686
687 String toString() {
688 if (origin !== null) {
689 return 'patch library(${getLibraryOrScriptName()})';
690 } else if (patch !== null) {
691 return 'origin library(${getLibraryOrScriptName()})';
692 } else {
693 return 'library(${getLibraryOrScriptName()})';
694 }
695 }
643 } 696 }
644 697
645 class PrefixElement extends Element { 698 class PrefixElement extends Element {
646 Map<SourceString, Element> imported; 699 Map<SourceString, Element> imported;
647 Token firstPosition; 700 Token firstPosition;
648 701
649 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition) 702 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition)
650 : imported = new Map<SourceString, Element>(), 703 : imported = new Map<SourceString, Element>(),
651 super(prefix, ElementKind.PREFIX, enclosing); 704 super(prefix, ElementKind.PREFIX, enclosing);
652 705
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 Typedef node = parseNode(compiler); 740 Typedef node = parseNode(compiler);
688 Link<DartType> parameters = 741 Link<DartType> parameters =
689 TypeDeclarationElement.createTypeVariables(this, node.typeParameters); 742 TypeDeclarationElement.createTypeVariables(this, node.typeParameters);
690 cachedType = new TypedefType(this, parameters); 743 cachedType = new TypedefType(this, parameters);
691 compiler.resolveTypedef(this); 744 compiler.resolveTypedef(this);
692 return cachedType; 745 return cachedType;
693 } 746 }
694 747
695 Link<DartType> get typeVariables => cachedType.typeArguments; 748 Link<DartType> get typeVariables => cachedType.typeArguments;
696 749
697 Scope buildScope() =>
698 new TypeDeclarationScope(enclosingElement.buildScope(), this);
699 750
751 Scope buildScope({bool patchScope: false}) => new TypeDeclarationScope(
ahe 2012/10/02 13:27:04 Optional arguments :-(
ahe 2012/10/02 13:27:04 If it doesn't fit on one line, use don't use the s
Johnni Winther 2012/10/03 09:22:59 Added a TODO.
Johnni Winther 2012/10/03 09:22:59 Done.
752 enclosingElement.buildScope(patchScope: patchScope), this);
700 TypedefElement cloneTo(Element enclosing, DiagnosticListener listener) { 753 TypedefElement cloneTo(Element enclosing, DiagnosticListener listener) {
701 TypedefElement result = new TypedefElement(name, enclosing); 754 TypedefElement result = new TypedefElement(name, enclosing);
702 return result; 755 return result;
703 } 756 }
704 } 757 }
705 758
706 class VariableElement extends Element { 759 class VariableElement extends Element {
707 final VariableListElement variables; 760 final VariableListElement variables;
708 Expression cachedNode; // The send or the identifier in the variables list. 761 Expression cachedNode; // The send or the identifier in the variables list.
709 762
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 } else { 900 } else {
848 result = new VariableListElement(kind, modifiers, enclosing); 901 result = new VariableListElement(kind, modifiers, enclosing);
849 } 902 }
850 return result; 903 return result;
851 } 904 }
852 905
853 bool isInstanceMember() { 906 bool isInstanceMember() {
854 return isMember() && !modifiers.isStatic(); 907 return isMember() && !modifiers.isStatic();
855 } 908 }
856 909
857 Scope buildScope() { 910 Scope buildScope({bool patchScope: false}) {
ahe 2012/10/02 13:27:04 Optional arguments :-(
Johnni Winther 2012/10/03 09:22:59 Added a TODO.
858 Scope result = new VariableScope(enclosingElement.buildScope(), this); 911 Scope result = new VariableScope(
912 enclosingElement.buildScope(patchScope: patchScope), this);
859 if (enclosingElement.isClass()) { 913 if (enclosingElement.isClass()) {
860 ClassScope clsScope = result.parent; 914 Scope clsScope = result.parent;
861 clsScope.inStaticContext = !isInstanceMember(); 915 clsScope.inStaticContext = !isInstanceMember();
862 } 916 }
863 return result; 917 return result;
864 } 918 }
865 } 919 }
866 920
867 class ForeignElement extends Element { 921 class ForeignElement extends Element {
868 ForeignElement(SourceString name, ContainerElement enclosingElement) 922 ForeignElement(SourceString name, ContainerElement enclosingElement)
869 : super(name, ElementKind.FOREIGN, enclosingElement); 923 : super(name, ElementKind.FOREIGN, enclosingElement);
870 924
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 1035
982 FunctionSignature functionSignature; 1036 FunctionSignature functionSignature;
983 1037
984 /** 1038 /**
985 * A function declaration that should be parsed instead of the current one. 1039 * A function declaration that should be parsed instead of the current one.
986 * The patch should be parsed as if it was in the current scope. Its 1040 * The patch should be parsed as if it was in the current scope. Its
987 * signature must match this function's signature. 1041 * signature must match this function's signature.
988 */ 1042 */
989 // TODO(lrn): Consider using [defaultImplementation] to store the patch. 1043 // TODO(lrn): Consider using [defaultImplementation] to store the patch.
990 FunctionElement patch = null; 1044 FunctionElement patch = null;
1045 FunctionElement origin = null;
991 1046
992 /** 1047 /**
993 * If this is an interface constructor, [defaultImplementation] will 1048 * If this is an interface constructor, [defaultImplementation] will
994 * changed by the resolver to point to the default 1049 * changed by the resolver to point to the default
995 * implementation. Otherwise, [:defaultImplementation === this:]. 1050 * implementation. Otherwise, [:defaultImplementation === this:].
996 */ 1051 */
997 FunctionElement defaultImplementation; 1052 FunctionElement defaultImplementation;
998 1053
999 FunctionElement(SourceString name, 1054 FunctionElement(SourceString name,
1000 ElementKind kind, 1055 ElementKind kind,
(...skipping 19 matching lines...) Expand all
1020 FunctionExpression this.cachedNode, 1075 FunctionExpression this.cachedNode,
1021 ElementKind kind, 1076 ElementKind kind,
1022 Modifiers this.modifiers, 1077 Modifiers this.modifiers,
1023 Element enclosing, 1078 Element enclosing,
1024 FunctionSignature this.functionSignature) 1079 FunctionSignature this.functionSignature)
1025 : super(name, kind, enclosing) { 1080 : super(name, kind, enclosing) {
1026 defaultImplementation = this; 1081 defaultImplementation = this;
1027 } 1082 }
1028 1083
1029 bool get isPatched => patch !== null; 1084 bool get isPatched => patch !== null;
1085 bool get isPatch => origin !== null;
1030 1086
1031 /** 1087 /**
1032 * Applies a patch function to this function. The patch function's body 1088 * Applies a patch function to this function. The patch function's body
1033 * is used as replacement when parsing this function's body. 1089 * is used as replacement when parsing this function's body.
1034 * This method must not be called after the function has been parsed, 1090 * This method must not be called after the function has been parsed,
1035 * and it must be called at most once. 1091 * and it must be called at most once.
1036 */ 1092 */
1037 void setPatch(FunctionElement patchElement) { 1093 void setPatch(FunctionElement patchElement) {
1038 // Sanity checks. The caller must check these things before calling. 1094 // Sanity checks. The caller must check these things before calling.
1039 assert(patch === null); 1095 assert(patch === null);
1040 assert(cachedNode === null);
1041 this.patch = patchElement; 1096 this.patch = patchElement;
1042 cachedNode = patchElement.cachedNode;
1043 } 1097 }
1044 1098
1045 bool isInstanceMember() { 1099 bool isInstanceMember() {
1046 return isMember() 1100 return isMember()
1047 && !isConstructor() 1101 && !isConstructor()
1048 && !modifiers.isStatic(); 1102 && !modifiers.isStatic();
1049 } 1103 }
1050 1104
1051 FunctionSignature computeSignature(Compiler compiler) { 1105 FunctionSignature computeSignature(Compiler compiler) {
1052 if (functionSignature !== null) return functionSignature; 1106 if (functionSignature !== null) return functionSignature;
(...skipping 16 matching lines...) Expand all
1069 } 1123 }
1070 1124
1071 FunctionType computeType(Compiler compiler) { 1125 FunctionType computeType(Compiler compiler) {
1072 if (type != null) return type; 1126 if (type != null) return type;
1073 type = compiler.computeFunctionType(declaration, 1127 type = compiler.computeFunctionType(declaration,
1074 computeSignature(compiler)); 1128 computeSignature(compiler));
1075 return type; 1129 return type;
1076 } 1130 }
1077 1131
1078 Node parseNode(DiagnosticListener listener) { 1132 Node parseNode(DiagnosticListener listener) {
1079 if (cachedNode !== null) return cachedNode;
1080 if (patch === null) { 1133 if (patch === null) {
1081 if (modifiers != null && modifiers.isExternal()) { 1134 if (modifiers != null && modifiers.isExternal()) {
1082 listener.cancel("Compiling external function with no implementation.", 1135 listener.cancel("Compiling external function with no implementation.",
1083 element: this); 1136 element: this);
1084 } 1137 }
1085 return null;
1086 } 1138 }
1087 cachedNode = patch.parseNode(listener);
1088 return cachedNode; 1139 return cachedNode;
1089 } 1140 }
1090 1141
1091 Token position() => cachedNode.getBeginToken(); 1142 Token position() => cachedNode.getBeginToken();
1092 1143
1093 FunctionElement asFunctionElement() => this; 1144 FunctionElement asFunctionElement() => this;
1094 1145
1095 String toString() { 1146 String toString() {
1096 if (isPatch) { 1147 if (isPatch) {
1097 return 'patch ${super.toString()}'; 1148 return 'patch ${super.toString()}';
1098 } else if (isPatched) { 1149 } else if (isPatched) {
1099 return 'origin ${super.toString()}'; 1150 return 'origin ${super.toString()}';
1100 } else { 1151 } else {
1101 return super.toString(); 1152 return super.toString();
1102 } 1153 }
1103 } 1154 }
1104 1155
1105 Scope buildScope() { 1156 Scope buildScope({bool patchScope: false}) {
ahe 2012/10/02 13:27:04 Yuck!
Johnni Winther 2012/10/03 09:22:59 Added a TODO.
1106 Scope result = 1157 Scope result = new MethodScope(
1107 new MethodScope(enclosingElement.buildScope(), this); 1158 enclosingElement.buildScope(patchScope: patchScope), this);
1108 if (enclosingElement.isClass()) { 1159 if (enclosingElement.isClass()) {
1109 Scope clsScope = result.parent; 1160 Scope clsScope = result.parent;
1110 clsScope.inStaticContext = !isInstanceMember() && !isConstructor(); 1161 clsScope.inStaticContext = !isInstanceMember() && !isConstructor();
1111 } 1162 }
1112 return result; 1163 return result;
1113 } 1164 }
1114 } 1165 }
1115 1166
1116 class ConstructorBodyElement extends FunctionElement { 1167 class ConstructorBodyElement extends FunctionElement {
1117 FunctionElement constructor; 1168 FunctionElement constructor;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 int resolutionState; 1274 int resolutionState;
1224 1275
1225 // backendMembers are members that have been added by the backend to simplify 1276 // backendMembers are members that have been added by the backend to simplify
1226 // compilation. They don't have any user-side counter-part. 1277 // compilation. They don't have any user-side counter-part.
1227 Link<Element> backendMembers = const EmptyLink<Element>(); 1278 Link<Element> backendMembers = const EmptyLink<Element>();
1228 1279
1229 Link<DartType> allSupertypes; 1280 Link<DartType> allSupertypes;
1230 1281
1231 // Lazily applied patch of class members. 1282 // Lazily applied patch of class members.
1232 ClassElement patch = null; 1283 ClassElement patch = null;
1284 ClassElement origin = null;
1233 1285
1234 ClassElement(SourceString name, Element enclosing, this.id, int initialState) 1286 ClassElement(SourceString name, Element enclosing, this.id, int initialState)
1235 : supertypeLoadState = initialState, 1287 : supertypeLoadState = initialState,
1236 resolutionState = initialState, 1288 resolutionState = initialState,
1237 super(name, ElementKind.CLASS, enclosing); 1289 super(name, ElementKind.CLASS, enclosing);
1238 1290
1239 InterfaceType computeType(compiler) { 1291 InterfaceType computeType(compiler) {
1240 if (type == null) { 1292 if (type == null) {
1241 ClassNode node = parseNode(compiler); 1293 if (origin === null) {
1242 Link<DartType> parameters = 1294 ClassNode node = parseNode(compiler);
1243 TypeDeclarationElement.createTypeVariables(this, node.typeParameters); 1295 Link<DartType> parameters =
1244 type = new InterfaceType(this, parameters); 1296 TypeDeclarationElement.createTypeVariables(this,
1297 node.typeParameters);
1298 type = new InterfaceType(this, parameters);
1299 } else {
1300 type = origin.computeType(compiler);
1301 }
1245 } 1302 }
1246 return type; 1303 return type;
1247 } 1304 }
1248 1305
1249 bool get isPatched => patch != null; 1306 bool get isPatched => patch != null;
1307 bool get isPatch => origin != null;
1308
1309 ClassElement get declaration => super.declaration;
1310 ClassElement get implementation => super.implementation;
1250 1311
1251 /** 1312 /**
1252 * Return [:true:] if this element is the [:Object:] class for the [compiler]. 1313 * Return [:true:] if this element is the [:Object:] class for the [compiler].
1253 */ 1314 */
1254 bool isObject(Compiler compiler) => 1315 bool isObject(Compiler compiler) =>
1255 declaration === compiler.objectClass; 1316 declaration === compiler.objectClass;
1256 1317
1257 Link<DartType> get typeVariables => type.arguments; 1318 Link<DartType> get typeVariables => type.arguments;
1258 1319
1259 ClassElement ensureResolved(Compiler compiler) { 1320 ClassElement ensureResolved(Compiler compiler) {
(...skipping 18 matching lines...) Expand all
1278 Element lookupSuperMember(SourceString memberName) { 1339 Element lookupSuperMember(SourceString memberName) {
1279 return lookupSuperMemberInLibrary(memberName, getLibrary()); 1340 return lookupSuperMemberInLibrary(memberName, getLibrary());
1280 } 1341 }
1281 1342
1282 /** 1343 /**
1283 * Lookup super members for the class that is accessible in [library]. 1344 * Lookup super members for the class that is accessible in [library].
1284 * This will ignore constructors. 1345 * This will ignore constructors.
1285 */ 1346 */
1286 Element lookupSuperMemberInLibrary(SourceString memberName, 1347 Element lookupSuperMemberInLibrary(SourceString memberName,
1287 LibraryElement library) { 1348 LibraryElement library) {
1349 bool includeInjectedMembers = isPatch;
1288 bool isPrivate = memberName.isPrivate(); 1350 bool isPrivate = memberName.isPrivate();
1289 for (ClassElement s = superclass; s != null; s = s.superclass) { 1351 for (ClassElement s = superclass; s != null; s = s.superclass) {
1290 // Private members from a different library are not visible. 1352 // Private members from a different library are not visible.
1291 if (isPrivate && library !== s.getLibrary()) continue; 1353 if (isPrivate && library !== s.getLibrary()) continue;
1354 s = includeInjectedMembers ? s.implementation : s;
1292 Element e = s.lookupLocalMember(memberName); 1355 Element e = s.lookupLocalMember(memberName);
1293 if (e === null) continue; 1356 if (e === null) continue;
1294 // Static members are not inherited. 1357 // Static members are not inherited.
1295 if (e.modifiers.isStatic()) continue; 1358 if (e.modifiers.isStatic()) continue;
1296 return e; 1359 return e;
1297 } 1360 }
1298 if (isInterface()) { 1361 if (isInterface()) {
1299 return lookupSuperInterfaceMember(memberName, getLibrary()); 1362 return lookupSuperInterfaceMember(memberName, getLibrary());
1300 } 1363 }
1301 return null; 1364 return null;
1302 } 1365 }
1303 1366
1304 Element lookupSuperInterfaceMember(SourceString memberName, 1367 Element lookupSuperInterfaceMember(SourceString memberName,
1305 LibraryElement fromLibrary) { 1368 LibraryElement fromLibrary) {
1369 bool includeInjectedMembers = isPatch;
1306 bool isPrivate = memberName.isPrivate(); 1370 bool isPrivate = memberName.isPrivate();
1307 for (InterfaceType t in interfaces) { 1371 for (InterfaceType t in interfaces) {
1308 ClassElement cls = t.element; 1372 ClassElement cls = t.element;
1373 cls = includeInjectedMembers ? cls.implementation : cls;
1309 Element e = cls.lookupLocalMember(memberName); 1374 Element e = cls.lookupLocalMember(memberName);
1310 if (e === null) continue; 1375 if (e === null) continue;
1311 // Private members from a different library are not visible. 1376 // Private members from a different library are not visible.
1312 if (isPrivate && fromLibrary !== e.getLibrary()) continue; 1377 if (isPrivate && fromLibrary !== e.getLibrary()) continue;
1313 // Static members are not inherited. 1378 // Static members are not inherited.
1314 if (e.modifiers.isStatic()) continue; 1379 if (e.modifiers.isStatic()) continue;
1315 return e; 1380 return e;
1316 } 1381 }
1317 return null; 1382 return null;
1318 } 1383 }
1319 1384
1320 /** 1385 /**
1321 * Find the first member in the class chain with the given [selector]. 1386 * Find the first member in the class chain with the given [selector].
1322 * 1387 *
1323 * This method is NOT to be used for resolving 1388 * This method is NOT to be used for resolving
1324 * unqualified sends because it does not implement the scoping 1389 * unqualified sends because it does not implement the scoping
1325 * rules, where library scope comes before superclass scope. 1390 * rules, where library scope comes before superclass scope.
1391 *
1392 * When called on the implementation element both members declared in the
1393 * origin and the patch class are returned.
1326 */ 1394 */
1327 Element lookupSelector(Selector selector) { 1395 Element lookupSelector(Selector selector) {
1328 SourceString memberName = selector.name; 1396 SourceString memberName = selector.name;
1329 LibraryElement library = selector.library; 1397 LibraryElement library = selector.library;
1330 Element localMember = lookupLocalMember(memberName); 1398 Element localMember = lookupLocalMember(memberName);
1331 if (localMember != null && 1399 if (localMember != null &&
1332 (!memberName.isPrivate() || getLibrary() == library)) { 1400 (!memberName.isPrivate() || getLibrary() == library)) {
1333 return localMember; 1401 return localMember;
1334 } 1402 }
1335 return lookupSuperMemberInLibrary(memberName, library); 1403 return lookupSuperMemberInLibrary(memberName, library);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1398 // Search in scope to be sure we search patched constructors. 1466 // Search in scope to be sure we search patched constructors.
1399 for (var element in localScope.getValues()) { 1467 for (var element in localScope.getValues()) {
1400 if (element.isConstructor()) return true; 1468 if (element.isConstructor()) return true;
1401 } 1469 }
1402 return false; 1470 return false;
1403 } 1471 }
1404 1472
1405 Link<Element> get constructors { 1473 Link<Element> get constructors {
1406 // TODO(ajohnsen): See if we can avoid this method at some point. 1474 // TODO(ajohnsen): See if we can avoid this method at some point.
1407 Link<Element> result = const EmptyLink<Element>(); 1475 Link<Element> result = const EmptyLink<Element>();
1408 for (Element member in localMembers) { 1476 // TODO(johnniwinther): Should we include injected constructors?
1477 forEachMember((_, Element member) {
1409 if (member.isConstructor()) result = result.prepend(member); 1478 if (member.isConstructor()) result = result.prepend(member);
1410 } 1479 });
1411 return result; 1480 return result;
1412 } 1481 }
1413 1482
1414 /** 1483 /**
1415 * Returns the super class, if any. 1484 * Returns the super class, if any.
1416 * 1485 *
1417 * The returned element may not be resolved yet. 1486 * The returned element may not be resolved yet.
1418 */ 1487 */
1419 ClassElement get superclass { 1488 ClassElement get superclass {
1420 assert(supertypeLoadState == STATE_DONE); 1489 assert(supertypeLoadState == STATE_DONE);
1421 return supertype === null ? null : supertype.element; 1490 return supertype === null ? null : supertype.element;
1422 } 1491 }
1423 1492
1424 /** 1493 /**
1425 * Runs through all members of this class. 1494 * Runs through all members of this class.
1426 * 1495 *
1427 * The enclosing class is passed to the callback. This is useful when 1496 * The enclosing class is passed to the callback. This is useful when
1428 * [includeSuperMembers] is [:true:]. 1497 * [includeSuperMembers] is [:true:].
1498 *
1499 * When called on an implementation element both the members in the origin
1500 * and patch class are included.
1429 */ 1501 */
1502 // TODO(johnniwinther): Clean up lookup to get rid of the include predicates.
1430 void forEachMember([void f(ClassElement enclosingClass, Element member), 1503 void forEachMember([void f(ClassElement enclosingClass, Element member),
1431 includeBackendMembers = false, 1504 includeBackendMembers = false,
1432 includeSuperMembers = false]) { 1505 includeSuperMembers = false]) {
1506 bool includeInjectedMembers = isPatch;
1433 Set<ClassElement> seen = new Set<ClassElement>(); 1507 Set<ClassElement> seen = new Set<ClassElement>();
1434 ClassElement classElement = this; 1508 ClassElement classElement = declaration;
1435 do { 1509 do {
1436 if (seen.contains(classElement)) return; 1510 if (seen.contains(classElement)) return;
1437 seen.add(classElement); 1511 seen.add(classElement);
1438 1512
1439 // Iterate through the members in textual order, which requires 1513 // Iterate through the members in textual order, which requires
1440 // to reverse the data structure [localMembers] we created. 1514 // to reverse the data structure [localMembers] we created.
1441 // Textual order may be important for certain operations, for 1515 // Textual order may be important for certain operations, for
1442 // example when emitting the initializers of fields. 1516 // example when emitting the initializers of fields.
1443 for (Element element in classElement.localMembers.reverse()) { 1517 for (Element element in classElement.localMembers.reverse()) {
1444 f(classElement, element); 1518 f(classElement, element);
1445 } 1519 }
1446 if (includeBackendMembers) { 1520 if (includeBackendMembers) {
1447 for (Element element in classElement.backendMembers) { 1521 for (Element element in classElement.backendMembers) {
1448 f(classElement, element); 1522 f(classElement, element);
1449 } 1523 }
1450 } 1524 }
1525 if (includeInjectedMembers) {
1526 if (classElement.patch != null) {
1527 for (Element element in classElement.patch.localMembers.reverse()) {
ahe 2012/10/02 13:27:04 Why are you calling reverse here?
Johnni Winther 2012/10/03 09:22:59 Because it was done above for [:classElement.local
1528 if (!element.isPatch) {
1529 f(classElement, element);
1530 }
1531 }
1532 }
1533 }
1451 classElement = includeSuperMembers ? classElement.superclass : null; 1534 classElement = includeSuperMembers ? classElement.superclass : null;
1452 } while(classElement !== null); 1535 } while(classElement !== null);
1453 } 1536 }
1454 1537
1455 /** 1538 /**
1456 * Runs through all instance-field members of this class. 1539 * Runs through all instance-field members of this class.
1457 * 1540 *
1458 * The enclosing class is passed to the callback. This is useful when 1541 * The enclosing class is passed to the callback. This is useful when
1459 * [includeSuperMembers] is [:true:]. 1542 * [includeSuperMembers] is [:true:].
1460 * 1543 *
1461 * When [includeBackendMembers] and [includeSuperMembers] are both [:true:] 1544 * When [includeBackendMembers] and [includeSuperMembers] are both [:true:]
1462 * then the fields are visited in the same order as they need to be given 1545 * then the fields are visited in the same order as they need to be given
1463 * to the JavaScript constructor. 1546 * to the JavaScript constructor.
1547 *
1548 * When called on the implementation element both the fields declared in the
1549 * origin and in the patch are included.
1464 */ 1550 */
1465 void forEachInstanceField([void f(ClassElement enclosingClass, Element field), 1551 void forEachInstanceField([void f(ClassElement enclosingClass, Element field),
1466 includeBackendMembers = false, 1552 includeBackendMembers = false,
1467 includeSuperMembers = false]) { 1553 includeSuperMembers = false]) {
1468 // Filters so that [f] is only invoked with instance fields. 1554 // Filters so that [f] is only invoked with instance fields.
1469 void fieldFilter(ClassElement enclosingClass, Element member) { 1555 void fieldFilter(ClassElement enclosingClass, Element member) {
1470 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) { 1556 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) {
1471 f(enclosingClass, member); 1557 f(enclosingClass, member);
1472 } 1558 }
1473 } 1559 }
(...skipping 22 matching lines...) Expand all
1496 for (ClassElement s = this; s != null; s = s.superclass) { 1582 for (ClassElement s = this; s != null; s = s.superclass) {
1497 if (s === cls) return true; 1583 if (s === cls) return true;
1498 } 1584 }
1499 return false; 1585 return false;
1500 } 1586 }
1501 1587
1502 bool isInterface() => false; 1588 bool isInterface() => false;
1503 bool isNative() => nativeName != null; 1589 bool isNative() => nativeName != null;
1504 int hashCode() => id; 1590 int hashCode() => id;
1505 1591
1506 Scope buildScope() => 1592 Scope buildScope({bool patchScope: false}) {
ahe 2012/10/02 13:27:04 Optional parameters :-(
Johnni Winther 2012/10/03 09:22:59 Added a TODO.
1507 new ClassScope(enclosingElement.buildScope(), this); 1593 if (origin !== null) {
1594 return new PatchClassScope(
1595 enclosingElement.buildScope(patchScope: patchScope), origin, this);
1596 } else if (patchScope && patch !== null) {
1597 return new PatchClassScope(
1598 enclosingElement.buildScope(patchScope: patchScope), this, patch);
1599 } else {
1600 return new ClassScope(
1601 enclosingElement.buildScope(patchScope: patchScope), this);
1602 }
1603 }
1604
1605 Scope buildLocalScope() {
1606 if (origin !== null) {
1607 return new LocalPatchClassScope(origin, this);
1608 } else {
1609 return new LocalClassScope(this);
1610 }
1611 }
1508 1612
1509 ClassElement cloneTo(Element enclosing, DiagnosticListener listener) { 1613 ClassElement cloneTo(Element enclosing, DiagnosticListener listener) {
1510 listener.internalErrorOnElement(this, 'unsupported operation'); 1614 listener.internalErrorOnElement(this, 'unsupported operation');
1511 } 1615 }
1512 1616
1513 Link<DartType> get allSupertypesAndSelf { 1617 Link<DartType> get allSupertypesAndSelf {
1514 return allSupertypes.prepend(new InterfaceType(this)); 1618 return allSupertypes.prepend(new InterfaceType(this));
1515 } 1619 }
1620
1621 String toString() {
1622 if (origin !== null) {
1623 return 'patch ${super.toString()}';
1624 } else if (patch !== null) {
1625 return 'origin ${super.toString()}';
1626 } else {
1627 return super.toString();
1628 }
1629 }
1516 } 1630 }
1517 1631
1518 class Elements { 1632 class Elements {
1519 static bool isUnresolved(Element e) => e == null || e.isErroneous(); 1633 static bool isUnresolved(Element e) => e == null || e.isErroneous();
1520 static bool isErroneousElement(Element e) => e != null && e.isErroneous(); 1634 static bool isErroneousElement(Element e) => e != null && e.isErroneous();
1521 1635
1522 static bool isLocal(Element element) { 1636 static bool isLocal(Element element) {
1523 return !Elements.isUnresolved(element) 1637 return !Elements.isUnresolved(element)
1524 && !element.isInstanceMember() 1638 && !element.isInstanceMember()
1525 && !isStaticOrTopLevelField(element) 1639 && !isStaticOrTopLevelField(element)
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 1904
1791 MetadataAnnotation ensureResolved(Compiler compiler) { 1905 MetadataAnnotation ensureResolved(Compiler compiler) {
1792 if (resolutionState == STATE_NOT_STARTED) { 1906 if (resolutionState == STATE_NOT_STARTED) {
1793 compiler.resolver.resolveMetadataAnnotation(this); 1907 compiler.resolver.resolveMetadataAnnotation(this);
1794 } 1908 }
1795 return this; 1909 return this;
1796 } 1910 }
1797 1911
1798 String toString() => 'MetadataAnnotation($value, $resolutionState)'; 1912 String toString() => 'MetadataAnnotation($value, $resolutionState)';
1799 } 1913 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698