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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/elements/modelx.dart

Issue 266913017: Convert property methods into getters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased Created 6 years, 7 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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.modelx; 5 library elements.modelx;
6 6
7 import 'elements.dart'; 7 import 'elements.dart';
8 import '../helpers/helpers.dart'; 8 import '../helpers/helpers.dart';
9 import '../tree/tree.dart'; 9 import '../tree/tree.dart';
10 import '../util/util.dart'; 10 import '../util/util.dart';
(...skipping 26 matching lines...) Expand all
37 abstract class ElementX implements Element { 37 abstract class ElementX implements Element {
38 static int elementHashCode = 0; 38 static int elementHashCode = 0;
39 39
40 final String name; 40 final String name;
41 final ElementKind kind; 41 final ElementKind kind;
42 final Element enclosingElement; 42 final Element enclosingElement;
43 final int hashCode = ++elementHashCode; 43 final int hashCode = ++elementHashCode;
44 Link<MetadataAnnotation> metadata = const Link<MetadataAnnotation>(); 44 Link<MetadataAnnotation> metadata = const Link<MetadataAnnotation>();
45 45
46 ElementX(this.name, this.kind, this.enclosingElement) { 46 ElementX(this.name, this.kind, this.enclosingElement) {
47 assert(isErroneous() || getImplementationLibrary() != null); 47 assert(isErroneous || implementationLibrary != null);
48 } 48 }
49 49
50 Modifiers get modifiers => Modifiers.EMPTY; 50 Modifiers get modifiers => Modifiers.EMPTY;
51 51
52 Node parseNode(DiagnosticListener listener) { 52 Node parseNode(DiagnosticListener listener) {
53 listener.internalError(this, 'Not implemented.'); 53 listener.internalError(this, 'Not implemented.');
54 return null; 54 return null;
55 } 55 }
56 56
57 DartType computeType(Compiler compiler) { 57 DartType computeType(Compiler compiler) {
58 compiler.internalError(this, "$this.computeType."); 58 compiler.internalError(this, "$this.computeType.");
59 return null; 59 return null;
60 } 60 }
61 61
62 void addMetadata(MetadataAnnotation annotation) { 62 void addMetadata(MetadataAnnotation annotation) {
63 assert(annotation.annotatedElement == null); 63 assert(annotation.annotatedElement == null);
64 annotation.annotatedElement = this; 64 annotation.annotatedElement = this;
65 addMetadataInternal(annotation); 65 addMetadataInternal(annotation);
66 } 66 }
67 67
68 void addMetadataInternal(MetadataAnnotation annotation) { 68 void addMetadataInternal(MetadataAnnotation annotation) {
69 metadata = metadata.prepend(annotation); 69 metadata = metadata.prepend(annotation);
70 } 70 }
71 71
72 72
73 bool isFunction() => identical(kind, ElementKind.FUNCTION); 73 bool get isFunction => identical(kind, ElementKind.FUNCTION);
74 bool isConstructor() => isFactoryConstructor() || isGenerativeConstructor(); 74 bool get isConstructor => isFactoryConstructor || isGenerativeConstructor;
75 bool isClosure() => false; 75 bool get isClosure => false;
76 bool isMember() { 76 bool get isMember {
77 // Check that this element is defined in the scope of a Class. 77 // Check that this element is defined in the scope of a Class.
78 return enclosingElement != null && enclosingElement.isClass(); 78 return enclosingElement != null && enclosingElement.isClass;
79 } 79 }
80 bool isInstanceMember() => false; 80 bool get isInstanceMember => false;
81 bool isDeferredLoaderGetter() => false; 81 bool get isDeferredLoaderGetter => false;
82 82
83 bool isFactoryConstructor() => modifiers.isFactory(); 83 bool get isFactoryConstructor => modifiers.isFactory;
84 bool isGenerativeConstructor() => 84 bool get isGenerativeConstructor =>
85 identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR); 85 identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR);
86 bool isGenerativeConstructorBody() => 86 bool get isGenerativeConstructorBody =>
87 identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR_BODY); 87 identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR_BODY);
88 bool isCompilationUnit() => identical(kind, ElementKind.COMPILATION_UNIT); 88 bool get isCompilationUnit => identical(kind, ElementKind.COMPILATION_UNIT);
89 bool isClass() => identical(kind, ElementKind.CLASS); 89 bool get isClass => identical(kind, ElementKind.CLASS);
90 bool isPrefix() => identical(kind, ElementKind.PREFIX); 90 bool get isPrefix => identical(kind, ElementKind.PREFIX);
91 bool isVariable() => identical(kind, ElementKind.VARIABLE); 91 bool get isVariable => identical(kind, ElementKind.VARIABLE);
92 bool isParameter() => identical(kind, ElementKind.PARAMETER); 92 bool get isParameter => identical(kind, ElementKind.PARAMETER);
93 bool isStatement() => identical(kind, ElementKind.STATEMENT); 93 bool get isStatement => identical(kind, ElementKind.STATEMENT);
94 bool isTypedef() => identical(kind, ElementKind.TYPEDEF); 94 bool get isTypedef => identical(kind, ElementKind.TYPEDEF);
95 bool isTypeVariable() => identical(kind, ElementKind.TYPE_VARIABLE); 95 bool get isTypeVariable => identical(kind, ElementKind.TYPE_VARIABLE);
96 bool isField() => identical(kind, ElementKind.FIELD); 96 bool get isField => identical(kind, ElementKind.FIELD);
97 bool isFieldParameter() => identical(kind, ElementKind.FIELD_PARAMETER); 97 bool get isFieldParameter => identical(kind, ElementKind.FIELD_PARAMETER);
98 bool isAbstractField() => identical(kind, ElementKind.ABSTRACT_FIELD); 98 bool get isAbstractField => identical(kind, ElementKind.ABSTRACT_FIELD);
99 bool isGetter() => identical(kind, ElementKind.GETTER); 99 bool get isGetter => identical(kind, ElementKind.GETTER);
100 bool isSetter() => identical(kind, ElementKind.SETTER); 100 bool get isSetter => identical(kind, ElementKind.SETTER);
101 bool isAccessor() => isGetter() || isSetter(); 101 bool get isAccessor => isGetter || isSetter;
102 bool isLibrary() => identical(kind, ElementKind.LIBRARY); 102 bool get isLibrary => identical(kind, ElementKind.LIBRARY);
103 bool impliesType() => (kind.category & ElementCategory.IMPLIES_TYPE) != 0; 103 bool get impliesType => (kind.category & ElementCategory.IMPLIES_TYPE) != 0;
104 104
105 /** See [ErroneousElement] for documentation. */ 105 /** See [ErroneousElement] for documentation. */
106 bool isErroneous() => false; 106 bool get isErroneous => false;
107 107
108 /** See [AmbiguousElement] for documentation. */ 108 /** See [AmbiguousElement] for documentation. */
109 bool isAmbiguous() => false; 109 bool get isAmbiguous => false;
110 110
111 /** See [WarnOnUseElement] for documentation. */ 111 /** See [WarnOnUseElement] for documentation. */
112 bool isWarnOnUse() => false; 112 bool get isWarnOnUse => false;
113 113
114 bool get isPatched => false; 114 bool get isPatched => false;
115 115
116 bool get isPatch => false; 116 bool get isPatch => false;
117 117
118 bool get isImplementation => true; 118 bool get isImplementation => true;
119 119
120 bool get isDeclaration => true; 120 bool get isDeclaration => true;
121 121
122 Element get implementation => this; 122 Element get implementation => this;
(...skipping 11 matching lines...) Expand all
134 bool get isSynthesized => false; 134 bool get isSynthesized => false;
135 135
136 bool get isForwardingConstructor => false; 136 bool get isForwardingConstructor => false;
137 137
138 bool get isMixinApplication => false; 138 bool get isMixinApplication => false;
139 139
140 // TODO(johnniwinther): This breaks for libraries (for which enclosing 140 // TODO(johnniwinther): This breaks for libraries (for which enclosing
141 // elements are null) and is invalid for top level variable declarations for 141 // elements are null) and is invalid for top level variable declarations for
142 // which the enclosing element is a VariableDeclarations and not a compilation 142 // which the enclosing element is a VariableDeclarations and not a compilation
143 // unit. 143 // unit.
144 bool isTopLevel() { 144 bool get isTopLevel {
145 return enclosingElement != null && enclosingElement.isCompilationUnit(); 145 return enclosingElement != null && enclosingElement.isCompilationUnit;
146 } 146 }
147 147
148 bool isAssignable() { 148 bool get isAssignable {
149 if (modifiers.isFinalOrConst()) return false; 149 if (modifiers.isFinalOrConst) return false;
150 if (isFunction() || isGenerativeConstructor()) return false; 150 if (isFunction || isGenerativeConstructor) return false;
151 return true; 151 return true;
152 } 152 }
153 153
154 Token position() => null; 154 Token get position => null;
155 155
156 Token findMyName(Token token) { 156 Token findMyName(Token token) {
157 return findNameToken(token, isConstructor(), name, enclosingElement.name); 157 return findNameToken(token, isConstructor, name, enclosingElement.name);
158 } 158 }
159 159
160 static Token findNameToken(Token token, bool isConstructor, String name, 160 static Token findNameToken(Token token, bool isConstructor, String name,
161 String enclosingClassName) { 161 String enclosingClassName) {
162 // We search for the token that has the name of this element. 162 // We search for the token that has the name of this element.
163 // For constructors, that doesn't work because they may have 163 // For constructors, that doesn't work because they may have
164 // named formed out of multiple tokens (named constructors) so 164 // named formed out of multiple tokens (named constructors) so
165 // for those we search for the class name instead. 165 // for those we search for the class name instead.
166 String needle = isConstructor ? enclosingClassName : name; 166 String needle = isConstructor ? enclosingClassName : name;
167 // The unary '-' operator has a special element name (specified). 167 // The unary '-' operator has a special element name (specified).
168 if (needle == 'unary-') needle = '-'; 168 if (needle == 'unary-') needle = '-';
169 for (Token t = token; EOF_TOKEN != t.kind; t = t.next) { 169 for (Token t = token; EOF_TOKEN != t.kind; t = t.next) {
170 if (needle == t.value) return t; 170 if (needle == t.value) return t;
171 } 171 }
172 return token; 172 return token;
173 } 173 }
174 174
175 CompilationUnitElement getCompilationUnit() { 175 CompilationUnitElement get compilationUnit {
176 Element element = this; 176 Element element = this;
177 while (!element.isCompilationUnit()) { 177 while (!element.isCompilationUnit) {
178 element = element.enclosingElement; 178 element = element.enclosingElement;
179 } 179 }
180 return element; 180 return element;
181 } 181 }
182 182
183 LibraryElement getLibrary() => enclosingElement.getLibrary(); 183 LibraryElement get library => enclosingElement.library;
184 184
185 LibraryElement getImplementationLibrary() { 185 LibraryElement get implementationLibrary {
186 Element element = this; 186 Element element = this;
187 while (!identical(element.kind, ElementKind.LIBRARY)) { 187 while (!identical(element.kind, ElementKind.LIBRARY)) {
188 element = element.enclosingElement; 188 element = element.enclosingElement;
189 } 189 }
190 return element; 190 return element;
191 } 191 }
192 192
193 ClassElement getEnclosingClass() { 193 ClassElement get enclosingClass {
194 for (Element e = this; e != null; e = e.enclosingElement) { 194 for (Element e = this; e != null; e = e.enclosingElement) {
195 if (e.isClass()) return e; 195 if (e.isClass) return e;
196 } 196 }
197 return null; 197 return null;
198 } 198 }
199 199
200 Element getEnclosingClassOrCompilationUnit() { 200 Element get enclosingClassOrCompilationUnit {
201 for (Element e = this; e != null; e = e.enclosingElement) { 201 for (Element e = this; e != null; e = e.enclosingElement) {
202 if (e.isClass() || e.isCompilationUnit()) return e; 202 if (e.isClass || e.isCompilationUnit) return e;
203 } 203 }
204 return null; 204 return null;
205 } 205 }
206 206
207 /** 207 /**
208 * Returns the member enclosing this element or the element itself if it is a 208 * Returns the member enclosing this element or the element itself if it is a
209 * member. If no enclosing element is found, [:null:] is returned. 209 * member. If no enclosing element is found, [:null:] is returned.
210 */ 210 */
211 Element getEnclosingMember() { 211 Element get enclosingMember {
212 for (Element e = this; e != null; e = e.enclosingElement) { 212 for (Element e = this; e != null; e = e.enclosingElement) {
213 if (e.isMember()) return e; 213 if (e.isMember) return e;
214 } 214 }
215 return null; 215 return null;
216 } 216 }
217 217
218 Element getOutermostEnclosingMemberOrTopLevel() { 218 Element get outermostEnclosingMemberOrTopLevel {
219 // TODO(lrn): Why is this called "Outermost"? 219 // TODO(lrn): Why is this called "Outermost"?
220 for (Element e = this; e != null; e = e.enclosingElement) { 220 for (Element e = this; e != null; e = e.enclosingElement) {
221 if (e.isMember() || e.isTopLevel()) { 221 if (e.isMember || e.isTopLevel) {
222 return e; 222 return e;
223 } 223 }
224 } 224 }
225 return null; 225 return null;
226 } 226 }
227 227
228 /** 228 /**
229 * Creates the scope for this element. 229 * Creates the scope for this element.
230 */ 230 */
231 Scope buildScope() => enclosingElement.buildScope(); 231 Scope buildScope() => enclosingElement.buildScope();
232 232
233 String toString() { 233 String toString() {
234 // TODO(johnniwinther): Test for nullness of name, or make non-nullness an 234 // TODO(johnniwinther): Test for nullness of name, or make non-nullness an
235 // invariant for all element types? 235 // invariant for all element types?
236 var nameText = name != null ? name : '?'; 236 var nameText = name != null ? name : '?';
237 if (enclosingElement != null && !isTopLevel()) { 237 if (enclosingElement != null && !isTopLevel) {
238 String holderName = enclosingElement.name != null 238 String holderName = enclosingElement.name != null
239 ? enclosingElement.name 239 ? enclosingElement.name
240 : '${enclosingElement.kind}?'; 240 : '${enclosingElement.kind}?';
241 return '$kind($holderName#${nameText})'; 241 return '$kind($holderName#${nameText})';
242 } else { 242 } else {
243 return '$kind(${nameText})'; 243 return '$kind(${nameText})';
244 } 244 }
245 } 245 }
246 246
247 String _fixedBackendName = null; 247 String _fixedBackendName = null;
248 bool _isNative = false; 248 bool _isNative = false;
249 bool isNative() => _isNative; 249 bool get isNative => _isNative;
250 bool hasFixedBackendName() => _fixedBackendName != null; 250 bool get hasFixedBackendName => _fixedBackendName != null;
251 String fixedBackendName() => _fixedBackendName; 251 String get fixedBackendName => _fixedBackendName;
252 // Marks this element as a native element. 252 // Marks this element as a native element.
253 void setNative(String name) { 253 void setNative(String name) {
254 _isNative = true; 254 _isNative = true;
255 _fixedBackendName = name; 255 _fixedBackendName = name;
256 } 256 }
257 void setFixedBackendName(String name) { 257 void setFixedBackendName(String name) {
258 _fixedBackendName = name; 258 _fixedBackendName = name;
259 } 259 }
260 260
261 FunctionElement asFunctionElement() => null; 261 FunctionElement asFunctionElement() => null;
262 262
263 bool get isAbstract => modifiers.isAbstract(); 263 bool get isAbstract => modifiers.isAbstract;
264 bool isForeign(Compiler compiler) => getLibrary() == compiler.foreignLibrary; 264 bool isForeign(Compiler compiler) => library == compiler.foreignLibrary;
265 265
266 FunctionElement get targetConstructor => null; 266 FunctionElement get targetConstructor => null;
267 267
268 void diagnose(Element context, DiagnosticListener listener) {} 268 void diagnose(Element context, DiagnosticListener listener) {}
269 269
270 TreeElements get treeElements => enclosingElement.treeElements; 270 TreeElements get treeElements => enclosingElement.treeElements;
271 } 271 }
272 272
273 /** 273 /**
274 * Represents an unresolvable or duplicated element. 274 * Represents an unresolvable or duplicated element.
(...skipping 13 matching lines...) Expand all
288 * [: element == null :]. 288 * [: element == null :].
289 */ 289 */
290 class ErroneousElementX extends ElementX implements ErroneousElement { 290 class ErroneousElementX extends ElementX implements ErroneousElement {
291 final MessageKind messageKind; 291 final MessageKind messageKind;
292 final Map messageArguments; 292 final Map messageArguments;
293 293
294 ErroneousElementX(this.messageKind, this.messageArguments, 294 ErroneousElementX(this.messageKind, this.messageArguments,
295 String name, Element enclosing) 295 String name, Element enclosing)
296 : super(name, ElementKind.ERROR, enclosing); 296 : super(name, ElementKind.ERROR, enclosing);
297 297
298 isErroneous() => true; 298 bool get isErroneous => true;
299 299
300 AbstractFieldElement abstractField; 300 AbstractFieldElement abstractField;
301 301
302 unsupported() { 302 unsupported() {
303 throw 'unsupported operation on erroneous element'; 303 throw 'unsupported operation on erroneous element';
304 } 304 }
305 305
306 Link<MetadataAnnotation> get metadata => unsupported(); 306 Link<MetadataAnnotation> get metadata => unsupported();
307 get node => unsupported(); 307 get node => unsupported();
308 get type => unsupported(); 308 get type => unsupported();
309 get cachedNode => unsupported(); 309 get cachedNode => unsupported();
310 get functionSignature => unsupported(); 310 get functionSignature => unsupported();
311 get patch => null; 311 get patch => null;
312 get origin => this; 312 get origin => this;
313 get defaultImplementation => unsupported(); 313 get defaultImplementation => unsupported();
314 get nestedClosures => unsupported(); 314 get nestedClosures => unsupported();
315 315
316 bool get isRedirectingFactory => unsupported(); 316 bool get isRedirectingFactory => unsupported();
317 317
318 computeSignature(compiler) => unsupported(); 318 computeSignature(compiler) => unsupported();
319 319
320 // TODO(kasperl): These seem unnecessary. 320 // TODO(kasperl): These seem unnecessary.
321 set defaultImplementation(value) => unsupported(); 321 set defaultImplementation(value) => unsupported();
322 322
323 get redirectionTarget => this; 323 get redirectionTarget => this;
324 324
325 getLibrary() => enclosingElement.getLibrary();
326
327 computeTargetType(InterfaceType newType) => unsupported(); 325 computeTargetType(InterfaceType newType) => unsupported();
328 326
329 String get message => '${messageKind.message(messageArguments)}'; 327 String get message => '${messageKind.message(messageArguments)}';
330 328
331 String toString() => '<$name: $message>'; 329 String toString() => '<$name: $message>';
332 330
333 accept(ElementVisitor visitor) => visitor.visitErroneousElement(this); 331 accept(ElementVisitor visitor) => visitor.visitErroneousElement(this);
334 } 332 }
335 333
336 /// A message attached to a [WarnOnUseElementX]. 334 /// A message attached to a [WarnOnUseElementX].
(...skipping 26 matching lines...) Expand all
363 final WrappedMessage info; 361 final WrappedMessage info;
364 362
365 /// The element whose usage cause a warning. 363 /// The element whose usage cause a warning.
366 final Element wrappedElement; 364 final Element wrappedElement;
367 365
368 WarnOnUseElementX(WrappedMessage this.warning, WrappedMessage this.info, 366 WarnOnUseElementX(WrappedMessage this.warning, WrappedMessage this.info,
369 Element enclosingElement, Element wrappedElement) 367 Element enclosingElement, Element wrappedElement)
370 : this.wrappedElement = wrappedElement, 368 : this.wrappedElement = wrappedElement,
371 super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement); 369 super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement);
372 370
373 bool isWarnOnUse() => true; 371 bool get isWarnOnUse => true;
374 372
375 Element unwrap(DiagnosticListener listener, Spannable usageSpannable) { 373 Element unwrap(DiagnosticListener listener, Spannable usageSpannable) {
376 var unwrapped = wrappedElement; 374 var unwrapped = wrappedElement;
377 if (warning != null) { 375 if (warning != null) {
378 Spannable spannable = warning.spannable; 376 Spannable spannable = warning.spannable;
379 if (spannable == null) spannable = usageSpannable; 377 if (spannable == null) spannable = usageSpannable;
380 listener.reportWarning( 378 listener.reportWarning(
381 spannable, warning.messageKind, warning.messageArguments); 379 spannable, warning.messageKind, warning.messageArguments);
382 } 380 }
383 if (info != null) { 381 if (info != null) {
384 Spannable spannable = info.spannable; 382 Spannable spannable = info.spannable;
385 if (spannable == null) spannable = usageSpannable; 383 if (spannable == null) spannable = usageSpannable;
386 listener.reportInfo( 384 listener.reportInfo(
387 spannable, info.messageKind, info.messageArguments); 385 spannable, info.messageKind, info.messageArguments);
388 } 386 }
389 if (unwrapped.isWarnOnUse()) { 387 if (unwrapped.isWarnOnUse) {
390 unwrapped = unwrapped.unwrap(listener, usageSpannable); 388 unwrapped = unwrapped.unwrap(listener, usageSpannable);
391 } 389 }
392 return unwrapped; 390 return unwrapped;
393 } 391 }
394 392
395 accept(ElementVisitor visitor) => visitor.visitWarnOnUseElement(this); 393 accept(ElementVisitor visitor) => visitor.visitWarnOnUseElement(this);
396 } 394 }
397 395
398 /** 396 /**
399 * An ambiguous element represents multiple elements accessible by the same name . 397 * An ambiguous element represents multiple elements accessible by the same name .
(...skipping 22 matching lines...) Expand all
422 * The second element that this ambiguous element might refer to. 420 * The second element that this ambiguous element might refer to.
423 */ 421 */
424 final Element newElement; 422 final Element newElement;
425 423
426 AmbiguousElementX(this.messageKind, this.messageArguments, 424 AmbiguousElementX(this.messageKind, this.messageArguments,
427 Element enclosingElement, Element existingElement, Element newElement) 425 Element enclosingElement, Element existingElement, Element newElement)
428 : this.existingElement = existingElement, 426 : this.existingElement = existingElement,
429 this.newElement = newElement, 427 this.newElement = newElement,
430 super(existingElement.name, ElementKind.AMBIGUOUS, enclosingElement); 428 super(existingElement.name, ElementKind.AMBIGUOUS, enclosingElement);
431 429
432 bool isAmbiguous() => true; 430 bool get isAmbiguous => true;
433 431
434 Setlet flatten() { 432 Setlet flatten() {
435 Element element = this; 433 Element element = this;
436 var set = new Setlet(); 434 var set = new Setlet();
437 while (element.isAmbiguous()) { 435 while (element.isAmbiguous) {
438 AmbiguousElement ambiguous = element; 436 AmbiguousElement ambiguous = element;
439 set.add(ambiguous.newElement); 437 set.add(ambiguous.newElement);
440 element = ambiguous.existingElement; 438 element = ambiguous.existingElement;
441 } 439 }
442 set.add(element); 440 set.add(element);
443 return set; 441 return set;
444 } 442 }
445 443
446 void diagnose(Element context, DiagnosticListener listener) { 444 void diagnose(Element context, DiagnosticListener listener) {
447 Setlet ambiguousElements = flatten(); 445 Setlet ambiguousElements = flatten();
448 MessageKind code = (ambiguousElements.length == 1) 446 MessageKind code = (ambiguousElements.length == 1)
449 ? MessageKind.AMBIGUOUS_REEXPORT : MessageKind.AMBIGUOUS_LOCATION; 447 ? MessageKind.AMBIGUOUS_REEXPORT : MessageKind.AMBIGUOUS_LOCATION;
450 LibraryElementX importer = context.getLibrary(); 448 LibraryElementX importer = context.library;
451 for (Element element in ambiguousElements) { 449 for (Element element in ambiguousElements) {
452 var arguments = {'name': element.name}; 450 var arguments = {'name': element.name};
453 listener.reportInfo(element, code, arguments); 451 listener.reportInfo(element, code, arguments);
454 Link<Import> importers = importer.importers.getImports(element); 452 Link<Import> importers = importer.importers.getImports(element);
455 listener.withCurrentElement(importer, () { 453 listener.withCurrentElement(importer, () {
456 for (; !importers.isEmpty; importers = importers.tail) { 454 for (; !importers.isEmpty; importers = importers.tail) {
457 listener.reportInfo( 455 listener.reportInfo(
458 importers.head, MessageKind.IMPORTED_HERE, arguments); 456 importers.head, MessageKind.IMPORTED_HERE, arguments);
459 } 457 }
460 }); 458 });
461 } 459 }
462 } 460 }
463 461
464 accept(ElementVisitor visitor) => visitor.visitAmbiguousElement(this); 462 accept(ElementVisitor visitor) => visitor.visitAmbiguousElement(this);
465 } 463 }
466 464
467 class ScopeX { 465 class ScopeX {
468 final Map<String, Element> contents = new Map<String, Element>(); 466 final Map<String, Element> contents = new Map<String, Element>();
469 467
470 bool get isEmpty => contents.isEmpty; 468 bool get isEmpty => contents.isEmpty;
471 Iterable<Element> get values => contents.values; 469 Iterable<Element> get values => contents.values;
472 470
473 Element lookup(String name) { 471 Element lookup(String name) {
474 return contents[name]; 472 return contents[name];
475 } 473 }
476 474
477 void add(Element element, DiagnosticListener listener) { 475 void add(Element element, DiagnosticListener listener) {
478 String name = element.name; 476 String name = element.name;
479 if (element.isAccessor()) { 477 if (element.isAccessor) {
480 addAccessor(element, contents[name], listener); 478 addAccessor(element, contents[name], listener);
481 } else { 479 } else {
482 Element existing = contents.putIfAbsent(name, () => element); 480 Element existing = contents.putIfAbsent(name, () => element);
483 if (!identical(existing, element)) { 481 if (!identical(existing, element)) {
484 listener.reportError( 482 listener.reportError(
485 element, MessageKind.DUPLICATE_DEFINITION, {'name': name}); 483 element, MessageKind.DUPLICATE_DEFINITION, {'name': name});
486 listener.reportInfo(existing, 484 listener.reportInfo(existing,
487 MessageKind.EXISTING_DEFINITION, {'name': name}); 485 MessageKind.EXISTING_DEFINITION, {'name': name});
488 } 486 }
489 } 487 }
(...skipping 24 matching lines...) Expand all
514 MessageKind.EXISTING_DEFINITION, 512 MessageKind.EXISTING_DEFINITION,
515 {'name': accessor.name}); 513 {'name': accessor.name});
516 } 514 }
517 515
518 if (existing != null) { 516 if (existing != null) {
519 if (!identical(existing.kind, ElementKind.ABSTRACT_FIELD)) { 517 if (!identical(existing.kind, ElementKind.ABSTRACT_FIELD)) {
520 reportError(existing); 518 reportError(existing);
521 } else { 519 } else {
522 AbstractFieldElementX field = existing; 520 AbstractFieldElementX field = existing;
523 accessor.abstractField = field; 521 accessor.abstractField = field;
524 if (accessor.isGetter()) { 522 if (accessor.isGetter) {
525 if (field.getter != null && field.getter != accessor) { 523 if (field.getter != null && field.getter != accessor) {
526 reportError(field.getter); 524 reportError(field.getter);
527 } 525 }
528 field.getter = accessor; 526 field.getter = accessor;
529 } else { 527 } else {
530 assert(accessor.isSetter()); 528 assert(accessor.isSetter);
531 if (field.setter != null && field.setter != accessor) { 529 if (field.setter != null && field.setter != accessor) {
532 reportError(field.setter); 530 reportError(field.setter);
533 } 531 }
534 field.setter = accessor; 532 field.setter = accessor;
535 } 533 }
536 } 534 }
537 } else { 535 } else {
538 Element container = accessor.getEnclosingClassOrCompilationUnit(); 536 Element container = accessor.enclosingClassOrCompilationUnit;
539 AbstractFieldElementX field = 537 AbstractFieldElementX field =
540 new AbstractFieldElementX(accessor.name, container); 538 new AbstractFieldElementX(accessor.name, container);
541 accessor.abstractField = field; 539 accessor.abstractField = field;
542 if (accessor.isGetter()) { 540 if (accessor.isGetter) {
543 field.getter = accessor; 541 field.getter = accessor;
544 } else { 542 } else {
545 field.setter = accessor; 543 field.setter = accessor;
546 } 544 }
547 add(field, listener); 545 add(field, listener);
548 } 546 }
549 } 547 }
550 } 548 }
551 549
552 class CompilationUnitElementX extends ElementX with AnalyzableElement 550 class CompilationUnitElementX extends ElementX with AnalyzableElement
(...skipping 12 matching lines...) Expand all
565 563
566 void forEachLocalMember(f(Element element)) { 564 void forEachLocalMember(f(Element element)) {
567 localMembers.forEach(f); 565 localMembers.forEach(f);
568 } 566 }
569 567
570 void addMember(Element element, DiagnosticListener listener) { 568 void addMember(Element element, DiagnosticListener listener) {
571 // Keep a list of top level members. 569 // Keep a list of top level members.
572 localMembers = localMembers.prepend(element); 570 localMembers = localMembers.prepend(element);
573 // Provide the member to the library to build scope. 571 // Provide the member to the library to build scope.
574 if (enclosingElement.isPatch) { 572 if (enclosingElement.isPatch) {
575 getImplementationLibrary().addMember(element, listener); 573 implementationLibrary.addMember(element, listener);
576 } else { 574 } else {
577 getLibrary().addMember(element, listener); 575 library.addMember(element, listener);
578 } 576 }
579 } 577 }
580 578
581 void setPartOf(PartOf tag, DiagnosticListener listener) { 579 void setPartOf(PartOf tag, DiagnosticListener listener) {
582 LibraryElementX library = enclosingElement; 580 LibraryElementX library = enclosingElement;
583 if (library.entryCompilationUnit == this) { 581 if (library.entryCompilationUnit == this) {
584 listener.reportError(tag, MessageKind.ILLEGAL_DIRECTIVE); 582 listener.reportError(tag, MessageKind.ILLEGAL_DIRECTIVE);
585 return; 583 return;
586 } 584 }
587 if (!localMembers.isEmpty) { 585 if (!localMembers.isEmpty) {
588 listener.reportError(tag, MessageKind.BEFORE_TOP_LEVEL); 586 listener.reportError(tag, MessageKind.BEFORE_TOP_LEVEL);
589 return; 587 return;
590 } 588 }
591 if (partTag != null) { 589 if (partTag != null) {
592 listener.reportWarning(tag, MessageKind.DUPLICATED_PART_OF); 590 listener.reportWarning(tag, MessageKind.DUPLICATED_PART_OF);
593 return; 591 return;
594 } 592 }
595 partTag = tag; 593 partTag = tag;
596 LibraryName libraryTag = getLibrary().libraryTag; 594 LibraryName libraryTag = library.libraryTag;
597 String actualName = tag.name.toString(); 595 String actualName = tag.name.toString();
598 if (libraryTag != null) { 596 if (libraryTag != null) {
599 String expectedName = libraryTag.name.toString(); 597 String expectedName = libraryTag.name.toString();
600 if (expectedName != actualName) { 598 if (expectedName != actualName) {
601 listener.reportWarning(tag.name, 599 listener.reportWarning(tag.name,
602 MessageKind.LIBRARY_NAME_MISMATCH, 600 MessageKind.LIBRARY_NAME_MISMATCH,
603 {'libraryName': expectedName}); 601 {'libraryName': expectedName});
604 } 602 }
605 } else { 603 } else {
606 listener.reportWarning(getLibrary(), 604 listener.reportWarning(library,
607 MessageKind.MISSING_LIBRARY_NAME, 605 MessageKind.MISSING_LIBRARY_NAME,
608 {'libraryName': actualName}); 606 {'libraryName': actualName});
609 listener.reportInfo(tag.name, 607 listener.reportInfo(tag.name,
610 MessageKind.THIS_IS_THE_PART_OF_TAG); 608 MessageKind.THIS_IS_THE_PART_OF_TAG);
611 } 609 }
612 } 610 }
613 611
614 bool get hasMembers => !localMembers.isEmpty; 612 bool get hasMembers => !localMembers.isEmpty;
615 613
616 int compareTo(CompilationUnitElement other) { 614 int compareTo(CompilationUnitElement other) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 * Adds [element] to the import scope of this library. 652 * Adds [element] to the import scope of this library.
655 * 653 *
656 * If an element by the same name is already in the imported scope, an 654 * If an element by the same name is already in the imported scope, an
657 * [ErroneousElement] will be put in the imported scope, allowing for 655 * [ErroneousElement] will be put in the imported scope, allowing for
658 * detection of ambiguous uses of imported names. 656 * detection of ambiguous uses of imported names.
659 */ 657 */
660 void addImport(Element enclosingElement, 658 void addImport(Element enclosingElement,
661 Element element, 659 Element element,
662 Import import, 660 Import import,
663 DiagnosticListener listener) { 661 DiagnosticListener listener) {
664 LibraryElementX library = enclosingElement.getLibrary(); 662 LibraryElementX library = enclosingElement.library;
665 Importers importers = library.importers; 663 Importers importers = library.importers;
666 664
667 String name = element.name; 665 String name = element.name;
668 666
669 // The loadLibrary function always shadows existing bindings to that name. 667 // The loadLibrary function always shadows existing bindings to that name.
670 if (element.isDeferredLoaderGetter()) { 668 if (element.isDeferredLoaderGetter) {
671 importScope.remove(name); 669 importScope.remove(name);
672 // TODO(sigurdm): Print a hint. 670 // TODO(sigurdm): Print a hint.
673 } 671 }
674 Element existing = importScope.putIfAbsent(name, () => element); 672 Element existing = importScope.putIfAbsent(name, () => element);
675 importers.registerImport(element, import); 673 importers.registerImport(element, import);
676 674
677 void registerWarnOnUseElement(Import import, 675 void registerWarnOnUseElement(Import import,
678 MessageKind messageKind, 676 MessageKind messageKind,
679 Element hidingElement, 677 Element hidingElement,
680 Element hiddenElement) { 678 Element hiddenElement) {
681 Uri hiddenUri = hiddenElement.getLibrary().canonicalUri; 679 Uri hiddenUri = hiddenElement.library.canonicalUri;
682 Uri hidingUri = hidingElement.getLibrary().canonicalUri; 680 Uri hidingUri = hidingElement.library.canonicalUri;
683 Element element = new WarnOnUseElementX( 681 Element element = new WarnOnUseElementX(
684 new WrappedMessage( 682 new WrappedMessage(
685 null, // Report on reference to [hidingElement]. 683 null, // Report on reference to [hidingElement].
686 messageKind, 684 messageKind,
687 {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}), 685 {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}),
688 new WrappedMessage( 686 new WrappedMessage(
689 listener.spanFromSpannable(import), 687 listener.spanFromSpannable(import),
690 MessageKind.IMPORTED_HERE, 688 MessageKind.IMPORTED_HERE,
691 {'name': name}), 689 {'name': name}),
692 enclosingElement, hidingElement); 690 enclosingElement, hidingElement);
693 importScope[name] = element; 691 importScope[name] = element;
694 importers.registerImport(element, import); 692 importers.registerImport(element, import);
695 } 693 }
696 694
697 if (existing != element) { 695 if (existing != element) {
698 Import existingImport = importers.getImport(existing); 696 Import existingImport = importers.getImport(existing);
699 Element newElement; 697 Element newElement;
700 if (existing.getLibrary().isPlatformLibrary && 698 if (existing.library.isPlatformLibrary &&
701 !element.getLibrary().isPlatformLibrary) { 699 !element.library.isPlatformLibrary) {
702 // [existing] is implicitly hidden. 700 // [existing] is implicitly hidden.
703 registerWarnOnUseElement( 701 registerWarnOnUseElement(
704 import, MessageKind.HIDDEN_IMPORT, element, existing); 702 import, MessageKind.HIDDEN_IMPORT, element, existing);
705 } else if (!existing.getLibrary().isPlatformLibrary && 703 } else if (!existing.library.isPlatformLibrary &&
706 element.getLibrary().isPlatformLibrary) { 704 element.library.isPlatformLibrary) {
707 // [element] is implicitly hidden. 705 // [element] is implicitly hidden.
708 if (import == null) { 706 if (import == null) {
709 // [element] is imported implicitly (probably through dart:core). 707 // [element] is imported implicitly (probably through dart:core).
710 registerWarnOnUseElement( 708 registerWarnOnUseElement(
711 existingImport, MessageKind.HIDDEN_IMPLICIT_IMPORT, 709 existingImport, MessageKind.HIDDEN_IMPLICIT_IMPORT,
712 existing, element); 710 existing, element);
713 } else { 711 } else {
714 registerWarnOnUseElement( 712 registerWarnOnUseElement(
715 import, MessageKind.HIDDEN_IMPORT, existing, element); 713 import, MessageKind.HIDDEN_IMPORT, existing, element);
716 } 714 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 769
772 Link<MetadataAnnotation> get metadata { 770 Link<MetadataAnnotation> get metadata {
773 return (libraryTag == null) ? super.metadata : libraryTag.metadata; 771 return (libraryTag == null) ? super.metadata : libraryTag.metadata;
774 } 772 }
775 773
776 set metadata(value) { 774 set metadata(value) {
777 // The metadata is stored on [libraryTag]. 775 // The metadata is stored on [libraryTag].
778 throw new SpannableAssertionFailure(this, 'Cannot set metadata on Library'); 776 throw new SpannableAssertionFailure(this, 'Cannot set metadata on Library');
779 } 777 }
780 778
781 CompilationUnitElement getCompilationUnit() => entryCompilationUnit; 779 CompilationUnitElement get compilationUnit => entryCompilationUnit;
782 780
783 void addCompilationUnit(CompilationUnitElement element) { 781 void addCompilationUnit(CompilationUnitElement element) {
784 compilationUnits = compilationUnits.prepend(element); 782 compilationUnits = compilationUnits.prepend(element);
785 } 783 }
786 784
787 void addTag(LibraryTag tag, DiagnosticListener listener) { 785 void addTag(LibraryTag tag, DiagnosticListener listener) {
788 tags = tags.prepend(tag); 786 tags = tags.prepend(tag);
789 } 787 }
790 788
791 void recordResolvedTag(LibraryDependency tag, LibraryElement library) { 789 void recordResolvedTag(LibraryDependency tag, LibraryElement library) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 assert(invariant(this, !exportsHandled, 840 assert(invariant(this, !exportsHandled,
843 message: 'Exports already set to $slotForExports on $this')); 841 message: 'Exports already set to $slotForExports on $this'));
844 assert(invariant(this, exportedElements != null)); 842 assert(invariant(this, exportedElements != null));
845 var builder = new LinkBuilder<Element>(); 843 var builder = new LinkBuilder<Element>();
846 for (Element export in exportedElements) { 844 for (Element export in exportedElements) {
847 builder.addLast(export); 845 builder.addLast(export);
848 } 846 }
849 slotForExports = builder.toLink(); 847 slotForExports = builder.toLink();
850 } 848 }
851 849
852 LibraryElement getLibrary() => isPatch ? origin : this; 850 LibraryElement get library => isPatch ? origin : this;
853 851
854 /** 852 /**
855 * Look up a top-level element in this library. The element could 853 * Look up a top-level element in this library. The element could
856 * potentially have been imported from another library. Returns 854 * potentially have been imported from another library. Returns
857 * null if no such element exist and an [ErroneousElement] if multiple 855 * null if no such element exist and an [ErroneousElement] if multiple
858 * elements have been imported. 856 * elements have been imported.
859 */ 857 */
860 Element find(String elementName) { 858 Element find(String elementName) {
861 Element result = localScope.lookup(elementName); 859 Element result = localScope.lookup(elementName);
862 if (result != null) return result; 860 if (result != null) return result;
863 if (origin != null) { 861 if (origin != null) {
864 result = origin.localScope.lookup(elementName); 862 result = origin.localScope.lookup(elementName);
865 if (result != null) return result; 863 if (result != null) return result;
866 } 864 }
867 result = importScope[elementName]; 865 result = importScope[elementName];
868 if (result != null) return result; 866 if (result != null) return result;
869 if (origin != null) { 867 if (origin != null) {
870 result = origin.importScope[elementName]; 868 result = origin.importScope[elementName];
871 if (result != null) return result; 869 if (result != null) return result;
872 } 870 }
873 return null; 871 return null;
874 } 872 }
875 873
876 /** Look up a top-level element in this library, but only look for 874 /** Look up a top-level element in this library, but only look for
877 * non-imported elements. Returns null if no such element exist. */ 875 * non-imported elements. Returns null if no such element exist. */
878 Element findLocal(String elementName) { 876 Element findLocal(String elementName) {
879 // TODO(johnniwinther): How to handle injected elements in the patch 877 // TODO(johnniwinther): How to handle injected elements in the patch
880 // library? 878 // library?
881 Element result = localScope.lookup(elementName); 879 Element result = localScope.lookup(elementName);
882 if (result == null || result.getLibrary() != this) return null; 880 if (result == null || result.library != this) return null;
883 return result; 881 return result;
884 } 882 }
885 883
886 Element findExported(String elementName) { 884 Element findExported(String elementName) {
887 for (Link link = exports; !link.isEmpty; link = link.tail) { 885 for (Link link = exports; !link.isEmpty; link = link.tail) {
888 Element element = link.head; 886 Element element = link.head;
889 if (element.name == elementName) return element; 887 if (element.name == elementName) return element;
890 } 888 }
891 return null; 889 return null;
892 } 890 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 Import _deferredImport; 991 Import _deferredImport;
994 Import get deferredImport => _deferredImport; 992 Import get deferredImport => _deferredImport;
995 993
996 PrefixElementX(String prefix, Element enclosing, this.firstPosition) 994 PrefixElementX(String prefix, Element enclosing, this.firstPosition)
997 : super(prefix, ElementKind.PREFIX, enclosing); 995 : super(prefix, ElementKind.PREFIX, enclosing);
998 996
999 Element lookupLocalMember(String memberName) => importScope[memberName]; 997 Element lookupLocalMember(String memberName) => importScope[memberName];
1000 998
1001 DartType computeType(Compiler compiler) => compiler.types.dynamicType; 999 DartType computeType(Compiler compiler) => compiler.types.dynamicType;
1002 1000
1003 Token position() => firstPosition; 1001 Token get position => firstPosition;
1004 1002
1005 void addImport(Element element, Import import, DiagnosticListener listener) { 1003 void addImport(Element element, Import import, DiagnosticListener listener) {
1006 importScope.addImport(this, element, import, listener); 1004 importScope.addImport(this, element, import, listener);
1007 } 1005 }
1008 1006
1009 accept(ElementVisitor visitor) => visitor.visitPrefixElement(this); 1007 accept(ElementVisitor visitor) => visitor.visitPrefixElement(this);
1010 1008
1011 void markAsDeferred(Import deferredImport) { 1009 void markAsDeferred(Import deferredImport) {
1012 _deferredImport = deferredImport; 1010 _deferredImport = deferredImport;
1013 } 1011 }
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 }); 1175 });
1178 return variables.computeType(this, compiler); 1176 return variables.computeType(this, compiler);
1179 } 1177 }
1180 1178
1181 DartType get type { 1179 DartType get type {
1182 assert(invariant(this, variables.type != null, 1180 assert(invariant(this, variables.type != null,
1183 message: "Type has not been computed for $this.")); 1181 message: "Type has not been computed for $this."));
1184 return variables.type; 1182 return variables.type;
1185 } 1183 }
1186 1184
1187 bool isInstanceMember() => isMember() && !modifiers.isStatic(); 1185 bool get isInstanceMember => isMember && !modifiers.isStatic;
1188 1186
1189 // Note: cachedNode.getBeginToken() will not be correct in all 1187 // Note: cachedNode.beginToken will not be correct in all
1190 // cases, for example, for function typed parameters. 1188 // cases, for example, for function typed parameters.
1191 Token position() => token; 1189 Token get position => token;
1192 1190
1193 accept(ElementVisitor visitor) => visitor.visitVariableElement(this); 1191 accept(ElementVisitor visitor) => visitor.visitVariableElement(this);
1194 } 1192 }
1195 1193
1196 class FieldElementX extends VariableElementX implements FieldElement { 1194 class FieldElementX extends VariableElementX implements FieldElement {
1197 List<FunctionElement> nestedClosures = new List<FunctionElement>(); 1195 List<FunctionElement> nestedClosures = new List<FunctionElement>();
1198 1196
1199 FieldElementX(Identifier name, 1197 FieldElementX(Identifier name,
1200 Element enclosingElement, 1198 Element enclosingElement,
1201 VariableList variables) 1199 VariableList variables)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 ParameterElementX(ElementKind elementKind, 1245 ParameterElementX(ElementKind elementKind,
1248 Element enclosingElement, 1246 Element enclosingElement,
1249 this.definitions, 1247 this.definitions,
1250 Identifier identifier, 1248 Identifier identifier,
1251 this.initializer) 1249 this.initializer)
1252 : this.identifier = identifier, 1250 : this.identifier = identifier,
1253 super(identifier.source, elementKind, enclosingElement); 1251 super(identifier.source, elementKind, enclosingElement);
1254 1252
1255 Modifiers get modifiers => definitions.modifiers; 1253 Modifiers get modifiers => definitions.modifiers;
1256 1254
1257 Token position() => identifier.getBeginToken(); 1255 Token get position => identifier.getBeginToken();
1258 1256
1259 Node parseNode(DiagnosticListener listener) => definitions; 1257 Node parseNode(DiagnosticListener listener) => definitions;
1260 1258
1261 DartType computeType(Compiler compiler) { 1259 DartType computeType(Compiler compiler) {
1262 assert(invariant(this, type != null, 1260 assert(invariant(this, type != null,
1263 message: "Parameter type has not been set for $this.")); 1261 message: "Parameter type has not been set for $this."));
1264 return type; 1262 return type;
1265 } 1263 }
1266 1264
1267 DartType get type { 1265 DartType get type {
(...skipping 23 matching lines...) Expand all
1291 : super(name, ElementKind.ABSTRACT_FIELD, enclosing); 1289 : super(name, ElementKind.ABSTRACT_FIELD, enclosing);
1292 1290
1293 DartType computeType(Compiler compiler) { 1291 DartType computeType(Compiler compiler) {
1294 throw "internal error: AbstractFieldElement has no type"; 1292 throw "internal error: AbstractFieldElement has no type";
1295 } 1293 }
1296 1294
1297 Node parseNode(DiagnosticListener listener) { 1295 Node parseNode(DiagnosticListener listener) {
1298 throw "internal error: AbstractFieldElement has no node"; 1296 throw "internal error: AbstractFieldElement has no node";
1299 } 1297 }
1300 1298
1301 Token position() { 1299 Token get position {
1302 // The getter and setter may be defined in two different 1300 // The getter and setter may be defined in two different
1303 // compilation units. However, we know that one of them is 1301 // compilation units. However, we know that one of them is
1304 // non-null and defined in the same compilation unit as the 1302 // non-null and defined in the same compilation unit as the
1305 // abstract element. 1303 // abstract element.
1306 // TODO(lrn): No we don't know that if the element from the same 1304 // TODO(lrn): No we don't know that if the element from the same
1307 // compilation unit is patched. 1305 // compilation unit is patched.
1308 // 1306 //
1309 // We need to make sure that the position returned is relative to 1307 // We need to make sure that the position returned is relative to
1310 // the compilation unit of the abstract element. 1308 // the compilation unit of the abstract element.
1311 if (getter != null 1309 if (getter != null
1312 && identical(getter.getCompilationUnit(), getCompilationUnit())) { 1310 && identical(getter.compilationUnit, compilationUnit)) {
1313 return getter.position(); 1311 return getter.position;
1314 } else { 1312 } else {
1315 return setter.position(); 1313 return setter.position;
1316 } 1314 }
1317 } 1315 }
1318 1316
1319 Modifiers get modifiers { 1317 Modifiers get modifiers {
1320 // The resolver ensures that the flags match (ignoring abstract). 1318 // The resolver ensures that the flags match (ignoring abstract).
1321 if (getter != null) { 1319 if (getter != null) {
1322 return new Modifiers.withFlags( 1320 return new Modifiers.withFlags(
1323 getter.modifiers.nodes, 1321 getter.modifiers.nodes,
1324 getter.modifiers.flags | Modifiers.FLAG_ABSTRACT); 1322 getter.modifiers.flags | Modifiers.FLAG_ABSTRACT);
1325 } else { 1323 } else {
1326 return new Modifiers.withFlags( 1324 return new Modifiers.withFlags(
1327 setter.modifiers.nodes, 1325 setter.modifiers.nodes,
1328 setter.modifiers.flags | Modifiers.FLAG_ABSTRACT); 1326 setter.modifiers.flags | Modifiers.FLAG_ABSTRACT);
1329 } 1327 }
1330 } 1328 }
1331 1329
1332 bool isInstanceMember() { 1330 bool get isInstanceMember {
1333 return isMember() && !modifiers.isStatic(); 1331 return isMember && !modifiers.isStatic;
1334 } 1332 }
1335 1333
1336 accept(ElementVisitor visitor) => visitor.visitAbstractFieldElement(this); 1334 accept(ElementVisitor visitor) => visitor.visitAbstractFieldElement(this);
1337 1335
1338 bool get isAbstract { 1336 bool get isAbstract {
1339 return getter != null && getter.isAbstract 1337 return getter != null && getter.isAbstract
1340 || setter != null && setter.isAbstract; 1338 || setter != null && setter.isAbstract;
1341 } 1339 }
1342 } 1340 }
1343 1341
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1499 } 1497 }
1500 1498
1501 InterfaceType computeTargetType(InterfaceType newType) { 1499 InterfaceType computeTargetType(InterfaceType newType) {
1502 if (!isRedirectingFactory) return newType; 1500 if (!isRedirectingFactory) return newType;
1503 assert(invariant(this, redirectionTargetType != null, 1501 assert(invariant(this, redirectionTargetType != null,
1504 message: 'Redirection target type has not yet been computed for ' 1502 message: 'Redirection target type has not yet been computed for '
1505 '$this.')); 1503 '$this.'));
1506 return redirectionTargetType.substByContext(newType); 1504 return redirectionTargetType.substByContext(newType);
1507 } 1505 }
1508 1506
1509 bool isInstanceMember() { 1507 bool get isInstanceMember {
1510 return isMember() 1508 return isMember
1511 && !isConstructor() 1509 && !isConstructor
1512 && !modifiers.isStatic(); 1510 && !modifiers.isStatic;
1513 } 1511 }
1514 1512
1515 FunctionSignature computeSignature(Compiler compiler) { 1513 FunctionSignature computeSignature(Compiler compiler) {
1516 if (functionSignatureCache != null) return functionSignatureCache; 1514 if (functionSignatureCache != null) return functionSignatureCache;
1517 compiler.withCurrentElement(this, () { 1515 compiler.withCurrentElement(this, () {
1518 functionSignatureCache = compiler.resolveSignature(this); 1516 functionSignatureCache = compiler.resolveSignature(this);
1519 }); 1517 });
1520 return functionSignatureCache; 1518 return functionSignatureCache;
1521 } 1519 }
1522 1520
(...skipping 10 matching lines...) Expand all
1533 } 1531 }
1534 1532
1535 FunctionType get type { 1533 FunctionType get type {
1536 assert(invariant(this, typeCache != null, 1534 assert(invariant(this, typeCache != null,
1537 message: "Type has not been computed for $this.")); 1535 message: "Type has not been computed for $this."));
1538 return typeCache; 1536 return typeCache;
1539 } 1537 }
1540 1538
1541 FunctionExpression parseNode(DiagnosticListener listener) { 1539 FunctionExpression parseNode(DiagnosticListener listener) {
1542 if (patch == null) { 1540 if (patch == null) {
1543 if (modifiers.isExternal()) { 1541 if (modifiers.isExternal) {
1544 listener.internalError(this, 1542 listener.internalError(this,
1545 "Compiling external function with no implementation."); 1543 "Compiling external function with no implementation.");
1546 } 1544 }
1547 } 1545 }
1548 return cachedNode; 1546 return cachedNode;
1549 } 1547 }
1550 1548
1551 FunctionExpression get node { 1549 FunctionExpression get node {
1552 assert(invariant(this, cachedNode != null, 1550 assert(invariant(this, cachedNode != null,
1553 message: "Node has not been computed for $this.")); 1551 message: "Node has not been computed for $this."));
1554 return cachedNode; 1552 return cachedNode;
1555 } 1553 }
1556 1554
1557 Token position() { 1555 Token get position {
1558 // Use the name as position if this is not an unnamed closure. 1556 // Use the name as position if this is not an unnamed closure.
1559 if (cachedNode.name != null) { 1557 if (cachedNode.name != null) {
1560 return cachedNode.name.getBeginToken(); 1558 return cachedNode.name.getBeginToken();
1561 } else { 1559 } else {
1562 return cachedNode.getBeginToken(); 1560 return cachedNode.getBeginToken();
1563 } 1561 }
1564 } 1562 }
1565 1563
1566 FunctionElement asFunctionElement() => this; 1564 FunctionElement asFunctionElement() => this;
1567 1565
1568 String toString() { 1566 String toString() {
1569 if (isPatch) { 1567 if (isPatch) {
1570 return 'patch ${super.toString()}'; 1568 return 'patch ${super.toString()}';
1571 } else if (isPatched) { 1569 } else if (isPatched) {
1572 return 'origin ${super.toString()}'; 1570 return 'origin ${super.toString()}';
1573 } else { 1571 } else {
1574 return super.toString(); 1572 return super.toString();
1575 } 1573 }
1576 } 1574 }
1577 1575
1578 bool get isAbstract { 1576 bool get isAbstract {
1579 return !modifiers.isExternal() && 1577 return !modifiers.isExternal &&
1580 (isFunction() || isAccessor()) && 1578 (isFunction || isAccessor) &&
1581 _hasNoBody; 1579 _hasNoBody;
1582 } 1580 }
1583 1581
1584 accept(ElementVisitor visitor) => visitor.visitFunctionElement(this); 1582 accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
1585 } 1583 }
1586 1584
1587 class SynthesizedCallMethodElementX extends FunctionElementX { 1585 class SynthesizedCallMethodElementX extends FunctionElementX {
1588 final FunctionElement expression; 1586 final FunctionElement expression;
1589 1587
1590 SynthesizedCallMethodElementX(String name, 1588 SynthesizedCallMethodElementX(String name,
(...skipping 20 matching lines...) Expand all
1611 FunctionSignature computeSignature(Compiler compiler) { 1609 FunctionSignature computeSignature(Compiler compiler) {
1612 if (functionSignatureCache != null) return functionSignature; 1610 if (functionSignatureCache != null) return functionSignature;
1613 compiler.withCurrentElement(this, () { 1611 compiler.withCurrentElement(this, () {
1614 DartType inner = new FunctionType(this, compiler.types.dynamicType); 1612 DartType inner = new FunctionType(this, compiler.types.dynamicType);
1615 functionSignatureCache = new FunctionSignatureX(const Link(), 1613 functionSignatureCache = new FunctionSignatureX(const Link(),
1616 const Link(), 0, 0, false, [], inner); 1614 const Link(), 0, 0, false, [], inner);
1617 }); 1615 });
1618 return functionSignatureCache; 1616 return functionSignatureCache;
1619 } 1617 }
1620 1618
1621 bool isMember() => false; 1619 bool get isMember => false;
1622 1620
1623 bool isForeign(Compiler compiler) => true; 1621 bool isForeign(Compiler compiler) => true;
1624 1622
1625 bool get isSynthesized => true; 1623 bool get isSynthesized => true;
1626 1624
1627 bool isFunction() => false; 1625 bool get isFunction => false;
1628 1626
1629 bool isDeferredLoaderGetter() => true; 1627 bool get isDeferredLoaderGetter => true;
1630 1628
1631 bool isGetter() => true; 1629 bool get isGetter => true;
1632 1630
1633 // By having position null, the enclosing elements location is printed in 1631 // By having position null, the enclosing elements location is printed in
1634 // error messages. 1632 // error messages.
1635 Token position() => null; 1633 Token get position => null;
1636 } 1634 }
1637 1635
1638 class ConstructorBodyElementX extends FunctionElementX 1636 class ConstructorBodyElementX extends FunctionElementX
1639 implements ConstructorBodyElement { 1637 implements ConstructorBodyElement {
1640 FunctionElement constructor; 1638 FunctionElement constructor;
1641 1639
1642 ConstructorBodyElementX(FunctionElement constructor) 1640 ConstructorBodyElementX(FunctionElement constructor)
1643 : this.constructor = constructor, 1641 : this.constructor = constructor,
1644 super(constructor.name, 1642 super(constructor.name,
1645 ElementKind.GENERATIVE_CONSTRUCTOR_BODY, 1643 ElementKind.GENERATIVE_CONSTRUCTOR_BODY,
1646 Modifiers.EMPTY, 1644 Modifiers.EMPTY,
1647 constructor.enclosingElement, false) { 1645 constructor.enclosingElement, false) {
1648 functionSignatureCache = constructor.functionSignature; 1646 functionSignatureCache = constructor.functionSignature;
1649 } 1647 }
1650 1648
1651 bool isInstanceMember() => true; 1649 bool get isInstanceMember => true;
1652 1650
1653 FunctionType computeType(Compiler compiler) { 1651 FunctionType computeType(Compiler compiler) {
1654 compiler.internalError(this, '$this.computeType.'); 1652 compiler.internalError(this, '$this.computeType.');
1655 return null; 1653 return null;
1656 } 1654 }
1657 1655
1658 Node parseNode(DiagnosticListener listener) { 1656 Node parseNode(DiagnosticListener listener) {
1659 if (cachedNode != null) return cachedNode; 1657 if (cachedNode != null) return cachedNode;
1660 cachedNode = constructor.parseNode(listener); 1658 cachedNode = constructor.parseNode(listener);
1661 assert(cachedNode != null); 1659 assert(cachedNode != null);
1662 return cachedNode; 1660 return cachedNode;
1663 } 1661 }
1664 1662
1665 Token position() => constructor.position(); 1663 Token get position => constructor.position;
1666 1664
1667 Element getOutermostEnclosingMemberOrTopLevel() => constructor; 1665 Element get outermostEnclosingMemberOrTopLevel => constructor;
1668 1666
1669 accept(ElementVisitor visitor) => visitor.visitConstructorBodyElement(this); 1667 accept(ElementVisitor visitor) => visitor.visitConstructorBodyElement(this);
1670 } 1668 }
1671 1669
1672 /** 1670 /**
1673 * A constructor that is not defined in the source code but rather implied by 1671 * A constructor that is not defined in the source code but rather implied by
1674 * the language semantics. 1672 * the language semantics.
1675 * 1673 *
1676 * This class is used to represent default constructors and forwarding 1674 * This class is used to represent default constructors and forwarding
1677 * constructors for mixin applications. 1675 * constructors for mixin applications.
1678 */ 1676 */
1679 class SynthesizedConstructorElementX extends FunctionElementX { 1677 class SynthesizedConstructorElementX extends FunctionElementX {
1680 final FunctionElement superMember; 1678 final FunctionElement superMember;
1681 final bool isDefaultConstructor; 1679 final bool isDefaultConstructor;
1682 1680
1683 SynthesizedConstructorElementX(String name, 1681 SynthesizedConstructorElementX(String name,
1684 this.superMember, 1682 this.superMember,
1685 Element enclosing, 1683 Element enclosing,
1686 this.isDefaultConstructor) 1684 this.isDefaultConstructor)
1687 : super(name, 1685 : super(name,
1688 ElementKind.GENERATIVE_CONSTRUCTOR, 1686 ElementKind.GENERATIVE_CONSTRUCTOR,
1689 Modifiers.EMPTY, 1687 Modifiers.EMPTY,
1690 enclosing, false); 1688 enclosing, false);
1691 1689
1692 SynthesizedConstructorElementX.forDefault(superMember, Element enclosing) 1690 SynthesizedConstructorElementX.forDefault(superMember, Element enclosing)
1693 : this('', superMember, enclosing, true); 1691 : this('', superMember, enclosing, true);
1694 1692
1695 Token position() => enclosingElement.position(); 1693 Token get position => enclosingElement.position;
1696 1694
1697 bool get isSynthesized => true; 1695 bool get isSynthesized => true;
1698 1696
1699 FunctionElement get targetConstructor => superMember; 1697 FunctionElement get targetConstructor => superMember;
1700 1698
1701 FunctionSignature computeSignature(compiler) { 1699 FunctionSignature computeSignature(compiler) {
1702 if (functionSignatureCache != null) return functionSignatureCache; 1700 if (functionSignatureCache != null) return functionSignatureCache;
1703 if (isDefaultConstructor) { 1701 if (isDefaultConstructor) {
1704 return functionSignatureCache = new FunctionSignatureX( 1702 return functionSignatureCache = new FunctionSignatureX(
1705 const Link<Element>(), const Link<Element>(), 0, 0, false, 1703 const Link<Element>(), const Link<Element>(), 0, 0, false,
1706 const <Element>[], 1704 const <Element>[],
1707 new FunctionType(this, getEnclosingClass().thisType)); 1705 new FunctionType(this, enclosingClass.thisType));
1708 } 1706 }
1709 if (superMember.isErroneous()) { 1707 if (superMember.isErroneous) {
1710 return functionSignatureCache = 1708 return functionSignatureCache =
1711 compiler.objectClass.localLookup('').computeSignature(compiler); 1709 compiler.objectClass.localLookup('').computeSignature(compiler);
1712 } 1710 }
1713 // TODO(johnniwinther): Ensure that the function signature (and with it the 1711 // TODO(johnniwinther): Ensure that the function signature (and with it the
1714 // function type) substitutes type variables correctly. 1712 // function type) substitutes type variables correctly.
1715 return functionSignatureCache = superMember.computeSignature(compiler); 1713 return functionSignatureCache = superMember.computeSignature(compiler);
1716 } 1714 }
1717 1715
1718 get declaration => this; 1716 get declaration => this;
1719 get implementation => this; 1717 get implementation => this;
1720 get defaultImplementation => this; 1718 get defaultImplementation => this;
1721 1719
1722 accept(ElementVisitor visitor) { 1720 accept(ElementVisitor visitor) {
1723 return visitor.visitFunctionElement(this); 1721 return visitor.visitFunctionElement(this);
1724 } 1722 }
1725 } 1723 }
1726 1724
1727 class VoidElementX extends ElementX implements VoidElement { 1725 class VoidElementX extends ElementX implements VoidElement {
1728 VoidElementX(Element enclosing) : super('void', ElementKind.VOID, enclosing); 1726 VoidElementX(Element enclosing) : super('void', ElementKind.VOID, enclosing);
1729 DartType computeType(compiler) => compiler.types.voidType; 1727 DartType computeType(compiler) => compiler.types.voidType;
1730 Node parseNode(_) { 1728 Node parseNode(_) {
1731 throw 'internal error: parseNode on void'; 1729 throw 'internal error: parseNode on void';
1732 } 1730 }
1733 bool impliesType() => true; 1731 bool get impliesType => true;
1734 1732
1735 accept(ElementVisitor visitor) => visitor.visitVoidElement(this); 1733 accept(ElementVisitor visitor) => visitor.visitVoidElement(this);
1736 } 1734 }
1737 1735
1738 abstract class TypeDeclarationElementX<T extends GenericType> 1736 abstract class TypeDeclarationElementX<T extends GenericType>
1739 implements TypeDeclarationElement { 1737 implements TypeDeclarationElement {
1740 /** 1738 /**
1741 * The `this type` for this type declaration. 1739 * The `this type` for this type declaration.
1742 * 1740 *
1743 * The type of [:this:] is the generic type based on this element in which 1741 * The type of [:this:] is the generic type based on this element in which
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1901 void ensureResolved(Compiler compiler) { 1899 void ensureResolved(Compiler compiler) {
1902 if (resolutionState == STATE_NOT_STARTED) { 1900 if (resolutionState == STATE_NOT_STARTED) {
1903 compiler.resolver.resolveClass(this); 1901 compiler.resolver.resolveClass(this);
1904 } 1902 }
1905 } 1903 }
1906 1904
1907 void setDefaultConstructor(FunctionElement constructor, Compiler compiler); 1905 void setDefaultConstructor(FunctionElement constructor, Compiler compiler);
1908 1906
1909 void addBackendMember(Element member) { 1907 void addBackendMember(Element member) {
1910 // TODO(ngeoffray): Deprecate this method. 1908 // TODO(ngeoffray): Deprecate this method.
1911 assert(member.isGenerativeConstructorBody()); 1909 assert(member.isGenerativeConstructorBody);
1912 backendMembers = backendMembers.prepend(member); 1910 backendMembers = backendMembers.prepend(member);
1913 } 1911 }
1914 1912
1915 void reverseBackendMembers() { 1913 void reverseBackendMembers() {
1916 backendMembers = backendMembers.reverse(); 1914 backendMembers = backendMembers.reverse();
1917 } 1915 }
1918 1916
1919 /** 1917 /**
1920 * Lookup local members in the class. This will ignore constructors. 1918 * Lookup local members in the class. This will ignore constructors.
1921 */ 1919 */
1922 Element lookupLocalMember(String memberName) { 1920 Element lookupLocalMember(String memberName) {
1923 var result = localLookup(memberName); 1921 var result = localLookup(memberName);
1924 if (result != null && result.isConstructor()) return null; 1922 if (result != null && result.isConstructor) return null;
1925 return result; 1923 return result;
1926 } 1924 }
1927 1925
1928 /// Lookup a synthetic element created by the backend. 1926 /// Lookup a synthetic element created by the backend.
1929 Element lookupBackendMember(String memberName) { 1927 Element lookupBackendMember(String memberName) {
1930 for (Element element in backendMembers) { 1928 for (Element element in backendMembers) {
1931 if (element.name == memberName) { 1929 if (element.name == memberName) {
1932 return element; 1930 return element;
1933 } 1931 }
1934 } 1932 }
1935 return null; 1933 return null;
1936 } 1934 }
1937 /** 1935 /**
1938 * Lookup super members for the class. This will ignore constructors. 1936 * Lookup super members for the class. This will ignore constructors.
1939 */ 1937 */
1940 Element lookupSuperMember(String memberName) { 1938 Element lookupSuperMember(String memberName) {
1941 return lookupSuperMemberInLibrary(memberName, getLibrary()); 1939 return lookupSuperMemberInLibrary(memberName, library);
1942 } 1940 }
1943 1941
1944 /** 1942 /**
1945 * Lookup super members for the class that is accessible in [library]. 1943 * Lookup super members for the class that is accessible in [library].
1946 * This will ignore constructors. 1944 * This will ignore constructors.
1947 */ 1945 */
1948 Element lookupSuperMemberInLibrary(String memberName, 1946 Element lookupSuperMemberInLibrary(String memberName,
1949 LibraryElement library) { 1947 LibraryElement library) {
1950 bool isPrivate = isPrivateName(memberName); 1948 bool isPrivate = isPrivateName(memberName);
1951 for (ClassElement s = superclass; s != null; s = s.superclass) { 1949 for (ClassElement s = superclass; s != null; s = s.superclass) {
1952 // Private members from a different library are not visible. 1950 // Private members from a different library are not visible.
1953 if (isPrivate && !identical(library, s.getLibrary())) continue; 1951 if (isPrivate && !identical(library, s.library)) continue;
1954 Element e = s.lookupLocalMember(memberName); 1952 Element e = s.lookupLocalMember(memberName);
1955 if (e == null) continue; 1953 if (e == null) continue;
1956 // Static members are not inherited. 1954 // Static members are not inherited.
1957 if (e.modifiers.isStatic()) continue; 1955 if (e.modifiers.isStatic) continue;
1958 return e; 1956 return e;
1959 } 1957 }
1960 return null; 1958 return null;
1961 } 1959 }
1962 1960
1963 /** 1961 /**
1964 * Find the first member in the class chain with the given [selector]. 1962 * Find the first member in the class chain with the given [selector].
1965 * 1963 *
1966 * This method is NOT to be used for resolving 1964 * This method is NOT to be used for resolving
1967 * unqualified sends because it does not implement the scoping 1965 * unqualified sends because it does not implement the scoping
(...skipping 20 matching lines...) Expand all
1988 current != null; 1986 current != null;
1989 current = current.superclass) { 1987 current = current.superclass) {
1990 Element member = current.lookupLocalMember(name); 1988 Element member = current.lookupLocalMember(name);
1991 if (member == null && current.isPatched) { 1989 if (member == null && current.isPatched) {
1992 // Doing lookups on selectors is done after resolution, so it 1990 // Doing lookups on selectors is done after resolution, so it
1993 // is safe to look in the patch class. 1991 // is safe to look in the patch class.
1994 member = current.patch.lookupLocalMember(name); 1992 member = current.patch.lookupLocalMember(name);
1995 } 1993 }
1996 if (member == null) continue; 1994 if (member == null) continue;
1997 // Private members from a different library are not visible. 1995 // Private members from a different library are not visible.
1998 if (isPrivate && !identical(library, member.getLibrary())) continue; 1996 if (isPrivate && !identical(library, member.library)) continue;
1999 // Static members are not inherited. 1997 // Static members are not inherited.
2000 if (member.modifiers.isStatic() && !identical(this, current)) continue; 1998 if (member.modifiers.isStatic && !identical(this, current)) continue;
2001 // If we find an abstract field we have to make sure that it has 1999 // If we find an abstract field we have to make sure that it has
2002 // the getter or setter part we're actually looking 2000 // the getter or setter part we're actually looking
2003 // for. Otherwise, we continue up the superclass chain. 2001 // for. Otherwise, we continue up the superclass chain.
2004 if (member.isAbstractField()) { 2002 if (member.isAbstractField) {
2005 AbstractFieldElement field = member; 2003 AbstractFieldElement field = member;
2006 FunctionElement getter = field.getter; 2004 FunctionElement getter = field.getter;
2007 FunctionElement setter = field.setter; 2005 FunctionElement setter = field.setter;
2008 if (selector.isSetter()) { 2006 if (selector.isSetter) {
2009 // Abstract members can be defined in a super class. 2007 // Abstract members can be defined in a super class.
2010 if (setter != null && !setter.isAbstract) return setter; 2008 if (setter != null && !setter.isAbstract) return setter;
2011 } else { 2009 } else {
2012 assert(selector.isGetter() || selector.isCall()); 2010 assert(selector.isGetter || selector.isCall);
2013 if (getter != null && !getter.isAbstract) return getter; 2011 if (getter != null && !getter.isAbstract) return getter;
2014 } 2012 }
2015 // Abstract members can be defined in a super class. 2013 // Abstract members can be defined in a super class.
2016 } else if (!member.isAbstract) { 2014 } else if (!member.isAbstract) {
2017 return member; 2015 return member;
2018 } 2016 }
2019 } 2017 }
2020 return null; 2018 return null;
2021 } 2019 }
2022 2020
2023 /** 2021 /**
2024 * Find the first member in the class chain with the given 2022 * Find the first member in the class chain with the given
2025 * [memberName]. This method is NOT to be used for resolving 2023 * [memberName]. This method is NOT to be used for resolving
2026 * unqualified sends because it does not implement the scoping 2024 * unqualified sends because it does not implement the scoping
2027 * rules, where library scope comes before superclass scope. 2025 * rules, where library scope comes before superclass scope.
2028 */ 2026 */
2029 Element lookupMember(String memberName) { 2027 Element lookupMember(String memberName) {
2030 Element localMember = lookupLocalMember(memberName); 2028 Element localMember = lookupLocalMember(memberName);
2031 return localMember == null ? lookupSuperMember(memberName) : localMember; 2029 return localMember == null ? lookupSuperMember(memberName) : localMember;
2032 } 2030 }
2033 2031
2034 /** 2032 /**
2035 * Returns true if the [fieldMember] shadows another field. The given 2033 * Returns true if the [fieldMember] shadows another field. The given
2036 * [fieldMember] must be a member of this class, i.e. if there is a field of 2034 * [fieldMember] must be a member of this class, i.e. if there is a field of
2037 * the same name in the superclass chain. 2035 * the same name in the superclass chain.
2038 * 2036 *
2039 * This method also works if the [fieldMember] is private. 2037 * This method also works if the [fieldMember] is private.
2040 */ 2038 */
2041 bool hasFieldShadowedBy(Element fieldMember) { 2039 bool hasFieldShadowedBy(Element fieldMember) {
2042 assert(fieldMember.isField()); 2040 assert(fieldMember.isField);
2043 String fieldName = fieldMember.name; 2041 String fieldName = fieldMember.name;
2044 bool isPrivate = isPrivateName(fieldName); 2042 bool isPrivate = isPrivateName(fieldName);
2045 LibraryElement memberLibrary = fieldMember.getLibrary(); 2043 LibraryElement memberLibrary = fieldMember.library;
2046 ClassElement lookupClass = this.superclass; 2044 ClassElement lookupClass = this.superclass;
2047 while (lookupClass != null) { 2045 while (lookupClass != null) {
2048 Element foundMember = lookupClass.lookupLocalMember(fieldName); 2046 Element foundMember = lookupClass.lookupLocalMember(fieldName);
2049 if (foundMember != null) { 2047 if (foundMember != null) {
2050 if (foundMember.isField()) { 2048 if (foundMember.isField) {
2051 if (!isPrivate || memberLibrary == foundMember.getLibrary()) { 2049 if (!isPrivate || memberLibrary == foundMember.library) {
2052 // Private fields can only be shadowed by a field declared in the 2050 // Private fields can only be shadowed by a field declared in the
2053 // same library. 2051 // same library.
2054 return true; 2052 return true;
2055 } 2053 }
2056 } 2054 }
2057 } 2055 }
2058 lookupClass = lookupClass.superclass; 2056 lookupClass = lookupClass.superclass;
2059 } 2057 }
2060 return false; 2058 return false;
2061 } 2059 }
2062 2060
2063 Element validateConstructorLookupResults(Selector selector, 2061 Element validateConstructorLookupResults(Selector selector,
2064 Element result, 2062 Element result,
2065 Element noMatch(Element)) { 2063 Element noMatch(Element)) {
2066 if (result == null 2064 if (result == null
2067 || !result.isConstructor() 2065 || !result.isConstructor
2068 || (isPrivateName(selector.name) 2066 || (isPrivateName(selector.name)
2069 && result.getLibrary() != selector.library)) { 2067 && result.library != selector.library)) {
2070 result = noMatch != null ? noMatch(result) : null; 2068 result = noMatch != null ? noMatch(result) : null;
2071 } 2069 }
2072 return result; 2070 return result;
2073 } 2071 }
2074 2072
2075 // TODO(aprelev@gmail.com): Peter believes that it would be great to 2073 // TODO(aprelev@gmail.com): Peter believes that it would be great to
2076 // make noMatch a required argument. Peter's suspicion is that most 2074 // make noMatch a required argument. Peter's suspicion is that most
2077 // callers of this method would benefit from using the noMatch method. 2075 // callers of this method would benefit from using the noMatch method.
2078 Element lookupConstructor(Selector selector, [Element noMatch(Element)]) { 2076 Element lookupConstructor(Selector selector, [Element noMatch(Element)]) {
2079 Element result = localLookup(selector.name); 2077 Element result = localLookup(selector.name);
2080 return validateConstructorLookupResults(selector, result, noMatch); 2078 return validateConstructorLookupResults(selector, result, noMatch);
2081 } 2079 }
2082 2080
2083 Link<Element> get constructors { 2081 Link<Element> get constructors {
2084 // TODO(ajohnsen): See if we can avoid this method at some point. 2082 // TODO(ajohnsen): See if we can avoid this method at some point.
2085 Link<Element> result = const Link<Element>(); 2083 Link<Element> result = const Link<Element>();
2086 // TODO(johnniwinther): Should we include injected constructors? 2084 // TODO(johnniwinther): Should we include injected constructors?
2087 forEachMember((_, Element member) { 2085 forEachMember((_, Element member) {
2088 if (member.isConstructor()) result = result.prepend(member); 2086 if (member.isConstructor) result = result.prepend(member);
2089 }); 2087 });
2090 return result; 2088 return result;
2091 } 2089 }
2092 2090
2093 /** 2091 /**
2094 * Returns the super class, if any. 2092 * Returns the super class, if any.
2095 * 2093 *
2096 * The returned element may not be resolved yet. 2094 * The returned element may not be resolved yet.
2097 */ 2095 */
2098 ClassElement get superclass { 2096 ClassElement get superclass {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 * [includeSuperAndInjectedMembers] is [:true:]. 2142 * [includeSuperAndInjectedMembers] is [:true:].
2145 * 2143 *
2146 * When called on the implementation element both the fields declared in the 2144 * When called on the implementation element both the fields declared in the
2147 * origin and in the patch are included. 2145 * origin and in the patch are included.
2148 */ 2146 */
2149 void forEachInstanceField(void f(ClassElement enclosingClass, 2147 void forEachInstanceField(void f(ClassElement enclosingClass,
2150 FieldElement field), 2148 FieldElement field),
2151 {bool includeSuperAndInjectedMembers: false}) { 2149 {bool includeSuperAndInjectedMembers: false}) {
2152 // Filters so that [f] is only invoked with instance fields. 2150 // Filters so that [f] is only invoked with instance fields.
2153 void fieldFilter(ClassElement enclosingClass, Element member) { 2151 void fieldFilter(ClassElement enclosingClass, Element member) {
2154 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) { 2152 if (member.isInstanceMember && member.kind == ElementKind.FIELD) {
2155 f(enclosingClass, member); 2153 f(enclosingClass, member);
2156 } 2154 }
2157 } 2155 }
2158 2156
2159 forEachMember(fieldFilter, 2157 forEachMember(fieldFilter,
2160 includeSuperAndInjectedMembers: includeSuperAndInjectedMembers); 2158 includeSuperAndInjectedMembers: includeSuperAndInjectedMembers);
2161 } 2159 }
2162 2160
2163 /// Similar to [forEachInstanceField] but visits static fields. 2161 /// Similar to [forEachInstanceField] but visits static fields.
2164 void forEachStaticField(void f(ClassElement enclosingClass, Element field)) { 2162 void forEachStaticField(void f(ClassElement enclosingClass, Element field)) {
2165 // Filters so that [f] is only invoked with static fields. 2163 // Filters so that [f] is only invoked with static fields.
2166 void fieldFilter(ClassElement enclosingClass, Element member) { 2164 void fieldFilter(ClassElement enclosingClass, Element member) {
2167 if (!member.isInstanceMember() && member.kind == ElementKind.FIELD) { 2165 if (!member.isInstanceMember && member.kind == ElementKind.FIELD) {
2168 f(enclosingClass, member); 2166 f(enclosingClass, member);
2169 } 2167 }
2170 } 2168 }
2171 2169
2172 forEachMember(fieldFilter); 2170 forEachMember(fieldFilter);
2173 } 2171 }
2174 2172
2175 void forEachBackendMember(void f(Element member)) { 2173 void forEachBackendMember(void f(Element member)) {
2176 backendMembers.forEach(f); 2174 backendMembers.forEach(f);
2177 } 2175 }
(...skipping 18 matching lines...) Expand all
2196 bool isSubclassOf(ClassElement cls) { 2194 bool isSubclassOf(ClassElement cls) {
2197 // Use [declaration] for both [this] and [cls], because 2195 // Use [declaration] for both [this] and [cls], because
2198 // declaration classes hold the superclass hierarchy. 2196 // declaration classes hold the superclass hierarchy.
2199 cls = cls.declaration; 2197 cls = cls.declaration;
2200 for (ClassElement s = declaration; s != null; s = s.superclass) { 2198 for (ClassElement s = declaration; s != null; s = s.superclass) {
2201 if (identical(s, cls)) return true; 2199 if (identical(s, cls)) return true;
2202 } 2200 }
2203 return false; 2201 return false;
2204 } 2202 }
2205 2203
2206 bool isNative() => nativeTagInfo != null; 2204 bool get isNative => nativeTagInfo != null;
2207 void setNative(String name) { 2205 void setNative(String name) {
2208 nativeTagInfo = name; 2206 nativeTagInfo = name;
2209 } 2207 }
2210 2208
2211 FunctionType get callType { 2209 FunctionType get callType {
2212 MemberSignature member = 2210 MemberSignature member =
2213 lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME)); 2211 lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME));
2214 return member != null && member.isMethod ? member.type : null; 2212 return member != null && member.isMethod ? member.type : null;
2215 } 2213 }
2216 2214
(...skipping 13 matching lines...) Expand all
2230 2228
2231 bool get isMixinApplication => false; 2229 bool get isMixinApplication => false;
2232 bool get hasLocalScopeMembers => !localScope.isEmpty; 2230 bool get hasLocalScopeMembers => !localScope.isEmpty;
2233 2231
2234 void addMember(Element element, DiagnosticListener listener) { 2232 void addMember(Element element, DiagnosticListener listener) {
2235 localMembers = localMembers.prepend(element); 2233 localMembers = localMembers.prepend(element);
2236 addToScope(element, listener); 2234 addToScope(element, listener);
2237 } 2235 }
2238 2236
2239 void addToScope(Element element, DiagnosticListener listener) { 2237 void addToScope(Element element, DiagnosticListener listener) {
2240 if (element.isField() && element.name == name) { 2238 if (element.isField && element.name == name) {
2241 listener.reportError(element, MessageKind.MEMBER_USES_CLASS_NAME); 2239 listener.reportError(element, MessageKind.MEMBER_USES_CLASS_NAME);
2242 } 2240 }
2243 localScope.add(element, listener); 2241 localScope.add(element, listener);
2244 } 2242 }
2245 2243
2246 Element localLookup(String elementName) { 2244 Element localLookup(String elementName) {
2247 Element result = localScope.lookup(elementName); 2245 Element result = localScope.lookup(elementName);
2248 if (result == null && isPatch) { 2246 if (result == null && isPatch) {
2249 result = origin.localLookup(elementName); 2247 result = origin.localLookup(elementName);
2250 } 2248 }
2251 return result; 2249 return result;
2252 } 2250 }
2253 2251
2254 void forEachLocalMember(void f(Element member)) { 2252 void forEachLocalMember(void f(Element member)) {
2255 localMembers.reverse().forEach(f); 2253 localMembers.reverse().forEach(f);
2256 } 2254 }
2257 2255
2258 bool get hasConstructor { 2256 bool get hasConstructor {
2259 // Search in scope to be sure we search patched constructors. 2257 // Search in scope to be sure we search patched constructors.
2260 for (var element in localScope.values) { 2258 for (var element in localScope.values) {
2261 if (element.isConstructor()) return true; 2259 if (element.isConstructor) return true;
2262 } 2260 }
2263 return false; 2261 return false;
2264 } 2262 }
2265 2263
2266 void setDefaultConstructor(FunctionElement constructor, Compiler compiler) { 2264 void setDefaultConstructor(FunctionElement constructor, Compiler compiler) {
2267 addToScope(constructor, compiler); 2265 addToScope(constructor, compiler);
2268 // The default constructor, although synthetic, is part of a class' API. 2266 // The default constructor, although synthetic, is part of a class' API.
2269 localMembers = localMembers.prepend(constructor); 2267 localMembers = localMembers.prepend(constructor);
2270 } 2268 }
2271 2269
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2303 ClassElement get mixin => mixinType != null ? mixinType.element : null; 2301 ClassElement get mixin => mixinType != null ? mixinType.element : null;
2304 2302
2305 bool get isMixinApplication => true; 2303 bool get isMixinApplication => true;
2306 bool get isUnnamedMixinApplication => node is! NamedMixinApplication; 2304 bool get isUnnamedMixinApplication => node is! NamedMixinApplication;
2307 bool get hasConstructor => !constructors.isEmpty; 2305 bool get hasConstructor => !constructors.isEmpty;
2308 bool get hasLocalScopeMembers => !constructors.isEmpty; 2306 bool get hasLocalScopeMembers => !constructors.isEmpty;
2309 2307
2310 get patch => null; 2308 get patch => null;
2311 get origin => null; 2309 get origin => null;
2312 2310
2313 Token position() => node.getBeginToken(); 2311 Token get position => node.getBeginToken();
2314 2312
2315 Node parseNode(DiagnosticListener listener) => node; 2313 Node parseNode(DiagnosticListener listener) => node;
2316 2314
2317 FunctionElement lookupLocalConstructor(String name) { 2315 FunctionElement lookupLocalConstructor(String name) {
2318 for (Link<Element> link = constructors; 2316 for (Link<Element> link = constructors;
2319 !link.isEmpty; 2317 !link.isEmpty;
2320 link = link.tail) { 2318 link = link.tail) {
2321 if (link.head.name == name) return link.head; 2319 if (link.head.name == name) return link.head;
2322 } 2320 }
2323 return null; 2321 return null;
2324 } 2322 }
2325 2323
2326 Element localLookup(String name) { 2324 Element localLookup(String name) {
2327 Element constructor = lookupLocalConstructor(name); 2325 Element constructor = lookupLocalConstructor(name);
2328 if (constructor != null) return constructor; 2326 if (constructor != null) return constructor;
2329 if (mixin == null) return null; 2327 if (mixin == null) return null;
2330 Element mixedInElement = mixin.localLookup(name); 2328 Element mixedInElement = mixin.localLookup(name);
2331 if (mixedInElement == null) return null; 2329 if (mixedInElement == null) return null;
2332 return mixedInElement.isInstanceMember() ? mixedInElement : null; 2330 return mixedInElement.isInstanceMember ? mixedInElement : null;
2333 } 2331 }
2334 2332
2335 void forEachLocalMember(void f(Element member)) { 2333 void forEachLocalMember(void f(Element member)) {
2336 constructors.forEach(f); 2334 constructors.forEach(f);
2337 if (mixin != null) mixin.forEachLocalMember((Element mixedInElement) { 2335 if (mixin != null) mixin.forEachLocalMember((Element mixedInElement) {
2338 if (mixedInElement.isInstanceMember()) f(mixedInElement); 2336 if (mixedInElement.isInstanceMember) f(mixedInElement);
2339 }); 2337 });
2340 } 2338 }
2341 2339
2342 void addMember(Element element, DiagnosticListener listener) { 2340 void addMember(Element element, DiagnosticListener listener) {
2343 throw new UnsupportedError("Cannot add member to $this."); 2341 throw new UnsupportedError("Cannot add member to $this.");
2344 } 2342 }
2345 2343
2346 void addToScope(Element element, DiagnosticListener listener) { 2344 void addToScope(Element element, DiagnosticListener listener) {
2347 listener.internalError(this, 'Cannot add to scope of $this.'); 2345 listener.internalError(this, 'Cannot add to scope of $this.');
2348 } 2346 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2394 target.isBreakTarget = true; 2392 target.isBreakTarget = true;
2395 } 2393 }
2396 void setContinueTarget() { 2394 void setContinueTarget() {
2397 isContinueTarget = true; 2395 isContinueTarget = true;
2398 target.isContinueTarget = true; 2396 target.isContinueTarget = true;
2399 } 2397 }
2400 2398
2401 bool get isTarget => isBreakTarget || isContinueTarget; 2399 bool get isTarget => isBreakTarget || isContinueTarget;
2402 Node parseNode(DiagnosticListener l) => label; 2400 Node parseNode(DiagnosticListener l) => label;
2403 2401
2404 Token position() => label.getBeginToken(); 2402 Token get position => label.getBeginToken();
2405 String toString() => "${labelName}:"; 2403 String toString() => "${labelName}:";
2406 2404
2407 accept(ElementVisitor visitor) => visitor.visitLabelElement(this); 2405 accept(ElementVisitor visitor) => visitor.visitLabelElement(this);
2408 } 2406 }
2409 2407
2410 // Represents a reference to a statement or switch-case, either by label or the 2408 // Represents a reference to a statement or switch-case, either by label or the
2411 // default target of a break or continue. 2409 // default target of a break or continue.
2412 class TargetElementX extends ElementX implements TargetElement { 2410 class TargetElementX extends ElementX implements TargetElement {
2413 final Node statement; 2411 final Node statement;
2414 final int nestingLevel; 2412 final int nestingLevel;
2415 Link<LabelElement> labels = const Link<LabelElement>(); 2413 Link<LabelElement> labels = const Link<LabelElement>();
2416 bool isBreakTarget = false; 2414 bool isBreakTarget = false;
2417 bool isContinueTarget = false; 2415 bool isContinueTarget = false;
2418 2416
2419 TargetElementX(this.statement, this.nestingLevel, Element enclosingElement) 2417 TargetElementX(this.statement, this.nestingLevel, Element enclosingElement)
2420 : super("target", ElementKind.STATEMENT, enclosingElement); 2418 : super("target", ElementKind.STATEMENT, enclosingElement);
2421 bool get isTarget => isBreakTarget || isContinueTarget; 2419 bool get isTarget => isBreakTarget || isContinueTarget;
2422 2420
2423 LabelElement addLabel(Label label, String labelName) { 2421 LabelElement addLabel(Label label, String labelName) {
2424 LabelElement result = new LabelElementX(label, labelName, this, 2422 LabelElement result = new LabelElementX(label, labelName, this,
2425 enclosingElement); 2423 enclosingElement);
2426 labels = labels.prepend(result); 2424 labels = labels.prepend(result);
2427 return result; 2425 return result;
2428 } 2426 }
2429 2427
2430 Node parseNode(DiagnosticListener l) => statement; 2428 Node parseNode(DiagnosticListener l) => statement;
2431 2429
2432 bool get isSwitch => statement is SwitchStatement; 2430 bool get isSwitch => statement is SwitchStatement;
2433 2431
2434 Token position() => statement.getBeginToken(); 2432 Token get position => statement.getBeginToken();
2435 String toString() => statement.toString(); 2433 String toString() => statement.toString();
2436 2434
2437 accept(ElementVisitor visitor) => visitor.visitTargetElement(this); 2435 accept(ElementVisitor visitor) => visitor.visitTargetElement(this);
2438 } 2436 }
2439 2437
2440 class TypeVariableElementX extends ElementX implements TypeVariableElement { 2438 class TypeVariableElementX extends ElementX implements TypeVariableElement {
2441 final Node cachedNode; 2439 final Node cachedNode;
2442 TypeVariableType typeCache; 2440 TypeVariableType typeCache;
2443 DartType boundCache; 2441 DartType boundCache;
2444 2442
(...skipping 11 matching lines...) Expand all
2456 DartType get bound { 2454 DartType get bound {
2457 assert(invariant(this, boundCache != null, 2455 assert(invariant(this, boundCache != null,
2458 message: "Bound has not been set on $this.")); 2456 message: "Bound has not been set on $this."));
2459 return boundCache; 2457 return boundCache;
2460 } 2458 }
2461 2459
2462 Node parseNode(compiler) => cachedNode; 2460 Node parseNode(compiler) => cachedNode;
2463 2461
2464 String toString() => "${enclosingElement.toString()}.${name}"; 2462 String toString() => "${enclosingElement.toString()}.${name}";
2465 2463
2466 Token position() => cachedNode.getBeginToken(); 2464 Token get position => cachedNode.getBeginToken();
2467 2465
2468 accept(ElementVisitor visitor) => visitor.visitTypeVariableElement(this); 2466 accept(ElementVisitor visitor) => visitor.visitTypeVariableElement(this);
2469 } 2467 }
2470 2468
2471 /** 2469 /**
2472 * A single metadata annotation. 2470 * A single metadata annotation.
2473 * 2471 *
2474 * For example, consider: 2472 * For example, consider:
2475 * 2473 *
2476 * class Data { 2474 * class Data {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2557 assert(invariant(this, this.origin == null, 2555 assert(invariant(this, this.origin == null,
2558 message: "Origin element is a patch.")); 2556 message: "Origin element is a patch."));
2559 assert(invariant(patch, patch.origin == null, 2557 assert(invariant(patch, patch.origin == null,
2560 message: "Element is patched twice.")); 2558 message: "Element is patched twice."));
2561 assert(invariant(patch, patch.patch == null, 2559 assert(invariant(patch, patch.patch == null,
2562 message: "Patch element is patched.")); 2560 message: "Patch element is patched."));
2563 this.patch = patch; 2561 this.patch = patch;
2564 patch.origin = this; 2562 patch.origin = this;
2565 } 2563 }
2566 } 2564 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698