Passing DataFlowInfo to local classes/objects

#KT-2835 In Progress
#KT-2225 In Progress
#KT-338 In Progress
This commit is contained in:
Andrey Breslav
2013-08-19 17:34:46 +04:00
parent c95f2b78c8
commit 63c284e200
15 changed files with 185 additions and 35 deletions
@@ -26,19 +26,20 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorUtil;
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.context.ExpressionPosition;
import org.jetbrains.jet.lang.resolve.calls.context.SimpleResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemCompleter;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.scopes.*;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.expressions.DataFlowUtils;
import org.jetbrains.jet.lang.types.expressions.DelegatedPropertyUtils;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
@@ -52,7 +53,8 @@ import java.util.*;
import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.CONSTRAINT_SYSTEM_COMPLETER;
import static org.jetbrains.jet.lang.resolve.BindingContext.DEFERRED_TYPE;
import static org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults.Code;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
@@ -209,9 +211,11 @@ public class BodyResolver {
JetScope scope = scopeForConstructor == null
? scopeForMemberResolution
: scopeForConstructor;
JetType type = typeInferrer.getType(scope, delegateExpression, NO_EXPECTED_TYPE, DataFlowInfo.EMPTY, trace);
if (type != null && supertype != null && !JetTypeChecker.INSTANCE.isSubtypeOf(type, supertype)) {
trace.report(TYPE_MISMATCH.on(delegateExpression, supertype, type));
JetType type = typeInferrer.getType(scope, delegateExpression, NO_EXPECTED_TYPE, context.getOuterDataFlowInfo(), trace);
if (type != null && supertype != null) {
DataFlowUtils.checkType(type, delegateExpression,
new SimpleResolutionContext(trace, scope, supertype, context.getOuterDataFlowInfo(),
ExpressionPosition.FREE));
}
}
}
@@ -232,7 +236,7 @@ public class BodyResolver {
}
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall(
trace, scopeForConstructor,
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call), NO_EXPECTED_TYPE, DataFlowInfo.EMPTY);
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call), NO_EXPECTED_TYPE, context.getOuterDataFlowInfo());
if (results.isSuccess()) {
JetType supertype = results.getResultingDescriptor().getReturnType();
recordSupertype(typeReference, supertype);
@@ -359,7 +363,7 @@ public class BodyResolver {
List<JetClassInitializer> anonymousInitializers = jetClassOrObject.getAnonymousInitializers();
if (primaryConstructor != null) {
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
expressionTypingServices.getType(scopeForInitializers, anonymousInitializer.getBody(), NO_EXPECTED_TYPE, DataFlowInfo.EMPTY, trace);
expressionTypingServices.getType(scopeForInitializers, anonymousInitializer.getBody(), NO_EXPECTED_TYPE, context.getOuterDataFlowInfo(), trace);
}
}
else {
@@ -528,7 +532,7 @@ public class BodyResolver {
traceToResolveDelegatedProperty.record(CONSTRAINT_SYSTEM_COMPLETER, calleeExpression, completer);
}
JetType delegateType = expressionTypingServices.safeGetType(propertyDeclarationInnerScope, delegateExpression, NO_EXPECTED_TYPE,
DataFlowInfo.EMPTY, traceToResolveDelegatedProperty);
context.getOuterDataFlowInfo(), traceToResolveDelegatedProperty);
traceToResolveDelegatedProperty.commit(new TraceEntryFilter() {
@Override
public boolean accept(@NotNull WritableSlice<?, ?> slice, Object key) {
@@ -625,7 +629,7 @@ public class BodyResolver {
JetScope propertyDeclarationInnerScope = descriptorResolver.getPropertyDeclarationInnerScopeForInitializer(
scope, propertyDescriptor.getTypeParameters(), NO_RECEIVER_PARAMETER, trace);
JetType expectedTypeForInitializer = property.getTypeRef() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer, DataFlowInfo.EMPTY, trace);
expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer, context.getOuterDataFlowInfo(), trace);
if (AnnotationUtils.isPropertyAcceptableAsAnnotationParameter(propertyDescriptor)) {
CompileTimeConstant<?> constant = annotationResolver.resolveExpressionToCompileTimeValue(initializer, expectedTypeForInitializer, trace);
if (constant != null) {
@@ -668,7 +672,7 @@ public class BodyResolver {
JetExpression bodyExpression = function.getBodyExpression();
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(declaringScope, functionDescriptor, trace);
if (bodyExpression != null) {
expressionTypingServices.checkFunctionReturnType(functionInnerScope, function, functionDescriptor, DataFlowInfo.EMPTY, null, trace);
expressionTypingServices.checkFunctionReturnType(functionInnerScope, function, functionDescriptor, context.getOuterDataFlowInfo(), null, trace);
}
List<JetParameter> valueParameters = function.getValueParameters();
@@ -702,7 +706,7 @@ public class BodyResolver {
if (valueParameterDescriptor.hasDefaultValue()) {
JetExpression defaultValue = jetParameter.getDefaultValue();
if (defaultValue != null) {
expressionTypingServices.getType(declaringScope, defaultValue, valueParameterDescriptor.getType(), DataFlowInfo.EMPTY, trace);
expressionTypingServices.getType(declaringScope, defaultValue, valueParameterDescriptor.getType(), context.getOuterDataFlowInfo(), trace);
if (DescriptorUtils.isAnnotationClass(DescriptorUtils.getContainingClass(declaringScope))) {
CompileTimeConstant<?> constant =
annotationResolver.resolveExpressionToCompileTimeValue(defaultValue, valueParameterDescriptor.getType(), trace);
@@ -179,16 +179,24 @@ public class DeclarationResolver {
// TODO : Extensions
}
private void resolveFunctionAndPropertyHeaders(@NotNull List<JetDeclaration> declarations,
final @NotNull JetScope scopeForFunctions,
final @NotNull JetScope scopeForPropertyInitializers, final @NotNull JetScope scopeForPropertyAccessors,
final @NotNull NamespaceLikeBuilder namespaceLike)
private void resolveFunctionAndPropertyHeaders(
@NotNull List<JetDeclaration> declarations,
@NotNull final JetScope scopeForFunctions,
@NotNull final JetScope scopeForPropertyInitializers,
@NotNull final JetScope scopeForPropertyAccessors,
@NotNull final NamespaceLikeBuilder namespaceLike)
{
for (JetDeclaration declaration : declarations) {
declaration.accept(new JetVisitorVoid() {
@Override
public void visitNamedFunction(JetNamedFunction function) {
SimpleFunctionDescriptor functionDescriptor = descriptorResolver.resolveFunctionDescriptor(namespaceLike.getOwnerForChildren(), scopeForFunctions, function, trace);
SimpleFunctionDescriptor functionDescriptor = descriptorResolver.resolveFunctionDescriptor(
namespaceLike.getOwnerForChildren(),
scopeForFunctions,
function,
trace,
context.getOuterDataFlowInfo()
);
namespaceLike.addFunctionDescriptor(functionDescriptor);
context.getFunctions().put(function, functionDescriptor);
context.registerDeclaringScope(function, scopeForFunctions);
@@ -250,9 +250,10 @@ public class DescriptorResolver {
@NotNull DeclarationDescriptor containingDescriptor,
@NotNull JetScope scope,
@NotNull JetNamedFunction function,
@NotNull BindingTrace trace
@NotNull BindingTrace trace,
@NotNull DataFlowInfo dataFlowInfo
) {
return resolveFunctionDescriptor(containingDescriptor, scope, function, trace,
return resolveFunctionDescriptor(containingDescriptor, scope, function, trace, dataFlowInfo,
annotationResolver.resolveAnnotationsWithArguments(scope, function.getModifierList(), trace));
}
@@ -261,9 +262,10 @@ public class DescriptorResolver {
@NotNull DeclarationDescriptor containingDescriptor,
@NotNull JetScope scope,
@NotNull JetNamedFunction function,
@NotNull BindingTrace trace
@NotNull BindingTrace trace,
@NotNull DataFlowInfo dataFlowInfo
) {
return resolveFunctionDescriptor(containingDescriptor, scope, function, trace,
return resolveFunctionDescriptor(containingDescriptor, scope, function, trace, dataFlowInfo,
annotationResolver.resolveAnnotations(scope, function.getModifierList(), trace));
}
@@ -273,6 +275,7 @@ public class DescriptorResolver {
@NotNull final JetScope scope,
@NotNull final JetNamedFunction function,
@NotNull final BindingTrace trace,
@NotNull final DataFlowInfo dataFlowInfo,
@NotNull List<AnnotationDescriptor> annotations
) {
final SimpleFunctionDescriptorImpl functionDescriptor = new SimpleFunctionDescriptorImpl(
@@ -320,7 +323,7 @@ public class DescriptorResolver {
DeferredType.create(trace, new RecursionIntolerantLazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
@Override
protected JetType compute() {
JetType type = expressionTypingServices.getBodyExpressionType(trace, scope, function, functionDescriptor);
JetType type = expressionTypingServices.getBodyExpressionType(trace, scope, dataFlowInfo, function, functionDescriptor);
return transformAnonymousTypeIfNeeded(functionDescriptor, function, type, trace);
}
});
@@ -0,0 +1,35 @@
package org.jetbrains.jet.lang.resolve.calls.context;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.JetType;
public class SimpleResolutionContext extends ResolutionContext<SimpleResolutionContext> {
public SimpleResolutionContext(
@NotNull BindingTrace trace,
@NotNull JetScope scope,
@NotNull JetType expectedType,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull ExpressionPosition expressionPosition
) {
super(trace, scope, expectedType, dataFlowInfo, expressionPosition);
}
@Override
protected SimpleResolutionContext create(
@NotNull BindingTrace trace,
@NotNull JetScope scope,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType,
@NotNull ExpressionPosition expressionPosition
) {
return new SimpleResolutionContext(trace, scope, expectedType, dataFlowInfo, expressionPosition);
}
@Override
protected SimpleResolutionContext self() {
return this;
}
}
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassInfoUtil;
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProvider;
@@ -151,9 +152,14 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
Collection<JetNamedFunction> declarations = declarationProvider.getFunctionDeclarations(name);
for (JetNamedFunction functionDeclaration : declarations) {
JetScope resolutionScope = getScopeForMemberDeclarationResolution(functionDeclaration);
result.add(resolveSession.getInjector().getDescriptorResolver().resolveFunctionDescriptorWithAnnotationArguments(thisDescriptor, resolutionScope,
functionDeclaration,
resolveSession.getTrace()));
result.add(resolveSession.getInjector().getDescriptorResolver().resolveFunctionDescriptorWithAnnotationArguments(
thisDescriptor, resolutionScope,
functionDeclaration,
resolveSession.getTrace(),
// this relies on the assumption that a lazily resolved declaration is not a local one,
// thus doesn't have a surrounding data flow
DataFlowInfo.EMPTY)
);
}
getNonDeclaredFunctions(name, result);
@@ -17,7 +17,9 @@
package org.jetbrains.jet.lang.types.expressions;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,9 +43,9 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens;
import javax.inject.Inject;
import java.util.Iterator;
import java.util.List;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.LABEL_TARGET;
import static org.jetbrains.jet.lang.resolve.BindingContext.STATEMENT;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.makeTraceInterceptingTypeMismatch;
@@ -214,6 +216,7 @@ public class ExpressionTypingServices {
public JetType getBodyExpressionType(
@NotNull BindingTrace trace,
@NotNull JetScope outerScope,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull JetDeclarationWithBody function,
@NotNull FunctionDescriptor functionDescriptor
) {
@@ -222,7 +225,7 @@ public class ExpressionTypingServices {
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace);
ExpressionTypingContext context = ExpressionTypingContext.newContext(
this, trace, functionInnerScope, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE, ExpressionPosition.FREE
this, trace, functionInnerScope, dataFlowInfo, NO_EXPECTED_TYPE, ExpressionPosition.FREE
);
JetTypeInfo typeInfo = expressionTypingFacade.getTypeInfo(bodyExpression, context, !function.hasBlockBody());
@@ -157,7 +157,8 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
@Override
public JetTypeInfo visitNamedFunction(JetNamedFunction function, ExpressionTypingContext context) {
SimpleFunctionDescriptor functionDescriptor = context.expressionTypingServices.getDescriptorResolver().
resolveFunctionDescriptorWithAnnotationArguments(scope.getContainingDeclaration(), scope, function, context.trace);
resolveFunctionDescriptorWithAnnotationArguments(
scope.getContainingDeclaration(), scope, function, context.trace, context.dataFlowInfo);
scope.addFunctionDescriptor(functionDescriptor);
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace);