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

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

Issue 10831262: Revert "Revert "Allow patch files to add top-level declarations to the patched library."" (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixed bugs Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/compiler/implementation/compiler.dart ('k') | lib/compiler/implementation/lib/math.dartp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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('../tree/tree.dart'); 7 #import('../tree/tree.dart');
8 #import('../scanner/scannerlib.dart'); 8 #import('../scanner/scannerlib.dart');
9 #import('../leg.dart'); // TODO(karlklose): we only need type. 9 #import('../leg.dart'); // TODO(karlklose): we only need type.
10 #import('../util/util.dart'); 10 #import('../util/util.dart');
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 static final ElementKind GETTER = 76 static final ElementKind GETTER =
77 const ElementKind('getter', ElementCategory.NONE); 77 const ElementKind('getter', ElementCategory.NONE);
78 static final ElementKind SETTER = 78 static final ElementKind SETTER =
79 const ElementKind('setter', ElementCategory.NONE); 79 const ElementKind('setter', ElementCategory.NONE);
80 static final ElementKind TYPE_VARIABLE = 80 static final ElementKind TYPE_VARIABLE =
81 const ElementKind('type_variable', ElementCategory.TYPE_VARIABLE); 81 const ElementKind('type_variable', ElementCategory.TYPE_VARIABLE);
82 static final ElementKind ABSTRACT_FIELD = 82 static final ElementKind ABSTRACT_FIELD =
83 const ElementKind('abstract_field', ElementCategory.VARIABLE); 83 const ElementKind('abstract_field', ElementCategory.VARIABLE);
84 static final ElementKind LIBRARY = 84 static final ElementKind LIBRARY =
85 const ElementKind('library', ElementCategory.NONE); 85 const ElementKind('library', ElementCategory.NONE);
86 static final ElementKind COMPILATION_UNIT_OVERRIDE =
87 const ElementKind('compilation_unit_override', ElementCategory.NONE);
86 static final ElementKind PREFIX = 88 static final ElementKind PREFIX =
87 const ElementKind('prefix', ElementCategory.PREFIX); 89 const ElementKind('prefix', ElementCategory.PREFIX);
88 static final ElementKind TYPEDEF = 90 static final ElementKind TYPEDEF =
89 const ElementKind('typedef', ElementCategory.ALIAS); 91 const ElementKind('typedef', ElementCategory.ALIAS);
90 92
91 static final ElementKind STATEMENT = 93 static final ElementKind STATEMENT =
92 const ElementKind('statement', ElementCategory.NONE); 94 const ElementKind('statement', ElementCategory.NONE);
93 static final ElementKind LABEL = 95 static final ElementKind LABEL =
94 const ElementKind('label', ElementCategory.NONE); 96 const ElementKind('label', ElementCategory.NONE);
95 static final ElementKind VOID = 97 static final ElementKind VOID =
96 const ElementKind('void', ElementCategory.NONE); 98 const ElementKind('void', ElementCategory.NONE);
97 99
98 toString() => id; 100 toString() => id;
99 } 101 }
100 102
101 class Element implements Hashable { 103 class Element implements Hashable {
102 final SourceString name; 104 final SourceString name;
103 final ElementKind kind; 105 final ElementKind kind;
104 final Element enclosingElement; 106 final Element enclosingElement;
105 Link<Node> metadata = const EmptyLink<Node>(); 107 Link<Node> metadata = const EmptyLink<Node>();
108
109
110 Element(this.name, this.kind, this.enclosingElement) {
111 assert(getLibrary() !== null);
112 }
113
106 Modifiers get modifiers() => null; 114 Modifiers get modifiers() => null;
107 115
108 Node parseNode(DiagnosticListener listener) { 116 Node parseNode(DiagnosticListener listener) {
109 listener.cancel("Internal Error: $this.parseNode", token: position()); 117 listener.cancel("Internal Error: $this.parseNode", token: position());
110 } 118 }
111 119
112 Type computeType(Compiler compiler) { 120 Type computeType(Compiler compiler) {
113 compiler.internalError("$this.computeType.", token: position()); 121 compiler.internalError("$this.computeType.", token: position());
114 } 122 }
115 123
116 void addMetadata(Node node) { 124 void addMetadata(Node node) {
117 metadata = metadata.prepend(node); 125 metadata = metadata.prepend(node);
118 } 126 }
119 127
120 bool isFunction() => kind === ElementKind.FUNCTION; 128 bool isFunction() => kind === ElementKind.FUNCTION;
121 bool isConstructor() => isFactoryConstructor() || isGenerativeConstructor(); 129 bool isConstructor() => isFactoryConstructor() || isGenerativeConstructor();
122 bool isClosure() => false; 130 bool isClosure() => false;
123 bool isMember() { 131 bool isMember() {
124 // Check that this element is defined in the scope of a Class. 132 // Check that this element is defined in the scope of a Class.
125 Element enclosing = enclosingElement; 133 Element enclosing = enclosingElement;
134 if (enclosing !== null &&
135 enclosing.kind === ElementKind.COMPILATION_UNIT_OVERRIDE) {
136 enclosing = enclosing.enclosingElement;
137 }
126 // TODO(lrn): Skip any synthetic elements inserted, e.g., 138 // TODO(lrn): Skip any synthetic elements inserted, e.g.,
127 // a compilation unit override. 139 // a compilation unit override.
128 return enclosing !== null && enclosing.isClass(); 140 return enclosing !== null && enclosing.isClass();
129 } 141 }
130 bool isInstanceMember() => false; 142 bool isInstanceMember() => false;
131 bool isFactoryConstructor() => modifiers !== null && modifiers.isFactory(); 143 bool isFactoryConstructor() => modifiers !== null && modifiers.isFactory();
132 bool isGenerativeConstructor() => kind === ElementKind.GENERATIVE_CONSTRUCTOR; 144 bool isGenerativeConstructor() => kind === ElementKind.GENERATIVE_CONSTRUCTOR;
133 bool isGenerativeConstructorBody() => 145 bool isGenerativeConstructorBody() =>
134 kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY; 146 kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY;
135 bool isCompilationUnit() { 147 bool isCompilationUnit() {
136 return kind === ElementKind.COMPILATION_UNIT || 148 return kind === ElementKind.COMPILATION_UNIT ||
137 kind === ElementKind.LIBRARY; 149 kind === ElementKind.LIBRARY ||
150 kind === ElementKind.COMPILATION_UNIT_OVERRIDE;
138 } 151 }
152 /**
153 * Provides the compilation unit corresponding to this element.
154 * Returns non-null for elements where [isCompilationUnit] returns true,
155 * but may not return the current [Element].
156 */
157 CompilationUnitElement asCompilationUnit() => null;
139 bool isClass() => kind === ElementKind.CLASS; 158 bool isClass() => kind === ElementKind.CLASS;
140 bool isPrefix() => kind === ElementKind.PREFIX; 159 bool isPrefix() => kind === ElementKind.PREFIX;
141 bool isVariable() => kind === ElementKind.VARIABLE; 160 bool isVariable() => kind === ElementKind.VARIABLE;
142 bool isParameter() => kind === ElementKind.PARAMETER; 161 bool isParameter() => kind === ElementKind.PARAMETER;
143 bool isStatement() => kind === ElementKind.STATEMENT; 162 bool isStatement() => kind === ElementKind.STATEMENT;
144 bool isTypedef() => kind === ElementKind.TYPEDEF; 163 bool isTypedef() => kind === ElementKind.TYPEDEF;
145 bool isTypeVariable() => kind === ElementKind.TYPE_VARIABLE; 164 bool isTypeVariable() => kind === ElementKind.TYPE_VARIABLE;
146 bool isField() => kind === ElementKind.FIELD; 165 bool isField() => kind === ElementKind.FIELD;
147 bool isGetter() => kind === ElementKind.GETTER; 166 bool isGetter() => kind === ElementKind.GETTER;
148 bool isSetter() => kind === ElementKind.SETTER; 167 bool isSetter() => kind === ElementKind.SETTER;
(...skipping 17 matching lines...) Expand all
166 185
167 Token position() => null; 186 Token position() => null;
168 187
169 Token findMyName(Token token) { 188 Token findMyName(Token token) {
170 for (Token t = token; t.kind !== EOF_TOKEN; t = t.next) { 189 for (Token t = token; t.kind !== EOF_TOKEN; t = t.next) {
171 if (t.value == name) return t; 190 if (t.value == name) return t;
172 } 191 }
173 return token; 192 return token;
174 } 193 }
175 194
176 Element(this.name, this.kind, this.enclosingElement) {
177 assert(getLibrary() !== null);
178 }
179
180 // TODO(kasperl): This is a very bad hash code for the element and 195 // TODO(kasperl): This is a very bad hash code for the element and
181 // there's no reason why two elements with the same name should have 196 // there's no reason why two elements with the same name should have
182 // the same hash code. Replace this with a simple id in the element? 197 // the same hash code. Replace this with a simple id in the element?
183 int hashCode() => name === null ? 0 : name.hashCode(); 198 int hashCode() => name === null ? 0 : name.hashCode();
184 199
200 Script getScript() {
201 return getCompilationUnit().script;
202 }
203
185 CompilationUnitElement getCompilationUnit() { 204 CompilationUnitElement getCompilationUnit() {
186 Element element = this; 205 Element element = this;
187 while (element !== null && !element.isCompilationUnit()) { 206 while (element !== null && !element.isCompilationUnit()) {
188 element = element.enclosingElement; 207 element = element.enclosingElement;
189 } 208 }
190 return element; 209 return element.asCompilationUnit();
191 } 210 }
192 211
193 LibraryElement getLibrary() { 212 LibraryElement getLibrary() {
194 Element element = this; 213 Element element = this;
195 while (element.kind !== ElementKind.LIBRARY) { 214 while (element.kind !== ElementKind.LIBRARY) {
196 element = element.enclosingElement; 215 element = element.enclosingElement;
197 } 216 }
198 return element; 217 return element;
199 } 218 }
200 219
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 } else { 264 } else {
246 return '$kind(${nameText})'; 265 return '$kind(${nameText})';
247 } 266 }
248 } 267 }
249 268
250 bool _isNative = false; 269 bool _isNative = false;
251 void setNative() { _isNative = true; } 270 void setNative() { _isNative = true; }
252 bool isNative() => _isNative; 271 bool isNative() => _isNative;
253 272
254 FunctionElement asFunctionElement() => null; 273 FunctionElement asFunctionElement() => null;
274
275 Element cloneTo(Element enclosing, DiagnosticListener listener) {
276 listener.cancel("Unimplemented cloneTo", element: this);
277 }
255 } 278 }
256 279
257 class ContainerElement extends Element { 280 class ContainerElement extends Element {
258 ContainerElement(name, kind, enclosingElement) : 281 ContainerElement(name, kind, enclosingElement) :
259 super(name, kind, enclosingElement); 282 super(name, kind, enclosingElement);
260 283
261 abstract void addMember(Element element, DiagnosticListener listener); 284 abstract void addMember(Element element, DiagnosticListener listener);
262 285
263 void addGetterOrSetter(Element element, 286 void addGetterOrSetter(Element element,
264 Element existing, 287 Element existing,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 CompilationUnitElement(Script script, Element enclosing) 328 CompilationUnitElement(Script script, Element enclosing)
306 : this.script = script, 329 : this.script = script,
307 super(new SourceString(script.name), 330 super(new SourceString(script.name),
308 ElementKind.COMPILATION_UNIT, 331 ElementKind.COMPILATION_UNIT,
309 enclosing); 332 enclosing);
310 333
311 CompilationUnitElement.library(Script script) 334 CompilationUnitElement.library(Script script)
312 : this.script = script, 335 : this.script = script,
313 super(new SourceString(script.name), ElementKind.LIBRARY, null); 336 super(new SourceString(script.name), ElementKind.LIBRARY, null);
314 337
338 CompilationUnitElement asCompilationUnit() => this;
339
315 void addMember(Element element, DiagnosticListener listener) { 340 void addMember(Element element, DiagnosticListener listener) {
316 LibraryElement library = enclosingElement; 341 LibraryElement library = enclosingElement;
317 library.addMember(element, listener); 342 library.addMember(element, listener);
318 topLevelElements = topLevelElements.prepend(element); 343 topLevelElements = topLevelElements.prepend(element);
319 } 344 }
320 345
321 void define(Element element, DiagnosticListener listener) { 346 void define(Element element, DiagnosticListener listener) {
322 LibraryElement library = enclosingElement; 347 LibraryElement library = enclosingElement;
323 library.define(element, listener); 348 library.define(element, listener);
324 } 349 }
325 350
326 void addTag(ScriptTag tag, DiagnosticListener listener) { 351 void addTag(ScriptTag tag, DiagnosticListener listener) {
327 listener.cancel("script tags not allowed here", node: tag); 352 listener.cancel("script tags not allowed here", node: tag);
328 } 353 }
329 } 354 }
330 355
356 class CompilationUnitOverrideElement extends Element {
357 final CompilationUnitElement compilationUnit;
358
359 CompilationUnitOverrideElement(CompilationUnitElement compilationUnit,
360 Element enclosing)
361 : this.compilationUnit = compilationUnit,
362 super(compilationUnit.name,
363 ElementKind.COMPILATION_UNIT_OVERRIDE,
364 enclosing);
365
366 CompilationUnitElement asCompilationUnit() => compilationUnit;
367 }
368
331 class LibraryElement extends CompilationUnitElement { 369 class LibraryElement extends CompilationUnitElement {
332 // TODO(ahe): Library element should not be a subclass of 370 // TODO(ahe): Library element should not be a subclass of
333 // CompilationUnitElement. 371 // CompilationUnitElement.
334 372
335 Link<CompilationUnitElement> compilationUnits = 373 Link<CompilationUnitElement> compilationUnits =
336 const EmptyLink<CompilationUnitElement>(); 374 const EmptyLink<CompilationUnitElement>();
337 Link<ScriptTag> tags = const EmptyLink<ScriptTag>(); 375 Link<ScriptTag> tags = const EmptyLink<ScriptTag>();
338 ScriptTag libraryTag; 376 ScriptTag libraryTag;
339 Map<SourceString, Element> elements; 377 Map<SourceString, Element> elements;
340 bool canUseNative = false; 378 bool canUseNative = false;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 return path.substring(path.lastIndexOf('/') + 1); 451 return path.substring(path.lastIndexOf('/') + 1);
414 } 452 }
415 } 453 }
416 454
417 Scope buildEnclosingScope() => new TopScope(this); 455 Scope buildEnclosingScope() => new TopScope(this);
418 } 456 }
419 457
420 class PrefixElement extends Element { 458 class PrefixElement extends Element {
421 Map<SourceString, Element> imported; 459 Map<SourceString, Element> imported;
422 Token firstPosition; 460 Token firstPosition;
423 final CompilationUnitElement patchSource;
424 461
425 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition, 462 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition)
426 [this.patchSource]) 463 : imported = new Map<SourceString, Element>(),
427 : imported = new Map<SourceString, Element>(), 464 super(prefix, ElementKind.PREFIX, enclosing);
428 super(prefix, ElementKind.PREFIX, enclosing);
429
430 CompilationUnitElement getCompilationUnit() {
431 if (patchSource !== null) return patchSource;
432 return super.getCompilationUnit();
433 }
434 465
435 lookupLocalMember(SourceString memberName) => imported[memberName]; 466 lookupLocalMember(SourceString memberName) => imported[memberName];
436 467
437 Type computeType(Compiler compiler) => compiler.types.dynamicType; 468 Type computeType(Compiler compiler) => compiler.types.dynamicType;
438 469
439 Token position() => firstPosition; 470 Token position() => firstPosition;
471
472 PrefixElement cloneTo(Element enclosing, DiagnosticListener listener) {
473 return new PrefixElement(name, enclosing, firstPosition);
474 }
440 } 475 }
441 476
442 class TypedefElement extends Element implements TypeDeclarationElement { 477 class TypedefElement extends Element implements TypeDeclarationElement {
443 Type cachedType; 478 Type cachedType;
444 Typedef cachedNode; 479 Typedef cachedNode;
445 480
446 TypedefElement(SourceString name, Element enclosing) 481 TypedefElement(SourceString name, Element enclosing)
447 : super(name, ElementKind.TYPEDEF, enclosing); 482 : super(name, ElementKind.TYPEDEF, enclosing);
448 483
449 Type computeType(Compiler compiler) { 484 Type computeType(Compiler compiler) {
450 if (cachedType !== null) return cachedType; 485 if (cachedType !== null) return cachedType;
451 cachedType = compiler.computeFunctionType( 486 cachedType = compiler.computeFunctionType(
452 this, compiler.resolveTypedef(this)); 487 this, compiler.resolveTypedef(this));
453 return cachedType; 488 return cachedType;
454 } 489 }
455 490
456 Link<Type> get typeVariables() => const EmptyLink<Type>(); 491 Link<Type> get typeVariables() => const EmptyLink<Type>();
457 492
458 Scope buildScope() => 493 Scope buildScope() =>
459 new TypeDeclarationScope(enclosingElement.buildScope(), this); 494 new TypeDeclarationScope(enclosingElement.buildScope(), this);
495
496 TypedefElement cloneTo(Element enclosing, DiagnosticListener listener) {
497 TypedefElement result = new TypedefElement(name, enclosing);
498 return result;
499 }
460 } 500 }
461 501
462 class VariableElement extends Element { 502 class VariableElement extends Element {
463 final VariableListElement variables; 503 final VariableListElement variables;
464 Expression cachedNode; // The send or the identifier in the variables list. 504 Expression cachedNode; // The send or the identifier in the variables list.
465 505
466 Modifiers get modifiers() => variables.modifiers; 506 Modifiers get modifiers() => variables.modifiers;
467 507
468 VariableElement(SourceString name, 508 VariableElement(SourceString name,
469 VariableListElement this.variables, 509 VariableListElement this.variables,
(...skipping 26 matching lines...) Expand all
496 536
497 Type get type() => variables.type; 537 Type get type() => variables.type;
498 538
499 bool isInstanceMember() { 539 bool isInstanceMember() {
500 return isMember() && !modifiers.isStatic(); 540 return isMember() && !modifiers.isStatic();
501 } 541 }
502 542
503 // Note: cachedNode.getBeginToken() will not be correct in all 543 // Note: cachedNode.getBeginToken() will not be correct in all
504 // cases, for example, for function typed parameters. 544 // cases, for example, for function typed parameters.
505 Token position() => findMyName(variables.position()); 545 Token position() => findMyName(variables.position());
546
547 VariableElement cloneTo(Element enclosing, DiagnosticListener listener) {
548 VariableListElement clonedVariables =
549 variables.cloneTo(enclosing, listener);
550 VariableElement result = new VariableElement(
551 name, clonedVariables, kind, enclosing, cachedNode);
552 return result;
553 }
506 } 554 }
507 555
508 /** 556 /**
509 * Parameters in constructors that directly initialize fields. For example: 557 * Parameters in constructors that directly initialize fields. For example:
510 * [:A(this.field):]. 558 * [:A(this.field):].
511 */ 559 */
512 class FieldParameterElement extends VariableElement { 560 class FieldParameterElement extends VariableElement {
513 VariableElement fieldElement; 561 VariableElement fieldElement;
514 562
515 FieldParameterElement(SourceString name, 563 FieldParameterElement(SourceString name,
516 this.fieldElement, 564 this.fieldElement,
517 VariableListElement variables, 565 VariableListElement variables,
518 Element enclosing, 566 Element enclosing,
519 Node node) 567 Node node)
520 : super(name, variables, ElementKind.FIELD_PARAMETER, enclosing, node); 568 : super(name, variables, ElementKind.FIELD_PARAMETER, enclosing, node);
569
570 FieldParameterElement cloneTo(Element enclosing,
571 DiagnosticListener listener) {
572 FieldParameterElement result =
573 new FieldParameterElement(name, fieldElement,
574 variables.cloneTo(enclosing, listener),
575 enclosing, cachedNode);
576 return result;
577 }
521 } 578 }
522 579
523 // This element represents a list of variable or field declaration. 580 // This element represents a list of variable or field declaration.
524 // It contains the node, and the type. A [VariableElement] always 581 // It contains the node, and the type. A [VariableElement] always
525 // references its [VariableListElement]. It forwards its 582 // references its [VariableListElement]. It forwards its
526 // [computeType] and [parseNode] methods to this element. 583 // [computeType] and [parseNode] methods to this element.
527 class VariableListElement extends Element { 584 class VariableListElement extends Element {
528 VariableDefinitions cachedNode; 585 VariableDefinitions cachedNode;
529 Type type; 586 Type type;
530 final Modifiers modifiers; 587 final Modifiers modifiers;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 functionSignature); 630 functionSignature);
574 } else { 631 } else {
575 type = compiler.types.dynamicType; 632 type = compiler.types.dynamicType;
576 } 633 }
577 } 634 }
578 assert(type != null); 635 assert(type != null);
579 return type; 636 return type;
580 } 637 }
581 638
582 Token position() => cachedNode.getBeginToken(); 639 Token position() => cachedNode.getBeginToken();
640
641 VariableListElement cloneTo(Element enclosing, DiagnosticListener listener) {
642 VariableListElement result;
643 if (cachedNode !== null) {
644 result = new VariableListElement(cachedNode, kind, enclosing);
645 } else {
646 result = new VariableListElement(kind, modifiers, enclosing);
647 }
648 return result;
649 }
583 } 650 }
584 651
585 class ForeignElement extends Element { 652 class ForeignElement extends Element {
586 ForeignElement(SourceString name, ContainerElement enclosingElement) 653 ForeignElement(SourceString name, ContainerElement enclosingElement)
587 : super(name, ElementKind.FOREIGN, enclosingElement); 654 : super(name, ElementKind.FOREIGN, enclosingElement);
588 655
589 Type computeType(Compiler compiler) { 656 Type computeType(Compiler compiler) {
590 return compiler.types.dynamicType; 657 return compiler.types.dynamicType;
591 } 658 }
592 659
593 parseNode(DiagnosticListener listener) { 660 parseNode(DiagnosticListener listener) {
594 throw "internal error: ForeignElement has no node"; 661 throw "internal error: ForeignElement has no node";
595 } 662 }
663
664 ForeignElement cloneTo(Element enclosing, DiagnosticListener listener) {
665 ForeignElement result = new ForeignElement(name, kind, enclosing);
666 return result;
667 }
596 } 668 }
597 669
598 class AbstractFieldElement extends Element { 670 class AbstractFieldElement extends Element {
599 FunctionElement getter; 671 FunctionElement getter;
600 FunctionElement setter; 672 FunctionElement setter;
601 673
602 AbstractFieldElement(SourceString name, Element enclosing) 674 AbstractFieldElement(SourceString name, Element enclosing)
603 : super(name, ElementKind.ABSTRACT_FIELD, enclosing); 675 : super(name, ElementKind.ABSTRACT_FIELD, enclosing);
604 676
605 Type computeType(Compiler compiler) { 677 Type computeType(Compiler compiler) {
(...skipping 24 matching lines...) Expand all
630 if (getter !== null) { 702 if (getter !== null) {
631 return new Modifiers.withFlags( 703 return new Modifiers.withFlags(
632 getter.modifiers.nodes, 704 getter.modifiers.nodes,
633 getter.modifiers.flags | Modifiers.FLAG_ABSTRACT); 705 getter.modifiers.flags | Modifiers.FLAG_ABSTRACT);
634 } else { 706 } else {
635 return new Modifiers.withFlags( 707 return new Modifiers.withFlags(
636 setter.modifiers.nodes, 708 setter.modifiers.nodes,
637 setter.modifiers.flags | Modifiers.FLAG_ABSTRACT); 709 setter.modifiers.flags | Modifiers.FLAG_ABSTRACT);
638 } 710 }
639 } 711 }
712
713 AbstractFieldElement cloneTo(Element enclosing, DiagnosticListener listener) {
714 listener.cancel("Cannot clone synthetic AbstractFieldElement",
715 element: this);
716 }
640 } 717 }
641 718
642 // TODO(johnniwinther): [FunctionSignature] should be merged with 719 // TODO(johnniwinther): [FunctionSignature] should be merged with
643 // [FunctionType]. 720 // [FunctionType].
644 class FunctionSignature { 721 class FunctionSignature {
645 Link<Element> requiredParameters; 722 Link<Element> requiredParameters;
646 Link<Element> optionalParameters; 723 Link<Element> optionalParameters;
647 Type returnType; 724 Type returnType;
648 int requiredParameterCount; 725 int requiredParameterCount;
649 int optionalParameterCount; 726 int optionalParameterCount;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 FunctionElement.tooMuchOverloading(SourceString name, 791 FunctionElement.tooMuchOverloading(SourceString name,
715 FunctionExpression this.cachedNode, 792 FunctionExpression this.cachedNode,
716 ElementKind kind, 793 ElementKind kind,
717 Modifiers this.modifiers, 794 Modifiers this.modifiers,
718 Element enclosing, 795 Element enclosing,
719 FunctionSignature this.functionSignature) 796 FunctionSignature this.functionSignature)
720 : super(name, kind, enclosing) { 797 : super(name, kind, enclosing) {
721 defaultImplementation = this; 798 defaultImplementation = this;
722 } 799 }
723 800
724 CompilationUnitElement getCompilationUnit() { 801 Script getScript() {
725 if (patch !== null) return patch.getCompilationUnit(); 802 if (patch !== null) return patch.getScript();
726 return super.getCompilationUnit(); 803 return super.getScript();
727 } 804 }
728 805
729 bool get isPatched() => patch !== null; 806 bool get isPatched() => patch !== null;
730 807
731 /** 808 /**
732 * Applies a patch function to this function. The patch function's body 809 * Applies a patch function to this function. The patch function's body
733 * is used as replacement when parsing this function's body. 810 * is used as replacement when parsing this function's body.
734 * This method must not be called after the function has been parsed, 811 * This method must not be called after the function has been parsed,
735 * and it must be called at most once. 812 * and it must be called at most once.
736 */ 813 */
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 } 861 }
785 return null; 862 return null;
786 } 863 }
787 cachedNode = patch.parseNode(listener); 864 cachedNode = patch.parseNode(listener);
788 return cachedNode; 865 return cachedNode;
789 } 866 }
790 867
791 Token position() => cachedNode.getBeginToken(); 868 Token position() => cachedNode.getBeginToken();
792 869
793 FunctionElement asFunctionElement() => this; 870 FunctionElement asFunctionElement() => this;
871
872 FunctionElement cloneTo(Element enclosing, DiagnosticListener listener) {
873 FunctionElement result = new FunctionElement.tooMuchOverloading(
874 name, cachedNode, kind, modifiers, enclosing, functionSignature);
875 result.defaultImplementation = defaultImplementation;
876 result.type = type;
877 return result;
878 }
794 } 879 }
795 880
881
796 class ConstructorBodyElement extends FunctionElement { 882 class ConstructorBodyElement extends FunctionElement {
797 FunctionElement constructor; 883 FunctionElement constructor;
798 884
799 ConstructorBodyElement(FunctionElement constructor) 885 ConstructorBodyElement(FunctionElement constructor)
800 : this.constructor = constructor, 886 : this.constructor = constructor,
801 super(constructor.name, 887 super(constructor.name,
802 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, 888 ElementKind.GENERATIVE_CONSTRUCTOR_BODY,
803 null, 889 null,
804 constructor.enclosingElement) { 890 constructor.enclosingElement) {
805 functionSignature = constructor.functionSignature; 891 functionSignature = constructor.functionSignature;
806 } 892 }
807 893
808 bool isInstanceMember() => true; 894 bool isInstanceMember() => true;
809 895
810 FunctionType computeType(Compiler compiler) { 896 FunctionType computeType(Compiler compiler) {
811 compiler.reportFatalError('Internal error: $this.computeType', this); 897 compiler.reportFatalError('Internal error: $this.computeType', this);
812 } 898 }
813 899
814 Node parseNode(DiagnosticListener listener) { 900 Node parseNode(DiagnosticListener listener) {
815 if (cachedNode !== null) return cachedNode; 901 if (cachedNode !== null) return cachedNode;
816 cachedNode = constructor.parseNode(listener); 902 cachedNode = constructor.parseNode(listener);
817 assert(cachedNode !== null); 903 assert(cachedNode !== null);
818 return cachedNode; 904 return cachedNode;
819 } 905 }
820 906
821 Token position() => constructor.position(); 907 Token position() => constructor.position();
908
909 ConstructorBodyElement cloneTo(Element enclosing,
910 DiagnosticListener listener) {
911 ConstructorBodyElement result =
912 new ConstructorBodyElement(constructor.cloneTo(enclosing, listener));
913 return result;
914 }
822 } 915 }
823 916
824 class SynthesizedConstructorElement extends FunctionElement { 917 class SynthesizedConstructorElement extends FunctionElement {
825 SynthesizedConstructorElement(Element enclosing) 918 SynthesizedConstructorElement(Element enclosing)
826 : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR, 919 : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR,
827 null, enclosing); 920 null, enclosing);
828 921
829 Token position() => enclosingElement.position(); 922 Token position() => enclosingElement.position();
923
924 SynthesizedConstructorElement cloneTo(Element enclosing,
925 DiagnosticListener listener) {
926 return new SynthesizedConstructorElement(enclosing);
927 }
830 } 928 }
831 929
832 class VoidElement extends Element { 930 class VoidElement extends Element {
833 VoidElement(Element enclosing) 931 VoidElement(Element enclosing)
834 : super(const SourceString('void'), ElementKind.VOID, enclosing); 932 : super(const SourceString('void'), ElementKind.VOID, enclosing);
835 Type computeType(compiler) => compiler.types.voidType; 933 Type computeType(compiler) => compiler.types.voidType;
836 Node parseNode(_) { 934 Node parseNode(_) {
837 throw 'internal error: parseNode on void'; 935 throw 'internal error: parseNode on void';
838 } 936 }
839 bool impliesType() => true; 937 bool impliesType() => true;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
882 class ClassElement extends ContainerElement 980 class ClassElement extends ContainerElement
883 implements TypeDeclarationElement { 981 implements TypeDeclarationElement {
884 final int id; 982 final int id;
885 InterfaceType type; 983 InterfaceType type;
886 Type supertype; 984 Type supertype;
887 Type defaultClass; 985 Type defaultClass;
888 Link<Element> members = const EmptyLink<Element>(); 986 Link<Element> members = const EmptyLink<Element>();
889 Map<SourceString, Element> localMembers; 987 Map<SourceString, Element> localMembers;
890 Map<SourceString, Element> constructors; 988 Map<SourceString, Element> constructors;
891 Link<Type> interfaces = const EmptyLink<Type>(); 989 Link<Type> interfaces = const EmptyLink<Type>();
990
991 LinkedHashMap<SourceString, TypeVariableElement> typeParameters;
992 SourceString nativeName;
993
892 bool isResolved = false; 994 bool isResolved = false;
893 bool isBeingResolved = false; 995 bool isBeingResolved = false;
894 // backendMembers are members that have been added by the backend to simplify 996 // backendMembers are members that have been added by the backend to simplify
895 // compilation. They don't have any user-side counter-part. 997 // compilation. They don't have any user-side counter-part.
896 Link<Element> backendMembers = const EmptyLink<Element>(); 998 Link<Element> backendMembers = const EmptyLink<Element>();
897 999
898 Link<Type> allSupertypes; 1000 Link<Type> allSupertypes;
899 ClassElement patch = null;
900 1001
901 ClassElement(SourceString name, CompilationUnitElement enclosing, this.id) 1002 ClassElement(SourceString name, Element enclosing, this.id)
902 : localMembers = new Map<SourceString, Element>(), 1003 : localMembers = new Map<SourceString, Element>(),
903 constructors = new Map<SourceString, Element>(), 1004 constructors = new Map<SourceString, Element>(),
904 super(name, ElementKind.CLASS, enclosing); 1005 super(name, ElementKind.CLASS, enclosing);
905 1006
906 void addMember(Element element, DiagnosticListener listener) { 1007 void addMember(Element element, DiagnosticListener listener) {
907 members = members.prepend(element); 1008 members = members.prepend(element);
908 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR || 1009 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR ||
909 element.modifiers.isFactory()) { 1010 element.modifiers.isFactory()) {
910 constructors[element.name] = element; 1011 constructors[element.name] = element;
911 } else if (element.kind == ElementKind.GETTER 1012 } else if (element.kind == ElementKind.GETTER
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 // lookupMember will work. 1080 // lookupMember will work.
980 while (lookupClass.getLibrary() != memberLibrary) { 1081 while (lookupClass.getLibrary() != memberLibrary) {
981 lookupClass = lookupClass.superclass; 1082 lookupClass = lookupClass.superclass;
982 } 1083 }
983 } 1084 }
984 SourceString fieldName = fieldMember.name; 1085 SourceString fieldName = fieldMember.name;
985 while (true) { 1086 while (true) {
986 Element foundMember = lookupClass.lookupMember(fieldName); 1087 Element foundMember = lookupClass.lookupMember(fieldName);
987 if (foundMember == fieldMember) return false; 1088 if (foundMember == fieldMember) return false;
988 if (foundMember.isField()) return true; 1089 if (foundMember.isField()) return true;
989 lookupClass = (foundMember.enclosingElement as ClassElement).superclass; 1090 lookupClass = foundMember.getEnclosingClass().superclass;
990 } 1091 }
991 } 1092 }
992 1093
993 Element lookupConstructor(SourceString className, 1094 Element lookupConstructor(SourceString className,
994 [SourceString constructorName = 1095 [SourceString constructorName =
995 const SourceString(''), 1096 const SourceString(''),
996 Element noMatch(Element)]) { 1097 Element noMatch(Element)]) {
997 // TODO(karlklose): have a map from class names to a map of constructors 1098 // TODO(karlklose): have a map from class names to a map of constructors
998 // instead of creating the name here? 1099 // instead of creating the name here?
999 SourceString normalizedName; 1100 SourceString normalizedName;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1088 */ 1189 */
1089 bool isSubclassOf(ClassElement cls) { 1190 bool isSubclassOf(ClassElement cls) {
1090 for (ClassElement s = this; s != null; s = s.superclass) { 1191 for (ClassElement s = this; s != null; s = s.superclass) {
1091 if (s === cls) return true; 1192 if (s === cls) return true;
1092 } 1193 }
1093 return false; 1194 return false;
1094 } 1195 }
1095 1196
1096 bool isInterface() => false; 1197 bool isInterface() => false;
1097 bool isNative() => nativeName != null; 1198 bool isNative() => nativeName != null;
1098 SourceString nativeName;
1099 int hashCode() => id; 1199 int hashCode() => id;
1100 1200
1101 Scope buildScope() => 1201 Scope buildScope() =>
1102 new ClassScope(enclosingElement.buildScope(), this); 1202 new ClassScope(enclosingElement.buildScope(), this);
1203
1204 void cloneMembersTo(Element target, DiagnosticListener listener) {
1205 target.type = type;
1206 target.supertype = supertype;
1207 target.defaultClass = defaultClass;
1208 target.interfaces = interfaces;
1209 if (typeParameters !== null) {
1210 target.typeParameters =
1211 new LinkedHashMap<SourceString, TypeVariableElement>();
1212 typeParameters.forEach((SourceString name, TypeVariableElement type) {
1213 target.typeParameters[name] = type.cloneTo(target, listener);
1214 });
1215 }
1216 target.nativeName = nativeName;
1217 target.isResolved = isResolved;
1218 target.isBeingResolved = isBeingResolved;
1219 target.allSupertypes = allSupertypes;
1220 if (!backendMembers.isEmpty()) {
1221 listener.cancel("Cloning backend-modified class.", element: this);
1222 }
1223
1224 Link<Element> elementList = this.members;
1225 while (!elementList.isEmpty()) {
1226 target.addMember(elementList.head.cloneTo(target, listener), listener);
1227 elementList = elementList.tail;
1228 }
1229 }
1230
1231 ClassElement cloneTo(Element enclosing, DiagnosticListener listener) {
1232 // TODO(lrn): Is copying id acceptable?
1233 ClassElement result = new ClassElement(name, enclosing, id);
1234 cloneMembersTo(result, listener);
1235 return result;
1236 }
1103 } 1237 }
1104 1238
1105 class Elements { 1239 class Elements {
1106 static bool isLocal(Element element) { 1240 static bool isLocal(Element element) {
1107 return ((element !== null) 1241 return ((element !== null)
1108 && !element.isInstanceMember() 1242 && !element.isInstanceMember()
1109 && !isStaticOrTopLevelField(element) 1243 && !isStaticOrTopLevelField(element)
1110 && !isStaticOrTopLevelFunction(element) 1244 && !isStaticOrTopLevelFunction(element)
1111 && (element.kind === ElementKind.VARIABLE || 1245 && (element.kind === ElementKind.VARIABLE ||
1112 element.kind === ElementKind.PARAMETER || 1246 element.kind === ElementKind.PARAMETER ||
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 || (element == coreLibrary.find(const SourceString('Pattern'))); 1346 || (element == coreLibrary.find(const SourceString('Pattern')));
1213 } 1347 }
1214 1348
1215 static bool isListSupertype(Element element, Compiler compiler) { 1349 static bool isListSupertype(Element element, Compiler compiler) {
1216 LibraryElement coreLibrary = compiler.coreLibrary; 1350 LibraryElement coreLibrary = compiler.coreLibrary;
1217 return (element == coreLibrary.find(const SourceString('Collection'))) 1351 return (element == coreLibrary.find(const SourceString('Collection')))
1218 || (element == coreLibrary.find(const SourceString('Iterable'))); 1352 || (element == coreLibrary.find(const SourceString('Iterable')));
1219 } 1353 }
1220 } 1354 }
1221 1355
1222
1223 class LabelElement extends Element { 1356 class LabelElement extends Element {
1224 // We store the original label here so it can be returned by [parseNode]. 1357 // We store the original label here so it can be returned by [parseNode].
1225 final Label label; 1358 final Label label;
1226 final String labelName; 1359 final String labelName;
1227 final TargetElement target; 1360 final TargetElement target;
1228 bool isBreakTarget = false; 1361 bool isBreakTarget = false;
1229 bool isContinueTarget = false; 1362 bool isContinueTarget = false;
1230 LabelElement(Label label, this.labelName, this.target, 1363 LabelElement(Label label, this.labelName, this.target,
1231 Element enclosingElement) 1364 Element enclosingElement)
1232 : this.label = label, 1365 : this.label = label,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 1416
1284 TypeVariableElement(name, Element enclosing, this.cachedNode, 1417 TypeVariableElement(name, Element enclosing, this.cachedNode,
1285 [this.type, this.bound]) 1418 [this.type, this.bound])
1286 : super(name, ElementKind.TYPE_VARIABLE, enclosing); 1419 : super(name, ElementKind.TYPE_VARIABLE, enclosing);
1287 1420
1288 TypeVariableType computeType(compiler) => type; 1421 TypeVariableType computeType(compiler) => type;
1289 1422
1290 Node parseNode(compiler) => cachedNode; 1423 Node parseNode(compiler) => cachedNode;
1291 1424
1292 String toString() => "${enclosingElement.toString()}.${name.slowToString()}"; 1425 String toString() => "${enclosingElement.toString()}.${name.slowToString()}";
1426
1427 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) {
1428 TypeVariableElement result =
1429 new TypeVariableElement(name, enclosing, node, type, bound);
1430 return result;
1431 }
1293 } 1432 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/compiler.dart ('k') | lib/compiler/implementation/lib/math.dartp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698