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

Unified Diff: compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java

Issue 9689080: Add ClassNodeElement and allow Analyzer to use cached unimplemented members (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
index c84dd4eb7d9877d4a10809fad940b9bbf57bb256..79c1276028125ef19c6ccdd8ca701fe82b873aa8 100644
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
@@ -95,6 +95,7 @@ import com.google.dart.compiler.ast.Modifiers;
import com.google.dart.compiler.common.HasSourceInfo;
import com.google.dart.compiler.parser.Token;
import com.google.dart.compiler.resolver.ClassElement;
+import com.google.dart.compiler.resolver.ClassNodeElement;
import com.google.dart.compiler.resolver.ConstructorElement;
import com.google.dart.compiler.resolver.CoreTypeProvider;
import com.google.dart.compiler.resolver.CyclicDeclarationException;
@@ -109,17 +110,14 @@ import com.google.dart.compiler.resolver.TypeErrorCode;
import com.google.dart.compiler.resolver.VariableElement;
import com.google.dart.compiler.type.InterfaceType.Member;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
/**
* Analyzer of static type information.
@@ -139,10 +137,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
Token.ASSIGN_DIV,
Token.ASSIGN_MOD,
Token.ASSIGN_TRUNC);
- private final ConcurrentHashMap<ClassElement, List<Element>> unimplementedElements =
- new ConcurrentHashMap<ClassElement, List<Element>>();
- private final Set<ClassElement> diagnosedAbstractClasses =
- Collections.newSetFromMap(new ConcurrentHashMap<ClassElement, Boolean>());
+ private final Set<ClassElement> diagnosedAbstractClasses = Sets.newHashSet();
/**
* Perform type analysis on the given AST rooted at <code>node</code>.
@@ -156,20 +151,15 @@ public class TypeAnalyzer implements DartCompilationPhase {
*/
public static Type analyze(DartNode node, CoreTypeProvider typeProvider,
DartCompilerContext context, InterfaceType currentClass) {
- ConcurrentHashMap<ClassElement, List<Element>> unimplementedElements =
- new ConcurrentHashMap<ClassElement, List<Element>>();
- Set<ClassElement> diagnosed =
- Collections.newSetFromMap(new ConcurrentHashMap<ClassElement, Boolean>());
- Analyzer analyzer = new Analyzer(context, typeProvider, unimplementedElements, diagnosed);
+ Set<ClassElement> diagnosed = Sets.newHashSet();
+ Analyzer analyzer = new Analyzer(context, typeProvider, diagnosed);
analyzer.setCurrentClass(currentClass);
return node.accept(analyzer);
}
@Override
- public DartUnit exec(DartUnit unit, DartCompilerContext context,
- CoreTypeProvider typeProvider) {
- unit.accept(new Analyzer(context, typeProvider, unimplementedElements,
- diagnosedAbstractClasses));
+ public DartUnit exec(DartUnit unit, DartCompilerContext context, CoreTypeProvider typeProvider) {
+ unit.accept(new Analyzer(context, typeProvider, diagnosedAbstractClasses));
return unit;
}
@@ -183,7 +173,6 @@ public class TypeAnalyzer implements DartCompilationPhase {
private final Types types;
private Type expected;
private InterfaceType currentClass;
- private final ConcurrentHashMap<ClassElement, List<Element>> unimplementedElements;
private final InterfaceType boolType;
private final InterfaceType numType;
private final InterfaceType intType;
@@ -199,11 +188,9 @@ public class TypeAnalyzer implements DartCompilationPhase {
private int catchDepth = 0;
Analyzer(DartCompilerContext context, CoreTypeProvider typeProvider,
- ConcurrentHashMap<ClassElement, List<Element>> unimplementedElements,
Set<ClassElement> diagnosedAbstractClasses) {
this.context = context;
this.developerModeChecks = context.getCompilerConfiguration().developerModeChecks();
- this.unimplementedElements = unimplementedElements;
this.types = Types.getInstance(typeProvider);
this.dynamicType = typeProvider.getDynamicType();
this.stringType = typeProvider.getStringType();
@@ -429,7 +416,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
}
private List<Type> analyzeArgumentTypes(List<? extends DartExpression> argumentNodes) {
- List<Type> argumentTypes = new ArrayList<Type>(argumentNodes.size());
+ List<Type> argumentTypes = Lists.newArrayListWithCapacity(argumentNodes.size());
for (DartExpression argumentNode : argumentNodes) {
argumentTypes.add(nonVoidTypeOf(argumentNode));
}
@@ -563,7 +550,6 @@ public class TypeAnalyzer implements DartCompilationPhase {
Set<String> usedNamedParametersNamed = Sets.newHashSet();
// Prepare named parameters.
Map<String, Type> namedParameterTypes = ftype.getNamedParameterTypes();
- assert namedParameterTypes.isEmpty() || namedParameterTypes instanceof LinkedHashMap;
Iterator<Entry<String, Type>> namedParameterTypesIterator =
namedParameterTypes.entrySet().iterator();
// Check positional arguments for named parameters.
@@ -656,7 +642,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
List<Type> parameters,
boolean badBoundIsError) {
if (arguments.size() == parameters.size() && arguments.size() == diagnosticNodes.size()) {
- List<Type> bounds = new ArrayList<Type>(parameters.size());
+ List<Type> bounds = Lists.newArrayListWithCapacity(parameters.size());
for (Type parameter : parameters) {
TypeVariable variable = (TypeVariable) parameter;
Type bound = variable.getTypeVariableElement().getBound();
@@ -699,7 +685,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
case VARIABLE: {
TypeVariable boundType = (TypeVariable)bound;
if (boundType.equals(variable)) {
- onError(boundType.getElement().getNode(),
+ onError(boundType.getElement(),
TypeErrorCode.CYCLIC_REFERENCE_TO_TYPE_VARIABLE,
boundType.getElement().getOriginalName());
}
@@ -838,10 +824,10 @@ public class TypeAnalyzer implements DartCompilationPhase {
@Override
public Type visitClass(DartClass node) {
- ClassElement element = node.getElement();
+ ClassNodeElement element = node.getElement();
InterfaceType type = element.getType();
checkCyclicBounds(type.getArguments());
- findUnimplementedMembers(element);
+ List<Element> unimplementedMembers = findUnimplementedMembers(element);
setCurrentClass(type);
visit(node.getTypeParameters());
if (node.getSuperclass() != null) {
@@ -857,14 +843,12 @@ public class TypeAnalyzer implements DartCompilationPhase {
checkInterfaceConstructors(element);
// Report unimplemented members.
if (!node.isAbstract()) {
- ClassElement cls = node.getElement();
- List<Element> unimplementedMembers = findUnimplementedMembers(cls);
if (unimplementedMembers.size() > 0) {
- StringBuilder sb = getUnimplementedMembersMessage(cls, unimplementedMembers);
+ StringBuilder sb = getUnimplementedMembersMessage(element, unimplementedMembers);
typeError(
node.getName(),
TypeErrorCode.ABSTRACT_CLASS_WITHOUT_ABSTRACT_MODIFIER,
- cls.getName(),
+ element.getName(),
sb);
}
}
@@ -897,7 +881,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
if (interfaceTypes.size() == defaultTypes.size()
&& !interfaceTypes.equals(defaultTypes)) {
onError(
- interfaceConstructor.getNode(),
+ interfaceConstructor,
TypeErrorCode.DEFAULT_CONSTRUCTOR_TYPES,
Elements.getRawMethodName(interfaceConstructor),
interfaceClassName,
@@ -911,25 +895,26 @@ public class TypeAnalyzer implements DartCompilationPhase {
}
}
- private List<Element> findUnimplementedMembers(ClassElement element) {
- if (element.isInterface()) {
- element.getNode().accept(new AbstractMethodFinder(element.getType()));
- return Collections.emptyList();
- }
- List<Element> members = unimplementedElements.get(element);
+ private List<Element> findUnimplementedMembers(ClassElement classElement) {
+ // May be has members already (cached or already analyzed ClassNodeElement).
+ List<Element> members = classElement.getUnimplementedMembers();
if (members != null) {
return members;
}
- synchronized (element) {
- members = unimplementedElements.get(element);
- if (members != null) {
- return members;
- }
- AbstractMethodFinder finder = new AbstractMethodFinder(element.getType());
- element.getNode().accept(finder);
- unimplementedElements.put(element, finder.unimplementedElements);
- return finder.unimplementedElements;
+ // If no cached result, then should be node based.
+ ClassNodeElement classNodeElement = (ClassNodeElement) classElement;
+ // Analyze ClassElement node.
+ AbstractMethodFinder finder = new AbstractMethodFinder(classNodeElement.getType());
+ classNodeElement.getNode().accept(finder);
+ // Prepare unimplemented members.
+ if (classNodeElement.isInterface()) {
+ members = Collections.emptyList();
+ } else {
+ members = finder.unimplementedElements;
}
+ // Remember unimplemented methods.
+ classNodeElement.setUnimplementedMembers(members);
+ return members;
}
@Override
@@ -1612,7 +1597,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
private Type checkInvocation(DartInvocation node, DartNode diagnosticNode, String name,
Type type) {
List<DartExpression> argumentNodes = node.getArguments();
- List<Type> argumentTypes = new ArrayList<Type>(argumentNodes.size());
+ List<Type> argumentTypes = Lists.newArrayListWithCapacity(argumentNodes.size());
for (DartExpression argumentNode : argumentNodes) {
argumentTypes.add(nonVoidTypeOf(argumentNode));
}
@@ -1804,13 +1789,11 @@ public class TypeAnalyzer implements DartCompilationPhase {
private class AbstractMethodFinder extends ASTVisitor<Void> {
private final InterfaceType currentClass;
- private final Multimap<String, Element> superMembers;
- private final List<Element> unimplementedElements;
+ private final Multimap<String, Element> superMembers = LinkedListMultimap.create();
+ private final List<Element> unimplementedElements = Lists.newArrayList();
private AbstractMethodFinder(InterfaceType currentClass) {
this.currentClass = currentClass;
- this.superMembers = LinkedListMultimap.create();
- this.unimplementedElements = new ArrayList<Element>();
}
@Override
@@ -1897,7 +1880,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
if (superMembers != null) {
FieldElement field = node.getElement();
String name = field.getName();
- List<Element> overridden = new ArrayList<Element>(superMembers.removeAll(name));
+ Collection<Element> overridden = superMembers.removeAll(name);
for (Element element : overridden) {
if (canOverride(node.getName(), field.getModifiers(), element)) {
switch (element.getKind()) {
@@ -1951,13 +1934,13 @@ public class TypeAnalyzer implements DartCompilationPhase {
* Report a compile-time error if either modifiers or elements.getModifiers() is static.
* @returns true if no compile-time error was reported
*/
- private boolean canOverride(DartExpression node, Modifiers modifiers, Element element) {
+ private boolean canOverride(HasSourceInfo errorTarget, Modifiers modifiers, Element element) {
if (element.getModifiers().isStatic()) {
- onError(node, TypeErrorCode.OVERRIDING_INHERITED_STATIC_MEMBER,
+ onError(errorTarget, TypeErrorCode.OVERRIDING_INHERITED_STATIC_MEMBER,
element.getName(), element.getEnclosingElement().getName());
return false;
} else if (modifiers.isStatic()) {
- onError(node, ResolverErrorCode.CANNOT_OVERRIDE_INSTANCE_MEMBER,
+ onError(errorTarget, ResolverErrorCode.CANNOT_OVERRIDE_INSTANCE_MEMBER,
element.getName(), element.getEnclosingElement().getName());
return false;
}
@@ -1968,15 +1951,15 @@ public class TypeAnalyzer implements DartCompilationPhase {
* Report a static type error if member cannot override superElement, that
* is, they are not assignable.
*/
- private void checkOverride(DartExpression node, Element member, Element superElement) {
+ private void checkOverride(HasSourceInfo errorTarget, Element member, Element superElement) {
String name = member.getName();
Type superMember = typeAsMemberOf(superElement, currentClass);
if (member.getKind() == ElementKind.METHOD && superElement.getKind() == ElementKind.METHOD) {
MethodElement method = (MethodElement) member;
MethodElement superMethod = (MethodElement) superElement;
- if (hasLegalMethodOverrideSignature(node, method, superMethod)) {
+ if (hasLegalMethodOverrideSignature(errorTarget, method, superMethod)) {
if (!types.isSubtype(member.getType(), superMember)) {
- typeError(node,
+ typeError(errorTarget,
TypeErrorCode.CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE,
name,
superElement.getEnclosingElement().getName(),
@@ -1985,7 +1968,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
}
}
} else if (!types.isAssignable(superMember, member.getType())) {
- typeError(node,
+ typeError(errorTarget,
TypeErrorCode.CANNOT_OVERRIDE_TYPED_MEMBER,
name,
superElement.getEnclosingElement().getName(),
@@ -1997,7 +1980,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
/**
* @return <code>true</code> if given "method" has signature compatible with "superMethod".
*/
- private boolean hasLegalMethodOverrideSignature(DartNode node,
+ private boolean hasLegalMethodOverrideSignature(HasSourceInfo errorTarget,
MethodElement method,
MethodElement superMethod) {
// Prepare parameters.
@@ -2008,7 +1991,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
int numRequired = getNumRequiredParameters(parameters);
int superNumRequired = getNumRequiredParameters(superParameters);
if (numRequired != superNumRequired) {
- onError(node,
+ onError(errorTarget,
ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NUM_REQUIRED_PARAMS,
method.getName());
return false;
@@ -2027,7 +2010,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
continue;
}
}
- onError(node, ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NAMED_PARAMS, method.getName());
+ onError(errorTarget, ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NAMED_PARAMS, method.getName());
return false;
}
return true;

Powered by Google App Engine
This is Rietveld 408576698