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
This commit is contained in:
Alexander Udalov
2013-08-06 23:13:53 +04:00
parent 45346071a3
commit be3d835203
8 changed files with 240 additions and 105 deletions
@@ -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.JavaAnnotationResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationArgumentResolver; 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.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.JavaTypeParameterResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaTypeTransformer; import org.jetbrains.jet.lang.resolve.java.resolver.JavaTypeTransformer;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver;
@@ -51,6 +52,7 @@ public class InjectorForJavaDescriptorResolver {
private final JavaAnnotationResolver javaAnnotationResolver; private final JavaAnnotationResolver javaAnnotationResolver;
private final JavaAnnotationArgumentResolver javaAnnotationArgumentResolver; private final JavaAnnotationArgumentResolver javaAnnotationArgumentResolver;
private final JavaFunctionResolver javaFunctionResolver; private final JavaFunctionResolver javaFunctionResolver;
private final ExternalSignatureResolver externalSignatureResolver;
private final JavaTypeParameterResolver javaTypeParameterResolver; private final JavaTypeParameterResolver javaTypeParameterResolver;
private final JavaTypeTransformer javaTypeTransformer; private final JavaTypeTransformer javaTypeTransformer;
private final JavaValueParameterResolver javaValueParameterResolver; private final JavaValueParameterResolver javaValueParameterResolver;
@@ -75,6 +77,7 @@ public class InjectorForJavaDescriptorResolver {
this.javaAnnotationResolver = new JavaAnnotationResolver(); this.javaAnnotationResolver = new JavaAnnotationResolver();
this.javaAnnotationArgumentResolver = new JavaAnnotationArgumentResolver(); this.javaAnnotationArgumentResolver = new JavaAnnotationArgumentResolver();
this.javaFunctionResolver = new JavaFunctionResolver(); this.javaFunctionResolver = new JavaFunctionResolver();
this.externalSignatureResolver = new ExternalSignatureResolver();
this.javaTypeParameterResolver = new JavaTypeParameterResolver(); this.javaTypeParameterResolver = new JavaTypeParameterResolver();
this.javaTypeTransformer = new JavaTypeTransformer(); this.javaTypeTransformer = new JavaTypeTransformer();
this.javaValueParameterResolver = new JavaValueParameterResolver(); this.javaValueParameterResolver = new JavaValueParameterResolver();
@@ -113,11 +116,14 @@ public class InjectorForJavaDescriptorResolver {
javaAnnotationArgumentResolver.setClassResolver(javaClassResolver); javaAnnotationArgumentResolver.setClassResolver(javaClassResolver);
javaFunctionResolver.setAnnotationResolver(javaAnnotationResolver); javaFunctionResolver.setAnnotationResolver(javaAnnotationResolver);
javaFunctionResolver.setExternalSignatureResolver(externalSignatureResolver);
javaFunctionResolver.setTrace(bindingTrace); javaFunctionResolver.setTrace(bindingTrace);
javaFunctionResolver.setTypeParameterResolver(javaTypeParameterResolver); javaFunctionResolver.setTypeParameterResolver(javaTypeParameterResolver);
javaFunctionResolver.setTypeTransformer(javaTypeTransformer); javaFunctionResolver.setTypeTransformer(javaTypeTransformer);
javaFunctionResolver.setValueParameterResolver(javaValueParameterResolver); javaFunctionResolver.setValueParameterResolver(javaValueParameterResolver);
externalSignatureResolver.setTrace(bindingTrace);
javaTypeParameterResolver.setTypeTransformer(javaTypeTransformer); javaTypeParameterResolver.setTypeTransformer(javaTypeTransformer);
javaTypeTransformer.setClassResolver(javaClassResolver); javaTypeTransformer.setClassResolver(javaClassResolver);
@@ -142,6 +148,7 @@ public class InjectorForJavaDescriptorResolver {
javaSupertypeResolver.setTrace(bindingTrace); javaSupertypeResolver.setTrace(bindingTrace);
javaSupertypeResolver.setTypeTransformer(javaTypeTransformer); javaSupertypeResolver.setTypeTransformer(javaTypeTransformer);
javaConstructorResolver.setExternalSignatureResolver(externalSignatureResolver);
javaConstructorResolver.setTrace(bindingTrace); javaConstructorResolver.setTrace(bindingTrace);
javaConstructorResolver.setTypeTransformer(javaTypeTransformer); javaConstructorResolver.setTypeTransformer(javaTypeTransformer);
javaConstructorResolver.setValueParameterResolver(javaValueParameterResolver); javaConstructorResolver.setValueParameterResolver(javaValueParameterResolver);
@@ -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.JavaAnnotationResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationArgumentResolver; 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.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.JavaTypeParameterResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaTypeTransformer; import org.jetbrains.jet.lang.resolve.java.resolver.JavaTypeTransformer;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver;
@@ -105,6 +106,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
private final JavaAnnotationResolver javaAnnotationResolver; private final JavaAnnotationResolver javaAnnotationResolver;
private final JavaAnnotationArgumentResolver javaAnnotationArgumentResolver; private final JavaAnnotationArgumentResolver javaAnnotationArgumentResolver;
private final JavaFunctionResolver javaFunctionResolver; private final JavaFunctionResolver javaFunctionResolver;
private final ExternalSignatureResolver externalSignatureResolver;
private final JavaTypeParameterResolver javaTypeParameterResolver; private final JavaTypeParameterResolver javaTypeParameterResolver;
private final JavaTypeTransformer javaTypeTransformer; private final JavaTypeTransformer javaTypeTransformer;
private final JavaValueParameterResolver javaValueParameterResolver; private final JavaValueParameterResolver javaValueParameterResolver;
@@ -158,6 +160,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
this.javaAnnotationResolver = new JavaAnnotationResolver(); this.javaAnnotationResolver = new JavaAnnotationResolver();
this.javaAnnotationArgumentResolver = new JavaAnnotationArgumentResolver(); this.javaAnnotationArgumentResolver = new JavaAnnotationArgumentResolver();
this.javaFunctionResolver = new JavaFunctionResolver(); this.javaFunctionResolver = new JavaFunctionResolver();
this.externalSignatureResolver = new ExternalSignatureResolver();
this.javaTypeParameterResolver = new JavaTypeParameterResolver(); this.javaTypeParameterResolver = new JavaTypeParameterResolver();
this.javaTypeTransformer = new JavaTypeTransformer(); this.javaTypeTransformer = new JavaTypeTransformer();
this.javaValueParameterResolver = new JavaValueParameterResolver(); this.javaValueParameterResolver = new JavaValueParameterResolver();
@@ -300,11 +303,14 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
javaAnnotationArgumentResolver.setClassResolver(javaClassResolver); javaAnnotationArgumentResolver.setClassResolver(javaClassResolver);
javaFunctionResolver.setAnnotationResolver(javaAnnotationResolver); javaFunctionResolver.setAnnotationResolver(javaAnnotationResolver);
javaFunctionResolver.setExternalSignatureResolver(externalSignatureResolver);
javaFunctionResolver.setTrace(bindingTrace); javaFunctionResolver.setTrace(bindingTrace);
javaFunctionResolver.setTypeParameterResolver(javaTypeParameterResolver); javaFunctionResolver.setTypeParameterResolver(javaTypeParameterResolver);
javaFunctionResolver.setTypeTransformer(javaTypeTransformer); javaFunctionResolver.setTypeTransformer(javaTypeTransformer);
javaFunctionResolver.setValueParameterResolver(javaValueParameterResolver); javaFunctionResolver.setValueParameterResolver(javaValueParameterResolver);
externalSignatureResolver.setTrace(bindingTrace);
javaTypeParameterResolver.setTypeTransformer(javaTypeTransformer); javaTypeParameterResolver.setTypeTransformer(javaTypeTransformer);
javaTypeTransformer.setClassResolver(javaClassResolver); javaTypeTransformer.setClassResolver(javaClassResolver);
@@ -329,6 +335,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
javaSupertypeResolver.setTrace(bindingTrace); javaSupertypeResolver.setTrace(bindingTrace);
javaSupertypeResolver.setTypeTransformer(javaTypeTransformer); javaSupertypeResolver.setTypeTransformer(javaTypeTransformer);
javaConstructorResolver.setExternalSignatureResolver(externalSignatureResolver);
javaConstructorResolver.setTrace(bindingTrace); javaConstructorResolver.setTrace(bindingTrace);
javaConstructorResolver.setTypeTransformer(javaTypeTransformer); javaConstructorResolver.setTypeTransformer(javaTypeTransformer);
javaConstructorResolver.setValueParameterResolver(javaValueParameterResolver); javaConstructorResolver.setValueParameterResolver(javaValueParameterResolver);
@@ -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.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.jet.lang.psi.*; 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.java.structure.JavaMethod;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType; 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 { public class AlternativeMethodSignatureData extends ElementAlternativeSignatureData {
private final JetNamedFunction altFunDeclaration; private final JetNamedFunction altFunDeclaration;
private JavaValueParameterResolver.ValueParameters altValueParameters; private List<ValueParameterDescriptor> altValueParameters;
private JetType altReturnType; private JetType altReturnType;
private List<TypeParameterDescriptor> altTypeParameters; private List<TypeParameterDescriptor> altTypeParameters;
@@ -54,7 +53,8 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD
public AlternativeMethodSignatureData( public AlternativeMethodSignatureData(
@NotNull JavaMethod method, @NotNull JavaMethod method,
@NotNull JavaValueParameterResolver.ValueParameters valueParameters, @Nullable JetType receiverType,
@NotNull List<ValueParameterDescriptor> valueParameters,
@Nullable JetType originalReturnType, @Nullable JetType originalReturnType,
@NotNull List<TypeParameterDescriptor> methodTypeParameters, @NotNull List<TypeParameterDescriptor> methodTypeParameters,
boolean hasSuperMethods boolean hasSuperMethods
@@ -67,6 +67,10 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD
return; return;
} }
if (receiverType != null) {
throw new UnsupportedOperationException("Alternative annotations for extension functions are not supported yet");
}
setAnnotated(true); setAnnotated(true);
Project project = method.getPsi().getProject(); Project project = method.getPsi().getProject();
altFunDeclaration = JetPsiFactory.createFunction(project, signature); altFunDeclaration = JetPsiFactory.createFunction(project, signature);
@@ -94,15 +98,15 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD
} }
private void checkParameterAndReturnTypesForOverridingMethods( private void checkParameterAndReturnTypesForOverridingMethods(
@NotNull JavaValueParameterResolver.ValueParameters valueParameters, @NotNull List<ValueParameterDescriptor> valueParameters,
@NotNull List<TypeParameterDescriptor> methodTypeParameters, @NotNull List<TypeParameterDescriptor> methodTypeParameters,
@Nullable JetType returnType @Nullable JetType returnType
) { ) {
TypeSubstitutor substitutor = SignaturesUtil.createSubstitutorForTypeParameters(originalToAltTypeParameters); TypeSubstitutor substitutor = SignaturesUtil.createSubstitutorForTypeParameters(originalToAltTypeParameters);
for (ValueParameterDescriptor parameter : valueParameters.getDescriptors()) { for (ValueParameterDescriptor parameter : valueParameters) {
int index = parameter.getIndex(); int index = parameter.getIndex();
ValueParameterDescriptor altParameter = altValueParameters.getDescriptors().get(index); ValueParameterDescriptor altParameter = altValueParameters.get(index);
JetType substituted = substitutor.substitute(parameter.getType(), Variance.INVARIANT); JetType substituted = substitutor.substitute(parameter.getType(), Variance.INVARIANT);
assert substituted != null; assert substituted != null;
@@ -141,12 +145,12 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD
} }
@NotNull @NotNull
public JavaValueParameterResolver.ValueParameters getValueParameters() { public List<ValueParameterDescriptor> getValueParameters() {
checkForErrors(); checkForErrors();
return altValueParameters; return altValueParameters;
} }
@NotNull @Nullable
public JetType getReturnType() { public JetType getReturnType() {
checkForErrors(); checkForErrors();
return altReturnType; return altReturnType;
@@ -158,9 +162,7 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD
return altTypeParameters; return altTypeParameters;
} }
private void computeValueParameters(JavaValueParameterResolver.ValueParameters valueParameters) { private void computeValueParameters(@NotNull List<ValueParameterDescriptor> parameterDescriptors) {
List<ValueParameterDescriptor> parameterDescriptors = valueParameters.getDescriptors();
if (parameterDescriptors.size() != altFunDeclaration.getValueParameters().size()) { if (parameterDescriptors.size() != altFunDeclaration.getValueParameters().size()) {
throw new AlternativeSignatureMismatchException("Method signature has %d value parameters, but alternative signature has %d", throw new AlternativeSignatureMismatchException("Method signature has %d value parameters, but alternative signature has %d",
parameterDescriptors.size(), altFunDeclaration.getValueParameters().size()); parameterDescriptors.size(), altFunDeclaration.getValueParameters().size());
@@ -207,11 +209,7 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD
alternativeVarargElementType)); alternativeVarargElementType));
} }
if (valueParameters.getReceiverType() != null) { altValueParameters = altParamDescriptors;
throw new UnsupportedOperationException("Alternative annotations for extension functions are not supported yet");
}
altValueParameters = new JavaValueParameterResolver.ValueParameters(null, altParamDescriptors);
} }
private void computeTypeParameters(List<TypeParameterDescriptor> typeParameters) { private void computeTypeParameters(List<TypeParameterDescriptor> typeParameters) {
@@ -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.TypeUsage;
import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetClsMethod; 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.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.JavaClass;
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
import org.jetbrains.jet.lang.resolve.name.FqName; 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 static final Logger LOG = Logger.getInstance(SignaturesPropagationData.class);
private final List<TypeParameterDescriptor> modifiedTypeParameters; private final List<TypeParameterDescriptor> modifiedTypeParameters;
private final JavaValueParameterResolver.ValueParameters modifiedValueParameters; private final ValueParameters modifiedValueParameters;
private final JetType modifiedReturnType; private final JetType modifiedReturnType;
private final List<String> signatureErrors = Lists.newArrayList(); private final List<String> signatureErrors = Lists.newArrayList();
@@ -69,7 +68,8 @@ public class SignaturesPropagationData {
public SignaturesPropagationData( public SignaturesPropagationData(
@NotNull ClassDescriptor containingClass, @NotNull ClassDescriptor containingClass,
@NotNull JetType autoReturnType, // type built by JavaTypeTransformer from Java signature and @NotNull annotations @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<ValueParameterDescriptor> autoValueParameters, // descriptors built by parameters resolver
@NotNull List<TypeParameterDescriptor> autoTypeParameters, // descriptors built by signature resolver @NotNull List<TypeParameterDescriptor> autoTypeParameters, // descriptors built by signature resolver
@NotNull JavaMethod method, @NotNull JavaMethod method,
@NotNull BindingTrace trace @NotNull BindingTrace trace
@@ -81,15 +81,19 @@ public class SignaturesPropagationData {
modifiedTypeParameters = modifyTypeParametersAccordingToSuperMethods(autoTypeParameters); modifiedTypeParameters = modifyTypeParametersAccordingToSuperMethods(autoTypeParameters);
modifiedReturnType = modifyReturnTypeAccordingToSuperMethods(autoReturnType); modifiedReturnType = modifyReturnTypeAccordingToSuperMethods(autoReturnType);
modifiedValueParameters = modifyValueParametersAccordingToSuperMethods(autoValueParameters); modifiedValueParameters = modifyValueParametersAccordingToSuperMethods(receiverType, autoValueParameters);
} }
public List<TypeParameterDescriptor> getModifiedTypeParameters() { public List<TypeParameterDescriptor> getModifiedTypeParameters() {
return modifiedTypeParameters; return modifiedTypeParameters;
} }
public JavaValueParameterResolver.ValueParameters getModifiedValueParameters() { public JetType getModifiedReceiverType() {
return modifiedValueParameters; return modifiedValueParameters.receiverType;
}
public List<ValueParameterDescriptor> getModifiedValueParameters() {
return modifiedValueParameters.descriptors;
} }
public JetType getModifiedReturnType() { public JetType getModifiedReturnType() {
@@ -157,19 +161,20 @@ public class SignaturesPropagationData {
return result; return result;
} }
private JavaValueParameterResolver.ValueParameters modifyValueParametersAccordingToSuperMethods( private ValueParameters modifyValueParametersAccordingToSuperMethods(
@NotNull JavaValueParameterResolver.ValueParameters parameters // descriptors built by parameters resolver @Nullable JetType receiverType,
@NotNull List<ValueParameterDescriptor> parameters // descriptors built by parameters resolver
) { ) {
assert parameters.getReceiverType() == null : "Parameters before propagation have receiver type," + assert receiverType == null : "Parameters before propagation have receiver type," +
" but propagation should be disabled for functions compiled from Kotlin in class: " + " but propagation should be disabled for functions compiled from Kotlin in class: " +
DescriptorUtils.getFQName(containingClass); DescriptorUtils.getFQName(containingClass);
JetType receiverType = null; JetType resultReceiverType = null;
List<ValueParameterDescriptor> resultParameters = Lists.newArrayList(); List<ValueParameterDescriptor> resultParameters = Lists.newArrayList();
boolean shouldBeExtension = checkIfShouldBeExtension(); boolean shouldBeExtension = checkIfShouldBeExtension();
for (ValueParameterDescriptor originalParam : parameters.getDescriptors()) { for (ValueParameterDescriptor originalParam : parameters) {
final int originalIndex = originalParam.getIndex(); final int originalIndex = originalParam.getIndex();
List<TypeAndVariance> typesFromSuperMethods = ContainerUtil.map(superFunctions, List<TypeAndVariance> typesFromSuperMethods = ContainerUtil.map(superFunctions,
new Function<FunctionDescriptor, TypeAndVariance>() { new Function<FunctionDescriptor, TypeAndVariance>() {
@@ -190,7 +195,7 @@ public class SignaturesPropagationData {
JetType altType = modifyTypeAccordingToSuperMethods(varargCheckResult.parameterType, typesFromSuperMethods, MEMBER_SIGNATURE_CONTRAVARIANT); JetType altType = modifyTypeAccordingToSuperMethods(varargCheckResult.parameterType, typesFromSuperMethods, MEMBER_SIGNATURE_CONTRAVARIANT);
if (shouldBeExtension && originalIndex == 0) { if (shouldBeExtension && originalIndex == 0) {
receiverType = altType; resultReceiverType = altType;
} }
else { else {
resultParameters.add(new ValueParameterDescriptorImpl( 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<FunctionDescriptor> getSuperFunctionsForMethod( private static List<FunctionDescriptor> getSuperFunctionsForMethod(
@@ -738,4 +743,14 @@ public class SignaturesPropagationData {
return type.toString(); return type.toString();
} }
} }
private static class ValueParameters {
private final JetType receiverType;
private final List<ValueParameterDescriptor> descriptors;
public ValueParameters(@Nullable JetType receiverType, @NotNull List<ValueParameterDescriptor> descriptors) {
this.receiverType = receiverType;
this.descriptors = descriptors;
}
}
} }
@@ -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<ValueParameterDescriptor> valueParameters;
private final List<TypeParameterDescriptor> typeParameters;
private final String signatureError;
public AlternativeMethodSignature(
@Nullable JetType returnType,
@Nullable JetType receiverType,
@NotNull List<ValueParameterDescriptor> valueParameters,
@NotNull List<TypeParameterDescriptor> 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<ValueParameterDescriptor> getValueParameters() {
return valueParameters;
}
@NotNull
public List<TypeParameterDescriptor> getTypeParameters() {
return typeParameters;
}
@NotNull
public List<String> getErrors() {
return signatureError == null ? Collections.<String>emptyList() : Collections.singletonList(signatureError);
}
}
@NotNull
public SignaturesPropagationData resolvePropagatedSignature(
@NotNull JavaMethod method,
@NotNull ClassDescriptor owner,
@NotNull JetType returnType,
@Nullable JetType receiverType,
@NotNull List<ValueParameterDescriptor> valueParameters,
@NotNull List<TypeParameterDescriptor> 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<ValueParameterDescriptor> valueParameters,
@NotNull List<TypeParameterDescriptor> 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<String> signatureErrors) {
trace.record(JavaBindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, descriptor, signatureErrors);
}
}
@@ -28,10 +28,8 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; 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.JavaVisibilities;
import org.jetbrains.jet.lang.resolve.java.descriptor.SamAdapterDescriptor; 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.JavaArrayType;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
@@ -51,6 +49,7 @@ public final class JavaConstructorResolver {
private BindingTrace trace; private BindingTrace trace;
private JavaTypeTransformer typeTransformer; private JavaTypeTransformer typeTransformer;
private JavaValueParameterResolver valueParameterResolver; private JavaValueParameterResolver valueParameterResolver;
private ExternalSignatureResolver externalSignatureResolver;
public JavaConstructorResolver() { public JavaConstructorResolver() {
} }
@@ -70,6 +69,11 @@ public final class JavaConstructorResolver {
this.valueParameterResolver = valueParameterResolver; this.valueParameterResolver = valueParameterResolver;
} }
@Inject
public void setExternalSignatureResolver(ExternalSignatureResolver externalSignatureResolver) {
this.externalSignatureResolver = externalSignatureResolver;
}
@NotNull @NotNull
public Collection<ConstructorDescriptor> resolveConstructors(@NotNull JavaClass javaClass, @NotNull ClassDescriptor containingClass) { public Collection<ConstructorDescriptor> resolveConstructors(@NotNull JavaClass javaClass, @NotNull ClassDescriptor containingClass) {
Collection<ConstructorDescriptor> result = Lists.newArrayList(); Collection<ConstructorDescriptor> result = Lists.newArrayList();
@@ -198,27 +202,22 @@ public final class JavaConstructorResolver {
List<TypeParameterDescriptor> typeParameters = classDescriptor.getTypeConstructor().getParameters(); List<TypeParameterDescriptor> typeParameters = classDescriptor.getTypeConstructor().getParameters();
JavaValueParameterResolver.ValueParameters valueParameters = valueParameterResolver.resolveValueParameters( List<ValueParameterDescriptor> valueParameters = valueParameterResolver.resolveValueParameters(
constructorDescriptor, constructor, constructorDescriptor, constructor,
new TypeVariableResolver(typeParameters, classDescriptor) new TypeVariableResolver(typeParameters, classDescriptor)
); );
if (valueParameters.getReceiverType() != null) { ExternalSignatureResolver.AlternativeMethodSignature effectiveSignature = externalSignatureResolver
throw new IllegalStateException(); .resolveAlternativeMethodSignature(constructor, false, null, null, valueParameters,
} Collections.<TypeParameterDescriptor>emptyList());
AlternativeMethodSignatureData alternativeMethodSignatureData = constructorDescriptor
new AlternativeMethodSignatureData(constructor, valueParameters, null, .initialize(typeParameters, effectiveSignature.getValueParameters(), constructor.getVisibility(), isStaticClass);
Collections.<TypeParameterDescriptor>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, valueParameters.getDescriptors(), constructor.getVisibility(), isStaticClass); List<String> signatureErrors = effectiveSignature.getErrors();
if (!signatureErrors.isEmpty()) {
externalSignatureResolver.reportSignatureErrors(constructorDescriptor, signatureErrors);
}
trace.record(BindingContext.CONSTRUCTOR, constructor.getPsi(), constructorDescriptor); trace.record(BindingContext.CONSTRUCTOR, constructor.getPsi(), constructorDescriptor);
return constructorDescriptor; return constructorDescriptor;
@@ -31,13 +31,11 @@ import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; 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.TypeUsage;
import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; 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.JavaMethodDescriptor;
import org.jetbrains.jet.lang.resolve.java.descriptor.SamAdapterDescriptor; 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.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.SignaturesPropagationData;
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesUtil; import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesUtil;
import org.jetbrains.jet.lang.resolve.java.scope.NamedMembers; import org.jetbrains.jet.lang.resolve.java.scope.NamedMembers;
@@ -64,6 +62,7 @@ public final class JavaFunctionResolver {
private JavaTypeParameterResolver typeParameterResolver; private JavaTypeParameterResolver typeParameterResolver;
private JavaValueParameterResolver valueParameterResolver; private JavaValueParameterResolver valueParameterResolver;
private JavaAnnotationResolver annotationResolver; private JavaAnnotationResolver annotationResolver;
private ExternalSignatureResolver externalSignatureResolver;
@Inject @Inject
public void setTypeTransformer(JavaTypeTransformer typeTransformer) { public void setTypeTransformer(JavaTypeTransformer typeTransformer) {
@@ -90,6 +89,11 @@ public final class JavaFunctionResolver {
this.annotationResolver = annotationResolver; this.annotationResolver = annotationResolver;
} }
@Inject
public void setExternalSignatureResolver(ExternalSignatureResolver externalSignatureResolver) {
this.externalSignatureResolver = externalSignatureResolver;
}
@Nullable @Nullable
SimpleFunctionDescriptor resolveFunctionMutely(@NotNull JavaMethod method, @NotNull ClassOrNamespaceDescriptor owner) { SimpleFunctionDescriptor resolveFunctionMutely(@NotNull JavaMethod method, @NotNull ClassOrNamespaceDescriptor owner) {
return resolveMethodToFunctionDescriptor(method, owner, false); return resolveMethodToFunctionDescriptor(method, owner, false);
@@ -128,46 +132,46 @@ public final class JavaFunctionResolver {
TypeVariableResolver typeVariableResolver = new TypeVariableResolver(methodTypeParameters, functionDescriptorImpl); TypeVariableResolver typeVariableResolver = new TypeVariableResolver(methodTypeParameters, functionDescriptorImpl);
JavaValueParameterResolver.ValueParameters valueParameters = valueParameterResolver List<ValueParameterDescriptor> valueParameters =
.resolveValueParameters(functionDescriptorImpl, method, typeVariableResolver); valueParameterResolver.resolveValueParameters(functionDescriptorImpl, method, typeVariableResolver);
JetType returnType = makeReturnType(returnJavaType, method, typeVariableResolver); JetType returnType = makeReturnType(returnJavaType, method, typeVariableResolver);
List<String> signatureErrors = Lists.newArrayList();
List<String> signatureErrors;
List<FunctionDescriptor> superFunctions; List<FunctionDescriptor> superFunctions;
if (ownerDescriptor instanceof ClassDescriptor) { ExternalSignatureResolver.AlternativeMethodSignature effectiveSignature;
SignaturesPropagationData signaturesPropagationData = new SignaturesPropagationData(
(ClassDescriptor) ownerDescriptor, returnType, valueParameters, methodTypeParameters, method, trace);
superFunctions = signaturesPropagationData.getSuperFunctions();
returnType = signaturesPropagationData.getModifiedReturnType(); if (ownerDescriptor instanceof NamespaceDescriptor) {
valueParameters = signaturesPropagationData.getModifiedValueParameters(); superFunctions = Collections.emptyList();
methodTypeParameters = signaturesPropagationData.getModifiedTypeParameters(); 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<String>(propagated.getSignatureErrors());
signatureErrors.addAll(effectiveSignature.getErrors());
} }
else { else {
superFunctions = Collections.emptyList(); throw new IllegalStateException("Unknown class or namespace descriptor: " + ownerDescriptor);
}
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());
} }
functionDescriptorImpl.initialize( functionDescriptorImpl.initialize(
valueParameters.getReceiverType(), effectiveSignature.getReceiverType(),
DescriptorUtils.getExpectedThisObjectIfNeeded(ownerDescriptor), DescriptorUtils.getExpectedThisObjectIfNeeded(ownerDescriptor),
methodTypeParameters, effectiveSignature.getTypeParameters(),
valueParameters.getDescriptors(), effectiveSignature.getValueParameters(),
returnType, effectiveSignature.getReturnType(),
Modality.convertFromFlags(method.isAbstract(), !method.isFinal()), Modality.convertFromFlags(method.isAbstract(), !method.isFinal()),
method.getVisibility(), method.getVisibility(),
/*isInline = */ false /*isInline = */ false
@@ -183,10 +187,8 @@ public final class JavaFunctionResolver {
if (signatureErrors.isEmpty()) { if (signatureErrors.isEmpty()) {
checkFunctionsOverrideCorrectly(method, superFunctions, functionDescriptorImpl); checkFunctionsOverrideCorrectly(method, superFunctions, functionDescriptorImpl);
} }
else { else if (record) {
if (record) { externalSignatureResolver.reportSignatureErrors(functionDescriptorImpl, signatureErrors);
trace.record(JavaBindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, functionDescriptorImpl, signatureErrors);
}
} }
} }
@@ -17,7 +17,6 @@
package org.jetbrains.jet.lang.resolve.java.resolver; package org.jetbrains.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
@@ -97,7 +96,7 @@ public final class JavaValueParameterResolver {
} }
@NotNull @NotNull
public ValueParameters resolveValueParameters( public List<ValueParameterDescriptor> resolveValueParameters(
@NotNull DeclarationDescriptor container, @NotNull DeclarationDescriptor container,
@NotNull JavaMethod method, @NotNull JavaMethod method,
@NotNull TypeVariableResolver typeVariableResolver @NotNull TypeVariableResolver typeVariableResolver
@@ -109,26 +108,6 @@ public final class JavaValueParameterResolver {
result.add(resolveValueParameter(container, index, parameter, typeVariableResolver)); result.add(resolveValueParameter(container, index, parameter, typeVariableResolver));
index++; index++;
} }
return new ValueParameters(null, result); return result;
}
public static class ValueParameters {
private final JetType receiverType;
private final List<ValueParameterDescriptor> descriptors;
public ValueParameters(@Nullable JetType receiverType, @NotNull List<ValueParameterDescriptor> descriptors) {
this.receiverType = receiverType;
this.descriptors = descriptors;
}
@Nullable
public JetType getReceiverType() {
return receiverType;
}
@NotNull
public List<ValueParameterDescriptor> getDescriptors() {
return descriptors;
}
} }
} }