Throwing exception only if no loading errors happened.

This commit is contained in:
Evgeny Gerashchenko
2012-11-19 20:10:21 +04:00
parent b09e0aa520
commit 4525e05268
7 changed files with 63 additions and 38 deletions
@@ -20,6 +20,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.intellij.psi.HierarchicalMethodSignature;
import jet.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -41,14 +42,15 @@ public class SignaturesPropagation {
public static JetType modifyReturnTypeAccordingToSuperMethods(
@NotNull JetType autoType, // type built by JavaTypeTransformer
@NotNull PsiMethodWrapper method,
@NotNull BindingTrace trace
@NotNull BindingTrace trace,
@NotNull Function1<String, Void> reportError
) {
Set<JetType> typesFromSuperMethods = Sets.newHashSet();
for (FunctionDescriptor superFunction : getSuperFunctionsForMethod(method, trace)) {
typesFromSuperMethods.add(superFunction.getReturnType());
}
return modifyReturnTypeAccordingToSuperMethods(autoType, typesFromSuperMethods, true);
return modifyReturnTypeAccordingToSuperMethods(autoType, typesFromSuperMethods, true, reportError);
}
public static List<FunctionDescriptor> getSuperFunctionsForMethod(
@@ -77,14 +79,15 @@ public class SignaturesPropagation {
private static JetType modifyReturnTypeAccordingToSuperMethods(
@NotNull JetType autoType,
@NotNull Collection<JetType> typesFromSuper,
boolean covariantPosition
boolean covariantPosition,
@NotNull Function1<String, Void> reportError
) {
if (ErrorUtils.isErrorType(autoType)) {
return autoType;
}
boolean resultNullable = returnTypeMustBeNullable(autoType, typesFromSuper, covariantPosition);
List<TypeProjection> resultArguments = getTypeArgsOfReturnType(autoType, typesFromSuper);
boolean resultNullable = returnTypeMustBeNullable(autoType, typesFromSuper, covariantPosition, reportError);
List<TypeProjection> resultArguments = getTypeArgsOfReturnType(autoType, typesFromSuper, reportError);
JetScope resultScope;
ClassifierDescriptor classifierDescriptor = getReturnTypeClassifier(autoType, typesFromSuper);
if (classifierDescriptor instanceof ClassDescriptor) {
@@ -102,7 +105,11 @@ public class SignaturesPropagation {
}
@NotNull
private static List<TypeProjection> getTypeArgsOfReturnType(@NotNull JetType autoType, @NotNull Collection<JetType> typesFromSuper) {
private static List<TypeProjection> getTypeArgsOfReturnType(
@NotNull JetType autoType,
@NotNull Collection<JetType> typesFromSuper,
@NotNull Function1<String, Void> reportError
) {
TypeConstructor typeConstructor = autoType.getConstructor();
ClassifierDescriptor classifier = typeConstructor.getDeclarationDescriptor();
List<TypeProjection> autoArguments = autoType.getArguments();
@@ -128,15 +135,19 @@ public class SignaturesPropagation {
Collection<JetType> argTypesFromSuper = getTypes(projectionsFromSuper);
boolean covariantPosition = effectiveProjectionKind == TypeCheckingProcedure.EnrichedProjectionKind.OUT;
JetType type = modifyReturnTypeAccordingToSuperMethods(argumentType, argTypesFromSuper, covariantPosition);
Variance projectionKind = calculateArgumentProjectionKindFromSuper(argument, projectionsFromSuper);
JetType type = modifyReturnTypeAccordingToSuperMethods(argumentType, argTypesFromSuper, covariantPosition, reportError);
Variance projectionKind = calculateArgumentProjectionKindFromSuper(argument, projectionsFromSuper, reportError);
resultArguments.add(new TypeProjection(projectionKind, type));
}
return resultArguments;
}
private static Variance calculateArgumentProjectionKindFromSuper(TypeProjection argument, List<TypeProjection> projectionsFromSuper) {
private static Variance calculateArgumentProjectionKindFromSuper(
@NotNull TypeProjection argument,
@NotNull List<TypeProjection> projectionsFromSuper,
@NotNull Function1<String, Void> reportError
) {
Set<Variance> projectionKindsInSuper = Sets.newHashSet();
for (TypeProjection projection : projectionsFromSuper) {
projectionKindsInSuper.add(projection.getProjectionKind());
@@ -152,12 +163,13 @@ public class SignaturesPropagation {
return projectionKindInSuper;
}
else {
// TODO report error
reportError.invoke("Incompatible projection kinds in type arguments of super methods' return types: "
+ projectionsFromSuper + ", defined in current: " + argument);
return defaultProjectionKind;
}
}
else {
// TODO report error
reportError.invoke("Incompatible projection kinds in type arguments of super methods' return types: " + projectionsFromSuper);
return defaultProjectionKind;
}
}
@@ -226,7 +238,12 @@ public class SignaturesPropagation {
return parameterToArgumentsFromSuper;
}
private static boolean returnTypeMustBeNullable(JetType autoType, Collection<JetType> typesFromSuper, boolean covariantPosition) {
private static boolean returnTypeMustBeNullable(
@NotNull JetType autoType,
@NotNull Collection<JetType> typesFromSuper,
boolean covariantPosition,
@NotNull Function1<String, Void> reportError
) {
if (typesFromSuper.isEmpty()) {
return autoType.isNullable();
}
@@ -247,8 +264,7 @@ public class SignaturesPropagation {
return false;
}
else {
// TODO error!
return true;
reportError.invoke("Incompatible return types in super types: " + typesFromSuper);
}
}
@@ -198,7 +198,7 @@ public final class JavaConstructorResolver {
valueParameterDescriptors = alternativeMethodSignatureData.getValueParameters();
}
else if (alternativeMethodSignatureData.hasErrors()) {
trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, constructorDescriptor,
trace.record(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERROR, constructorDescriptor,
alternativeMethodSignatureData.getError());
}
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.PsiFormatUtil;
import jet.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
@@ -117,7 +118,7 @@ public final class JavaFunctionResolver {
return trace.get(BindingContext.FUNCTION, psiMethod);
}
SimpleFunctionDescriptorImpl functionDescriptorImpl = new SimpleFunctionDescriptorImpl(
final SimpleFunctionDescriptorImpl functionDescriptorImpl = new SimpleFunctionDescriptorImpl(
ownerDescriptor,
annotationResolver.resolveAnnotations(psiMethod),
Name.identifier(method.getName()),
@@ -139,7 +140,13 @@ public final class JavaFunctionResolver {
.resolveParameterDescriptors(functionDescriptorImpl, method.getParameters(), methodTypeVariableResolver);
JetType returnType = makeReturnType(returnPsiType, method, methodTypeVariableResolver);
returnType = SignaturesPropagation.modifyReturnTypeAccordingToSuperMethods(returnType, method, trace);
returnType = SignaturesPropagation.modifyReturnTypeAccordingToSuperMethods(returnType, method, trace, new Function1<String, Void>() {
@Override
public Void invoke(String error) {
trace.record(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERROR, functionDescriptorImpl, error);
return null;
}
});
// TODO consider better place for this check
AlternativeMethodSignatureData alternativeMethodSignatureData =
@@ -150,7 +157,7 @@ public final class JavaFunctionResolver {
methodTypeParameters = alternativeMethodSignatureData.getTypeParameters();
}
else if (alternativeMethodSignatureData.hasErrors()) {
trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, functionDescriptorImpl,
trace.record(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERROR, functionDescriptorImpl,
alternativeMethodSignatureData.getError());
}
@@ -177,22 +184,24 @@ public final class JavaFunctionResolver {
throw new IllegalStateException("non-static method in subclass");
}
List<FunctionDescriptor> superFunctions = SignaturesPropagation.getSuperFunctionsForMethod(method, trace);
for (FunctionDescriptor superFunction : superFunctions) {
TypeSubstitutor substitutor = SubstitutionUtils.buildDeepSubstitutor(((ClassDescriptor) ownerDescriptor).getDefaultType());
FunctionDescriptor superFunctionSubstituted = superFunction.substitute(substitutor);
if (trace.get(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERROR, functionDescriptorImpl) == null) {
List<FunctionDescriptor> superFunctions = SignaturesPropagation.getSuperFunctionsForMethod(method, trace);
for (FunctionDescriptor superFunction : superFunctions) {
TypeSubstitutor substitutor = SubstitutionUtils.buildDeepSubstitutor(((ClassDescriptor) ownerDescriptor).getDefaultType());
FunctionDescriptor superFunctionSubstituted = superFunction.substitute(substitutor);
// TODO replace asserted condition when propagation for parameters is supported
//OverridingUtil.OverrideCompatibilityInfo.Result overridableResult =
// OverridingUtil.isOverridableBy(superFunctionSubstituted, functionDescriptorImpl).getResult();
//if (overridableResult != OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
// || !OverridingUtil.isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, superFunctionSubstituted, functionDescriptorImpl)) {
if (!OverridingUtil.isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, superFunctionSubstituted, functionDescriptorImpl)) {
throw new IllegalStateException("Loaded Java method overrides another, but resolved as Kotlin function, doesn't.\n"
+ "super function = " + superFunction + "\n"
+ "this function = " + functionDescriptorImpl + "\n"
+ "this method = " + PsiFormatUtil.getExternalName(psiMethod) + "\n"
+ "@KotlinSignature = " + method.getSignatureAnnotation().signature());
// TODO replace asserted condition when propagation for parameters is supported
//OverridingUtil.OverrideCompatibilityInfo.Result overridableResult =
// OverridingUtil.isOverridableBy(superFunctionSubstituted, functionDescriptorImpl).getResult();
//if (overridableResult != OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
// || !OverridingUtil.isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, superFunctionSubstituted, functionDescriptorImpl)) {
if (!OverridingUtil.isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, superFunctionSubstituted, functionDescriptorImpl)) {
throw new IllegalStateException("Loaded Java method overrides another, but resolved as Kotlin function, doesn't.\n"
+ "super function = " + superFunction + "\n"
+ "this function = " + functionDescriptorImpl + "\n"
+ "this method = " + PsiFormatUtil.getExternalName(psiMethod) + "\n"
+ "@KotlinSignature = " + method.getSignatureAnnotation().signature());
}
}
}
@@ -269,7 +269,7 @@ public final class JavaPropertyResolver {
}
}
else {
trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, propertyDescriptor, signatureData.getError());
trace.record(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERROR, propertyDescriptor, signatureData.getError());
}
return propertyType;
}