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

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

Issue 10834330: Clean-up of getCompilationUnit. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #library('elements'); 5 #library('elements');
6 6
7 #import('dart:uri'); 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 101
102 toString() => id; 102 toString() => id;
103 } 103 }
104 104
105 class Element implements Hashable { 105 class Element implements Hashable {
106 final SourceString name; 106 final SourceString name;
107 final ElementKind kind; 107 final ElementKind kind;
108 final Element enclosingElement; 108 final Element enclosingElement;
109 Link<Node> metadata = const EmptyLink<Node>(); 109 Link<Node> metadata = const EmptyLink<Node>();
110 110
111
112 Element(this.name, this.kind, this.enclosingElement) { 111 Element(this.name, this.kind, this.enclosingElement) {
113 assert(getLibrary() !== null); 112 assert(getLibrary() !== null);
114 } 113 }
115 114
116 Modifiers get modifiers() => null; 115 Modifiers get modifiers() => null;
117 116
118 Node parseNode(DiagnosticListener listener) { 117 Node parseNode(DiagnosticListener listener) {
119 listener.cancel("Internal Error: $this.parseNode", token: position()); 118 listener.cancel("Internal Error: $this.parseNode", token: position());
120 } 119 }
121 120
122 Type computeType(Compiler compiler) { 121 Type computeType(Compiler compiler) {
123 compiler.internalError("$this.computeType.", token: position()); 122 compiler.internalError("$this.computeType.", token: position());
124 } 123 }
125 124
126 void addMetadata(Node node) { 125 void addMetadata(Node node) {
127 metadata = metadata.prepend(node); 126 metadata = metadata.prepend(node);
128 } 127 }
129 128
130 bool isFunction() => kind === ElementKind.FUNCTION; 129 bool isFunction() => kind === ElementKind.FUNCTION;
131 bool isConstructor() => isFactoryConstructor() || isGenerativeConstructor(); 130 bool isConstructor() => isFactoryConstructor() || isGenerativeConstructor();
132 bool isClosure() => false; 131 bool isClosure() => false;
133 bool isMember() { 132 bool isMember() {
134 // Check that this element is defined in the scope of a Class. 133 // Check that this element is defined in the scope of a Class.
135 Element enclosing = enclosingElement; 134 Element enclosing = enclosingElement;
136 if (enclosing !== null && 135 if (enclosing !== null &&
137 enclosing.kind === ElementKind.COMPILATION_UNIT_OVERRIDE) { 136 enclosing.kind === ElementKind.COMPILATION_UNIT_OVERRIDE) {
138 enclosing = enclosing.enclosingElement; 137 enclosing = enclosing.enclosingElement;
139 } 138 }
140 // TODO(lrn): Skip any synthetic elements inserted, e.g.,
141 // a compilation unit override.
142 return enclosing !== null && enclosing.isClass(); 139 return enclosing !== null && enclosing.isClass();
143 } 140 }
144 bool isInstanceMember() => false; 141 bool isInstanceMember() => false;
145 bool isFactoryConstructor() => modifiers !== null && modifiers.isFactory(); 142 bool isFactoryConstructor() => modifiers !== null && modifiers.isFactory();
146 bool isGenerativeConstructor() => kind === ElementKind.GENERATIVE_CONSTRUCTOR; 143 bool isGenerativeConstructor() => kind === ElementKind.GENERATIVE_CONSTRUCTOR;
147 bool isGenerativeConstructorBody() => 144 bool isGenerativeConstructorBody() =>
148 kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY; 145 kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY;
149 bool isCompilationUnit() { 146 bool isCompilationUnit() => kind === ElementKind.COMPILATION_UNIT;
150 return kind === ElementKind.COMPILATION_UNIT ||
151 kind === ElementKind.LIBRARY ||
152 kind === ElementKind.COMPILATION_UNIT_OVERRIDE;
153 }
154 /**
155 * Provides the compilation unit corresponding to this element.
156 * Returns non-null for elements where [isCompilationUnit] returns true,
157 * but may not return the current [Element].
158 */
159 CompilationUnitElement asCompilationUnit() => null;
160 bool isClass() => kind === ElementKind.CLASS; 147 bool isClass() => kind === ElementKind.CLASS;
161 bool isPrefix() => kind === ElementKind.PREFIX; 148 bool isPrefix() => kind === ElementKind.PREFIX;
162 bool isVariable() => kind === ElementKind.VARIABLE; 149 bool isVariable() => kind === ElementKind.VARIABLE;
163 bool isParameter() => kind === ElementKind.PARAMETER; 150 bool isParameter() => kind === ElementKind.PARAMETER;
164 bool isStatement() => kind === ElementKind.STATEMENT; 151 bool isStatement() => kind === ElementKind.STATEMENT;
165 bool isTypedef() => kind === ElementKind.TYPEDEF; 152 bool isTypedef() => kind === ElementKind.TYPEDEF;
166 bool isTypeVariable() => kind === ElementKind.TYPE_VARIABLE; 153 bool isTypeVariable() => kind === ElementKind.TYPE_VARIABLE;
167 bool isField() => kind === ElementKind.FIELD; 154 bool isField() => kind === ElementKind.FIELD;
168 bool isGetter() => kind === ElementKind.GETTER; 155 bool isGetter() => kind === ElementKind.GETTER;
169 bool isSetter() => kind === ElementKind.SETTER; 156 bool isSetter() => kind === ElementKind.SETTER;
170 bool isAccessor() => isGetter() || isSetter(); 157 bool isAccessor() => isGetter() || isSetter();
171 bool isForeign() => kind === ElementKind.FOREIGN; 158 bool isForeign() => kind === ElementKind.FOREIGN;
172 bool isLibrary() => kind === ElementKind.LIBRARY; 159 bool isLibrary() => kind === ElementKind.LIBRARY;
173 bool impliesType() => (kind.category & ElementCategory.IMPLIES_TYPE) != 0; 160 bool impliesType() => (kind.category & ElementCategory.IMPLIES_TYPE) != 0;
174 bool isExtendable() => (kind.category & ElementCategory.IS_EXTENDABLE) != 0; 161 bool isExtendable() => (kind.category & ElementCategory.IS_EXTENDABLE) != 0;
175 162
176 // TODO(johnniwinther): This breaks for libraries (for which enclosing 163 // TODO(johnniwinther): This breaks for libraries (for which enclosing
177 // elements are null) and is invalid for top level variable declarations for 164 // elements are null) and is invalid for top level variable declarations for
178 // which the enclosing element is a VariableDeclarations and not a compilation 165 // which the enclosing element is a VariableDeclarations and not a compilation
179 // unit. 166 // unit.
180 bool isTopLevel() => enclosingElement.isCompilationUnit(); 167 bool isTopLevel() {
168 return enclosingElement !== null && enclosingElement.isCompilationUnit();
169 }
181 170
182 bool isAssignable() { 171 bool isAssignable() {
183 if (modifiers != null && modifiers.isFinal()) return false; 172 if (modifiers != null && modifiers.isFinal()) return false;
184 if (isFunction() || isGenerativeConstructor()) return false; 173 if (isFunction() || isGenerativeConstructor()) return false;
185 return true; 174 return true;
186 } 175 }
187 176
188 Token position() => null; 177 Token position() => null;
189 178
190 Token findMyName(Token token) { 179 Token findMyName(Token token) {
191 for (Token t = token; t.kind !== EOF_TOKEN; t = t.next) { 180 for (Token t = token; t.kind !== EOF_TOKEN; t = t.next) {
192 if (t.value == name) return t; 181 if (t.value == name) return t;
193 } 182 }
194 return token; 183 return token;
195 } 184 }
196 185
197 // TODO(kasperl): This is a very bad hash code for the element and 186 // TODO(kasperl): This is a very bad hash code for the element and
198 // there's no reason why two elements with the same name should have 187 // there's no reason why two elements with the same name should have
199 // the same hash code. Replace this with a simple id in the element? 188 // the same hash code. Replace this with a simple id in the element?
200 int hashCode() => name === null ? 0 : name.hashCode(); 189 int hashCode() => name === null ? 0 : name.hashCode();
201 190
202 Script getScript() {
203 return getCompilationUnit().script;
204 }
205
206 CompilationUnitElement getCompilationUnit() { 191 CompilationUnitElement getCompilationUnit() {
207 if (isCompilationUnit()) return this; 192 Element element = this;
208 return enclosingElement.getCompilationUnit(); 193 while (element !== null && !element.isCompilationUnit()) {
194 if (element is CompilationUnitOverrideElement) {
195 CompilationUnitOverrideElement override = element;
196 return override.compilationUnit;
197 }
198 if (element.isLibrary()) {
199 LibraryElement library = element;
200 return library.entryCompilationUnit;
201 }
202 element = element.enclosingElement;
203 if (element is FunctionElement) {
204 FunctionElement function = element;
205 if (function.isPatched) {
206 element = function.patch;
207 }
208 }
209 }
210 return element;
209 } 211 }
210 212
211 LibraryElement getLibrary() { 213 LibraryElement getLibrary() {
212 Element element = this; 214 Element element = this;
213 while (element.kind !== ElementKind.LIBRARY) { 215 while (element.kind !== ElementKind.LIBRARY) {
214 element = element.enclosingElement; 216 element = element.enclosingElement;
215 } 217 }
216 return element; 218 return element;
217 } 219 }
218 220
219 ClassElement getEnclosingClass() { 221 ClassElement getEnclosingClass() {
220 for (Element e = this; e !== null; e = e.enclosingElement) { 222 for (Element e = this; e !== null; e = e.enclosingElement) {
221 if (e.isClass()) return e; 223 if (e.isClass()) return e;
222 } 224 }
223 return null; 225 return null;
224 } 226 }
225 227
228 Element getEnclosingClassOrCompilationUnit() {
229 for (Element e = this; e !== null; e = e.enclosingElement) {
230 if (e.isClass() || e.isCompilationUnit()) return e;
231 }
232 return null;
233 }
234
226 Element getEnclosingMember() { 235 Element getEnclosingMember() {
227 for (Element e = this; e !== null; e = e.enclosingElement) { 236 for (Element e = this; e !== null; e = e.enclosingElement) {
228 if (e.isMember()) return e; 237 if (e.isMember()) return e;
229 } 238 }
230 return null; 239 return null;
231 } 240 }
232 241
233 Element getOutermostEnclosingMemberOrTopLevel() { 242 Element getOutermostEnclosingMemberOrTopLevel() {
234 // TODO(lrn): Why is this called "Outermost"? 243 // TODO(lrn): Why is this called "Outermost"?
235 for (Element e = this; e !== null; e = e.enclosingElement) { 244 for (Element e = this; e !== null; e = e.enclosingElement) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 listener.cancel('duplicate definition', token: element.position()); 322 listener.cancel('duplicate definition', token: element.position());
314 listener.cancel('existing definition', token: existing.position()); 323 listener.cancel('existing definition', token: existing.position());
315 } 324 }
316 } 325 }
317 } 326 }
318 327
319 Element localLookup(SourceString elementName) { 328 Element localLookup(SourceString elementName) {
320 return localScope[elementName]; 329 return localScope[elementName];
321 } 330 }
322 331
323 void addGetterOrSetter(Element element, 332 void addGetterOrSetter(FunctionElement element,
324 Element existing, 333 Element existing,
325 DiagnosticListener listener) { 334 DiagnosticListener listener) {
326 void reportError(Element other) { 335 void reportError(Element other) {
327 // TODO(ahe): Do something similar to Resolver.reportErrorWithContext. 336 // TODO(ahe): Do something similar to Resolver.reportErrorWithContext.
328 listener.cancel('duplicate definition of ${element.name.slowToString()}', 337 listener.cancel('duplicate definition of ${element.name.slowToString()}',
329 element: element); 338 element: element);
330 listener.cancel('existing definition', element: other); 339 listener.cancel('existing definition', element: other);
331 } 340 }
332 341
333 if (existing != null) { 342 if (existing != null) {
334 if (existing.kind !== ElementKind.ABSTRACT_FIELD) { 343 if (existing.kind !== ElementKind.ABSTRACT_FIELD) {
335 reportError(existing); 344 reportError(existing);
336 } else { 345 } else {
337 AbstractFieldElement field = existing; 346 AbstractFieldElement field = existing;
338 if (element.kind == ElementKind.GETTER) { 347 if (element.kind == ElementKind.GETTER) {
339 if (field.getter != null && field.getter != element) { 348 if (field.getter != null && field.getter != element) {
340 reportError(field.getter); 349 reportError(field.getter);
341 } 350 }
342 field.getter = element; 351 field.getter = element;
343 } else { 352 } else {
344 if (field.setter != null && field.setter != element) { 353 if (field.setter != null && field.setter != element) {
345 reportError(field.setter); 354 reportError(field.setter);
346 } 355 }
347 field.setter = element; 356 field.setter = element;
348 } 357 }
349 } 358 }
350 } else { 359 } else {
351 AbstractFieldElement field = new AbstractFieldElement(element.name, this); 360 Element container = element.getEnclosingClassOrCompilationUnit();
361 AbstractFieldElement field =
362 new AbstractFieldElement(element.name, container);
352 if (element.kind == ElementKind.GETTER) { 363 if (element.kind == ElementKind.GETTER) {
353 field.getter = element; 364 field.getter = element;
354 } else { 365 } else {
355 field.setter = element; 366 field.setter = element;
356 } 367 }
357 addMember(field, listener); 368 addMember(field, listener);
358 } 369 }
359 } 370 }
360 } 371 }
361 372
(...skipping 16 matching lines...) Expand all
378 389
379 class CompilationUnitOverrideElement extends Element { 390 class CompilationUnitOverrideElement extends Element {
380 final CompilationUnitElement compilationUnit; 391 final CompilationUnitElement compilationUnit;
381 392
382 CompilationUnitOverrideElement(CompilationUnitElement compilationUnit, 393 CompilationUnitOverrideElement(CompilationUnitElement compilationUnit,
383 Element enclosing) 394 Element enclosing)
384 : this.compilationUnit = compilationUnit, 395 : this.compilationUnit = compilationUnit,
385 super(compilationUnit.name, 396 super(compilationUnit.name,
386 ElementKind.COMPILATION_UNIT_OVERRIDE, 397 ElementKind.COMPILATION_UNIT_OVERRIDE,
387 enclosing); 398 enclosing);
388
389 CompilationUnitElement asCompilationUnit() => compilationUnit;
390
391 CompilationUnitElement getCompilationUnit() => compilationUnit;
392 } 399 }
393 400
394 class LibraryElement extends ScopeContainerElement { 401 class LibraryElement extends ScopeContainerElement {
395 CompilationUnitElement entryCompilationUnit; 402 CompilationUnitElement entryCompilationUnit;
396 Link<CompilationUnitElement> compilationUnits = 403 Link<CompilationUnitElement> compilationUnits =
397 const EmptyLink<CompilationUnitElement>(); 404 const EmptyLink<CompilationUnitElement>();
398 405
399 Link<ScriptTag> tags = const EmptyLink<ScriptTag>(); 406 Link<ScriptTag> tags = const EmptyLink<ScriptTag>();
400 ScriptTag libraryTag; 407 ScriptTag libraryTag;
401 bool canUseNative = false; 408 bool canUseNative = false;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 String getLibraryOrScriptName() { 461 String getLibraryOrScriptName() {
455 if (libraryTag !== null) { 462 if (libraryTag !== null) {
456 return libraryTag.argument.dartString.slowToString(); 463 return libraryTag.argument.dartString.slowToString();
457 } else { 464 } else {
458 // Use the file name as script name. 465 // Use the file name as script name.
459 String path = uri.path; 466 String path = uri.path;
460 return path.substring(path.lastIndexOf('/') + 1); 467 return path.substring(path.lastIndexOf('/') + 1);
461 } 468 }
462 } 469 }
463 470
464 CompilationUnitElement getCompilationUnit() => entryCompilationUnit;
465
466 Scope buildEnclosingScope() => new TopScope(this); 471 Scope buildEnclosingScope() => new TopScope(this);
467 } 472 }
468 473
469 class PrefixElement extends Element { 474 class PrefixElement extends Element {
470 Map<SourceString, Element> imported; 475 Map<SourceString, Element> imported;
471 Token firstPosition; 476 Token firstPosition;
472 477
473 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition) 478 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition)
474 : imported = new Map<SourceString, Element>(), 479 : imported = new Map<SourceString, Element>(),
475 super(prefix, ElementKind.PREFIX, enclosing); 480 super(prefix, ElementKind.PREFIX, enclosing);
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 697
693 Node parseNode(DiagnosticListener listener) { 698 Node parseNode(DiagnosticListener listener) {
694 throw "internal error: AbstractFieldElement has no node"; 699 throw "internal error: AbstractFieldElement has no node";
695 } 700 }
696 701
697 position() { 702 position() {
698 // The getter and setter may be defined in two different 703 // The getter and setter may be defined in two different
699 // compilation units. However, we know that one of them is 704 // compilation units. However, we know that one of them is
700 // non-null and defined in the same compilation unit as the 705 // non-null and defined in the same compilation unit as the
701 // abstract element. 706 // abstract element.
707 // TODO(lrn): No we don't know that if the element from the same
708 // compilation unit is patched.
702 // 709 //
703 // We need to make sure that the position returned is relative to 710 // We need to make sure that the position returned is relative to
704 // the compilation unit of the abstract element. 711 // the compilation unit of the abstract element.
705 if (getter !== null 712 if (getter !== null
706 && getter.getCompilationUnit() === getCompilationUnit()) { 713 && getter.getCompilationUnit() === getCompilationUnit()) {
707 return getter.position(); 714 return getter.position();
708 } else { 715 } else {
709 return setter.position(); 716 return setter.position();
710 } 717 }
711 } 718 }
712 719
713 Modifiers get modifiers() { 720 Modifiers get modifiers() {
714 // The resolver ensures that the flags match (ignoring abstract). 721 // The resolver ensures that the flags match (ignoring abstract).
715 if (getter !== null) { 722 if (getter !== null) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 FunctionElement.tooMuchOverloading(SourceString name, 811 FunctionElement.tooMuchOverloading(SourceString name,
805 FunctionExpression this.cachedNode, 812 FunctionExpression this.cachedNode,
806 ElementKind kind, 813 ElementKind kind,
807 Modifiers this.modifiers, 814 Modifiers this.modifiers,
808 Element enclosing, 815 Element enclosing,
809 FunctionSignature this.functionSignature) 816 FunctionSignature this.functionSignature)
810 : super(name, kind, enclosing) { 817 : super(name, kind, enclosing) {
811 defaultImplementation = this; 818 defaultImplementation = this;
812 } 819 }
813 820
814 Script getScript() {
815 if (patch !== null) return patch.getScript();
816 return super.getScript();
817 }
818
819 bool get isPatched() => patch !== null; 821 bool get isPatched() => patch !== null;
820 822
821 /** 823 /**
822 * Applies a patch function to this function. The patch function's body 824 * Applies a patch function to this function. The patch function's body
823 * is used as replacement when parsing this function's body. 825 * is used as replacement when parsing this function's body.
824 * This method must not be called after the function has been parsed, 826 * This method must not be called after the function has been parsed,
825 * and it must be called at most once. 827 * and it must be called at most once.
826 */ 828 */
827 void setPatch(FunctionElement patchElement) { 829 void setPatch(FunctionElement patchElement) {
828 // Sanity checks. The caller must check these things before calling. 830 // Sanity checks. The caller must check these things before calling.
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 Node parseNode(compiler) => cachedNode; 1451 Node parseNode(compiler) => cachedNode;
1450 1452
1451 String toString() => "${enclosingElement.toString()}.${name.slowToString()}"; 1453 String toString() => "${enclosingElement.toString()}.${name.slowToString()}";
1452 1454
1453 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) { 1455 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) {
1454 TypeVariableElement result = 1456 TypeVariableElement result =
1455 new TypeVariableElement(name, enclosing, node, type, bound); 1457 new TypeVariableElement(name, enclosing, node, type, bound);
1456 return result; 1458 return result;
1457 } 1459 }
1458 } 1460 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/dart_backend/emitter.dart ('k') | lib/compiler/implementation/js/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698