From be3d83520385134f15061013ccf9ed4765bbccfc Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 6 Aug 2013 23:13:53 +0400 Subject: [PATCH] Refactor alternative method signatures Create ExternalSignatureResolver which can resolve propagated and alternative signatures, use it in JavaFunctionResolver and JavaConstructorResolver. Move JavaValueParameterResolver.ValueParameters to SignaturesPropagationData, since elsewhere it always had receiverType = null --- .../di/InjectorForJavaDescriptorResolver.java | 7 + .../di/InjectorForTopDownAnalyzerForJvm.java | 7 + .../AlternativeMethodSignatureData.java | 30 ++-- .../SignaturesPropagationData.java | 45 ++++-- .../resolver/ExternalSignatureResolver.java | 128 ++++++++++++++++++ .../resolver/JavaConstructorResolver.java | 33 +++-- .../java/resolver/JavaFunctionResolver.java | 70 +++++----- .../resolver/JavaValueParameterResolver.java | 25 +--- 8 files changed, 240 insertions(+), 105 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/ExternalSignatureResolver.java diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java index 2c8b8824640..7db4edc5f9e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java @@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.resolve.java.resolver.JavaClassResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationArgumentResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaFunctionResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.ExternalSignatureResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaTypeParameterResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaTypeTransformer; import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver; @@ -51,6 +52,7 @@ public class InjectorForJavaDescriptorResolver { private final JavaAnnotationResolver javaAnnotationResolver; private final JavaAnnotationArgumentResolver javaAnnotationArgumentResolver; private final JavaFunctionResolver javaFunctionResolver; + private final ExternalSignatureResolver externalSignatureResolver; private final JavaTypeParameterResolver javaTypeParameterResolver; private final JavaTypeTransformer javaTypeTransformer; private final JavaValueParameterResolver javaValueParameterResolver; @@ -75,6 +77,7 @@ public class InjectorForJavaDescriptorResolver { this.javaAnnotationResolver = new JavaAnnotationResolver(); this.javaAnnotationArgumentResolver = new JavaAnnotationArgumentResolver(); this.javaFunctionResolver = new JavaFunctionResolver(); + this.externalSignatureResolver = new ExternalSignatureResolver(); this.javaTypeParameterResolver = new JavaTypeParameterResolver(); this.javaTypeTransformer = new JavaTypeTransformer(); this.javaValueParameterResolver = new JavaValueParameterResolver(); @@ -113,11 +116,14 @@ public class InjectorForJavaDescriptorResolver { javaAnnotationArgumentResolver.setClassResolver(javaClassResolver); javaFunctionResolver.setAnnotationResolver(javaAnnotationResolver); + javaFunctionResolver.setExternalSignatureResolver(externalSignatureResolver); javaFunctionResolver.setTrace(bindingTrace); javaFunctionResolver.setTypeParameterResolver(javaTypeParameterResolver); javaFunctionResolver.setTypeTransformer(javaTypeTransformer); javaFunctionResolver.setValueParameterResolver(javaValueParameterResolver); + externalSignatureResolver.setTrace(bindingTrace); + javaTypeParameterResolver.setTypeTransformer(javaTypeTransformer); javaTypeTransformer.setClassResolver(javaClassResolver); @@ -142,6 +148,7 @@ public class InjectorForJavaDescriptorResolver { javaSupertypeResolver.setTrace(bindingTrace); javaSupertypeResolver.setTypeTransformer(javaTypeTransformer); + javaConstructorResolver.setExternalSignatureResolver(externalSignatureResolver); javaConstructorResolver.setTrace(bindingTrace); javaConstructorResolver.setTypeTransformer(javaTypeTransformer); javaConstructorResolver.setValueParameterResolver(javaValueParameterResolver); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java index 0284c3ac2ca..b6ef0b3f77c 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java @@ -53,6 +53,7 @@ import org.jetbrains.jet.lang.resolve.java.resolver.JavaClassResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationArgumentResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaFunctionResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.ExternalSignatureResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaTypeParameterResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaTypeTransformer; import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver; @@ -105,6 +106,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly private final JavaAnnotationResolver javaAnnotationResolver; private final JavaAnnotationArgumentResolver javaAnnotationArgumentResolver; private final JavaFunctionResolver javaFunctionResolver; + private final ExternalSignatureResolver externalSignatureResolver; private final JavaTypeParameterResolver javaTypeParameterResolver; private final JavaTypeTransformer javaTypeTransformer; private final JavaValueParameterResolver javaValueParameterResolver; @@ -158,6 +160,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly this.javaAnnotationResolver = new JavaAnnotationResolver(); this.javaAnnotationArgumentResolver = new JavaAnnotationArgumentResolver(); this.javaFunctionResolver = new JavaFunctionResolver(); + this.externalSignatureResolver = new ExternalSignatureResolver(); this.javaTypeParameterResolver = new JavaTypeParameterResolver(); this.javaTypeTransformer = new JavaTypeTransformer(); this.javaValueParameterResolver = new JavaValueParameterResolver(); @@ -300,11 +303,14 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly javaAnnotationArgumentResolver.setClassResolver(javaClassResolver); javaFunctionResolver.setAnnotationResolver(javaAnnotationResolver); + javaFunctionResolver.setExternalSignatureResolver(externalSignatureResolver); javaFunctionResolver.setTrace(bindingTrace); javaFunctionResolver.setTypeParameterResolver(javaTypeParameterResolver); javaFunctionResolver.setTypeTransformer(javaTypeTransformer); javaFunctionResolver.setValueParameterResolver(javaValueParameterResolver); + externalSignatureResolver.setTrace(bindingTrace); + javaTypeParameterResolver.setTypeTransformer(javaTypeTransformer); javaTypeTransformer.setClassResolver(javaClassResolver); @@ -329,6 +335,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly javaSupertypeResolver.setTrace(bindingTrace); javaSupertypeResolver.setTypeTransformer(javaTypeTransformer); + javaConstructorResolver.setExternalSignatureResolver(externalSignatureResolver); javaConstructorResolver.setTrace(bindingTrace); javaConstructorResolver.setTypeTransformer(javaTypeTransformer); javaConstructorResolver.setValueParameterResolver(javaValueParameterResolver); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeMethodSignatureData.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeMethodSignatureData.java index a218f62177f..3d020c86406 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeMethodSignatureData.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeMethodSignatureData.java @@ -26,7 +26,6 @@ import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver; import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.JetType; @@ -46,7 +45,7 @@ import static org.jetbrains.jet.lang.resolve.java.TypeUsage.UPPER_BOUND; public class AlternativeMethodSignatureData extends ElementAlternativeSignatureData { private final JetNamedFunction altFunDeclaration; - private JavaValueParameterResolver.ValueParameters altValueParameters; + private List altValueParameters; private JetType altReturnType; private List altTypeParameters; @@ -54,7 +53,8 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD public AlternativeMethodSignatureData( @NotNull JavaMethod method, - @NotNull JavaValueParameterResolver.ValueParameters valueParameters, + @Nullable JetType receiverType, + @NotNull List valueParameters, @Nullable JetType originalReturnType, @NotNull List methodTypeParameters, boolean hasSuperMethods @@ -67,6 +67,10 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD return; } + if (receiverType != null) { + throw new UnsupportedOperationException("Alternative annotations for extension functions are not supported yet"); + } + setAnnotated(true); Project project = method.getPsi().getProject(); altFunDeclaration = JetPsiFactory.createFunction(project, signature); @@ -94,15 +98,15 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD } private void checkParameterAndReturnTypesForOverridingMethods( - @NotNull JavaValueParameterResolver.ValueParameters valueParameters, + @NotNull List valueParameters, @NotNull List methodTypeParameters, @Nullable JetType returnType ) { TypeSubstitutor substitutor = SignaturesUtil.createSubstitutorForTypeParameters(originalToAltTypeParameters); - for (ValueParameterDescriptor parameter : valueParameters.getDescriptors()) { + for (ValueParameterDescriptor parameter : valueParameters) { int index = parameter.getIndex(); - ValueParameterDescriptor altParameter = altValueParameters.getDescriptors().get(index); + ValueParameterDescriptor altParameter = altValueParameters.get(index); JetType substituted = substitutor.substitute(parameter.getType(), Variance.INVARIANT); assert substituted != null; @@ -141,12 +145,12 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD } @NotNull - public JavaValueParameterResolver.ValueParameters getValueParameters() { + public List getValueParameters() { checkForErrors(); return altValueParameters; } - @NotNull + @Nullable public JetType getReturnType() { checkForErrors(); return altReturnType; @@ -158,9 +162,7 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD return altTypeParameters; } - private void computeValueParameters(JavaValueParameterResolver.ValueParameters valueParameters) { - List parameterDescriptors = valueParameters.getDescriptors(); - + private void computeValueParameters(@NotNull List parameterDescriptors) { if (parameterDescriptors.size() != altFunDeclaration.getValueParameters().size()) { throw new AlternativeSignatureMismatchException("Method signature has %d value parameters, but alternative signature has %d", parameterDescriptors.size(), altFunDeclaration.getValueParameters().size()); @@ -207,11 +209,7 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD alternativeVarargElementType)); } - if (valueParameters.getReceiverType() != null) { - throw new UnsupportedOperationException("Alternative annotations for extension functions are not supported yet"); - } - - altValueParameters = new JavaValueParameterResolver.ValueParameters(null, altParamDescriptors); + altValueParameters = altParamDescriptors; } private void computeTypeParameters(List typeParameters) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagationData.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagationData.java index 3514bcbbd9f..65565ed17e7 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagationData.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagationData.java @@ -38,7 +38,6 @@ import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; import org.jetbrains.jet.lang.resolve.java.TypeUsage; import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetClsMethod; import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver; import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; import org.jetbrains.jet.lang.resolve.name.FqName; @@ -58,7 +57,7 @@ public class SignaturesPropagationData { private static final Logger LOG = Logger.getInstance(SignaturesPropagationData.class); private final List modifiedTypeParameters; - private final JavaValueParameterResolver.ValueParameters modifiedValueParameters; + private final ValueParameters modifiedValueParameters; private final JetType modifiedReturnType; private final List signatureErrors = Lists.newArrayList(); @@ -69,7 +68,8 @@ public class SignaturesPropagationData { public SignaturesPropagationData( @NotNull ClassDescriptor containingClass, @NotNull JetType autoReturnType, // type built by JavaTypeTransformer from Java signature and @NotNull annotations - @NotNull JavaValueParameterResolver.ValueParameters autoValueParameters, // descriptors built by parameters resolver + @Nullable JetType receiverType, + @NotNull List autoValueParameters, // descriptors built by parameters resolver @NotNull List autoTypeParameters, // descriptors built by signature resolver @NotNull JavaMethod method, @NotNull BindingTrace trace @@ -81,15 +81,19 @@ public class SignaturesPropagationData { modifiedTypeParameters = modifyTypeParametersAccordingToSuperMethods(autoTypeParameters); modifiedReturnType = modifyReturnTypeAccordingToSuperMethods(autoReturnType); - modifiedValueParameters = modifyValueParametersAccordingToSuperMethods(autoValueParameters); + modifiedValueParameters = modifyValueParametersAccordingToSuperMethods(receiverType, autoValueParameters); } public List getModifiedTypeParameters() { return modifiedTypeParameters; } - public JavaValueParameterResolver.ValueParameters getModifiedValueParameters() { - return modifiedValueParameters; + public JetType getModifiedReceiverType() { + return modifiedValueParameters.receiverType; + } + + public List getModifiedValueParameters() { + return modifiedValueParameters.descriptors; } public JetType getModifiedReturnType() { @@ -157,19 +161,20 @@ public class SignaturesPropagationData { return result; } - private JavaValueParameterResolver.ValueParameters modifyValueParametersAccordingToSuperMethods( - @NotNull JavaValueParameterResolver.ValueParameters parameters // descriptors built by parameters resolver + private ValueParameters modifyValueParametersAccordingToSuperMethods( + @Nullable JetType receiverType, + @NotNull List parameters // descriptors built by parameters resolver ) { - assert parameters.getReceiverType() == null : "Parameters before propagation have receiver type," + - " but propagation should be disabled for functions compiled from Kotlin in class: " + - DescriptorUtils.getFQName(containingClass); + assert receiverType == null : "Parameters before propagation have receiver type," + + " but propagation should be disabled for functions compiled from Kotlin in class: " + + DescriptorUtils.getFQName(containingClass); - JetType receiverType = null; + JetType resultReceiverType = null; List resultParameters = Lists.newArrayList(); boolean shouldBeExtension = checkIfShouldBeExtension(); - for (ValueParameterDescriptor originalParam : parameters.getDescriptors()) { + for (ValueParameterDescriptor originalParam : parameters) { final int originalIndex = originalParam.getIndex(); List typesFromSuperMethods = ContainerUtil.map(superFunctions, new Function() { @@ -190,7 +195,7 @@ public class SignaturesPropagationData { JetType altType = modifyTypeAccordingToSuperMethods(varargCheckResult.parameterType, typesFromSuperMethods, MEMBER_SIGNATURE_CONTRAVARIANT); if (shouldBeExtension && originalIndex == 0) { - receiverType = altType; + resultReceiverType = altType; } else { resultParameters.add(new ValueParameterDescriptorImpl( @@ -205,7 +210,7 @@ public class SignaturesPropagationData { } } - return new JavaValueParameterResolver.ValueParameters(receiverType, resultParameters); + return new ValueParameters(resultReceiverType, resultParameters); } private static List getSuperFunctionsForMethod( @@ -738,4 +743,14 @@ public class SignaturesPropagationData { return type.toString(); } } + + private static class ValueParameters { + private final JetType receiverType; + private final List descriptors; + + public ValueParameters(@Nullable JetType receiverType, @NotNull List descriptors) { + this.receiverType = receiverType; + this.descriptors = descriptors; + } + } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/ExternalSignatureResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/ExternalSignatureResolver.java new file mode 100644 index 00000000000..8090d8ce2aa --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/ExternalSignatureResolver.java @@ -0,0 +1,128 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.java.resolver; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.resolve.BindingTrace; +import org.jetbrains.jet.lang.resolve.java.JavaBindingContext; +import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData; +import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesPropagationData; +import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; +import org.jetbrains.jet.lang.types.JetType; + +import javax.inject.Inject; +import java.util.Collections; +import java.util.List; + +public class ExternalSignatureResolver { + private BindingTrace trace; + + @Inject + public void setTrace(BindingTrace trace) { + this.trace = trace; + } + + public static class AlternativeMethodSignature { + private final JetType returnType; + private final JetType receiverType; + private final List valueParameters; + private final List typeParameters; + private final String signatureError; + + public AlternativeMethodSignature( + @Nullable JetType returnType, + @Nullable JetType receiverType, + @NotNull List valueParameters, + @NotNull List typeParameters, + @Nullable String signatureError + ) { + this.returnType = returnType; + this.receiverType = receiverType; + this.valueParameters = valueParameters; + this.typeParameters = typeParameters; + this.signatureError = signatureError; + } + + @Nullable + public JetType getReturnType() { + return returnType; + } + + @Nullable + public JetType getReceiverType() { + return receiverType; + } + + @NotNull + public List getValueParameters() { + return valueParameters; + } + + @NotNull + public List getTypeParameters() { + return typeParameters; + } + + @NotNull + public List getErrors() { + return signatureError == null ? Collections.emptyList() : Collections.singletonList(signatureError); + } + } + + @NotNull + public SignaturesPropagationData resolvePropagatedSignature( + @NotNull JavaMethod method, + @NotNull ClassDescriptor owner, + @NotNull JetType returnType, + @Nullable JetType receiverType, + @NotNull List valueParameters, + @NotNull List typeParameters + ) { + return new SignaturesPropagationData(owner, returnType, receiverType, valueParameters, typeParameters, method, trace); + } + + @SuppressWarnings("MethodMayBeStatic") + @NotNull + public AlternativeMethodSignature resolveAlternativeMethodSignature( + @NotNull JavaMethod method, + boolean hasSuperMethods, + @Nullable JetType returnType, + @Nullable JetType receiverType, + @NotNull List valueParameters, + @NotNull List typeParameters + ) { + AlternativeMethodSignatureData data = + new AlternativeMethodSignatureData(method, receiverType, valueParameters, returnType, typeParameters, hasSuperMethods); + + if (data.isAnnotated() && !data.hasErrors()) { + return new AlternativeMethodSignature(data.getReturnType(), receiverType, data.getValueParameters(), data.getTypeParameters(), + null); + } + + String error = data.hasErrors() ? data.getError() : null; + return new AlternativeMethodSignature(returnType, receiverType, valueParameters, typeParameters, error); + } + + public void reportSignatureErrors(@NotNull FunctionDescriptor descriptor, @NotNull List signatureErrors) { + trace.record(JavaBindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, descriptor, signatureErrors); + } +} 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 26b37b8e2f0..ad4c127caca 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 @@ -28,10 +28,8 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; -import org.jetbrains.jet.lang.resolve.java.JavaBindingContext; import org.jetbrains.jet.lang.resolve.java.JavaVisibilities; import org.jetbrains.jet.lang.resolve.java.descriptor.SamAdapterDescriptor; -import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData; import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType; import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; @@ -51,6 +49,7 @@ public final class JavaConstructorResolver { private BindingTrace trace; private JavaTypeTransformer typeTransformer; private JavaValueParameterResolver valueParameterResolver; + private ExternalSignatureResolver externalSignatureResolver; public JavaConstructorResolver() { } @@ -70,6 +69,11 @@ public final class JavaConstructorResolver { this.valueParameterResolver = valueParameterResolver; } + @Inject + public void setExternalSignatureResolver(ExternalSignatureResolver externalSignatureResolver) { + this.externalSignatureResolver = externalSignatureResolver; + } + @NotNull public Collection resolveConstructors(@NotNull JavaClass javaClass, @NotNull ClassDescriptor containingClass) { Collection result = Lists.newArrayList(); @@ -198,27 +202,22 @@ public final class JavaConstructorResolver { List typeParameters = classDescriptor.getTypeConstructor().getParameters(); - JavaValueParameterResolver.ValueParameters valueParameters = valueParameterResolver.resolveValueParameters( + List valueParameters = valueParameterResolver.resolveValueParameters( constructorDescriptor, constructor, new TypeVariableResolver(typeParameters, classDescriptor) ); - if (valueParameters.getReceiverType() != null) { - throw new IllegalStateException(); - } + ExternalSignatureResolver.AlternativeMethodSignature effectiveSignature = externalSignatureResolver + .resolveAlternativeMethodSignature(constructor, false, null, null, valueParameters, + Collections.emptyList()); - AlternativeMethodSignatureData alternativeMethodSignatureData = - new AlternativeMethodSignatureData(constructor, valueParameters, null, - Collections.emptyList(), false); - if (alternativeMethodSignatureData.isAnnotated() && !alternativeMethodSignatureData.hasErrors()) { - valueParameters = alternativeMethodSignatureData.getValueParameters(); - } - else if (alternativeMethodSignatureData.hasErrors()) { - trace.record(JavaBindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, constructorDescriptor, - Collections.singletonList(alternativeMethodSignatureData.getError())); - } + constructorDescriptor + .initialize(typeParameters, effectiveSignature.getValueParameters(), constructor.getVisibility(), isStaticClass); - constructorDescriptor.initialize(typeParameters, valueParameters.getDescriptors(), constructor.getVisibility(), isStaticClass); + List signatureErrors = effectiveSignature.getErrors(); + if (!signatureErrors.isEmpty()) { + externalSignatureResolver.reportSignatureErrors(constructorDescriptor, signatureErrors); + } trace.record(BindingContext.CONSTRUCTOR, constructor.getPsi(), constructorDescriptor); return constructorDescriptor; 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 d18a90c782c..7b0567092a6 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 @@ -31,13 +31,11 @@ import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; -import org.jetbrains.jet.lang.resolve.java.JavaBindingContext; import org.jetbrains.jet.lang.resolve.java.TypeUsage; import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; import org.jetbrains.jet.lang.resolve.java.descriptor.JavaMethodDescriptor; import org.jetbrains.jet.lang.resolve.java.descriptor.SamAdapterDescriptor; import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor; -import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData; import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesPropagationData; import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesUtil; import org.jetbrains.jet.lang.resolve.java.scope.NamedMembers; @@ -64,6 +62,7 @@ public final class JavaFunctionResolver { private JavaTypeParameterResolver typeParameterResolver; private JavaValueParameterResolver valueParameterResolver; private JavaAnnotationResolver annotationResolver; + private ExternalSignatureResolver externalSignatureResolver; @Inject public void setTypeTransformer(JavaTypeTransformer typeTransformer) { @@ -90,6 +89,11 @@ public final class JavaFunctionResolver { this.annotationResolver = annotationResolver; } + @Inject + public void setExternalSignatureResolver(ExternalSignatureResolver externalSignatureResolver) { + this.externalSignatureResolver = externalSignatureResolver; + } + @Nullable SimpleFunctionDescriptor resolveFunctionMutely(@NotNull JavaMethod method, @NotNull ClassOrNamespaceDescriptor owner) { return resolveMethodToFunctionDescriptor(method, owner, false); @@ -128,46 +132,46 @@ public final class JavaFunctionResolver { TypeVariableResolver typeVariableResolver = new TypeVariableResolver(methodTypeParameters, functionDescriptorImpl); - JavaValueParameterResolver.ValueParameters valueParameters = valueParameterResolver - .resolveValueParameters(functionDescriptorImpl, method, typeVariableResolver); + List valueParameters = + valueParameterResolver.resolveValueParameters(functionDescriptorImpl, method, typeVariableResolver); JetType returnType = makeReturnType(returnJavaType, method, typeVariableResolver); - List signatureErrors = Lists.newArrayList(); + List signatureErrors; List superFunctions; - if (ownerDescriptor instanceof ClassDescriptor) { - SignaturesPropagationData signaturesPropagationData = new SignaturesPropagationData( - (ClassDescriptor) ownerDescriptor, returnType, valueParameters, methodTypeParameters, method, trace); - superFunctions = signaturesPropagationData.getSuperFunctions(); + ExternalSignatureResolver.AlternativeMethodSignature effectiveSignature; - returnType = signaturesPropagationData.getModifiedReturnType(); - valueParameters = signaturesPropagationData.getModifiedValueParameters(); - methodTypeParameters = signaturesPropagationData.getModifiedTypeParameters(); + if (ownerDescriptor instanceof NamespaceDescriptor) { + superFunctions = Collections.emptyList(); + effectiveSignature = externalSignatureResolver + .resolveAlternativeMethodSignature(method, false, returnType, null, valueParameters, methodTypeParameters); + signatureErrors = effectiveSignature.getErrors(); + } + else if (ownerDescriptor instanceof ClassDescriptor) { + SignaturesPropagationData propagated = externalSignatureResolver + .resolvePropagatedSignature(method, (ClassDescriptor) ownerDescriptor, returnType, null, valueParameters, + methodTypeParameters); - signatureErrors.addAll(signaturesPropagationData.getSignatureErrors()); + superFunctions = propagated.getSuperFunctions(); + + effectiveSignature = externalSignatureResolver + .resolveAlternativeMethodSignature(method, !superFunctions.isEmpty(), propagated.getModifiedReturnType(), + propagated.getModifiedReceiverType(), propagated.getModifiedValueParameters(), + propagated.getModifiedTypeParameters()); + + signatureErrors = new ArrayList(propagated.getSignatureErrors()); + signatureErrors.addAll(effectiveSignature.getErrors()); } else { - superFunctions = Collections.emptyList(); - } - - AlternativeMethodSignatureData alternativeMethodSignatureData = - new AlternativeMethodSignatureData(method, valueParameters, returnType, methodTypeParameters, - !superFunctions.isEmpty()); - if (alternativeMethodSignatureData.isAnnotated() && !alternativeMethodSignatureData.hasErrors()) { - valueParameters = alternativeMethodSignatureData.getValueParameters(); - returnType = alternativeMethodSignatureData.getReturnType(); - methodTypeParameters = alternativeMethodSignatureData.getTypeParameters(); - } - else if (alternativeMethodSignatureData.hasErrors()) { - signatureErrors.add(alternativeMethodSignatureData.getError()); + throw new IllegalStateException("Unknown class or namespace descriptor: " + ownerDescriptor); } functionDescriptorImpl.initialize( - valueParameters.getReceiverType(), + effectiveSignature.getReceiverType(), DescriptorUtils.getExpectedThisObjectIfNeeded(ownerDescriptor), - methodTypeParameters, - valueParameters.getDescriptors(), - returnType, + effectiveSignature.getTypeParameters(), + effectiveSignature.getValueParameters(), + effectiveSignature.getReturnType(), Modality.convertFromFlags(method.isAbstract(), !method.isFinal()), method.getVisibility(), /*isInline = */ false @@ -183,10 +187,8 @@ public final class JavaFunctionResolver { if (signatureErrors.isEmpty()) { checkFunctionsOverrideCorrectly(method, superFunctions, functionDescriptorImpl); } - else { - if (record) { - trace.record(JavaBindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, functionDescriptorImpl, signatureErrors); - } + else if (record) { + externalSignatureResolver.reportSignatureErrors(functionDescriptorImpl, signatureErrors); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaValueParameterResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaValueParameterResolver.java index 32d17c361d4..c2fb6059474 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaValueParameterResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaValueParameterResolver.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.lang.resolve.java.resolver; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -97,7 +96,7 @@ public final class JavaValueParameterResolver { } @NotNull - public ValueParameters resolveValueParameters( + public List resolveValueParameters( @NotNull DeclarationDescriptor container, @NotNull JavaMethod method, @NotNull TypeVariableResolver typeVariableResolver @@ -109,26 +108,6 @@ public final class JavaValueParameterResolver { result.add(resolveValueParameter(container, index, parameter, typeVariableResolver)); index++; } - return new ValueParameters(null, result); - } - - public static class ValueParameters { - private final JetType receiverType; - private final List descriptors; - - public ValueParameters(@Nullable JetType receiverType, @NotNull List descriptors) { - this.receiverType = receiverType; - this.descriptors = descriptors; - } - - @Nullable - public JetType getReceiverType() { - return receiverType; - } - - @NotNull - public List getDescriptors() { - return descriptors; - } + return result; } }