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

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

Issue 10837140: Make addGetterOrSetter (now: defineAccessor) not add the abstract field as a member. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: cleaner validation of member accessors. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/compiler/implementation/compiler.dart ('k') | lib/compiler/implementation/resolver.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #library('elements'); 5 #library('elements');
6 6
7 #import('dart:uri'); 7 #import('dart:uri');
8 8
9 #import('../tree/tree.dart'); 9 #import('../tree/tree.dart');
10 #import('../scanner/scannerlib.dart'); 10 #import('../scanner/scannerlib.dart');
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 : super(name, kind, enclosingElement), 363 : super(name, kind, enclosingElement),
364 localScope = new Map<SourceString, Element>(); 364 localScope = new Map<SourceString, Element>();
365 365
366 void addMember(Element element, DiagnosticListener listener) { 366 void addMember(Element element, DiagnosticListener listener) {
367 super.addMember(element, listener); 367 super.addMember(element, listener);
368 addToScope(element, listener); 368 addToScope(element, listener);
369 } 369 }
370 370
371 void addToScope(Element element, DiagnosticListener listener) { 371 void addToScope(Element element, DiagnosticListener listener) {
372 if (element.isAccessor()) { 372 if (element.isAccessor()) {
373 addGetterOrSetter(element, localScope[element.name], listener); 373 addAccessorToScope(element, localScope[element.name], listener);
374 } else { 374 } else {
375 Element existing = localScope.putIfAbsent(element.name, () => element); 375 Element existing = localScope.putIfAbsent(element.name, () => element);
376 if (existing !== element) { 376 if (existing !== element) {
377 // TODO(ahe): Do something similar to Resolver.reportErrorWithContext. 377 // TODO(ahe): Do something similar to Resolver.reportErrorWithContext.
378 listener.cancel('duplicate definition', token: element.position()); 378 listener.cancel('duplicate definition', token: element.position());
379 listener.cancel('existing definition', token: existing.position()); 379 listener.cancel('existing definition', token: existing.position());
380 } 380 }
381 } 381 }
382 } 382 }
383 383
384 Element localLookup(SourceString elementName) { 384 Element localLookup(SourceString elementName) {
385 return localScope[elementName]; 385 return localScope[elementName];
386 } 386 }
387 387
388 void addGetterOrSetter(FunctionElement element, 388 /**
389 Element existing, 389 * Adds a definition for an [accessor] (getter or setter) to a container.
390 DiagnosticListener listener) { 390 * The definition binds to an abstract field that can hold both a getter
391 * and a setter.
392 *
393 * The abstract field is added once, for the first getter or setter, and
394 * reused if the other one is also added.
395 * The abstract field should not be treated as a proper member of the
396 * container, it's simply a way to return two results for one lookup.
397 * That is, the getter or setter does not have the abstract field as enclosing
398 * element, they are enclosed by the class or compilation unit, as is the
399 * abstract field.
400 */
401 void addAccessorToScope(Element accessor,
402 Element existing,
403 DiagnosticListener listener) {
391 void reportError(Element other) { 404 void reportError(Element other) {
392 // TODO(ahe): Do something similar to Resolver.reportErrorWithContext. 405 // TODO(ahe): Do something similar to Resolver.reportErrorWithContext.
393 listener.cancel('duplicate definition of ${element.name.slowToString()}', 406 listener.cancel('duplicate definition of ${accessor.name.slowToString()}',
394 element: element); 407 element: accessor);
395 listener.cancel('existing definition', element: other); 408 listener.cancel('existing definition', element: other);
396 } 409 }
397 410
398 if (existing != null) { 411 if (existing != null) {
399 if (existing.kind !== ElementKind.ABSTRACT_FIELD) { 412 if (existing.kind !== ElementKind.ABSTRACT_FIELD) {
400 reportError(existing); 413 reportError(existing);
401 } else { 414 } else {
402 AbstractFieldElement field = existing; 415 AbstractFieldElement field = existing;
403 if (element.kind == ElementKind.GETTER) { 416 if (accessor.isGetter()) {
404 if (field.getter != null && field.getter != element) { 417 if (field.getter != null && field.getter != accessor) {
405 reportError(field.getter); 418 reportError(field.getter);
406 } 419 }
407 field.getter = element; 420 field.getter = accessor;
408 } else { 421 } else {
409 if (field.setter != null && field.setter != element) { 422 assert(accessor.isSetter());
423 if (field.setter != null && field.setter != accessor) {
410 reportError(field.setter); 424 reportError(field.setter);
411 } 425 }
412 field.setter = element; 426 field.setter = accessor;
413 } 427 }
414 } 428 }
415 } else { 429 } else {
416 Element container = element.getEnclosingClassOrCompilationUnit(); 430 Element container = accessor.getEnclosingClassOrCompilationUnit();
417 AbstractFieldElement field = 431 AbstractFieldElement field =
418 new AbstractFieldElement(element.name, container); 432 new AbstractFieldElement(accessor.name, container);
419 if (element.kind == ElementKind.GETTER) { 433 if (accessor.isGetter()) {
420 field.getter = element; 434 field.getter = accessor;
421 } else { 435 } else {
422 field.setter = element; 436 field.setter = accessor;
423 } 437 }
424 addMember(field, listener); 438 addToScope(field, listener);
425 } 439 }
426 } 440 }
427 } 441 }
428 442
429 class CompilationUnitElement extends ContainerElement { 443 class CompilationUnitElement extends ContainerElement {
430 final Script script; 444 final Script script;
431 445
432 CompilationUnitElement(Script script, Element enclosing) 446 CompilationUnitElement(Script script, Element enclosing)
433 : this.script = script, 447 : this.script = script,
434 super(new SourceString(script.name), 448 super(new SourceString(script.name),
(...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1559 String toString() => "${enclosingElement.toString()}.${name.slowToString()}"; 1573 String toString() => "${enclosingElement.toString()}.${name.slowToString()}";
1560 1574
1561 Token position() => cachedNode.getBeginToken(); 1575 Token position() => cachedNode.getBeginToken();
1562 1576
1563 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) { 1577 TypeVariableElement cloneTo(Element enclosing, DiagnosticListener listener) {
1564 TypeVariableElement result = 1578 TypeVariableElement result =
1565 new TypeVariableElement(name, enclosing, cachedNode, type, bound); 1579 new TypeVariableElement(name, enclosing, cachedNode, type, bound);
1566 return result; 1580 return result;
1567 } 1581 }
1568 } 1582 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/compiler.dart ('k') | lib/compiler/implementation/resolver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698