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

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: Rebased. 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 Spannable { 110 class Element implements 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 => Modifiers.EMPTY; 120 Modifiers get modifiers => Modifiers.EMPTY;
121 121
122 Node parseNode(DiagnosticListener listener) { 122 Node parseNode(DiagnosticListener listener) {
123 listener.cancel("Internal Error: $this.parseNode", token: position()); 123 listener.internalErrorOnElement(this, 'not implemented');
124 } 124 }
125 125
126 DartType computeType(Compiler compiler) { 126 DartType computeType(Compiler compiler) {
127 compiler.internalError("$this.computeType.", token: position()); 127 compiler.internalError("$this.computeType.", token: position());
128 } 128 }
129 129
130 void addMetadata(MetadataAnnotation annotation) { 130 void addMetadata(MetadataAnnotation annotation) {
131 assert(annotation.annotatedElement === null); 131 assert(annotation.annotatedElement === null);
132 annotation.annotatedElement = this; 132 annotation.annotatedElement = this;
133 metadata = metadata.prepend(annotation); 133 metadata = metadata.prepend(annotation);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 182
183 /** 183 /**
184 * Is [:true:] if this element is a patch. 184 * Is [:true:] if this element is a patch.
185 * 185 *
186 * If [:true:] this element has a non-null [origin] field. 186 * If [:true:] this element has a non-null [origin] field.
187 * 187 *
188 * See [:patch_parser.dart:] for a description of the terminology. 188 * See [:patch_parser.dart:] for a description of the terminology.
189 */ 189 */
190 bool get isPatch => false; 190 bool get isPatch => false;
191 191
192
193 /** 192 /**
194 * Is [:true:] if this element defines the implementation for the entity of 193 * Is [:true:] if this element defines the implementation for the entity of
195 * this element. 194 * this element.
196 * 195 *
197 * See [:patch_parser.dart:] for a description of the terminology. 196 * See [:patch_parser.dart:] for a description of the terminology.
198 */ 197 */
199 bool get isImplementation => implementation === this; 198 bool get isImplementation => !isPatched;
200 199
201 /** 200 /**
202 * Is [:true:] if this element introduces the entity of this element. 201 * Is [:true:] if this element introduces the entity of this element.
203 * 202 *
204 * See [:patch_parser.dart:] for a description of the terminology. 203 * See [:patch_parser.dart:] for a description of the terminology.
205 */ 204 */
206 bool get isDeclaration => declaration === this; 205 bool get isDeclaration => !isPatch;
207 206
208 /** 207 /**
209 * Returns the element which defines the implementation for the entity of this 208 * Returns the element which defines the implementation for the entity of this
210 * element. 209 * element.
211 * 210 *
212 * See [:patch_parser.dart:] for a description of the terminology. 211 * See [:patch_parser.dart:] for a description of the terminology.
213 */ 212 */
214 Element get implementation => this; 213 Element get implementation => isPatched ? patch : this;
215 214
216 /** 215 /**
217 * Returns the element which introduces the entity of this element. 216 * Returns the element which introduces the entity of this element.
218 * 217 *
219 * See [:patch_parser.dart:] for a description of the terminology. 218 * See [:patch_parser.dart:] for a description of the terminology.
220 */ 219 */
221 Element get declaration => this; 220 Element get declaration => isPatch ? origin : this;
222 221
223 // TODO(johnniwinther): This breaks for libraries (for which enclosing 222 // TODO(johnniwinther): This breaks for libraries (for which enclosing
224 // elements are null) and is invalid for top level variable declarations for 223 // elements are null) and is invalid for top level variable declarations for
225 // which the enclosing element is a VariableDeclarations and not a compilation 224 // which the enclosing element is a VariableDeclarations and not a compilation
226 // unit. 225 // unit.
227 bool isTopLevel() { 226 bool isTopLevel() {
228 return enclosingElement !== null && enclosingElement.isCompilationUnit(); 227 return enclosingElement !== null && enclosingElement.isCompilationUnit();
229 } 228 }
230 229
231 bool isAssignable() { 230 bool isAssignable() {
(...skipping 21 matching lines...) Expand all
253 while (element !== null && !element.isCompilationUnit()) { 252 while (element !== null && !element.isCompilationUnit()) {
254 if (element is CompilationUnitOverrideElement) { 253 if (element is CompilationUnitOverrideElement) {
255 CompilationUnitOverrideElement override = element; 254 CompilationUnitOverrideElement override = element;
256 return override.compilationUnit; 255 return override.compilationUnit;
257 } 256 }
258 if (element.isLibrary()) { 257 if (element.isLibrary()) {
259 LibraryElement library = element; 258 LibraryElement library = element;
260 return library.entryCompilationUnit; 259 return library.entryCompilationUnit;
261 } 260 }
262 element = element.enclosingElement; 261 element = element.enclosingElement;
263 if (element is FunctionElement) {
264 FunctionElement function = element;
265 if (function.isPatched) {
266 element = function.patch;
267 }
268 }
269 } 262 }
270 return element; 263 return element;
271 } 264 }
272 265
273 LibraryElement getLibrary() { 266 LibraryElement getLibrary() => enclosingElement.getLibrary();
267
268 LibraryElement getImplementationLibrary() {
274 Element element = this; 269 Element element = this;
275 while (element.kind !== ElementKind.LIBRARY) { 270 while (element.kind !== ElementKind.LIBRARY) {
276 element = element.enclosingElement; 271 element = element.enclosingElement;
277 } 272 }
278 return element; 273 return element;
279 } 274 }
280 275
281 LibraryElement getImplementationLibrary() => getLibrary();
282
283 ClassElement getEnclosingClass() { 276 ClassElement getEnclosingClass() {
284 for (Element e = this; e !== null; e = e.enclosingElement) { 277 for (Element e = this; e !== null; e = e.enclosingElement) {
285 if (e.isClass()) return e; 278 if (e.isClass()) return e;
286 } 279 }
287 return null; 280 return null;
288 } 281 }
289 282
290 Element getEnclosingClassOrCompilationUnit() { 283 Element getEnclosingClassOrCompilationUnit() {
291 for (Element e = this; e !== null; e = e.enclosingElement) { 284 for (Element e = this; e !== null; e = e.enclosingElement) {
292 if (e.isClass() || e.isCompilationUnit()) return e; 285 if (e.isClass() || e.isCompilationUnit()) return e;
(...skipping 15 matching lines...) Expand all
308 return e; 301 return e;
309 } 302 }
310 } 303 }
311 return null; 304 return null;
312 } 305 }
313 306
314 /** 307 /**
315 * Creates the scope for this element. The scope of the 308 * Creates the scope for this element. The scope of the
316 * enclosing element will be the parent scope. 309 * enclosing element will be the parent scope.
317 */ 310 */
318 Scope buildScope() => buildEnclosingScope(); 311 // TODO(johnniwinther): Clean up scope generation. Possibly generation scopes
312 // externally.
313 Scope buildScope({bool patchScope: false}) =>
314 buildEnclosingScope(patchScope: patchScope);
319 315
320 /** 316 /**
321 * Creates the scope for the enclosing element. 317 * Creates the scope for the enclosing element.
322 */ 318 */
323 Scope buildEnclosingScope() => enclosingElement.buildScope(); 319 // TODO(johnniwinther): Remove buildEnclosingScope as part of scope clean-up.
320 Scope buildEnclosingScope({bool patchScope: false}) =>
321 enclosingElement.buildScope(patchScope: patchScope);
324 322
325 String toString() { 323 String toString() {
326 // TODO(johnniwinther): Test for nullness of name, or make non-nullness an 324 // TODO(johnniwinther): Test for nullness of name, or make non-nullness an
327 // invariant for all element types? 325 // invariant for all element types?
328 var nameText = name !== null ? name.slowToString() : '?'; 326 var nameText = name !== null ? name.slowToString() : '?';
329 if (enclosingElement !== null && !isTopLevel()) { 327 if (enclosingElement !== null && !isTopLevel()) {
330 String holderName = enclosingElement.name !== null 328 String holderName = enclosingElement.name !== null
331 ? enclosingElement.name.slowToString() 329 ? enclosingElement.name.slowToString()
332 : '${enclosingElement.kind}?'; 330 : '${enclosingElement.kind}?';
333 return '$kind($holderName#${nameText})'; 331 return '$kind($holderName#${nameText})';
334 } else { 332 } else {
335 return '$kind(${nameText})'; 333 return '$kind(${nameText})';
336 } 334 }
337 } 335 }
338 336
339 bool _isNative = false; 337 bool _isNative = false;
340 void setNative() { _isNative = true; } 338 void setNative() { _isNative = true; }
341 bool isNative() => _isNative; 339 bool isNative() => _isNative;
342 340
343 FunctionElement asFunctionElement() => null; 341 FunctionElement asFunctionElement() => null;
344 342
343 static bool isInvalid(Element e) => e == null || e.isErroneous();
345 Element cloneTo(Element enclosing, DiagnosticListener listener) { 344 Element cloneTo(Element enclosing, DiagnosticListener listener) {
346 listener.cancel("Unimplemented cloneTo", element: this); 345 listener.cancel("Unimplemented cloneTo", element: this);
347 } 346 }
348 } 347 }
349 348
350 /** 349 /**
351 * Represents an unresolvable or duplicated element. 350 * Represents an unresolvable or duplicated element.
352 * 351 *
353 * An [ErroneousElement] is used instead of [null] to provide additional 352 * An [ErroneousElement] is used instead of [null] to provide additional
354 * information about the error that caused the element to be unresolvable 353 * 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); 436 Element existing = localScope.putIfAbsent(element.name, () => element);
438 if (existing !== element) { 437 if (existing !== element) {
439 // TODO(ahe): Do something similar to Resolver.reportErrorWithContext. 438 // TODO(ahe): Do something similar to Resolver.reportErrorWithContext.
440 listener.cancel('duplicate definition', token: element.position()); 439 listener.cancel('duplicate definition', token: element.position());
441 listener.cancel('existing definition', token: existing.position()); 440 listener.cancel('existing definition', token: existing.position());
442 } 441 }
443 } 442 }
444 } 443 }
445 444
446 Element localLookup(SourceString elementName) { 445 Element localLookup(SourceString elementName) {
447 return localScope[elementName]; 446 Element result = localScope[elementName];
447 if (result == null && isPatch) {
448 result = origin.localScope[elementName];
449 }
450 return result;
448 } 451 }
449 452
450 /** 453 /**
451 * Adds a definition for an [accessor] (getter or setter) to a container. 454 * 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 455 * The definition binds to an abstract field that can hold both a getter
453 * and a setter. 456 * and a setter.
454 * 457 *
455 * The abstract field is added once, for the first getter or setter, and 458 * The abstract field is added once, for the first getter or setter, and
456 * reused if the other one is also added. 459 * reused if the other one is also added.
457 * The abstract field should not be treated as a proper member of the 460 * The abstract field should not be treated as a proper member of the
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 super(new SourceString(script.name), 513 super(new SourceString(script.name),
511 ElementKind.COMPILATION_UNIT, 514 ElementKind.COMPILATION_UNIT,
512 library) { 515 library) {
513 library.addCompilationUnit(this); 516 library.addCompilationUnit(this);
514 } 517 }
515 518
516 void addMember(Element element, DiagnosticListener listener) { 519 void addMember(Element element, DiagnosticListener listener) {
517 // Keep a list of top level members. 520 // Keep a list of top level members.
518 super.addMember(element, listener); 521 super.addMember(element, listener);
519 // Provide the member to the library to build scope. 522 // Provide the member to the library to build scope.
520 getLibrary().addMember(element, listener); 523 if (enclosingElement.isPatch) {
524 getImplementationLibrary().addMember(element, listener);
525 } else {
526 getLibrary().addMember(element, listener);
527 }
521 } 528 }
522 } 529 }
523 530
524 class CompilationUnitOverrideElement extends Element { 531 class CompilationUnitOverrideElement extends Element {
525 final CompilationUnitElement compilationUnit; 532 final CompilationUnitElement compilationUnit;
526 533
527 CompilationUnitOverrideElement(CompilationUnitElement compilationUnit, 534 CompilationUnitOverrideElement(CompilationUnitElement compilationUnit,
528 Element enclosing) 535 Element enclosing)
529 : this.compilationUnit = compilationUnit, 536 : this.compilationUnit = compilationUnit,
530 super(compilationUnit.name, 537 super(compilationUnit.name,
531 ElementKind.COMPILATION_UNIT_OVERRIDE, 538 ElementKind.COMPILATION_UNIT_OVERRIDE,
532 enclosing); 539 enclosing);
533 } 540 }
534 541
535 class LibraryElement extends ScopeContainerElement { 542 class LibraryElement extends ScopeContainerElement {
536 final Uri uri; 543 final Uri uri;
537 CompilationUnitElement entryCompilationUnit; 544 CompilationUnitElement entryCompilationUnit;
538 Link<CompilationUnitElement> compilationUnits = 545 Link<CompilationUnitElement> compilationUnits =
539 const EmptyLink<CompilationUnitElement>(); 546 const EmptyLink<CompilationUnitElement>();
540 Link<LibraryTag> tags = const EmptyLink<LibraryTag>(); 547 Link<LibraryTag> tags = const EmptyLink<LibraryTag>();
541 LibraryTag libraryTag; 548 LibraryTag libraryTag;
542 bool canUseNative = false; 549 bool canUseNative = false;
550
551 /**
552 * If this library is patched, [patch] points to the patch library.
553 *
554 * See [:patch_parser.dart:] for a description of the terminology.
555 */
543 LibraryElement patch = null; 556 LibraryElement patch = null;
544 557
545 /** 558 /**
559 * If this is a patch library, [origin] points to the origin library.
560 *
561 * See [:patch_parser.dart:] for a description of the terminology.
562 */
563 final LibraryElement origin;
564
565 /**
546 * Map for elements imported through import declarations. 566 * Map for elements imported through import declarations.
547 * 567 *
548 * Addition to the map is performed by [addImport]. Lookup is done trough 568 * Addition to the map is performed by [addImport]. Lookup is done trough
549 * [find]. 569 * [find].
550 */ 570 */
551 final Map<SourceString, Element> importScope; 571 final Map<SourceString, Element> importScope;
552 572
553 LibraryElement(Script script, [Uri uri]) 573 LibraryElement(Script script, [Uri uri, LibraryElement this.origin])
554 : this.uri = ((uri === null) ? script.uri : uri), 574 : this.uri = ((uri === null) ? script.uri : uri),
555 importScope = new Map<SourceString, Element>(), 575 importScope = new Map<SourceString, Element>(),
556 super(new SourceString(script.name), ElementKind.LIBRARY, null) { 576 super(new SourceString(script.name), ElementKind.LIBRARY, null) {
557 entryCompilationUnit = new CompilationUnitElement(script, this); 577 entryCompilationUnit = new CompilationUnitElement(script, this);
578 if (isPatch) {
579 origin.patch = this;
580 }
558 } 581 }
559 582
583 bool get isPatched => patch !== null;
584 bool get isPatch => origin !== null;
560 585
561 bool get isPatched => patch !== null; 586 LibraryElement get declaration => super.declaration;
587 LibraryElement get implementation => super.implementation;
562 588
563 void addCompilationUnit(CompilationUnitElement element) { 589 void addCompilationUnit(CompilationUnitElement element) {
564 compilationUnits = compilationUnits.prepend(element); 590 compilationUnits = compilationUnits.prepend(element);
565 } 591 }
566 592
567 void addTag(LibraryTag tag, DiagnosticListener listener) { 593 void addTag(LibraryTag tag, DiagnosticListener listener) {
568 tags = tags.prepend(tag); 594 tags = tags.prepend(tag);
569 } 595 }
570 596
571 /** 597 /**
572 * Adds [element] to the import scope of this library. 598 * Adds [element] to the import scope of this library.
573 * 599 *
574 * If an element by the same name is already in the imported scope, an 600 * If an element by the same name is already in the imported scope, an
575 * [ErroneousElement] will be put in the imported scope, allowing for the 601 * [ErroneousElement] will be put in the imported scope, allowing for the
576 * detection of ambiguous uses of imported names. 602 * detection of ambiguous uses of imported names.
577 */ 603 */
578 void addImport(Element element, DiagnosticListener listener) { 604 void addImport(Element element, DiagnosticListener listener) {
579 Element existing = importScope.putIfAbsent(element.name, () => element); 605 Element existing = importScope.putIfAbsent(element.name, () => element);
580 if (existing !== element && existing !== null) { 606 if (existing !== element && existing !== null) {
581 if (!existing.isErroneous()) { 607 if (!existing.isErroneous()) {
582 // TODO(johnniwinther): Provide access to both the new and existing 608 // TODO(johnniwinther): Provide access to both the new and existing
583 // elements. 609 // elements.
584 importScope[element.name] = new ErroneousElement( 610 importScope[element.name] = new ErroneousElement(
585 MessageKind.DUPLICATE_IMPORT, 611 MessageKind.DUPLICATE_IMPORT,
586 [element.name], element.name, this); 612 [element.name], element.name, this);
587 } 613 }
588 } 614 }
589 } 615 }
590 616
617 LibraryElement getLibrary() => isPatch ? origin : this;
591 618
592 /** 619 /**
593 * Look up a top-level element in this library. The element could 620 * Look up a top-level element in this library. The element could
594 * potentially have been imported from another library. Returns 621 * potentially have been imported from another library. Returns
595 * null if no such element exist and an [ErroneousElement] if multiple 622 * null if no such element exist and an [ErroneousElement] if multiple
596 * elements have been imported. 623 * elements have been imported.
597 */ 624 */
598 Element find(SourceString elementName) { 625 Element find(SourceString elementName) {
599 Element result = localScope[elementName]; 626 Element result = localScope[elementName];
600 if (result === null) { 627 if (result === null) {
601 result = importScope[elementName]; 628 result = importScope[elementName];
602 } 629 }
603 return result; 630 return result;
604 } 631 }
605 632
606 /** Look up a top-level element in this library, but only look for 633 /** Look up a top-level element in this library, but only look for
607 * non-imported elements. Returns null if no such element exist. */ 634 * non-imported elements. Returns null if no such element exist. */
608 Element findLocal(SourceString elementName) { 635 Element findLocal(SourceString elementName) {
636 // TODO(johnniwinther): How to handle injected elements in the patch
637 // library?
609 Element result = localScope[elementName]; 638 Element result = localScope[elementName];
610 if (result === null || result.getLibrary() != this) return null; 639 if (result === null || result.getLibrary() != this) return null;
611 return result; 640 return result;
612 } 641 }
613 642
614 void forEachExport(f(Element element)) { 643 void forEachExport(f(Element element)) {
615 localScope.forEach((_, Element e) { 644 localScope.forEach((_, Element e) {
616 if (this === e.getLibrary() 645 if (this === e.getLibrary()
617 && e.kind !== ElementKind.PREFIX 646 && e.kind !== ElementKind.PREFIX
618 && e.kind !== ElementKind.FOREIGN 647 && e.kind !== ElementKind.FOREIGN
619 && !e.name.isPrivate()) { 648 && !e.name.isPrivate()) {
620 f(e); 649 f(e);
621 } 650 }
622 }); 651 });
623 } 652 }
624 653
654 void forEachLocalMember(f(Element element)) {
655 if (isPatch) {
656 // Patch libraries traverse both origin and injected members.
657 origin.localMembers.forEach(f);
658
659 void filterPatch(Element element) {
660 if (!element.isPatch) {
661 // Do not traverse the patch members.
662 f(element);
663 }
664 }
665 localMembers.forEach(filterPatch);
666 } else {
667 localMembers.forEach(f);
668 }
669 }
670
625 bool hasLibraryName() => libraryTag !== null; 671 bool hasLibraryName() => libraryTag !== null;
626 672
627 /** 673 /**
628 * Returns the library name (as defined by the #library tag) or for script 674 * Returns the library name (as defined by the #library tag) or for script
629 * (which have no #library tag) the script file name. The latter case is used 675 * (which have no #library tag) the script file name. The latter case is used
630 * to private 'library name' for scripts to use for instance in dartdoc. 676 * to private 'library name' for scripts to use for instance in dartdoc.
631 */ 677 */
632 String getLibraryOrScriptName() { 678 String getLibraryOrScriptName() {
633 if (libraryTag !== null) { 679 if (libraryTag !== null) {
634 return libraryTag.argument.dartString.slowToString(); 680 return libraryTag.argument.dartString.slowToString();
635 } else { 681 } else {
636 // Use the file name as script name. 682 // Use the file name as script name.
637 String path = uri.path; 683 String path = uri.path;
638 return path.substring(path.lastIndexOf('/') + 1); 684 return path.substring(path.lastIndexOf('/') + 1);
639 } 685 }
640 } 686 }
641 687
642 Scope buildEnclosingScope() => new TopScope(this); 688 // TODO(johnniwinther): Rewrite to avoid the optional argument.
689 Scope buildEnclosingScope({bool patchScope: false}) {
690 if (origin !== null) {
691 return new PatchLibraryScope(origin, this);
692 } if (patchScope && patch !== null) {
693 return new PatchLibraryScope(this, patch);
694 } else {
695 return new TopScope(this);
696 }
697 }
643 698
644 bool get isPlatformLibrary => uri.scheme == "dart"; 699 bool get isPlatformLibrary => uri.scheme == "dart";
700
701 String toString() {
702 if (origin !== null) {
703 return 'patch library(${getLibraryOrScriptName()})';
704 } else if (patch !== null) {
705 return 'origin library(${getLibraryOrScriptName()})';
706 } else {
707 return 'library(${getLibraryOrScriptName()})';
708 }
709 }
645 } 710 }
646 711
647 class PrefixElement extends Element { 712 class PrefixElement extends Element {
648 Map<SourceString, Element> imported; 713 Map<SourceString, Element> imported;
649 Token firstPosition; 714 Token firstPosition;
650 715
651 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition) 716 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition)
652 : imported = new Map<SourceString, Element>(), 717 : imported = new Map<SourceString, Element>(),
653 super(prefix, ElementKind.PREFIX, enclosing); 718 super(prefix, ElementKind.PREFIX, enclosing);
654 719
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 Typedef node = parseNode(compiler); 754 Typedef node = parseNode(compiler);
690 Link<DartType> parameters = 755 Link<DartType> parameters =
691 TypeDeclarationElement.createTypeVariables(this, node.typeParameters); 756 TypeDeclarationElement.createTypeVariables(this, node.typeParameters);
692 cachedType = new TypedefType(this, parameters); 757 cachedType = new TypedefType(this, parameters);
693 compiler.resolveTypedef(this); 758 compiler.resolveTypedef(this);
694 return cachedType; 759 return cachedType;
695 } 760 }
696 761
697 Link<DartType> get typeVariables => cachedType.typeArguments; 762 Link<DartType> get typeVariables => cachedType.typeArguments;
698 763
699 Scope buildScope() => 764 // TODO(johnniwinther): Rewrite to avoid the optional argument.
700 new TypeDeclarationScope(enclosingElement.buildScope(), this); 765 Scope buildScope({bool patchScope: false}) {
766 return new TypeDeclarationScope(
767 enclosingElement.buildScope(patchScope: patchScope), this);
768 }
701 769
702 TypedefElement cloneTo(Element enclosing, DiagnosticListener listener) { 770 TypedefElement cloneTo(Element enclosing, DiagnosticListener listener) {
703 TypedefElement result = new TypedefElement(name, enclosing); 771 TypedefElement result = new TypedefElement(name, enclosing);
704 return result; 772 return result;
705 } 773 }
706 } 774 }
707 775
708 class VariableElement extends Element { 776 class VariableElement extends Element {
709 final VariableListElement variables; 777 final VariableListElement variables;
710 Expression cachedNode; // The send or the identifier in the variables list. 778 Expression cachedNode; // The send or the identifier in the variables list.
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 } else { 919 } else {
852 result = new VariableListElement(kind, modifiers, enclosing); 920 result = new VariableListElement(kind, modifiers, enclosing);
853 } 921 }
854 return result; 922 return result;
855 } 923 }
856 924
857 bool isInstanceMember() { 925 bool isInstanceMember() {
858 return isMember() && !modifiers.isStatic(); 926 return isMember() && !modifiers.isStatic();
859 } 927 }
860 928
861 Scope buildScope() { 929 // TODO(johnniwinther): Rewrite to avoid the optional argument.
862 Scope result = new VariableScope(enclosingElement.buildScope(), this); 930 Scope buildScope({bool patchScope: false}) {
931 Scope result = new VariableScope(
932 enclosingElement.buildScope(patchScope: patchScope), this);
863 if (enclosingElement.isClass()) { 933 if (enclosingElement.isClass()) {
864 ClassScope clsScope = result.parent; 934 Scope clsScope = result.parent;
865 clsScope.inStaticContext = !isInstanceMember(); 935 clsScope.inStaticContext = !isInstanceMember();
866 } 936 }
867 return result; 937 return result;
868 } 938 }
869 } 939 }
870 940
871 class ForeignElement extends Element { 941 class ForeignElement extends Element {
872 ForeignElement(SourceString name, ContainerElement enclosingElement) 942 ForeignElement(SourceString name, ContainerElement enclosingElement)
873 : super(name, ElementKind.FOREIGN, enclosingElement); 943 : super(name, ElementKind.FOREIGN, enclosingElement);
874 944
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 1075
1006 FunctionSignature functionSignature; 1076 FunctionSignature functionSignature;
1007 1077
1008 /** 1078 /**
1009 * A function declaration that should be parsed instead of the current one. 1079 * A function declaration that should be parsed instead of the current one.
1010 * The patch should be parsed as if it was in the current scope. Its 1080 * The patch should be parsed as if it was in the current scope. Its
1011 * signature must match this function's signature. 1081 * signature must match this function's signature.
1012 */ 1082 */
1013 // TODO(lrn): Consider using [defaultImplementation] to store the patch. 1083 // TODO(lrn): Consider using [defaultImplementation] to store the patch.
1014 FunctionElement patch = null; 1084 FunctionElement patch = null;
1085 FunctionElement origin = null;
1015 1086
1016 /** 1087 /**
1017 * If this is an interface constructor, [defaultImplementation] will 1088 * If this is an interface constructor, [defaultImplementation] will
1018 * changed by the resolver to point to the default 1089 * changed by the resolver to point to the default
1019 * implementation. Otherwise, [:defaultImplementation === this:]. 1090 * implementation. Otherwise, [:defaultImplementation === this:].
1020 */ 1091 */
1021 FunctionElement defaultImplementation; 1092 FunctionElement defaultImplementation;
1022 1093
1023 FunctionElement(SourceString name, 1094 FunctionElement(SourceString name,
1024 ElementKind kind, 1095 ElementKind kind,
(...skipping 20 matching lines...) Expand all
1045 ElementKind kind, 1116 ElementKind kind,
1046 Modifiers this.modifiers, 1117 Modifiers this.modifiers,
1047 Element enclosing, 1118 Element enclosing,
1048 FunctionSignature this.functionSignature) 1119 FunctionSignature this.functionSignature)
1049 : super(name, kind, enclosing) { 1120 : super(name, kind, enclosing) {
1050 assert(modifiers !== null); 1121 assert(modifiers !== null);
1051 defaultImplementation = this; 1122 defaultImplementation = this;
1052 } 1123 }
1053 1124
1054 bool get isPatched => patch !== null; 1125 bool get isPatched => patch !== null;
1126 bool get isPatch => origin !== null;
1055 1127
1056 /** 1128 /**
1057 * Applies a patch function to this function. The patch function's body 1129 * Applies a patch function to this function. The patch function's body
1058 * is used as replacement when parsing this function's body. 1130 * is used as replacement when parsing this function's body.
1059 * This method must not be called after the function has been parsed, 1131 * This method must not be called after the function has been parsed,
1060 * and it must be called at most once. 1132 * and it must be called at most once.
1061 */ 1133 */
1062 void setPatch(FunctionElement patchElement) { 1134 void setPatch(FunctionElement patchElement) {
1063 // Sanity checks. The caller must check these things before calling. 1135 // Sanity checks. The caller must check these things before calling.
1064 assert(patch === null); 1136 assert(patch === null);
1065 assert(cachedNode === null);
1066 this.patch = patchElement; 1137 this.patch = patchElement;
1067 cachedNode = patchElement.cachedNode;
1068 } 1138 }
1069 1139
1070 bool isInstanceMember() { 1140 bool isInstanceMember() {
1071 return isMember() 1141 return isMember()
1072 && !isConstructor() 1142 && !isConstructor()
1073 && !modifiers.isStatic(); 1143 && !modifiers.isStatic();
1074 } 1144 }
1075 1145
1076 FunctionSignature computeSignature(Compiler compiler) { 1146 FunctionSignature computeSignature(Compiler compiler) {
1077 if (functionSignature !== null) return functionSignature; 1147 if (functionSignature !== null) return functionSignature;
(...skipping 16 matching lines...) Expand all
1094 } 1164 }
1095 1165
1096 FunctionType computeType(Compiler compiler) { 1166 FunctionType computeType(Compiler compiler) {
1097 if (type != null) return type; 1167 if (type != null) return type;
1098 type = compiler.computeFunctionType(declaration, 1168 type = compiler.computeFunctionType(declaration,
1099 computeSignature(compiler)); 1169 computeSignature(compiler));
1100 return type; 1170 return type;
1101 } 1171 }
1102 1172
1103 Node parseNode(DiagnosticListener listener) { 1173 Node parseNode(DiagnosticListener listener) {
1104 if (cachedNode !== null) return cachedNode;
1105 if (patch === null) { 1174 if (patch === null) {
1106 if (modifiers.isExternal()) { 1175 if (modifiers.isExternal()) {
1107 listener.cancel("Compiling external function with no implementation.", 1176 listener.cancel("Compiling external function with no implementation.",
1108 element: this); 1177 element: this);
1109 } 1178 }
1110 return null;
1111 } 1179 }
1112 cachedNode = patch.parseNode(listener);
1113 return cachedNode; 1180 return cachedNode;
1114 } 1181 }
1115 1182
1116 Token position() => cachedNode.getBeginToken(); 1183 Token position() => cachedNode.getBeginToken();
1117 1184
1118 FunctionElement asFunctionElement() => this; 1185 FunctionElement asFunctionElement() => this;
1119 1186
1120 String toString() { 1187 String toString() {
1121 if (isPatch) { 1188 if (isPatch) {
1122 return 'patch ${super.toString()}'; 1189 return 'patch ${super.toString()}';
1123 } else if (isPatched) { 1190 } else if (isPatched) {
1124 return 'origin ${super.toString()}'; 1191 return 'origin ${super.toString()}';
1125 } else { 1192 } else {
1126 return super.toString(); 1193 return super.toString();
1127 } 1194 }
1128 } 1195 }
1129 1196
1130 Scope buildScope() { 1197 // TODO(johnniwinther): Rewrite to avoid the optional argument.
1131 Scope result = 1198 Scope buildScope({bool patchScope: false}) {
1132 new MethodScope(enclosingElement.buildScope(), this); 1199 Scope result = new MethodScope(
1200 enclosingElement.buildScope(patchScope: patchScope), this);
1133 if (enclosingElement.isClass()) { 1201 if (enclosingElement.isClass()) {
1134 ClassScope clsScope = result.parent; 1202 Scope clsScope = result.parent;
1135 clsScope.inStaticContext = !isInstanceMember() && !isConstructor(); 1203 clsScope.inStaticContext = !isInstanceMember() && !isConstructor();
1136 } 1204 }
1137 return result; 1205 return result;
1138 } 1206 }
1139 } 1207 }
1140 1208
1141 class ConstructorBodyElement extends FunctionElement { 1209 class ConstructorBodyElement extends FunctionElement {
1142 FunctionElement constructor; 1210 FunctionElement constructor;
1143 1211
1144 ConstructorBodyElement(FunctionElement constructor) 1212 ConstructorBodyElement(FunctionElement constructor)
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 int resolutionState; 1316 int resolutionState;
1249 1317
1250 // backendMembers are members that have been added by the backend to simplify 1318 // backendMembers are members that have been added by the backend to simplify
1251 // compilation. They don't have any user-side counter-part. 1319 // compilation. They don't have any user-side counter-part.
1252 Link<Element> backendMembers = const EmptyLink<Element>(); 1320 Link<Element> backendMembers = const EmptyLink<Element>();
1253 1321
1254 Link<DartType> allSupertypes; 1322 Link<DartType> allSupertypes;
1255 1323
1256 // Lazily applied patch of class members. 1324 // Lazily applied patch of class members.
1257 ClassElement patch = null; 1325 ClassElement patch = null;
1326 ClassElement origin = null;
1258 1327
1259 ClassElement(SourceString name, Element enclosing, this.id, int initialState) 1328 ClassElement(SourceString name, Element enclosing, this.id, int initialState)
1260 : supertypeLoadState = initialState, 1329 : supertypeLoadState = initialState,
1261 resolutionState = initialState, 1330 resolutionState = initialState,
1262 super(name, ElementKind.CLASS, enclosing); 1331 super(name, ElementKind.CLASS, enclosing);
1263 1332
1264 InterfaceType computeType(compiler) { 1333 InterfaceType computeType(compiler) {
1265 if (type == null) { 1334 if (type == null) {
1266 ClassNode node = parseNode(compiler); 1335 if (origin === null) {
1267 Link<DartType> parameters = 1336 ClassNode node = parseNode(compiler);
1268 TypeDeclarationElement.createTypeVariables(this, node.typeParameters); 1337 Link<DartType> parameters =
1269 type = new InterfaceType(this, parameters); 1338 TypeDeclarationElement.createTypeVariables(this,
1339 node.typeParameters);
1340 type = new InterfaceType(this, parameters);
1341 } else {
1342 type = origin.computeType(compiler);
1343 }
1270 } 1344 }
1271 return type; 1345 return type;
1272 } 1346 }
1273 1347
1274 bool get isPatched => patch != null; 1348 bool get isPatched => patch != null;
1349 bool get isPatch => origin != null;
1350
1351 ClassElement get declaration => super.declaration;
1352 ClassElement get implementation => super.implementation;
1275 1353
1276 /** 1354 /**
1277 * Return [:true:] if this element is the [:Object:] class for the [compiler]. 1355 * Return [:true:] if this element is the [:Object:] class for the [compiler].
1278 */ 1356 */
1279 bool isObject(Compiler compiler) => 1357 bool isObject(Compiler compiler) =>
1280 declaration === compiler.objectClass; 1358 declaration === compiler.objectClass;
1281 1359
1282 Link<DartType> get typeVariables => type.arguments; 1360 Link<DartType> get typeVariables => type.arguments;
1283 1361
1284 ClassElement ensureResolved(Compiler compiler) { 1362 ClassElement ensureResolved(Compiler compiler) {
(...skipping 18 matching lines...) Expand all
1303 Element lookupSuperMember(SourceString memberName) { 1381 Element lookupSuperMember(SourceString memberName) {
1304 return lookupSuperMemberInLibrary(memberName, getLibrary()); 1382 return lookupSuperMemberInLibrary(memberName, getLibrary());
1305 } 1383 }
1306 1384
1307 /** 1385 /**
1308 * Lookup super members for the class that is accessible in [library]. 1386 * Lookup super members for the class that is accessible in [library].
1309 * This will ignore constructors. 1387 * This will ignore constructors.
1310 */ 1388 */
1311 Element lookupSuperMemberInLibrary(SourceString memberName, 1389 Element lookupSuperMemberInLibrary(SourceString memberName,
1312 LibraryElement library) { 1390 LibraryElement library) {
1391 bool includeInjectedMembers = isPatch;
1313 bool isPrivate = memberName.isPrivate(); 1392 bool isPrivate = memberName.isPrivate();
1314 for (ClassElement s = superclass; s != null; s = s.superclass) { 1393 for (ClassElement s = superclass; s != null; s = s.superclass) {
1315 // Private members from a different library are not visible. 1394 // Private members from a different library are not visible.
1316 if (isPrivate && library !== s.getLibrary()) continue; 1395 if (isPrivate && library !== s.getLibrary()) continue;
1396 s = includeInjectedMembers ? s.implementation : s;
1317 Element e = s.lookupLocalMember(memberName); 1397 Element e = s.lookupLocalMember(memberName);
1318 if (e === null) continue; 1398 if (e === null) continue;
1319 // Static members are not inherited. 1399 // Static members are not inherited.
1320 if (e.modifiers.isStatic()) continue; 1400 if (e.modifiers.isStatic()) continue;
1321 return e; 1401 return e;
1322 } 1402 }
1323 if (isInterface()) { 1403 if (isInterface()) {
1324 return lookupSuperInterfaceMember(memberName, getLibrary()); 1404 return lookupSuperInterfaceMember(memberName, getLibrary());
1325 } 1405 }
1326 return null; 1406 return null;
1327 } 1407 }
1328 1408
1329 Element lookupSuperInterfaceMember(SourceString memberName, 1409 Element lookupSuperInterfaceMember(SourceString memberName,
1330 LibraryElement fromLibrary) { 1410 LibraryElement fromLibrary) {
1411 bool includeInjectedMembers = isPatch;
1331 bool isPrivate = memberName.isPrivate(); 1412 bool isPrivate = memberName.isPrivate();
1332 for (InterfaceType t in interfaces) { 1413 for (InterfaceType t in interfaces) {
1333 ClassElement cls = t.element; 1414 ClassElement cls = t.element;
1415 cls = includeInjectedMembers ? cls.implementation : cls;
1334 Element e = cls.lookupLocalMember(memberName); 1416 Element e = cls.lookupLocalMember(memberName);
1335 if (e === null) continue; 1417 if (e === null) continue;
1336 // Private members from a different library are not visible. 1418 // Private members from a different library are not visible.
1337 if (isPrivate && fromLibrary !== e.getLibrary()) continue; 1419 if (isPrivate && fromLibrary !== e.getLibrary()) continue;
1338 // Static members are not inherited. 1420 // Static members are not inherited.
1339 if (e.modifiers.isStatic()) continue; 1421 if (e.modifiers.isStatic()) continue;
1340 return e; 1422 return e;
1341 } 1423 }
1342 return null; 1424 return null;
1343 } 1425 }
1344 1426
1345 /** 1427 /**
1346 * Find the first member in the class chain with the given [selector]. 1428 * Find the first member in the class chain with the given [selector].
1347 * 1429 *
1348 * This method is NOT to be used for resolving 1430 * This method is NOT to be used for resolving
1349 * unqualified sends because it does not implement the scoping 1431 * unqualified sends because it does not implement the scoping
1350 * rules, where library scope comes before superclass scope. 1432 * rules, where library scope comes before superclass scope.
1433 *
1434 * When called on the implementation element both members declared in the
1435 * origin and the patch class are returned.
1351 */ 1436 */
1352 Element lookupSelector(Selector selector) { 1437 Element lookupSelector(Selector selector) {
1353 SourceString memberName = selector.name; 1438 SourceString memberName = selector.name;
1354 LibraryElement library = selector.library; 1439 LibraryElement library = selector.library;
1355 Element localMember = lookupLocalMember(memberName); 1440 Element localMember = lookupLocalMember(memberName);
1356 if (localMember != null && 1441 if (localMember != null &&
1357 (!memberName.isPrivate() || getLibrary() == library)) { 1442 (!memberName.isPrivate() || getLibrary() == library)) {
1358 return localMember; 1443 return localMember;
1359 } 1444 }
1360 return lookupSuperMemberInLibrary(memberName, library); 1445 return lookupSuperMemberInLibrary(memberName, library);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1423 // Search in scope to be sure we search patched constructors. 1508 // Search in scope to be sure we search patched constructors.
1424 for (var element in localScope.getValues()) { 1509 for (var element in localScope.getValues()) {
1425 if (element.isConstructor()) return true; 1510 if (element.isConstructor()) return true;
1426 } 1511 }
1427 return false; 1512 return false;
1428 } 1513 }
1429 1514
1430 Link<Element> get constructors { 1515 Link<Element> get constructors {
1431 // TODO(ajohnsen): See if we can avoid this method at some point. 1516 // TODO(ajohnsen): See if we can avoid this method at some point.
1432 Link<Element> result = const EmptyLink<Element>(); 1517 Link<Element> result = const EmptyLink<Element>();
1433 for (Element member in localMembers) { 1518 // TODO(johnniwinther): Should we include injected constructors?
1519 forEachMember((_, Element member) {
1434 if (member.isConstructor()) result = result.prepend(member); 1520 if (member.isConstructor()) result = result.prepend(member);
1435 } 1521 });
1436 return result; 1522 return result;
1437 } 1523 }
1438 1524
1439 /** 1525 /**
1440 * Returns the super class, if any. 1526 * Returns the super class, if any.
1441 * 1527 *
1442 * The returned element may not be resolved yet. 1528 * The returned element may not be resolved yet.
1443 */ 1529 */
1444 ClassElement get superclass { 1530 ClassElement get superclass {
1445 assert(supertypeLoadState == STATE_DONE); 1531 assert(supertypeLoadState == STATE_DONE);
1446 return supertype === null ? null : supertype.element; 1532 return supertype === null ? null : supertype.element;
1447 } 1533 }
1448 1534
1449 /** 1535 /**
1450 * Runs through all members of this class. 1536 * Runs through all members of this class.
1451 * 1537 *
1452 * The enclosing class is passed to the callback. This is useful when 1538 * The enclosing class is passed to the callback. This is useful when
1453 * [includeSuperMembers] is [:true:]. 1539 * [includeSuperMembers] is [:true:].
1540 *
1541 * When called on an implementation element both the members in the origin
1542 * and patch class are included.
1454 */ 1543 */
1544 // TODO(johnniwinther): Clean up lookup to get rid of the include predicates.
1455 void forEachMember([void f(ClassElement enclosingClass, Element member), 1545 void forEachMember([void f(ClassElement enclosingClass, Element member),
1456 includeBackendMembers = false, 1546 includeBackendMembers = false,
1457 includeSuperMembers = false]) { 1547 includeSuperMembers = false]) {
1548 bool includeInjectedMembers = isPatch;
1458 Set<ClassElement> seen = new Set<ClassElement>(); 1549 Set<ClassElement> seen = new Set<ClassElement>();
1459 ClassElement classElement = this; 1550 ClassElement classElement = declaration;
1460 do { 1551 do {
1461 if (seen.contains(classElement)) return; 1552 if (seen.contains(classElement)) return;
1462 seen.add(classElement); 1553 seen.add(classElement);
1463 1554
1464 // Iterate through the members in textual order, which requires 1555 // Iterate through the members in textual order, which requires
1465 // to reverse the data structure [localMembers] we created. 1556 // to reverse the data structure [localMembers] we created.
1466 // Textual order may be important for certain operations, for 1557 // Textual order may be important for certain operations, for
1467 // example when emitting the initializers of fields. 1558 // example when emitting the initializers of fields.
1468 for (Element element in classElement.localMembers.reverse()) { 1559 for (Element element in classElement.localMembers.reverse()) {
1469 f(classElement, element); 1560 f(classElement, element);
1470 } 1561 }
1471 if (includeBackendMembers) { 1562 if (includeBackendMembers) {
1472 for (Element element in classElement.backendMembers) { 1563 for (Element element in classElement.backendMembers) {
1473 f(classElement, element); 1564 f(classElement, element);
1474 } 1565 }
1475 } 1566 }
1567 if (includeInjectedMembers) {
1568 if (classElement.patch != null) {
1569 for (Element element in classElement.patch.localMembers.reverse()) {
1570 if (!element.isPatch) {
1571 f(classElement, element);
1572 }
1573 }
1574 }
1575 }
1476 classElement = includeSuperMembers ? classElement.superclass : null; 1576 classElement = includeSuperMembers ? classElement.superclass : null;
1477 } while(classElement !== null); 1577 } while(classElement !== null);
1478 } 1578 }
1479 1579
1480 /** 1580 /**
1481 * Runs through all instance-field members of this class. 1581 * Runs through all instance-field members of this class.
1482 * 1582 *
1483 * The enclosing class is passed to the callback. This is useful when 1583 * The enclosing class is passed to the callback. This is useful when
1484 * [includeSuperMembers] is [:true:]. 1584 * [includeSuperMembers] is [:true:].
1485 * 1585 *
1486 * When [includeBackendMembers] and [includeSuperMembers] are both [:true:] 1586 * When [includeBackendMembers] and [includeSuperMembers] are both [:true:]
1487 * then the fields are visited in the same order as they need to be given 1587 * then the fields are visited in the same order as they need to be given
1488 * to the JavaScript constructor. 1588 * to the JavaScript constructor.
1589 *
1590 * When called on the implementation element both the fields declared in the
1591 * origin and in the patch are included.
1489 */ 1592 */
1490 void forEachInstanceField([void f(ClassElement enclosingClass, Element field), 1593 void forEachInstanceField([void f(ClassElement enclosingClass, Element field),
1491 includeBackendMembers = false, 1594 includeBackendMembers = false,
1492 includeSuperMembers = false]) { 1595 includeSuperMembers = false]) {
1493 // Filters so that [f] is only invoked with instance fields. 1596 // Filters so that [f] is only invoked with instance fields.
1494 void fieldFilter(ClassElement enclosingClass, Element member) { 1597 void fieldFilter(ClassElement enclosingClass, Element member) {
1495 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) { 1598 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) {
1496 f(enclosingClass, member); 1599 f(enclosingClass, member);
1497 } 1600 }
1498 } 1601 }
(...skipping 22 matching lines...) Expand all
1521 for (ClassElement s = this; s != null; s = s.superclass) { 1624 for (ClassElement s = this; s != null; s = s.superclass) {
1522 if (s === cls) return true; 1625 if (s === cls) return true;
1523 } 1626 }
1524 return false; 1627 return false;
1525 } 1628 }
1526 1629
1527 bool isInterface() => false; 1630 bool isInterface() => false;
1528 bool isNative() => nativeName != null; 1631 bool isNative() => nativeName != null;
1529 int hashCode() => id; 1632 int hashCode() => id;
1530 1633
1531 Scope buildScope() => 1634 // TODO(johnniwinther): Rewrite to avoid the optional argument.
1532 new ClassScope(enclosingElement.buildScope(), this); 1635 Scope buildScope({bool patchScope: false}) {
1636 if (origin !== null) {
1637 return new PatchClassScope(
1638 enclosingElement.buildScope(patchScope: patchScope), origin, this);
1639 } else if (patchScope && patch !== null) {
1640 return new PatchClassScope(
1641 enclosingElement.buildScope(patchScope: patchScope), this, patch);
1642 } else {
1643 return new ClassScope(
1644 enclosingElement.buildScope(patchScope: patchScope), this);
1645 }
1646 }
1647
1648 Scope buildLocalScope() {
1649 if (origin !== null) {
1650 return new LocalPatchClassScope(origin, this);
1651 } else {
1652 return new LocalClassScope(this);
1653 }
1654 }
1533 1655
1534 ClassElement cloneTo(Element enclosing, DiagnosticListener listener) { 1656 ClassElement cloneTo(Element enclosing, DiagnosticListener listener) {
1535 listener.internalErrorOnElement(this, 'unsupported operation'); 1657 listener.internalErrorOnElement(this, 'unsupported operation');
1536 } 1658 }
1537 1659
1538 Link<DartType> get allSupertypesAndSelf { 1660 Link<DartType> get allSupertypesAndSelf {
1539 return allSupertypes.prepend(new InterfaceType(this)); 1661 return allSupertypes.prepend(new InterfaceType(this));
1540 } 1662 }
1663
1664 String toString() {
1665 if (origin !== null) {
1666 return 'patch ${super.toString()}';
1667 } else if (patch !== null) {
1668 return 'origin ${super.toString()}';
1669 } else {
1670 return super.toString();
1671 }
1672 }
1541 } 1673 }
1542 1674
1543 class Elements { 1675 class Elements {
1544 static bool isUnresolved(Element e) => e == null || e.isErroneous(); 1676 static bool isUnresolved(Element e) => e == null || e.isErroneous();
1545 static bool isErroneousElement(Element e) => e != null && e.isErroneous(); 1677 static bool isErroneousElement(Element e) => e != null && e.isErroneous();
1546 1678
1547 static bool isLocal(Element element) { 1679 static bool isLocal(Element element) {
1548 return !Elements.isUnresolved(element) 1680 return !Elements.isUnresolved(element)
1549 && !element.isInstanceMember() 1681 && !element.isInstanceMember()
1550 && !isStaticOrTopLevelField(element) 1682 && !isStaticOrTopLevelField(element)
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
1832 1964
1833 MetadataAnnotation ensureResolved(Compiler compiler) { 1965 MetadataAnnotation ensureResolved(Compiler compiler) {
1834 if (resolutionState == STATE_NOT_STARTED) { 1966 if (resolutionState == STATE_NOT_STARTED) {
1835 compiler.resolver.resolveMetadataAnnotation(this); 1967 compiler.resolver.resolveMetadataAnnotation(this);
1836 } 1968 }
1837 return this; 1969 return this;
1838 } 1970 }
1839 1971
1840 String toString() => 'MetadataAnnotation($value, $resolutionState)'; 1972 String toString() => 'MetadataAnnotation($value, $resolutionState)';
1841 } 1973 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698