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() {
|
public ErrorHandler getErrorHandler() {
|
||||||
return ErrorHandler.DO_NOTHING;
|
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
|
@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) {
|
public void removeStatementRecord(@NotNull JetElement statement) {
|
||||||
originalTrace.removeStatementRecord(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.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
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<JetFunctionLiteralExpression> blocks = new HashSet<JetFunctionLiteralExpression>();
|
||||||
private final Set<JetElement> statements = new HashSet<JetElement>();
|
private final Set<JetElement> statements = new HashSet<JetElement>();
|
||||||
private final Set<PropertyDescriptor> backingFieldRequired = new HashSet<PropertyDescriptor>();
|
private final Set<PropertyDescriptor> backingFieldRequired = new HashSet<PropertyDescriptor>();
|
||||||
|
private final Set<JetExpression> processed = Sets.newHashSet();
|
||||||
|
|
||||||
private Collection<JetDiagnostic> diagnostics = Lists.newArrayList();
|
private Collection<JetDiagnostic> diagnostics = Lists.newArrayList();
|
||||||
private ErrorHandler errorHandler = new ErrorHandler() {
|
private ErrorHandler errorHandler = new ErrorHandler() {
|
||||||
@@ -70,6 +72,7 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
|
|||||||
@Override
|
@Override
|
||||||
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
|
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
|
||||||
expressionTypes.put(expression, type);
|
expressionTypes.put(expression, type);
|
||||||
|
markAsProcessed(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -279,4 +282,19 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
|
|||||||
public Collection<JetDiagnostic> getDiagnostics() {
|
public Collection<JetDiagnostic> getDiagnostics() {
|
||||||
return diagnostics;
|
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>() {
|
returnType = new DeferredType(new LazyValue<JetType>() {
|
||||||
@Override
|
@Override
|
||||||
protected JetType compute() {
|
protected JetType compute() {
|
||||||
JetFlowInformationProvider flowInformationProvider = computeFlowData(function.asElement(), bodyExpression);
|
JetFlowInformationProvider flowInformationProvider = computeFlowData(function, bodyExpression);
|
||||||
return semanticServices.getTypeInferrer(trace, flowInformationProvider).getFunctionReturnType(scope, function, functionDescriptor);
|
return semanticServices.getTypeInferrer(trace, flowInformationProvider).getFunctionReturnType(scope, function, functionDescriptor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -863,6 +863,7 @@ public class TopDownAnalyzer {
|
|||||||
@NotNull MutableFunctionDescriptor functionDescriptor,
|
@NotNull MutableFunctionDescriptor functionDescriptor,
|
||||||
@NotNull JetScope declaringScope) {
|
@NotNull JetScope declaringScope) {
|
||||||
JetExpression bodyExpression = function.getBodyExpression();
|
JetExpression bodyExpression = function.getBodyExpression();
|
||||||
|
|
||||||
if (bodyExpression != null) {
|
if (bodyExpression != null) {
|
||||||
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(function.asElement(), bodyExpression);
|
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(function.asElement(), bodyExpression);
|
||||||
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(trace, flowInformationProvider);
|
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(trace, flowInformationProvider);
|
||||||
|
|||||||
@@ -57,4 +57,14 @@ public class DeferredType implements JetType {
|
|||||||
return "<Failed to compute this type>";
|
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) {
|
public static boolean isErrorType(JetType type) {
|
||||||
return type instanceof ErrorTypeImpl ||
|
return (type instanceof DeferredType && ((DeferredType) type).getActualType() == null) ||
|
||||||
|
type instanceof ErrorTypeImpl ||
|
||||||
isError(type.getConstructor());
|
isError(type.getConstructor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,4 +16,7 @@ public interface JetType extends Annotated {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
JetScope getMemberScope();
|
JetScope getMemberScope();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class JetTypeInferrer {
|
|||||||
assignmentOperationCounterparts.put(JetTokens.MINUSEQ, JetTokens.MINUS);
|
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 BindingTrace trace;
|
||||||
private final JetSemanticServices semanticServices;
|
private final JetSemanticServices semanticServices;
|
||||||
@@ -72,7 +72,7 @@ public class JetTypeInferrer {
|
|||||||
private final JetFlowInformationProvider flowInformationProvider;
|
private final JetFlowInformationProvider flowInformationProvider;
|
||||||
|
|
||||||
public JetTypeInferrer(@NotNull BindingTrace trace, @NotNull JetFlowInformationProvider flowInformationProvider, @NotNull JetSemanticServices semanticServices) {
|
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.semanticServices = semanticServices;
|
||||||
this.typeResolver = new TypeResolver(semanticServices, trace, true);
|
this.typeResolver = new TypeResolver(semanticServices, trace, true);
|
||||||
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
|
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
|
||||||
@@ -280,10 +280,10 @@ public class JetTypeInferrer {
|
|||||||
return types.isEmpty() ? JetStandardClasses.getNothingType() : semanticServices.getTypeChecker().commonSupertype(types);
|
return types.isEmpty() ? JetStandardClasses.getNothingType() : semanticServices.getTypeChecker().commonSupertype(types);
|
||||||
}
|
}
|
||||||
|
|
||||||
private JetType getCachedType(@NotNull JetExpression expression) {
|
// private JetType getCachedType(@NotNull JetExpression expression) {
|
||||||
// assert typeCache.containsKey(expression) : "No type cached for " + expression.getText();
|
//// assert typeCache.containsKey(expression) : "No type cached for " + expression.getText();
|
||||||
return typeCache.get(expression);
|
// return typeCache.get(expression);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void checkFunctionReturnType(@NotNull JetScope outerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor) {
|
public void checkFunctionReturnType(@NotNull JetScope outerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor) {
|
||||||
Map<JetElement, JetType> typeMap = collectReturnedExpressions(outerScope, function, functionDescriptor);
|
Map<JetElement, JetType> typeMap = collectReturnedExpressions(outerScope, function, functionDescriptor);
|
||||||
@@ -330,7 +330,7 @@ public class JetTypeInferrer {
|
|||||||
flowInformationProvider.collectReturnedInformation(function.asElement(), returnedExpressions, elementsReturningUnit);
|
flowInformationProvider.collectReturnedInformation(function.asElement(), returnedExpressions, elementsReturningUnit);
|
||||||
Map<JetElement,JetType> typeMap = new HashMap<JetElement, JetType>();
|
Map<JetElement,JetType> typeMap = new HashMap<JetElement, JetType>();
|
||||||
for (JetExpression returnedExpression : returnedExpressions) {
|
for (JetExpression returnedExpression : returnedExpressions) {
|
||||||
JetType cachedType = getCachedType(returnedExpression);
|
JetType cachedType = trace.getBindingContext().getExpressionType(returnedExpression);// getCachedType(returnedExpression);
|
||||||
trace.removeStatementRecord(returnedExpression);
|
trace.removeStatementRecord(returnedExpression);
|
||||||
if (cachedType != null) {
|
if (cachedType != null) {
|
||||||
typeMap.put(returnedExpression, cachedType);
|
typeMap.put(returnedExpression, cachedType);
|
||||||
@@ -592,10 +592,17 @@ public class JetTypeInferrer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public JetType getType(@NotNull JetExpression expression) {
|
public final JetType getType(@NotNull JetExpression expression) {
|
||||||
assert result == null;
|
assert result == null;
|
||||||
|
if (trace.isProcessed(expression)) {
|
||||||
|
return trace.getBindingContext().getExpressionType(expression);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
expression.accept(this);
|
expression.accept(this);
|
||||||
|
trace.markAsProcessed(expression);
|
||||||
|
if (result instanceof DeferredType) {
|
||||||
|
result = ((DeferredType) result).getActualType();
|
||||||
|
}
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
trace.recordExpressionType(expression, result);
|
trace.recordExpressionType(expression, result);
|
||||||
if (JetStandardClasses.isNothing(result) && !result.isNullable()) {
|
if (JetStandardClasses.isNothing(result) && !result.isNullable()) {
|
||||||
@@ -1688,16 +1695,16 @@ public class JetTypeInferrer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CachedBindingTrace extends BindingTraceAdapter {
|
// private class CachedBindingTrace extends BindingTraceAdapter {
|
||||||
|
//
|
||||||
public CachedBindingTrace(BindingTrace originalTrace) {
|
// public CachedBindingTrace(BindingTrace originalTrace) {
|
||||||
super(originalTrace);
|
// super(originalTrace);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
|
// public void recordExpressionType(@NotNull JetExpression expression, @NotNull JetType type) {
|
||||||
super.recordExpressionType(expression, type);
|
// super.recordExpressionType(expression, type);
|
||||||
typeCache.put(expression, type);
|
// typeCache.put(expression, type);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ public abstract class LazyValue<T> {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public final T get() {
|
public final T get() {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case NOT_COMPUTED:
|
case NOT_COMPUTED:
|
||||||
|
|||||||
Reference in New Issue
Block a user