Problem caused by the asymmetry of equals() for deferred types solved (ad hoc)

This commit is contained in:
Andrey Breslav
2011-05-13 19:48:56 +04:00
parent 5aad7021af
commit b67359a861
10 changed files with 110 additions and 35 deletions
@@ -64,30 +64,51 @@ public interface BindingTrace {
public ErrorHandler getErrorHandler() {
return ErrorHandler.DO_NOTHING;
}
@Override
public boolean isProcessed(@NotNull JetExpression expression) {
return false;
}
@Override
public void markAsProcessed(@NotNull JetExpression expression) {
}
@Override
public BindingContext getBindingContext() {
throw new UnsupportedOperationException();
}
};
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type);
void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type);
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor);
void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor);
public void recordLabelResolution(@NotNull JetReferenceExpression expression, @NotNull PsiElement element);
void recordLabelResolution(@NotNull JetReferenceExpression expression, @NotNull PsiElement element);
public void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor);
void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor);
public void recordValueParameterAsPropertyResolution(@NotNull JetParameter declaration, @NotNull PropertyDescriptor descriptor);
void recordValueParameterAsPropertyResolution(@NotNull JetParameter declaration, @NotNull PropertyDescriptor descriptor);
public void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull JetType type);
void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull JetType type);
public void recordBlock(JetFunctionLiteralExpression expression);
void recordBlock(JetFunctionLiteralExpression expression);
public void recordStatement(@NotNull JetElement statement);
void recordStatement(@NotNull JetElement statement);
public void removeStatementRecord(@NotNull JetElement statement);
void removeStatementRecord(@NotNull JetElement statement);
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression);
void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression);
public void requireBackingField(@NotNull PropertyDescriptor propertyDescriptor);
void requireBackingField(@NotNull PropertyDescriptor propertyDescriptor);
@NotNull
public ErrorHandler getErrorHandler();
ErrorHandler getErrorHandler();
boolean isProcessed(@NotNull JetExpression expression);
void markAsProcessed(@NotNull JetExpression expression);
BindingContext getBindingContext();
}
@@ -71,4 +71,19 @@ public class BindingTraceAdapter implements BindingTrace {
public void removeStatementRecord(@NotNull JetElement statement) {
originalTrace.removeStatementRecord(statement);
}
@Override
public void markAsProcessed(@NotNull JetExpression expression) {
originalTrace.markAsProcessed(expression);
}
@Override
public boolean isProcessed(@NotNull JetExpression expression) {
return originalTrace.isProcessed(expression);
}
@Override
public BindingContext getBindingContext() {
return originalTrace.getBindingContext();
}
}
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
@@ -31,6 +32,7 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
private final Set<JetFunctionLiteralExpression> blocks = new HashSet<JetFunctionLiteralExpression>();
private final Set<JetElement> statements = new HashSet<JetElement>();
private final Set<PropertyDescriptor> backingFieldRequired = new HashSet<PropertyDescriptor>();
private final Set<JetExpression> processed = Sets.newHashSet();
private Collection<JetDiagnostic> diagnostics = Lists.newArrayList();
private ErrorHandler errorHandler = new ErrorHandler() {
@@ -70,6 +72,7 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
@Override
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
expressionTypes.put(expression, type);
markAsProcessed(expression);
}
@Override
@@ -279,4 +282,19 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
public Collection<JetDiagnostic> getDiagnostics() {
return diagnostics;
}
@Override
public void markAsProcessed(@NotNull JetExpression expression) {
processed.add(expression);
}
@Override
public boolean isProcessed(@NotNull JetExpression expression) {
return processed.contains(expression);
}
@Override
public BindingContext getBindingContext() {
return this;
}
}
@@ -259,7 +259,7 @@ public class ClassDescriptorResolver {
returnType = new DeferredType(new LazyValue<JetType>() {
@Override
protected JetType compute() {
JetFlowInformationProvider flowInformationProvider = computeFlowData(function.asElement(), bodyExpression);
JetFlowInformationProvider flowInformationProvider = computeFlowData(function, bodyExpression);
return semanticServices.getTypeInferrer(trace, flowInformationProvider).getFunctionReturnType(scope, function, functionDescriptor);
}
});
@@ -863,6 +863,7 @@ public class TopDownAnalyzer {
@NotNull MutableFunctionDescriptor functionDescriptor,
@NotNull JetScope declaringScope) {
JetExpression bodyExpression = function.getBodyExpression();
if (bodyExpression != null) {
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(function.asElement(), bodyExpression);
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(trace, flowInformationProvider);
@@ -57,4 +57,14 @@ public class DeferredType implements JetType {
return "<Failed to compute this type>";
}
}
@Override
public boolean equals(Object obj) {
return getActualType().equals(obj);
}
@Override
public int hashCode() {
return getActualType().hashCode();
}
}
@@ -161,7 +161,8 @@ public class ErrorUtils {
}
public static boolean isErrorType(JetType type) {
return type instanceof ErrorTypeImpl ||
return (type instanceof DeferredType && ((DeferredType) type).getActualType() == null) ||
type instanceof ErrorTypeImpl ||
isError(type.getConstructor());
}
@@ -16,4 +16,7 @@ public interface JetType extends Annotated {
@NotNull
JetScope getMemberScope();
@Override
public boolean equals(Object other);
}
@@ -63,7 +63,7 @@ public class JetTypeInferrer {
assignmentOperationCounterparts.put(JetTokens.MINUSEQ, JetTokens.MINUS);
}
private final Map<JetExpression, JetType> typeCache = new HashMap<JetExpression, JetType>();
// private final Map<JetExpression, JetType> typeCache = new HashMap<JetExpression, JetType>();
private final BindingTrace trace;
private final JetSemanticServices semanticServices;
@@ -72,7 +72,7 @@ public class JetTypeInferrer {
private final JetFlowInformationProvider flowInformationProvider;
public JetTypeInferrer(@NotNull BindingTrace trace, @NotNull JetFlowInformationProvider flowInformationProvider, @NotNull JetSemanticServices semanticServices) {
this.trace = new CachedBindingTrace(trace);
this.trace = trace; //new CachedBindingTrace(trace);
this.semanticServices = semanticServices;
this.typeResolver = new TypeResolver(semanticServices, trace, true);
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
@@ -280,10 +280,10 @@ public class JetTypeInferrer {
return types.isEmpty() ? JetStandardClasses.getNothingType() : semanticServices.getTypeChecker().commonSupertype(types);
}
private JetType getCachedType(@NotNull JetExpression expression) {
// assert typeCache.containsKey(expression) : "No type cached for " + expression.getText();
return typeCache.get(expression);
}
// private JetType getCachedType(@NotNull JetExpression expression) {
//// assert typeCache.containsKey(expression) : "No type cached for " + expression.getText();
// return typeCache.get(expression);
// }
public void checkFunctionReturnType(@NotNull JetScope outerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor) {
Map<JetElement, JetType> typeMap = collectReturnedExpressions(outerScope, function, functionDescriptor);
@@ -330,7 +330,7 @@ public class JetTypeInferrer {
flowInformationProvider.collectReturnedInformation(function.asElement(), returnedExpressions, elementsReturningUnit);
Map<JetElement,JetType> typeMap = new HashMap<JetElement, JetType>();
for (JetExpression returnedExpression : returnedExpressions) {
JetType cachedType = getCachedType(returnedExpression);
JetType cachedType = trace.getBindingContext().getExpressionType(returnedExpression);// getCachedType(returnedExpression);
trace.removeStatementRecord(returnedExpression);
if (cachedType != null) {
typeMap.put(returnedExpression, cachedType);
@@ -592,10 +592,17 @@ public class JetTypeInferrer {
}
@Nullable
public JetType getType(@NotNull JetExpression expression) {
public final JetType getType(@NotNull JetExpression expression) {
assert result == null;
if (trace.isProcessed(expression)) {
return trace.getBindingContext().getExpressionType(expression);
}
try {
expression.accept(this);
trace.markAsProcessed(expression);
if (result instanceof DeferredType) {
result = ((DeferredType) result).getActualType();
}
if (result != null) {
trace.recordExpressionType(expression, result);
if (JetStandardClasses.isNothing(result) && !result.isNullable()) {
@@ -1688,16 +1695,16 @@ public class JetTypeInferrer {
}
}
private class CachedBindingTrace extends BindingTraceAdapter {
public CachedBindingTrace(BindingTrace originalTrace) {
super(originalTrace);
}
@Override
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
super.recordExpressionType(expression, type);
typeCache.put(expression, type);
}
}
// private class CachedBindingTrace extends BindingTraceAdapter {
//
// public CachedBindingTrace(BindingTrace originalTrace) {
// super(originalTrace);
// }
//
// @Override
// public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
// super.recordExpressionType(expression, type);
// typeCache.put(expression, type);
// }
// }
}
@@ -23,7 +23,6 @@ public abstract class LazyValue<T> {
return state;
}
@NotNull
public final T get() {
switch (state) {
case NOT_COMPUTED: