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
@@ -118,7 +118,7 @@ public final class AnalyzerWithCompilerReport {
private void reportAlternativeSignatureErrors() { private void reportAlternativeSignatureErrors() {
assert analyzeExhaust != null; assert analyzeExhaust != null;
BindingContext bc = analyzeExhaust.getBindingContext(); BindingContext bc = analyzeExhaust.getBindingContext();
Collection<DeclarationDescriptor> descriptorsWithErrors = bc.getKeys(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR); Collection<DeclarationDescriptor> descriptorsWithErrors = bc.getKeys(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERROR);
if (!descriptorsWithErrors.isEmpty()) { if (!descriptorsWithErrors.isEmpty()) {
StringBuilder message = new StringBuilder("The following Java entities have annotations wrong Kotlin signatures:\n"); StringBuilder message = new StringBuilder("The following Java entities have annotations wrong Kotlin signatures:\n");
for (DeclarationDescriptor descriptor : descriptorsWithErrors) { for (DeclarationDescriptor descriptor : descriptorsWithErrors) {
@@ -126,7 +126,7 @@ public final class AnalyzerWithCompilerReport {
assert declaration instanceof PsiModifierListOwner; assert declaration instanceof PsiModifierListOwner;
String externalName = PsiFormatUtil.getExternalName((PsiModifierListOwner) declaration); String externalName = PsiFormatUtil.getExternalName((PsiModifierListOwner) declaration);
message.append(externalName).append(": "); 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); messageCollectorWrapper.report(CompilerMessageSeverity.ERROR, message.toString(), CompilerMessageLocation.NO_LOCATION);
} }
@@ -20,6 +20,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.psi.HierarchicalMethodSignature; import com.intellij.psi.HierarchicalMethodSignature;
import jet.Function1;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -41,14 +42,15 @@ public class SignaturesPropagation {
public static JetType modifyReturnTypeAccordingToSuperMethods( public static JetType modifyReturnTypeAccordingToSuperMethods(
@NotNull JetType autoType, // type built by JavaTypeTransformer @NotNull JetType autoType, // type built by JavaTypeTransformer
@NotNull PsiMethodWrapper method, @NotNull PsiMethodWrapper method,
@NotNull BindingTrace trace @NotNull BindingTrace trace,
@NotNull Function1<String, Void> reportError
) { ) {
Set<JetType> typesFromSuperMethods = Sets.newHashSet(); Set<JetType> typesFromSuperMethods = Sets.newHashSet();
for (FunctionDescriptor superFunction : getSuperFunctionsForMethod(method, trace)) { for (FunctionDescriptor superFunction : getSuperFunctionsForMethod(method, trace)) {
typesFromSuperMethods.add(superFunction.getReturnType()); typesFromSuperMethods.add(superFunction.getReturnType());
} }
return modifyReturnTypeAccordingToSuperMethods(autoType, typesFromSuperMethods, true); return modifyReturnTypeAccordingToSuperMethods(autoType, typesFromSuperMethods, true, reportError);
} }
public static List<FunctionDescriptor> getSuperFunctionsForMethod( public static List<FunctionDescriptor> getSuperFunctionsForMethod(
@@ -77,14 +79,15 @@ public class SignaturesPropagation {
private static JetType modifyReturnTypeAccordingToSuperMethods( private static JetType modifyReturnTypeAccordingToSuperMethods(
@NotNull JetType autoType, @NotNull JetType autoType,
@NotNull Collection<JetType> typesFromSuper, @NotNull Collection<JetType> typesFromSuper,
boolean covariantPosition boolean covariantPosition,
@NotNull Function1<String, Void> reportError
) { ) {
if (ErrorUtils.isErrorType(autoType)) { if (ErrorUtils.isErrorType(autoType)) {
return autoType; return autoType;
} }
boolean resultNullable = returnTypeMustBeNullable(autoType, typesFromSuper, covariantPosition); boolean resultNullable = returnTypeMustBeNullable(autoType, typesFromSuper, covariantPosition, reportError);
List<TypeProjection> resultArguments = getTypeArgsOfReturnType(autoType, typesFromSuper); List<TypeProjection> resultArguments = getTypeArgsOfReturnType(autoType, typesFromSuper, reportError);
JetScope resultScope; JetScope resultScope;
ClassifierDescriptor classifierDescriptor = getReturnTypeClassifier(autoType, typesFromSuper); ClassifierDescriptor classifierDescriptor = getReturnTypeClassifier(autoType, typesFromSuper);
if (classifierDescriptor instanceof ClassDescriptor) { if (classifierDescriptor instanceof ClassDescriptor) {
@@ -102,7 +105,11 @@ public class SignaturesPropagation {
} }
@NotNull @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(); TypeConstructor typeConstructor = autoType.getConstructor();
ClassifierDescriptor classifier = typeConstructor.getDeclarationDescriptor(); ClassifierDescriptor classifier = typeConstructor.getDeclarationDescriptor();
List<TypeProjection> autoArguments = autoType.getArguments(); List<TypeProjection> autoArguments = autoType.getArguments();
@@ -128,15 +135,19 @@ public class SignaturesPropagation {
Collection<JetType> argTypesFromSuper = getTypes(projectionsFromSuper); Collection<JetType> argTypesFromSuper = getTypes(projectionsFromSuper);
boolean covariantPosition = effectiveProjectionKind == TypeCheckingProcedure.EnrichedProjectionKind.OUT; boolean covariantPosition = effectiveProjectionKind == TypeCheckingProcedure.EnrichedProjectionKind.OUT;
JetType type = modifyReturnTypeAccordingToSuperMethods(argumentType, argTypesFromSuper, covariantPosition); JetType type = modifyReturnTypeAccordingToSuperMethods(argumentType, argTypesFromSuper, covariantPosition, reportError);
Variance projectionKind = calculateArgumentProjectionKindFromSuper(argument, projectionsFromSuper); Variance projectionKind = calculateArgumentProjectionKindFromSuper(argument, projectionsFromSuper, reportError);
resultArguments.add(new TypeProjection(projectionKind, type)); resultArguments.add(new TypeProjection(projectionKind, type));
} }
return resultArguments; 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(); Set<Variance> projectionKindsInSuper = Sets.newHashSet();
for (TypeProjection projection : projectionsFromSuper) { for (TypeProjection projection : projectionsFromSuper) {
projectionKindsInSuper.add(projection.getProjectionKind()); projectionKindsInSuper.add(projection.getProjectionKind());
@@ -152,12 +163,13 @@ public class SignaturesPropagation {
return projectionKindInSuper; return projectionKindInSuper;
} }
else { else {
// TODO report error reportError.invoke("Incompatible projection kinds in type arguments of super methods' return types: "
+ projectionsFromSuper + ", defined in current: " + argument);
return defaultProjectionKind; return defaultProjectionKind;
} }
} }
else { else {
// TODO report error reportError.invoke("Incompatible projection kinds in type arguments of super methods' return types: " + projectionsFromSuper);
return defaultProjectionKind; return defaultProjectionKind;
} }
} }
@@ -226,7 +238,12 @@ public class SignaturesPropagation {
return parameterToArgumentsFromSuper; 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()) { if (typesFromSuper.isEmpty()) {
return autoType.isNullable(); return autoType.isNullable();
} }
@@ -247,8 +264,7 @@ public class SignaturesPropagation {
return false; return false;
} }
else { else {
// TODO error! reportError.invoke("Incompatible return types in super types: " + typesFromSuper);
return true;
} }
} }
@@ -198,7 +198,7 @@ public final class JavaConstructorResolver {
valueParameterDescriptors = alternativeMethodSignatureData.getValueParameters(); valueParameterDescriptors = alternativeMethodSignatureData.getValueParameters();
} }
else if (alternativeMethodSignatureData.hasErrors()) { else if (alternativeMethodSignatureData.hasErrors()) {
trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, constructorDescriptor, trace.record(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERROR, constructorDescriptor,
alternativeMethodSignatureData.getError()); alternativeMethodSignatureData.getError());
} }
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType; import com.intellij.psi.PsiType;
import com.intellij.psi.util.PsiFormatUtil; import com.intellij.psi.util.PsiFormatUtil;
import jet.Function1;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
@@ -117,7 +118,7 @@ public final class JavaFunctionResolver {
return trace.get(BindingContext.FUNCTION, psiMethod); return trace.get(BindingContext.FUNCTION, psiMethod);
} }
SimpleFunctionDescriptorImpl functionDescriptorImpl = new SimpleFunctionDescriptorImpl( final SimpleFunctionDescriptorImpl functionDescriptorImpl = new SimpleFunctionDescriptorImpl(
ownerDescriptor, ownerDescriptor,
annotationResolver.resolveAnnotations(psiMethod), annotationResolver.resolveAnnotations(psiMethod),
Name.identifier(method.getName()), Name.identifier(method.getName()),
@@ -139,7 +140,13 @@ public final class JavaFunctionResolver {
.resolveParameterDescriptors(functionDescriptorImpl, method.getParameters(), methodTypeVariableResolver); .resolveParameterDescriptors(functionDescriptorImpl, method.getParameters(), methodTypeVariableResolver);
JetType returnType = makeReturnType(returnPsiType, method, 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 // TODO consider better place for this check
AlternativeMethodSignatureData alternativeMethodSignatureData = AlternativeMethodSignatureData alternativeMethodSignatureData =
@@ -150,7 +157,7 @@ public final class JavaFunctionResolver {
methodTypeParameters = alternativeMethodSignatureData.getTypeParameters(); methodTypeParameters = alternativeMethodSignatureData.getTypeParameters();
} }
else if (alternativeMethodSignatureData.hasErrors()) { else if (alternativeMethodSignatureData.hasErrors()) {
trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, functionDescriptorImpl, trace.record(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERROR, functionDescriptorImpl,
alternativeMethodSignatureData.getError()); alternativeMethodSignatureData.getError());
} }
@@ -177,22 +184,24 @@ public final class JavaFunctionResolver {
throw new IllegalStateException("non-static method in subclass"); throw new IllegalStateException("non-static method in subclass");
} }
List<FunctionDescriptor> superFunctions = SignaturesPropagation.getSuperFunctionsForMethod(method, trace); if (trace.get(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERROR, functionDescriptorImpl) == null) {
for (FunctionDescriptor superFunction : superFunctions) { List<FunctionDescriptor> superFunctions = SignaturesPropagation.getSuperFunctionsForMethod(method, trace);
TypeSubstitutor substitutor = SubstitutionUtils.buildDeepSubstitutor(((ClassDescriptor) ownerDescriptor).getDefaultType()); for (FunctionDescriptor superFunction : superFunctions) {
FunctionDescriptor superFunctionSubstituted = superFunction.substitute(substitutor); TypeSubstitutor substitutor = SubstitutionUtils.buildDeepSubstitutor(((ClassDescriptor) ownerDescriptor).getDefaultType());
FunctionDescriptor superFunctionSubstituted = superFunction.substitute(substitutor);
// TODO replace asserted condition when propagation for parameters is supported // TODO replace asserted condition when propagation for parameters is supported
//OverridingUtil.OverrideCompatibilityInfo.Result overridableResult = //OverridingUtil.OverrideCompatibilityInfo.Result overridableResult =
// OverridingUtil.isOverridableBy(superFunctionSubstituted, functionDescriptorImpl).getResult(); // OverridingUtil.isOverridableBy(superFunctionSubstituted, functionDescriptorImpl).getResult();
//if (overridableResult != OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE //if (overridableResult != OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
// || !OverridingUtil.isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, superFunctionSubstituted, functionDescriptorImpl)) { // || !OverridingUtil.isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, superFunctionSubstituted, functionDescriptorImpl)) {
if (!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" throw new IllegalStateException("Loaded Java method overrides another, but resolved as Kotlin function, doesn't.\n"
+ "super function = " + superFunction + "\n" + "super function = " + superFunction + "\n"
+ "this function = " + functionDescriptorImpl + "\n" + "this function = " + functionDescriptorImpl + "\n"
+ "this method = " + PsiFormatUtil.getExternalName(psiMethod) + "\n" + "this method = " + PsiFormatUtil.getExternalName(psiMethod) + "\n"
+ "@KotlinSignature = " + method.getSignatureAnnotation().signature()); + "@KotlinSignature = " + method.getSignatureAnnotation().signature());
}
} }
} }
@@ -269,7 +269,7 @@ public final class JavaPropertyResolver {
} }
} }
else { else {
trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, propertyDescriptor, signatureData.getError()); trace.record(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERROR, propertyDescriptor, signatureData.getError());
} }
return propertyType; return propertyType;
} }
@@ -256,7 +256,7 @@ public interface BindingContext {
WritableSlice<ClassDescriptor, Boolean> INCOMPLETE_HIERARCHY = Slices.createCollectiveSetSlice(); WritableSlice<ClassDescriptor, Boolean> INCOMPLETE_HIERARCHY = Slices.createCollectiveSetSlice();
WritableSlice<DeclarationDescriptor, String> ALTERNATIVE_SIGNATURE_DATA_ERROR = WritableSlice<DeclarationDescriptor, String> LOAD_FROM_JAVA_SIGNATURE_ERROR =
new BasicWritableSlice<DeclarationDescriptor, String>(Slices.ONLY_REWRITE_TO_EQUAL, true); new BasicWritableSlice<DeclarationDescriptor, String>(Slices.ONLY_REWRITE_TO_EQUAL, true);
WritableSlice<CallableDescriptor, Boolean> IS_DECLARED_IN_JAVA = Slices.createSimpleSlice(); WritableSlice<CallableDescriptor, Boolean> IS_DECLARED_IN_JAVA = Slices.createSimpleSlice();
@@ -239,7 +239,7 @@ public class JdkAnnotationsSanityTest extends KotlinTestWithEnvironment {
} }
private Void visitDeclaration(@NotNull DeclarationDescriptor descriptor) { 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) { if (error != null) {
errors.put(descriptor, error); errors.put(descriptor, error);
} }