Issue 5255. Remember 'overridden' for getters/setters and fields

http://code.google.com/p/dart/issues/detail?id=5255

R=brianwilkerson@google.com
BUG=

Review URL: https://codereview.chromium.org//10961038

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@12714 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
scheglov@google.com
2012-09-21 14:43:16 +00:00
parent 915f60cc36
commit 4792aeac49
6 changed files with 151 additions and 4 deletions
@@ -198,8 +198,13 @@ public class Elements {
((AbstractNodeElement) element).setType(type);
}
public static void setOverridden(MethodElement methodElement, Set<Element> overridden) {
((MethodElementImplementation) methodElement).setOverridden(overridden);
public static void setOverridden(Element element, Set<Element> overridden) {
if (element instanceof MethodElementImplementation) {
((MethodElementImplementation) element).setOverridden(overridden);
}
if (element instanceof FieldElementImplementation) {
((FieldElementImplementation) element).setOverridden(overridden);
}
}
static FieldElementImplementation fieldFromNode(DartField node,
@@ -6,6 +6,8 @@ package com.google.dart.compiler.resolver;
import com.google.dart.compiler.type.Type;
import java.util.Set;
public interface FieldElement extends Element {
boolean isStatic();
@@ -19,4 +21,9 @@ public interface FieldElement extends Element {
* @return the inferred {@link Type} of this constant, may be <code>null</code> if not set yet.
*/
Type getConstantType();
/**
* @return {@link Element}s overridden by this {@link MethodElement}.
*/
Set<Element> getOverridden();
}
@@ -4,6 +4,7 @@
package com.google.dart.compiler.resolver;
import com.google.common.collect.ImmutableSet;
import com.google.dart.compiler.ast.DartField;
import com.google.dart.compiler.ast.DartNode;
import com.google.dart.compiler.ast.DartObsoleteMetadata;
@@ -11,6 +12,8 @@ import com.google.dart.compiler.ast.Modifiers;
import com.google.dart.compiler.common.SourceInfo;
import com.google.dart.compiler.type.Type;
import java.util.Set;
class FieldElementImplementation extends AbstractNodeElement implements FieldElement, FieldNodeElement {
private final EnclosingElement holder;
private final SourceInfo nameLocation;
@@ -20,6 +23,7 @@ class FieldElementImplementation extends AbstractNodeElement implements FieldEle
private MethodNodeElement getter;
private MethodNodeElement setter;
private Type constantType;
private Set<Element> overridden = ImmutableSet.of();
FieldElementImplementation(DartNode node,
SourceInfo nameLocation,
@@ -113,4 +117,12 @@ class FieldElementImplementation extends AbstractNodeElement implements FieldEle
public void setConstantType(Type type) {
constantType = type;
}
public void setOverridden(Set<Element> overridden) {
this.overridden = overridden;
}
public Set<Element> getOverridden() {
return overridden;
}
}
@@ -22,7 +22,7 @@ public interface MethodElement extends Element, EnclosingElement {
Type getReturnType();
FunctionType getFunctionType();
/**
* @return {@link Element}s overridden by this {@link MethodElement}.
*/
@@ -3036,6 +3036,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
for (InterfaceType supertype : supertypes) {
supertypeElements.add(supertype.getElement());
}
Set<String> artificialNames = Sets.newHashSet();
for (ClassElement interfaceElement : supertypeElements) {
for (Element member : interfaceElement.getMembers()) {
String name = member.getName();
@@ -3045,6 +3046,11 @@ public class TypeAnalyzer implements DartCompilationPhase {
}
}
superMembers.put(name, member);
if (member instanceof FieldElement
&& !((FieldElement) member).getModifiers().isAbstractField()) {
artificialNames.add("setter " + name);
superMembers.put("setter " + name, member);
}
}
}
@@ -3072,6 +3078,11 @@ public class TypeAnalyzer implements DartCompilationPhase {
}
supertype = supertype.getElement().getSupertype();
}
// Remove artificial "setter " members.
for (String name : artificialNames) {
superMembers.removeAll(name);
}
// All remaining methods are unimplemented.
for (String name : superMembers.keys()) {
@@ -3096,8 +3107,19 @@ public class TypeAnalyzer implements DartCompilationPhase {
public Void visitField(DartField node) {
if (superMembers != null) {
FieldElement field = node.getElement();
// prepare overridden elements
String name = field.getName();
Collection<Element> overridden = superMembers.removeAll(name);
Set<Element> overridden = Sets.newHashSet();
if (node.getAccessor() != null) {
if (node.getAccessor().getModifiers().isSetter()) {
overridden.addAll(superMembers.removeAll("setter " + name));
} else {
overridden.addAll(superMembers.removeAll(name));
}
} else {
overridden.addAll(superMembers.removeAll(name));
}
// check override
for (Element superElement : overridden) {
if (!(field.isStatic() && superElement.getModifiers().isStatic())) {
if (canOverride(node.getName(), field.getModifiers(), superElement)
@@ -3156,6 +3178,32 @@ public class TypeAnalyzer implements DartCompilationPhase {
}
}
}
// set super-elements for FieldElement
Elements.setOverridden(field, ImmutableSet.copyOf(overridden));
// set super-elements for getter/setter
if (node.getAccessor() != null) {
Set<Element> superGetters = Sets.newHashSet();
Set<Element> superSetters = Sets.newHashSet();
for (Element superElement : overridden) {
if (superElement instanceof FieldElement) {
FieldElement superField = (FieldElement) superElement;
if (superField.getGetter() != null) {
superGetters.add(superField.getGetter());
} else if (superField.getSetter() != null) {
superSetters.add(superField.getSetter());
} else {
superGetters.add(superField);
superSetters.add(superField);
}
}
}
if (node.getAccessor().getModifiers().isGetter()) {
Elements.setOverridden(node.getAccessor().getElement(), superGetters);
}
if (node.getAccessor().getModifiers().isSetter()) {
Elements.setOverridden(node.getAccessor().getElement(), superSetters);
}
}
}
return null;
}