diff --git a/compiler/cli/src/org/jetbrains/jet/cli/common/messages/AnalyzerWithCompilerReport.java b/compiler/cli/src/org/jetbrains/jet/cli/common/messages/AnalyzerWithCompilerReport.java index 72676399735..5da85566a1e 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/common/messages/AnalyzerWithCompilerReport.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/common/messages/AnalyzerWithCompilerReport.java @@ -118,7 +118,7 @@ public final class AnalyzerWithCompilerReport { private void reportAlternativeSignatureErrors() { assert analyzeExhaust != null; BindingContext bc = analyzeExhaust.getBindingContext(); - Collection descriptorsWithErrors = bc.getKeys(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR); + Collection descriptorsWithErrors = bc.getKeys(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERROR); if (!descriptorsWithErrors.isEmpty()) { StringBuilder message = new StringBuilder("The following Java entities have annotations wrong Kotlin signatures:\n"); for (DeclarationDescriptor descriptor : descriptorsWithErrors) { @@ -126,7 +126,7 @@ public final class AnalyzerWithCompilerReport { assert declaration instanceof PsiModifierListOwner; String externalName = PsiFormatUtil.getExternalName((PsiModifierListOwner) declaration); message.append(externalName).append(": "); - message.append(bc.get(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, descriptor)).append("\n"); + message.append(bc.get(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERROR, descriptor)).append("\n"); } messageCollectorWrapper.report(CompilerMessageSeverity.ERROR, message.toString(), CompilerMessageLocation.NO_LOCATION); } 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 198e6714950..a34ff08252b 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 @@ -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 reportError ) { Set 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 getSuperFunctionsForMethod( @@ -77,14 +79,15 @@ public class SignaturesPropagation { private static JetType modifyReturnTypeAccordingToSuperMethods( @NotNull JetType autoType, @NotNull Collection typesFromSuper, - boolean covariantPosition + boolean covariantPosition, + @NotNull Function1 reportError ) { if (ErrorUtils.isErrorType(autoType)) { return autoType; } - boolean resultNullable = returnTypeMustBeNullable(autoType, typesFromSuper, covariantPosition); - List resultArguments = getTypeArgsOfReturnType(autoType, typesFromSuper); + boolean resultNullable = returnTypeMustBeNullable(autoType, typesFromSuper, covariantPosition, reportError); + List 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 getTypeArgsOfReturnType(@NotNull JetType autoType, @NotNull Collection typesFromSuper) { + private static List getTypeArgsOfReturnType( + @NotNull JetType autoType, + @NotNull Collection typesFromSuper, + @NotNull Function1 reportError + ) { TypeConstructor typeConstructor = autoType.getConstructor(); ClassifierDescriptor classifier = typeConstructor.getDeclarationDescriptor(); List autoArguments = autoType.getArguments(); @@ -128,15 +135,19 @@ public class SignaturesPropagation { Collection 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 projectionsFromSuper) { + private static Variance calculateArgumentProjectionKindFromSuper( + @NotNull TypeProjection argument, + @NotNull List projectionsFromSuper, + @NotNull Function1 reportError + ) { Set 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 typesFromSuper, boolean covariantPosition) { + private static boolean returnTypeMustBeNullable( + @NotNull JetType autoType, + @NotNull Collection typesFromSuper, + boolean covariantPosition, + @NotNull Function1 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); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java index d5c474b7065..f9e60a7cb2d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java @@ -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()); } 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 d7aefc34897..912df59bfa7 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 @@ -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() { + @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 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 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()); + } } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java index 646d41ee69e..41de9c25927 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java @@ -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; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index c17dcefeefb..273d5d4266c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -256,7 +256,7 @@ public interface BindingContext { WritableSlice INCOMPLETE_HIERARCHY = Slices.createCollectiveSetSlice(); - WritableSlice ALTERNATIVE_SIGNATURE_DATA_ERROR = + WritableSlice LOAD_FROM_JAVA_SIGNATURE_ERROR = new BasicWritableSlice(Slices.ONLY_REWRITE_TO_EQUAL, true); WritableSlice IS_DECLARED_IN_JAVA = Slices.createSimpleSlice(); diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/JdkAnnotationsSanityTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/JdkAnnotationsSanityTest.java index b037a481d67..c57ef92d506 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/JdkAnnotationsSanityTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/JdkAnnotationsSanityTest.java @@ -239,7 +239,7 @@ public class JdkAnnotationsSanityTest extends KotlinTestWithEnvironment { } private Void visitDeclaration(@NotNull DeclarationDescriptor descriptor) { - String error = bindingContext.get(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, descriptor); + String error = bindingContext.get(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERROR, descriptor); if (error != null) { errors.put(descriptor, error); }