Problem caused by the asymmetry of equals() for deferred types solved (ad hoc)
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user