From b09e0aa520f87c96acff8200e9514d11c6839ee1 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Mon, 19 Nov 2012 17:30:33 +0400 Subject: [PATCH] Added assert that we load consistent method hierarchy from Java. --- .../SignaturesPropagation.java | 22 ++++++++++++++---- .../java/resolver/JavaFunctionResolver.java | 23 +++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagation.java index efbd98d98b5..198e6714950 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagation.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagation.java @@ -44,23 +44,35 @@ public class SignaturesPropagation { @NotNull BindingTrace trace ) { Set typesFromSuperMethods = Sets.newHashSet(); + for (FunctionDescriptor superFunction : getSuperFunctionsForMethod(method, trace)) { + typesFromSuperMethods.add(superFunction.getReturnType()); + } + + return modifyReturnTypeAccordingToSuperMethods(autoType, typesFromSuperMethods, true); + } + + public static List getSuperFunctionsForMethod( + @NotNull PsiMethodWrapper method, + @NotNull BindingTrace trace + ) { + List superFunctions = Lists.newArrayList(); for (HierarchicalMethodSignature superSignature : method.getPsiMethod().getHierarchicalMethodSignature().getSuperSignatures()) { DeclarationDescriptor superFun = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, superSignature.getMethod()); if (superFun instanceof FunctionDescriptor) { - typesFromSuperMethods.add(((FunctionDescriptor) superFun).getReturnType()); + superFunctions.add(((FunctionDescriptor) superFun)); } else { // Function descriptor can't be find iff superclass is java.lang.Collection or similar (translated to jet.* collections) assert !JavaToKotlinClassMap.getInstance().mapPlatformClass( new FqName(superSignature.getMethod().getContainingClass().getQualifiedName())).isEmpty(): - "Can't find super function for " + method.getPsiMethod() + " defined in " - + method.getPsiMethod().getContainingClass(); + "Can't find super function for " + method.getPsiMethod() + " defined in " + + method.getPsiMethod().getContainingClass(); } } - - return modifyReturnTypeAccordingToSuperMethods(autoType, typesFromSuperMethods, true); + return superFunctions; } + @NotNull private static JetType modifyReturnTypeAccordingToSuperMethods( @NotNull JetType autoType, diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java index 61ae730c53d..d7aefc34897 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java @@ -21,6 +21,7 @@ import com.google.common.collect.Sets; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiType; +import com.intellij.psi.util.PsiFormatUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; @@ -35,6 +36,8 @@ import org.jetbrains.jet.lang.resolve.java.provider.PsiDeclarationProvider; import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.SubstitutionUtils; +import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; @@ -173,6 +176,26 @@ public final class JavaFunctionResolver { if (containingClass != psiClass && !method.isStatic()) { throw new IllegalStateException("non-static method in subclass"); } + + List 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()); + } + } + return functionDescriptorImpl; }