Multi-declaration resolution logic moved to Util class
This commit is contained in:
+57
-6
@@ -36,10 +36,7 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
|||||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
import org.jetbrains.jet.lang.types.NamespaceType;
|
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
|
||||||
import org.jetbrains.jet.lang.types.Variance;
|
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||||
@@ -49,7 +46,7 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.RESULT_TYPE_MISMATCH;
|
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -248,7 +245,7 @@ public class ExpressionTypingUtils {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static OverloadResolutionResults<FunctionDescriptor> resolveFakeCall(
|
public static OverloadResolutionResults<FunctionDescriptor> resolveFakeCall(
|
||||||
@NotNull ExpressionReceiver receiver,
|
@NotNull ReceiverDescriptor receiver,
|
||||||
@NotNull ExpressionTypingContext context,
|
@NotNull ExpressionTypingContext context,
|
||||||
@NotNull Name name
|
@NotNull Name name
|
||||||
) {
|
) {
|
||||||
@@ -257,4 +254,58 @@ public class ExpressionTypingUtils {
|
|||||||
Call call = CallMaker.makeCall(fake, receiver, null, fake, Collections.<ValueArgument>emptyList());
|
Call call = CallMaker.makeCall(fake, receiver, null, fake, Collections.<ValueArgument>emptyList());
|
||||||
return context.replaceBindingTrace(fakeTrace).resolveCallWithGivenName(call, fake, name);
|
return context.replaceBindingTrace(fakeTrace).resolveCallWithGivenName(call, fake, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void defineLocalVariablesFromMultiDeclaration(
|
||||||
|
@NotNull WritableScope writableScope,
|
||||||
|
@NotNull JetMultiDeclaration multiDeclaration,
|
||||||
|
@NotNull ReceiverDescriptor receiver,
|
||||||
|
@NotNull JetExpression reportErrorsOn,
|
||||||
|
@NotNull ExpressionTypingContext context
|
||||||
|
) {
|
||||||
|
int componentIndex = 1;
|
||||||
|
for (JetMultiDeclarationEntry entry : multiDeclaration.getEntries()) {
|
||||||
|
final Name componentName = Name.identifier("component" + componentIndex);
|
||||||
|
componentIndex++;
|
||||||
|
|
||||||
|
JetType expectedType = getExpectedTypeForComponent(context, entry);
|
||||||
|
OverloadResolutionResults<FunctionDescriptor> results =
|
||||||
|
resolveFakeCall(receiver, context.replaceExpectedType(expectedType), componentName);
|
||||||
|
|
||||||
|
JetType componentType = null;
|
||||||
|
if (results.isSuccess()) {
|
||||||
|
context.trace.record(COMPONENT_RESOLVED_CALL, entry, results.getResultingCall());
|
||||||
|
componentType = results.getResultingDescriptor().getReturnType();
|
||||||
|
if (componentType != null && expectedType != TypeUtils.NO_EXPECTED_TYPE
|
||||||
|
&& !JetTypeChecker.INSTANCE.isSubtypeOf(componentType, expectedType)) {
|
||||||
|
|
||||||
|
context.trace.report(
|
||||||
|
COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.on(reportErrorsOn, componentName, componentType, expectedType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (results.isAmbiguity()) {
|
||||||
|
context.trace.report(COMPONENT_FUNCTION_AMBIGUITY.on(reportErrorsOn, componentName, results.getResultingCalls()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
context.trace.report(COMPONENT_FUNCTION_MISSING.on(reportErrorsOn, componentName));
|
||||||
|
}
|
||||||
|
if (componentType == null) {
|
||||||
|
componentType = ErrorUtils.createErrorType(componentName + "() return type");
|
||||||
|
}
|
||||||
|
VariableDescriptor variableDescriptor = context.expressionTypingServices.getDescriptorResolver().
|
||||||
|
resolveLocalVariableDescriptorWithType(writableScope.getContainingDeclaration(), entry, componentType, context.trace);
|
||||||
|
|
||||||
|
writableScope.addVariableDescriptor(variableDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static JetType getExpectedTypeForComponent(ExpressionTypingContext context, JetMultiDeclarationEntry entry) {
|
||||||
|
JetTypeReference entryTypeRef = entry.getTypeRef();
|
||||||
|
if (entryTypeRef != null) {
|
||||||
|
return context.expressionTypingServices.getTypeResolver().resolveType(context.scope, entryTypeRef, context.trace, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return TypeUtils.NO_EXPECTED_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-49
@@ -32,9 +32,7 @@ import org.jetbrains.jet.lang.resolve.name.Name;
|
|||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
|
||||||
import org.jetbrains.jet.lang.types.JetTypeInfo;
|
import org.jetbrains.jet.lang.types.JetTypeInfo;
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
|
||||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||||
@@ -44,7 +42,6 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.COMPONENT_RESOLVED_CALL;
|
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.VARIABLE_REASSIGNMENT;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.VARIABLE_REASSIGNMENT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -137,58 +134,16 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
|||||||
context.trace.report(INITIALIZER_REQUIRED_FOR_MULTIDECLARATION.on(multiDeclaration));
|
context.trace.report(INITIALIZER_REQUIRED_FOR_MULTIDECLARATION.on(multiDeclaration));
|
||||||
return JetTypeInfo.create(null, context.dataFlowInfo);
|
return JetTypeInfo.create(null, context.dataFlowInfo);
|
||||||
}
|
}
|
||||||
final ExpressionReceiver expressionReceiver = ExpressionTypingUtils.getExpressionReceiver(facade, initializer, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE));
|
final ExpressionReceiver expressionReceiver = ExpressionTypingUtils.getExpressionReceiver(facade, initializer,
|
||||||
|
context.replaceExpectedType(
|
||||||
|
TypeUtils.NO_EXPECTED_TYPE));
|
||||||
if (expressionReceiver == null) {
|
if (expressionReceiver == null) {
|
||||||
return JetTypeInfo.create(null, context.dataFlowInfo);
|
return JetTypeInfo.create(null, context.dataFlowInfo);
|
||||||
}
|
}
|
||||||
int componentIndex = 1;
|
ExpressionTypingUtils.defineLocalVariablesFromMultiDeclaration(scope, multiDeclaration, expressionReceiver, initializer, context);
|
||||||
for (JetMultiDeclarationEntry entry : multiDeclaration.getEntries()) {
|
|
||||||
final Name componentName = Name.identifier("component" + componentIndex);
|
|
||||||
componentIndex++;
|
|
||||||
|
|
||||||
JetType expectedType = getExpectedTypeForComponent(context, entry);
|
|
||||||
OverloadResolutionResults<FunctionDescriptor> results =
|
|
||||||
ExpressionTypingUtils.resolveFakeCall(expressionReceiver, context.replaceExpectedType(expectedType), componentName);
|
|
||||||
|
|
||||||
JetType componentType = null;
|
|
||||||
if (results.isSuccess()) {
|
|
||||||
context.trace.record(COMPONENT_RESOLVED_CALL, entry, results.getResultingCall());
|
|
||||||
componentType = results.getResultingDescriptor().getReturnType();
|
|
||||||
if (componentType != null && expectedType != TypeUtils.NO_EXPECTED_TYPE
|
|
||||||
&& !JetTypeChecker.INSTANCE.isSubtypeOf(componentType, expectedType)) {
|
|
||||||
|
|
||||||
context.trace.report(
|
|
||||||
COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.on(initializer, componentName, componentType, expectedType));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (results.isAmbiguity()) {
|
|
||||||
context.trace.report(COMPONENT_FUNCTION_AMBIGUITY.on(initializer, componentName, results.getResultingCalls()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
context.trace.report(COMPONENT_FUNCTION_MISSING.on(initializer, componentName));
|
|
||||||
}
|
|
||||||
if (componentType == null) {
|
|
||||||
componentType = ErrorUtils.createErrorType(componentName + "() return type");
|
|
||||||
}
|
|
||||||
VariableDescriptor variableDescriptor = context.expressionTypingServices.getDescriptorResolver().
|
|
||||||
resolveLocalVariableDescriptorWithType(scope.getContainingDeclaration(), entry, componentType, context.trace);
|
|
||||||
|
|
||||||
scope.addVariableDescriptor(variableDescriptor);
|
|
||||||
}
|
|
||||||
return DataFlowUtils.checkStatementType(multiDeclaration, context, context.dataFlowInfo);
|
return DataFlowUtils.checkStatementType(multiDeclaration, context, context.dataFlowInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static JetType getExpectedTypeForComponent(ExpressionTypingContext context, JetMultiDeclarationEntry entry) {
|
|
||||||
JetTypeReference entryTypeRef = entry.getTypeRef();
|
|
||||||
if (entryTypeRef != null) {
|
|
||||||
return context.expressionTypingServices.getTypeResolver().resolveType(context.scope, entryTypeRef, context.trace, true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return TypeUtils.NO_EXPECTED_TYPE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetTypeInfo visitNamedFunction(JetNamedFunction function, ExpressionTypingContext context) {
|
public JetTypeInfo visitNamedFunction(JetNamedFunction function, ExpressionTypingContext context) {
|
||||||
SimpleFunctionDescriptor functionDescriptor = context.expressionTypingServices.getDescriptorResolver().resolveFunctionDescriptor(scope.getContainingDeclaration(), scope, function, context.trace);
|
SimpleFunctionDescriptor functionDescriptor = context.expressionTypingServices.getDescriptorResolver().resolveFunctionDescriptor(scope.getContainingDeclaration(), scope, function, context.trace);
|
||||||
|
|||||||
Reference in New Issue
Block a user