Fields alternative signature processing with refactoring of AlternativeSignatureData

Refactoring details:
- Move and rename AlternativeSignatureData to kotlinSignature.AlternativeMethodSignatureData
- Extract TypeTransforming visitor
- Extract AlternativeSignatureMistmatchException
- Move errors, return type, and syntax processing to base class
This commit is contained in:
Nikolay Krasko
2012-10-05 14:46:59 +04:00
parent 4bb0181613
commit 572173a8f8
19 changed files with 763 additions and 293 deletions
@@ -27,8 +27,10 @@ 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.OverrideResolver; import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData;
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeFieldSignatureData;
import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils; import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils;
import org.jetbrains.jet.lang.resolve.java.kt.JetMethodAnnotation; import org.jetbrains.jet.lang.resolve.java.kt.JetMethodAnnotation;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiFieldWrapper;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper; import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
@@ -114,7 +116,6 @@ public final class JavaDescriptorPropertiesResolver {
} }
DeclarationDescriptor realOwner = getRealOwner(owner, scopeData, characteristicMember.getMember().isStatic()); DeclarationDescriptor realOwner = getRealOwner(owner, scopeData, characteristicMember.getMember().isStatic());
boolean isEnumEntry = DescriptorUtils.isEnumClassObject(realOwner); boolean isEnumEntry = DescriptorUtils.isEnumClassObject(realOwner);
boolean isPropertyForNamedObject = members.field != null && JvmAbi.INSTANCE_FIELD.equals(members.field.getMember().getName()); boolean isPropertyForNamedObject = members.field != null && JvmAbi.INSTANCE_FIELD.equals(members.field.getMember().getName());
PropertyDescriptor propertyDescriptor = new PropertyDescriptor( PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
@@ -182,6 +183,20 @@ public final class JavaDescriptorPropertiesResolver {
JetType propertyType = getPropertyType(members, characteristicMember, typeVariableResolverForPropertyInternals); JetType propertyType = getPropertyType(members, characteristicMember, typeVariableResolverForPropertyInternals);
JetType receiverType = getReceiverType(characteristicMember, typeVariableResolverForPropertyInternals); JetType receiverType = getReceiverType(characteristicMember, typeVariableResolverForPropertyInternals);
if (characteristicMember.isField()) {
AlternativeFieldSignatureData signatureData =
new AlternativeFieldSignatureData((PsiFieldWrapper) characteristicMember.getMember(), propertyType);
if (!signatureData.hasErrors()) {
if (signatureData.isAnnotated()) {
propertyType = signatureData.getReturnType();
}
}
else {
trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, propertyDescriptor, signatureData.getError());
}
}
propertyDescriptor.setType( propertyDescriptor.setType(
propertyType, propertyType,
typeParameters, typeParameters,
@@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.*; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.*;
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.JavaNamespaceDescriptor; import org.jetbrains.jet.lang.resolve.java.descriptor.JavaNamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData;
import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils; import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils;
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
import org.jetbrains.jet.lang.resolve.java.kt.PsiAnnotationWithFlags; import org.jetbrains.jet.lang.resolve.java.kt.PsiAnnotationWithFlags;
@@ -428,13 +429,13 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
throw new IllegalStateException(); throw new IllegalStateException();
} }
AlternativeSignatureData alternativeSignatureData = AlternativeMethodSignatureData alternativeMethodSignatureData =
new AlternativeSignatureData(constructor, valueParameterDescriptors, null, Collections.<TypeParameterDescriptor>emptyList()); new AlternativeMethodSignatureData(constructor, valueParameterDescriptors, null, Collections.<TypeParameterDescriptor>emptyList());
if (!alternativeSignatureData.isNone() && alternativeSignatureData.getError() == null) { if (alternativeMethodSignatureData.isAnnotated() && !alternativeMethodSignatureData.hasErrors()) {
valueParameterDescriptors = alternativeSignatureData.getValueParameters(); valueParameterDescriptors = alternativeMethodSignatureData.getValueParameters();
} }
else if (alternativeSignatureData.getError() != null) { else if (alternativeMethodSignatureData.hasErrors()) {
trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, constructorDescriptor, alternativeSignatureData.getError()); trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, constructorDescriptor, alternativeMethodSignatureData.getError());
} }
constructorDescriptor.initialize(classData.getClassDescriptor().getTypeConstructor().getParameters(), constructorDescriptor.initialize(classData.getClassDescriptor().getTypeConstructor().getParameters(),
@@ -808,14 +809,24 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
return psiClassFinder.findPsiClass(packageFQN.child(Name.identifier(JvmAbi.PACKAGE_CLASS)), PsiClassFinder.RuntimeClassesHandleMode.IGNORE); return psiClassFinder.findPsiClass(packageFQN.child(Name.identifier(JvmAbi.PACKAGE_CLASS)), PsiClassFinder.RuntimeClassesHandleMode.IGNORE);
} }
static class ValueParameterDescriptors { public static class ValueParameterDescriptors {
final JetType receiverType; final JetType receiverType;
final List<ValueParameterDescriptor> descriptors; final List<ValueParameterDescriptor> descriptors;
ValueParameterDescriptors(@Nullable JetType receiverType, List<ValueParameterDescriptor> descriptors) { public ValueParameterDescriptors(@Nullable JetType receiverType, @NotNull List<ValueParameterDescriptor> descriptors) {
this.receiverType = receiverType; this.receiverType = receiverType;
this.descriptors = descriptors; this.descriptors = descriptors;
} }
@Nullable
public JetType getReceiverType() {
return receiverType;
}
@NotNull
public List<ValueParameterDescriptor> getDescriptors() {
return descriptors;
}
} }
private enum JvmMethodParameterKind { private enum JvmMethodParameterKind {
@@ -1120,15 +1131,15 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
JetType returnType = makeReturnType(returnPsiType, method, methodTypeVariableResolver); JetType returnType = makeReturnType(returnPsiType, method, methodTypeVariableResolver);
// TODO consider better place for this check // TODO consider better place for this check
AlternativeSignatureData alternativeSignatureData = AlternativeMethodSignatureData alternativeMethodSignatureData =
new AlternativeSignatureData(method, valueParameterDescriptors, returnType, methodTypeParameters); new AlternativeMethodSignatureData(method, valueParameterDescriptors, returnType, methodTypeParameters);
if (!alternativeSignatureData.isNone() && alternativeSignatureData.getError() == null) { if (alternativeMethodSignatureData.isAnnotated() && !alternativeMethodSignatureData.hasErrors()) {
valueParameterDescriptors = alternativeSignatureData.getValueParameters(); valueParameterDescriptors = alternativeMethodSignatureData.getValueParameters();
returnType = alternativeSignatureData.getReturnType(); returnType = alternativeMethodSignatureData.getReturnType();
methodTypeParameters = alternativeSignatureData.getTypeParameters(); methodTypeParameters = alternativeMethodSignatureData.getTypeParameters();
} }
else if (alternativeSignatureData.getError() != null) { else if (alternativeMethodSignatureData.hasErrors()) {
trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, functionDescriptorImpl, alternativeSignatureData.getError()); trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, functionDescriptorImpl, alternativeMethodSignatureData.getError());
} }
functionDescriptorImpl.initialize( functionDescriptorImpl.initialize(
@@ -0,0 +1,69 @@
/*
* Copyright 2010-2012 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.kotlinSignature;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiFieldWrapper;
import org.jetbrains.jet.lang.types.JetType;
import java.util.HashMap;
public class AlternativeFieldSignatureData extends ElementAlternativeSignatureData {
private final PsiFieldWrapper field;
private JetType altReturnType;
public AlternativeFieldSignatureData(@NotNull PsiFieldWrapper field, @NotNull JetType originalReturnType) {
String signature = field.getSignatureAnnotation().signature();
JetProperty altPropertyDeclaration;
if (signature.isEmpty()) {
setAnnotated(false);
this.field = null;
return;
}
setAnnotated(true);
this.field = field;
Project project = field.getPsiMember().getProject();
altPropertyDeclaration = JetPsiFactory.createProperty(project, signature);
try {
checkForSyntaxErrors(altPropertyDeclaration);
altReturnType = computeReturnType(originalReturnType, altPropertyDeclaration.getTypeRef(),
new HashMap<TypeParameterDescriptor, TypeParameterDescriptorImpl>());
}
catch (AlternativeSignatureMismatchException e) {
setError(e.getMessage());
}
}
@NotNull
public JetType getReturnType() {
checkForErrors();
return altReturnType;
}
@Override
public String getSignature() {
return field.getPsiField().getText();
}
}
@@ -14,43 +14,41 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.jet.lang.resolve.java; package org.jetbrains.jet.lang.resolve.java.kotlinSignature;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiErrorElement; import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.PsiSubstitutor; import com.intellij.psi.PsiSubstitutor;
import com.intellij.psi.PsiType; import com.intellij.psi.PsiType;
import com.intellij.util.Function; import com.intellij.util.Function;
import com.intellij.util.containers.ComparatorUtil; import com.intellij.util.containers.ComparatorUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptorImpl;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper; import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* @author Evgeny Gerashchenko * @author Evgeny Gerashchenko
* @since 6/5/12 * @since 6/5/12
*/ */
class AlternativeSignatureData { public class AlternativeMethodSignatureData extends ElementAlternativeSignatureData {
private final JetNamedFunction altFunDeclaration; private final JetNamedFunction altFunDeclaration;
private final PsiMethodWrapper method; private final PsiMethodWrapper method;
private final boolean none;
private String error;
private JavaDescriptorResolver.ValueParameterDescriptors altValueParameters; private JavaDescriptorResolver.ValueParameterDescriptors altValueParameters;
private JetType altReturnType; private JetType altReturnType;
private List<TypeParameterDescriptor> altTypeParameters; private List<TypeParameterDescriptor> altTypeParameters;
@@ -58,56 +56,49 @@ class AlternativeSignatureData {
private final Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> originalToAltTypeParameters = private final Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> originalToAltTypeParameters =
new HashMap<TypeParameterDescriptor, TypeParameterDescriptorImpl>(); new HashMap<TypeParameterDescriptor, TypeParameterDescriptorImpl>();
AlternativeSignatureData( public AlternativeMethodSignatureData(
@NotNull PsiMethodWrapper method, @NotNull PsiMethodWrapper method,
@NotNull JavaDescriptorResolver.ValueParameterDescriptors valueParameterDescriptors, @NotNull JavaDescriptorResolver.ValueParameterDescriptors valueParameterDescriptors,
@Nullable JetType returnType, @Nullable JetType originalReturnType,
@NotNull List<TypeParameterDescriptor> methodTypeParameters) { @NotNull List<TypeParameterDescriptor> methodTypeParameters
) {
String signature = method.getSignatureAnnotation().signature(); String signature = method.getSignatureAnnotation().signature();
if (signature.isEmpty()) { if (signature.isEmpty()) {
none = true; setAnnotated(false);
altFunDeclaration = null; altFunDeclaration = null;
this.method = null; this.method = null;
return; return;
} }
none = false; setAnnotated(true);
this.method = method; this.method = method;
Project project = method.getPsiMethod().getProject(); Project project = method.getPsiMethod().getProject();
altFunDeclaration = JetPsiFactory.createFunction(project, signature); altFunDeclaration = JetPsiFactory.createFunction(project, signature);
for (TypeParameterDescriptor tp : methodTypeParameters) { for (TypeParameterDescriptor typeParameter : methodTypeParameters) {
originalToAltTypeParameters.put(tp, TypeParameterDescriptorImpl originalToAltTypeParameters.put(typeParameter,
.createForFurtherModification(tp.getContainingDeclaration(), tp.getAnnotations(), TypeParameterDescriptorImpl.createForFurtherModification(
tp.isReified(), tp.getVariance(), tp.getName(), tp.getIndex())); typeParameter.getContainingDeclaration(),
typeParameter.getAnnotations(),
typeParameter.isReified(),
typeParameter.getVariance(),
typeParameter.getName(),
typeParameter.getIndex()));
} }
try { try {
checkForSyntaxErrors(); checkForSyntaxErrors(altFunDeclaration);
checkEqualFunctionNames(altFunDeclaration, method);
computeTypeParameters(methodTypeParameters); computeTypeParameters(methodTypeParameters);
computeValueParameters(valueParameterDescriptors); computeValueParameters(valueParameterDescriptors);
if (returnType != null) {
computeReturnType(returnType); if (originalReturnType != null) {
altReturnType = computeReturnType(originalReturnType, altFunDeclaration.getReturnTypeRef(), originalToAltTypeParameters);
} }
} }
catch (AlternativeSignatureMismatchException e) { catch (AlternativeSignatureMismatchException e) {
error = e.getMessage(); setError(e.getMessage());
}
}
public boolean isNone() {
return none;
}
@Nullable
public String getError() {
return error;
}
private void checkForErrors() {
if (none || error != null) {
throw new IllegalStateException("Trying to read result while there is none");
} }
} }
@@ -129,86 +120,85 @@ class AlternativeSignatureData {
return altTypeParameters; return altTypeParameters;
} }
private JetType computeType(JetTypeElement alternativeTypeElement, JetType autoType) {
//noinspection NullableProblems
return alternativeTypeElement.accept(new TypeTransformingVisitor(autoType), null);
}
private void computeReturnType(@NotNull JetType autoType) {
JetTypeReference altReturnTypeRef = altFunDeclaration.getReturnTypeRef();
if (altReturnTypeRef == null) {
if (JetStandardClasses.isUnit(autoType)) {
altReturnType = autoType;
}
else {
fail("Return type in alternative signature is missing, while in real signature it is '%s'",
DescriptorRenderer.TEXT.renderType(autoType));
}
}
else {
altReturnType = computeType(altReturnTypeRef.getTypeElement(), autoType);
}
}
private void computeValueParameters(JavaDescriptorResolver.ValueParameterDescriptors valueParameterDescriptors) { private void computeValueParameters(JavaDescriptorResolver.ValueParameterDescriptors valueParameterDescriptors) {
List<ValueParameterDescriptor> parameterDescriptors = valueParameterDescriptors.descriptors; List<ValueParameterDescriptor> parameterDescriptors = valueParameterDescriptors.getDescriptors();
if (parameterDescriptors.size() != altFunDeclaration.getValueParameters().size()) { if (parameterDescriptors.size() != altFunDeclaration.getValueParameters().size()) {
fail("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());
} }
List<ValueParameterDescriptor> altParamDescriptors = new ArrayList<ValueParameterDescriptor>(); List<ValueParameterDescriptor> altParamDescriptors = new ArrayList<ValueParameterDescriptor>();
for (int i = 0, size = parameterDescriptors.size(); i < size; i++) { for (int i = 0, size = parameterDescriptors.size(); i < size; i++) {
ValueParameterDescriptor pd = parameterDescriptors.get(i); ValueParameterDescriptor originalParameterDescriptor = parameterDescriptors.get(i);
JetParameter valueParameter = altFunDeclaration.getValueParameters().get(i); JetParameter annotationValueParameter = altFunDeclaration.getValueParameters().get(i);
//noinspection ConstantConditions //noinspection ConstantConditions
JetTypeElement alternativeTypeElement = valueParameter.getTypeReference().getTypeElement(); JetTypeElement alternativeTypeElement = annotationValueParameter.getTypeReference().getTypeElement();
assert alternativeTypeElement != null;
JetType alternativeType; JetType alternativeType;
JetType alternativeVarargElementType; JetType alternativeVarargElementType;
if (pd.getVarargElementType() == null) {
if (valueParameter.isVarArg()) { JetType originalParamVarargElementType = originalParameterDescriptor.getVarargElementType();
fail("Parameter in method signature is not vararg, but in alternative signature it is vararg"); if (originalParamVarargElementType == null) {
if (annotationValueParameter.isVarArg()) {
throw new AlternativeSignatureMismatchException("Parameter in method signature is not vararg, but in alternative signature it is vararg");
} }
alternativeType = computeType(alternativeTypeElement, pd.getType());
alternativeType = TypeTransformingVisitor.computeType(alternativeTypeElement, originalParameterDescriptor.getType(), originalToAltTypeParameters);
alternativeVarargElementType = null; alternativeVarargElementType = null;
} }
else { else {
if (!valueParameter.isVarArg()) { if (!annotationValueParameter.isVarArg()) {
fail("Parameter in method signature is vararg, but in alternative signature it is not"); throw new AlternativeSignatureMismatchException("Parameter in method signature is vararg, but in alternative signature it is not");
} }
alternativeVarargElementType = computeType(alternativeTypeElement, pd.getVarargElementType());
alternativeVarargElementType = TypeTransformingVisitor.computeType(alternativeTypeElement, originalParamVarargElementType,
originalToAltTypeParameters);
alternativeType = JetStandardLibrary.getInstance().getArrayType(alternativeVarargElementType); alternativeType = JetStandardLibrary.getInstance().getArrayType(alternativeVarargElementType);
} }
altParamDescriptors.add(new ValueParameterDescriptorImpl(pd.getContainingDeclaration(), pd.getIndex(), pd.getAnnotations(),
pd.getName(), pd.isVar(), alternativeType, pd.declaresDefaultValue(), altParamDescriptors.add(new ValueParameterDescriptorImpl(
alternativeVarargElementType)); originalParameterDescriptor.getContainingDeclaration(),
originalParameterDescriptor.getIndex(),
originalParameterDescriptor.getAnnotations(),
originalParameterDescriptor.getName(),
originalParameterDescriptor.isVar(),
alternativeType,
originalParameterDescriptor.declaresDefaultValue(),
alternativeVarargElementType));
} }
if (valueParameterDescriptors.receiverType != null) {
if (valueParameterDescriptors.getReceiverType() != null) {
throw new UnsupportedOperationException("Alternative annotations for extension functions are not supported yet"); throw new UnsupportedOperationException("Alternative annotations for extension functions are not supported yet");
} }
altValueParameters = new JavaDescriptorResolver.ValueParameterDescriptors(null, altParamDescriptors); altValueParameters = new JavaDescriptorResolver.ValueParameterDescriptors(null, altParamDescriptors);
} }
private void computeTypeParameters(List<TypeParameterDescriptor> typeParameters) { private void computeTypeParameters(List<TypeParameterDescriptor> typeParameters) {
if (typeParameters.size() != altFunDeclaration.getTypeParameters().size()) { if (typeParameters.size() != altFunDeclaration.getTypeParameters().size()) {
fail("Method signature has %d type parameters, but alternative signature has %d", throw new AlternativeSignatureMismatchException("Method signature has %d type parameters, but alternative signature has %d",
typeParameters.size(), altFunDeclaration.getTypeParameters().size()); typeParameters.size(), altFunDeclaration.getTypeParameters().size());
} }
altTypeParameters = new ArrayList<TypeParameterDescriptor>(); altTypeParameters = new ArrayList<TypeParameterDescriptor>();
for (int i = 0, size = typeParameters.size(); i < size; i++) { for (int i = 0, size = typeParameters.size(); i < size; i++) {
TypeParameterDescriptor pd = typeParameters.get(i); TypeParameterDescriptor originalTypeParamDescriptor = typeParameters.get(i);
TypeParameterDescriptorImpl altParamDescriptor = originalToAltTypeParameters.get(pd);
TypeParameterDescriptorImpl altParamDescriptor = originalToAltTypeParameters.get(originalTypeParamDescriptor);
JetTypeParameter altTypeParameter = altFunDeclaration.getTypeParameters().get(i);
int upperBoundIndex = 0; int upperBoundIndex = 0;
for (JetType upperBound : pd.getUpperBounds()) { for (JetType upperBound : originalTypeParamDescriptor.getUpperBounds()) {
JetTypeElement altTypeElement; JetTypeElement altTypeElement;
JetTypeParameter parameter = altFunDeclaration.getTypeParameters().get(i);
if (upperBoundIndex == 0) { if (upperBoundIndex == 0) {
JetTypeReference extendsBound = parameter.getExtendsBound(); JetTypeReference extendsBound = altTypeParameter.getExtendsBound();
if (extendsBound == null) { // default upper bound if (extendsBound == null) { // default upper bound
assert pd.getUpperBounds().size() == 1; assert originalTypeParamDescriptor.getUpperBounds().size() == 1;
altParamDescriptor.addDefaultUpperBound(); altParamDescriptor.addDefaultUpperBound();
break; break;
} }
@@ -218,18 +208,24 @@ class AlternativeSignatureData {
} }
else { else {
JetTypeConstraint constraint = JetTypeConstraint constraint =
findTypeParameterConstraint(altFunDeclaration, pd.getName(), upperBoundIndex); findTypeParameterConstraint(altFunDeclaration, originalTypeParamDescriptor.getName(), upperBoundIndex);
if (constraint == null) { if (constraint == null) {
fail("Upper bound #%d for type parameter %s is missing", upperBoundIndex, pd.getName()); throw new AlternativeSignatureMismatchException("Upper bound #%d for type parameter %s is missing",
upperBoundIndex, originalTypeParamDescriptor.getName());
} }
//noinspection ConstantConditions //noinspection ConstantConditions
altTypeElement = constraint.getBoundTypeReference().getTypeElement(); altTypeElement = constraint.getBoundTypeReference().getTypeElement();
} }
altParamDescriptor.addUpperBound(computeType(altTypeElement, upperBound));
assert (altTypeElement != null);
altParamDescriptor.addUpperBound(TypeTransformingVisitor.computeType(altTypeElement, upperBound,
originalToAltTypeParameters));
upperBoundIndex++; upperBoundIndex++;
} }
if (findTypeParameterConstraint(altFunDeclaration, pd.getName(), upperBoundIndex) != null) {
fail("Extra upper bound #%d for type parameter %s", upperBoundIndex, pd.getName()); if (findTypeParameterConstraint(altFunDeclaration, originalTypeParamDescriptor.getName(), upperBoundIndex) != null) {
throw new AlternativeSignatureMismatchException("Extra upper bound #%d for type parameter %s", upperBoundIndex, originalTypeParamDescriptor.getName());
} }
altParamDescriptor.setInitialized(); altParamDescriptor.setInitialized();
@@ -237,9 +233,21 @@ class AlternativeSignatureData {
} }
} }
@Override
public String getSignature() {
String paramsString = StringUtil.join(method.getPsiMethod().getSignature(PsiSubstitutor.EMPTY).getParameterTypes(),
new Function<PsiType, String>() {
@Override
public String fun(PsiType psiType) {
return psiType.getPresentableText();
}
}, ", ");
return String.format("%s(%s)", altFunDeclaration.getName(), paramsString);
}
@Nullable @Nullable
private static JetTypeConstraint findTypeParameterConstraint(@NotNull JetFunction function, @NotNull Name typeParameterName, private static JetTypeConstraint findTypeParameterConstraint(@NotNull JetFunction function, @NotNull Name typeParameterName, int index) {
int index) {
if (index != 0) { if (index != 0) {
int currentIndex = 0; int currentIndex = 0;
for (JetTypeConstraint constraint : function.getTypeConstraints()) { for (JetTypeConstraint constraint : function.getTypeConstraints()) {
@@ -256,184 +264,10 @@ class AlternativeSignatureData {
return null; return null;
} }
private void checkForSyntaxErrors() { private static void checkEqualFunctionNames(PsiNamedElement namedElement, PsiMethodWrapper method) {
List<PsiErrorElement> syntaxErrors = AnalyzingUtils.getSyntaxErrorRanges(altFunDeclaration); if (!ComparatorUtil.equalsNullable(method.getName(), namedElement.getName())) {
if (!syntaxErrors.isEmpty()) { throw new AlternativeSignatureMismatchException("Function names mismatch, original: %s, alternative: %s",
String textSignature = String.format("%s(%s)", method.getName(), method.getName(), namedElement.getName());
StringUtil.join(method.getPsiMethod().getSignature(PsiSubstitutor.EMPTY).getParameterTypes(),
new Function<PsiType, String>() {
@Override
public String fun(PsiType psiType) {
return psiType.getPresentableText();
}
}, ", "));
int errorOffset = syntaxErrors.get(0).getTextOffset();
String syntaxErrorDescription = syntaxErrors.get(0).getErrorDescription();
if (syntaxErrors.size() == 1) {
fail("Alternative signature for %s has syntax error at %d: %s",
textSignature, errorOffset, syntaxErrorDescription);
}
else {
fail("Alternative signature for %s has %d syntax errors, first is at %d: %s",
textSignature, syntaxErrors.size(), errorOffset, syntaxErrorDescription);
}
} }
if (!ComparatorUtil.equalsNullable(method.getName(), altFunDeclaration.getName())) {
fail("Function names mismatch, original: %s, alternative: %s", method.getName(), altFunDeclaration.getName());
}
}
private static void fail(String format, Object... params) {
throw new AlternativeSignatureMismatchException(String.format(format, params));
}
private static class AlternativeSignatureMismatchException extends RuntimeException {
private AlternativeSignatureMismatchException(String message) {
super(message);
}
}
private class TypeTransformingVisitor extends JetVisitor<JetType, Void> {
private final JetType autoType;
public TypeTransformingVisitor(JetType autoType) {
this.autoType = autoType;
}
@Override
public JetType visitNullableType(JetNullableType nullableType, Void data) {
if (!autoType.isNullable()) {
fail("Auto type '%s' is not-null, while type in alternative signature is nullable: '%s'",
DescriptorRenderer.TEXT.renderType(autoType), nullableType.getText());
}
return TypeUtils.makeNullable(computeType(nullableType.getInnerType(), autoType));
}
@Override
public JetType visitFunctionType(JetFunctionType type, Void data) {
return visitCommonType(type.getReceiverTypeRef() == null
? JetStandardClasses.getFunction(type.getParameters().size())
: JetStandardClasses.getReceiverFunction(type.getParameters().size()), type);
}
@Override
public JetType visitTupleType(JetTupleType type, Void data) {
return visitCommonType(JetStandardClasses.getTuple(type.getComponentTypeRefs().size()), type);
}
@Override
public JetType visitUserType(JetUserType type, Void data) {
JetUserType qualifier = type.getQualifier();
//noinspection ConstantConditions
String shortName = type.getReferenceExpression().getReferencedName();
String longName = (qualifier == null ? "" : qualifier.getText() + ".") + shortName;
if (JetStandardClasses.UNIT_ALIAS.getName().equals(longName)) {
return visitCommonType(JetStandardClasses.getTuple(0), type);
}
return visitCommonType(longName, type);
}
private JetType visitCommonType(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeElement type) {
return visitCommonType(DescriptorUtils.getFQName(classDescriptor).toSafe().getFqName(), type);
}
private JetType visitCommonType(@NotNull String qualifiedName, @NotNull JetTypeElement type) {
TypeConstructor originalTypeConstructor = autoType.getConstructor();
ClassifierDescriptor declarationDescriptor = originalTypeConstructor.getDeclarationDescriptor();
assert declarationDescriptor != null;
String fqName = DescriptorUtils.getFQName(declarationDescriptor).toSafe().getFqName();
ClassDescriptor classFromLibrary = getAutoTypeAnalogWithinBuiltins(qualifiedName);
if (!isSameName(qualifiedName, fqName) && classFromLibrary == null) {
fail("Alternative signature type mismatch, expected: %s, actual: %s", qualifiedName, fqName);
}
List<TypeProjection> arguments = autoType.getArguments();
if (arguments.size() != type.getTypeArgumentsAsTypes().size()) {
fail("'%s' type in method signature has %d type arguments, while '%s' in alternative signature has %d of them",
DescriptorRenderer.TEXT.renderType(autoType), arguments.size(), type.getText(),
type.getTypeArgumentsAsTypes().size());
}
List<TypeProjection> altArguments = new ArrayList<TypeProjection>();
for (int i = 0, size = arguments.size(); i < size; i++) {
JetTypeElement argumentAlternativeTypeElement = type.getTypeArgumentsAsTypes().get(i).getTypeElement();
TypeProjection argument = arguments.get(i);
JetType alternativeType =
computeType(argumentAlternativeTypeElement, argument.getType());
Variance variance = argument.getProjectionKind();
if (type instanceof JetUserType) {
JetTypeProjection typeProjection = ((JetUserType) type).getTypeArguments().get(i);
Variance altVariance = Variance.INVARIANT;
switch (typeProjection.getProjectionKind()) {
case IN:
altVariance = Variance.IN_VARIANCE;
break;
case OUT:
altVariance = Variance.OUT_VARIANCE;
break;
case STAR:
fail("Star projection is not available in alternative signatures");
default:
}
if (altVariance != variance && variance != Variance.INVARIANT) {
fail("Variance mismatch, actual: %s, in alternative signature: %s", variance, altVariance);
}
}
altArguments.add(new TypeProjection(variance, alternativeType));
}
TypeConstructor typeConstructor;
if (classFromLibrary != null) {
typeConstructor = classFromLibrary.getTypeConstructor();
}
else {
typeConstructor = originalTypeConstructor;
}
ClassifierDescriptor typeConstructorClassifier = typeConstructor.getDeclarationDescriptor();
if (typeConstructorClassifier instanceof TypeParameterDescriptor
&& originalToAltTypeParameters.containsKey(typeConstructorClassifier)) {
typeConstructor = originalToAltTypeParameters.get(typeConstructorClassifier).getTypeConstructor();
}
JetScope memberScope;
if (typeConstructorClassifier instanceof TypeParameterDescriptor) {
memberScope = ((TypeParameterDescriptor) typeConstructorClassifier).getUpperBoundsAsType().getMemberScope();
}
else if (typeConstructorClassifier instanceof ClassDescriptor) {
memberScope = ((ClassDescriptor) typeConstructorClassifier).getMemberScope(altArguments);
}
else {
throw new AssertionError("Unexpected class of type constructor classifier "
+ (typeConstructorClassifier == null ? "null" : typeConstructorClassifier.getClass().getName()));
}
return new JetTypeImpl(autoType.getAnnotations(), typeConstructor, false,
altArguments, memberScope);
}
@Nullable
private ClassDescriptor getAutoTypeAnalogWithinBuiltins(String qualifiedName) {
Type javaAnalog = KotlinToJavaTypesMap.getInstance().getJavaAnalog(autoType);
if (javaAnalog == null || javaAnalog.getSort() != Type.OBJECT) return null;
Collection<ClassDescriptor> descriptors =
JavaToKotlinClassMap.getInstance().mapPlatformClass(JvmClassName.byType(javaAnalog).getFqName());
for (ClassDescriptor descriptor : descriptors) {
String fqName = DescriptorUtils.getFQName(descriptor).getFqName();
if (isSameName(qualifiedName, fqName)) {
return descriptor;
}
}
return null;
}
@Override
public JetType visitSelfType(JetSelfType type, Void data) {
throw new UnsupportedOperationException("Self-types are not supported yet");
}
}
private static boolean isSameName(String qualifiedName, String fullyQualifiedName) {
return fullyQualifiedName.equals(qualifiedName) || fullyQualifiedName.endsWith("." + qualifiedName);
} }
} }
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2012 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.kotlinSignature;
class AlternativeSignatureMismatchException extends RuntimeException {
AlternativeSignatureMismatchException(String format, Object... params) {
this(String.format(format, params));
}
AlternativeSignatureMismatchException(String message) {
super(message);
}
}
@@ -0,0 +1,111 @@
/*
* Copyright 2010-2012 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.kotlinSignature;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiErrorElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.psi.JetTypeElement;
import org.jetbrains.jet.lang.psi.JetTypeReference;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.List;
import java.util.Map;
public abstract class ElementAlternativeSignatureData {
private String error;
private boolean isAnnotated;
public final boolean hasErrors() {
return error != null;
}
@NotNull
public final String getError() {
if (error == null) {
throw new IllegalStateException("There are no errors");
}
return error;
}
protected final void setError(@Nullable String error) {
this.error = error;
}
public boolean isAnnotated() {
return this.isAnnotated;
}
protected final void checkForErrors() {
if (!isAnnotated() || hasErrors()) {
throw new IllegalStateException("Trying to read result while there is none");
}
}
protected final void setAnnotated(boolean isAnnotated) {
this.isAnnotated = isAnnotated;
}
public abstract String getSignature();
protected void checkForSyntaxErrors(PsiElement namedElement) {
List<PsiErrorElement> syntaxErrors = AnalyzingUtils.getSyntaxErrorRanges(namedElement);
if (!syntaxErrors.isEmpty()) {
String textSignature = getSignature();
int errorOffset = syntaxErrors.get(0).getTextOffset();
String syntaxErrorDescription = syntaxErrors.get(0).getErrorDescription();
if (syntaxErrors.size() == 1) {
throw new AlternativeSignatureMismatchException("Alternative signature for %s has syntax error at %d: %s",
textSignature, errorOffset, syntaxErrorDescription);
}
else {
throw new AlternativeSignatureMismatchException("Alternative signature for %s has %d syntax errors, first is at %d: %s",
textSignature, syntaxErrors.size(), errorOffset, syntaxErrorDescription);
}
}
}
protected static JetType computeReturnType(
@NotNull JetType originalType,
@Nullable JetTypeReference altReturnTypeReference,
@NotNull Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> originalToAltTypeParameters) {
if (altReturnTypeReference == null) {
if (JetStandardClasses.isUnit(originalType)) {
return originalType;
}
else {
throw new AlternativeSignatureMismatchException(
"Return type in alternative signature is missing, while in real signature it is '%s'",
DescriptorRenderer.TEXT.renderType(originalType));
}
}
JetTypeElement typeElement = altReturnTypeReference.getTypeElement();
assert (typeElement != null);
return TypeTransformingVisitor.computeType(typeElement, originalType, originalToAltTypeParameters);
}
}
@@ -0,0 +1,197 @@
/*
* Copyright 2010-2012 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.kotlinSignature;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JavaToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.KotlinToJavaTypesMap;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.*;
class TypeTransformingVisitor extends JetVisitor<JetType, Void> {
private final JetType originalType;
private final Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> originalToAltTypeParameters;
private TypeTransformingVisitor(
JetType originalType,
Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> originalToAltTypeParameters
) {
this.originalType = originalType;
this.originalToAltTypeParameters = Collections.unmodifiableMap(originalToAltTypeParameters);
}
@NotNull
public static JetType computeType(
@NotNull JetTypeElement alternativeTypeElement,
@NotNull JetType originalType,
@NotNull Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> originalToAltTypeParameters
) {
JetType computedType = alternativeTypeElement.accept(new TypeTransformingVisitor(originalType, originalToAltTypeParameters), null);
assert (computedType != null);
return computedType;
}
@Override
public JetType visitNullableType(JetNullableType nullableType, Void aVoid) {
if (!originalType.isNullable()) {
throw new AlternativeSignatureMismatchException("Auto type '%s' is not-null, while type in alternative signature is nullable: '%s'",
DescriptorRenderer.TEXT.renderType(originalType), nullableType.getText());
}
return TypeUtils.makeNullable(computeType(nullableType.getInnerType(), originalType, originalToAltTypeParameters));
}
@Override
public JetType visitFunctionType(JetFunctionType type, Void data) {
return visitCommonType(type.getReceiverTypeRef() == null
? JetStandardClasses.getFunction(type.getParameters().size())
: JetStandardClasses.getReceiverFunction(type.getParameters().size()), type);
}
@Override
public JetType visitTupleType(JetTupleType type, Void data) {
return visitCommonType(JetStandardClasses.getTuple(type.getComponentTypeRefs().size()), type);
}
@Override
public JetType visitUserType(JetUserType type, Void data) {
JetUserType qualifier = type.getQualifier();
//noinspection ConstantConditions
String shortName = type.getReferenceExpression().getReferencedName();
String longName = (qualifier == null ? "" : qualifier.getText() + ".") + shortName;
if (JetStandardClasses.UNIT_ALIAS.getName().equals(longName)) {
return visitCommonType(JetStandardClasses.getTuple(0), type);
}
return visitCommonType(longName, type);
}
private JetType visitCommonType(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeElement type) {
return visitCommonType(DescriptorUtils.getFQName(classDescriptor).toSafe().getFqName(), type);
}
private JetType visitCommonType(@NotNull String qualifiedName, @NotNull JetTypeElement type) {
TypeConstructor originalTypeConstructor = originalType.getConstructor();
ClassifierDescriptor declarationDescriptor = originalTypeConstructor.getDeclarationDescriptor();
assert declarationDescriptor != null;
String fqName = DescriptorUtils.getFQName(declarationDescriptor).toSafe().getFqName();
ClassDescriptor classFromLibrary = getAutoTypeAnalogWithinBuiltins(qualifiedName);
if (!isSameName(qualifiedName, fqName) && classFromLibrary == null) {
throw new AlternativeSignatureMismatchException("Alternative signature type mismatch, expected: %s, actual: %s", qualifiedName, fqName);
}
List<TypeProjection> arguments = originalType.getArguments();
if (arguments.size() != type.getTypeArgumentsAsTypes().size()) {
throw new AlternativeSignatureMismatchException("'%s' type in method signature has %d type arguments, while '%s' in alternative signature has %d of them",
DescriptorRenderer.TEXT.renderType(originalType), arguments.size(), type.getText(),
type.getTypeArgumentsAsTypes().size());
}
List<TypeProjection> altArguments = new ArrayList<TypeProjection>();
for (int i = 0, size = arguments.size(); i < size; i++) {
JetTypeElement argumentAlternativeTypeElement = type.getTypeArgumentsAsTypes().get(i).getTypeElement();
assert argumentAlternativeTypeElement != null;
TypeProjection argument = arguments.get(i);
JetType alternativeType = computeType(argumentAlternativeTypeElement, argument.getType(), originalToAltTypeParameters);
Variance variance = argument.getProjectionKind();
if (type instanceof JetUserType) {
JetTypeProjection typeProjection = ((JetUserType) type).getTypeArguments().get(i);
Variance altVariance = Variance.INVARIANT;
switch (typeProjection.getProjectionKind()) {
case IN:
altVariance = Variance.IN_VARIANCE;
break;
case OUT:
altVariance = Variance.OUT_VARIANCE;
break;
case STAR:
throw new AlternativeSignatureMismatchException("Star projection is not available in alternative signatures");
default:
}
if (altVariance != variance && variance != Variance.INVARIANT) {
throw new AlternativeSignatureMismatchException("Variance mismatch, actual: %s, in alternative signature: %s", variance, altVariance);
}
}
altArguments.add(new TypeProjection(variance, alternativeType));
}
TypeConstructor typeConstructor;
if (classFromLibrary != null) {
typeConstructor = classFromLibrary.getTypeConstructor();
}
else {
typeConstructor = originalTypeConstructor;
}
ClassifierDescriptor typeConstructorClassifier = typeConstructor.getDeclarationDescriptor();
if (typeConstructorClassifier instanceof TypeParameterDescriptor && originalToAltTypeParameters.containsKey(typeConstructorClassifier)) {
typeConstructor = originalToAltTypeParameters.get(typeConstructorClassifier).getTypeConstructor();
}
JetScope memberScope;
if (typeConstructorClassifier instanceof TypeParameterDescriptor) {
memberScope = ((TypeParameterDescriptor) typeConstructorClassifier).getUpperBoundsAsType().getMemberScope();
}
else if (typeConstructorClassifier instanceof ClassDescriptor) {
memberScope = ((ClassDescriptor) typeConstructorClassifier).getMemberScope(altArguments);
}
else {
throw new AssertionError("Unexpected class of type constructor classifier "
+ (typeConstructorClassifier == null ? "null" : typeConstructorClassifier.getClass().getName()));
}
return new JetTypeImpl(originalType.getAnnotations(), typeConstructor, false,
altArguments, memberScope);
}
@Nullable
private ClassDescriptor getAutoTypeAnalogWithinBuiltins(String qualifiedName) {
Type javaAnalog = KotlinToJavaTypesMap.getInstance().getJavaAnalog(originalType);
if (javaAnalog == null || javaAnalog.getSort() != Type.OBJECT) return null;
Collection<ClassDescriptor> descriptors =
JavaToKotlinClassMap.getInstance().mapPlatformClass(JvmClassName.byType(javaAnalog).getFqName());
for (ClassDescriptor descriptor : descriptors) {
String fqName = DescriptorUtils.getFQName(descriptor).getFqName();
if (isSameName(qualifiedName, fqName)) {
return descriptor;
}
}
return null;
}
@Override
public JetType visitSelfType(JetSelfType type, Void data) {
throw new UnsupportedOperationException("Self-types are not supported yet");
}
private static boolean isSameName(String qualifiedName, String fullyQualifiedName) {
return fullyQualifiedName.equals(qualifiedName) || fullyQualifiedName.endsWith("." + qualifiedName);
}
}
@@ -20,6 +20,7 @@ import com.intellij.psi.PsiField;
import com.intellij.psi.PsiMember; import com.intellij.psi.PsiMember;
import com.intellij.psi.PsiType; import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.java.kt.KotlinSignatureAnnotation;
/** /**
* @author Stepan Koltsov * @author Stepan Koltsov
@@ -41,4 +42,13 @@ public class PsiFieldWrapper extends PsiMemberWrapper {
public boolean isAbstract() { public boolean isAbstract() {
return false; return false;
} }
private KotlinSignatureAnnotation signatureAnnotation;
@NotNull
public KotlinSignatureAnnotation getSignatureAnnotation() {
if (signatureAnnotation == null) {
signatureAnnotation = KotlinSignatureAnnotation.get(getPsiMember());
}
return signatureAnnotation;
}
} }
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2012 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 test;
import java.lang.String;
import java.util.ArrayList;
import jet.runtime.typeinfo.KotlinSignature;
public class PropertyArrayTypes<T> {
@KotlinSignature("fun PropertyArrayTypes(genericTypeParam : T)")
public PropertyArrayTypes(T genericTypeParam) {
// For initializing genericType field in kotlin
}
@KotlinSignature("var arrayOfArrays : Array<Array<String>>")
public String[][] arrayOfArrays;
@KotlinSignature("var array : Array<String>")
public String[] array;
@KotlinSignature("var genericArray : Array<T>")
public T[] genericArray;
}
@@ -0,0 +1,9 @@
package test
import java.util.*
public open class PropertyArrayTypes<T>(p0 : T) : java.lang.Object() {
public var arrayOfArrays : Array<Array<String>> = Array<Array<String>>(0, { Array<String>(0, { "" })})
public var array : Array<String> = Array<String>(0, { "" })
public var genericArray : Array<T> = Array<T>(0, { p0 })
}
@@ -0,0 +1,8 @@
namespace test
public open class test.PropertyArrayTypes</*0*/ T : jet.Any?> : java.lang.Object {
public final /*constructor*/ fun </*0*/ T : jet.Any?><init>(/*0*/ p0: T): test.PropertyArrayTypes<T>
public final var array: jet.Array<jet.String>
public final var arrayOfArrays: jet.Array<jet.Array<jet.String>>
public final var genericArray: jet.Array<T>
}
@@ -0,0 +1,41 @@
/*
* Copyright 2010-2012 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 test;
import java.lang.String;
import java.util.ArrayList;
import jet.runtime.typeinfo.KotlinSignature;
public class PropertyComplexTypes<T> {
@KotlinSignature("fun PropertyComplexTypes(genericTypeParam : T)")
public PropertyComplexTypes(T genericTypeParam) {
// For initializing genericType field in kotlin
}
@KotlinSignature("var genericType : T")
public T genericType;
@KotlinSignature("var listDefinedGeneric : ArrayList<String>")
public ArrayList<String> listDefinedGeneric;
@KotlinSignature("var listGeneric : ArrayList<T>")
public ArrayList<T> listGeneric;
@KotlinSignature("var listOfGenericList : ArrayList<ArrayList<T>>")
public ArrayList<ArrayList<T>> listOfGenericList;
}
@@ -0,0 +1,10 @@
package test
import java.util.*
public open class PropertyComplexTypes<T>(p0 : T) : java.lang.Object() {
public var genericType : T = p0
public var listDefinedGeneric : ArrayList<String> = ArrayList<String>()
public var listGeneric : ArrayList<T> = ArrayList<T>()
public var listOfGenericList : ArrayList<ArrayList<T>> = ArrayList<ArrayList<T>>()
}
@@ -0,0 +1,9 @@
namespace test
public open class test.PropertyComplexTypes</*0*/ T : jet.Any?> : java.lang.Object {
public final /*constructor*/ fun </*0*/ T : jet.Any?><init>(/*0*/ p0: T): test.PropertyComplexTypes<T>
public final var genericType: T
public final var listDefinedGeneric: java.util.ArrayList<jet.String>
public final var listGeneric: java.util.ArrayList<T>
public final var listOfGenericList: java.util.ArrayList<java.util.ArrayList<T>>
}
@@ -0,0 +1,34 @@
/*
* Copyright 2010-2012 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 test;
import java.lang.String;
import jet.runtime.typeinfo.KotlinSignature;
public class PropertySimpleType {
@KotlinSignature("val publicFieldVal : String")
public String publicFieldVal;
@KotlinSignature("var publicFieldVar : String?")
public String publicFieldVar;
@KotlinSignature("var protectedField : String")
protected String protectedField;
@KotlinSignature("var privateField : String")
private String privateField;
}
@@ -0,0 +1,9 @@
package test
import java.util.*
public open class PropertySimpleType : java.lang.Object() {
public var publicFieldVal : String = ""
public var publicFieldVar : String? = null
protected var protectedField : String = ""
}
@@ -0,0 +1,8 @@
namespace test
public open class test.PropertySimpleType : java.lang.Object {
public final /*constructor*/ fun <init>(): test.PropertySimpleType
protected final var protectedField: jet.String
public final var publicFieldVal: jet.String
public final var publicFieldVar: jet.String?
}
@@ -282,6 +282,21 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
doTest("compiler/testData/loadJava/kotlinSignature/MethodWithVararg.java"); doTest("compiler/testData/loadJava/kotlinSignature/MethodWithVararg.java");
} }
@TestMetadata("PropertyArrayTypes.java")
public void testPropertyArrayTypes() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.java");
}
@TestMetadata("PropertyComplexTypes.java")
public void testPropertyComplexTypes() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.java");
}
@TestMetadata("PropertySimpleType.java")
public void testPropertySimpleType() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/PropertySimpleType.java");
}
@TestMetadata("compiler/testData/loadJava/kotlinSignature/error") @TestMetadata("compiler/testData/loadJava/kotlinSignature/error")
public static class Error extends AbstractLoadJavaTest { public static class Error extends AbstractLoadJavaTest {
@TestMetadata("AddingNullability.java") @TestMetadata("AddingNullability.java")
@@ -327,7 +342,7 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
public void testWrongMethodName() throws Exception { public void testWrongMethodName() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/error/WrongMethodName.java"); doTest("compiler/testData/loadJava/kotlinSignature/error/WrongMethodName.java");
} }
@TestMetadata("WrongReturnTypeStructure.java") @TestMetadata("WrongReturnTypeStructure.java")
public void testWrongReturnTypeStructure() throws Exception { public void testWrongReturnTypeStructure() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/error/WrongReturnTypeStructure.java"); doTest("compiler/testData/loadJava/kotlinSignature/error/WrongReturnTypeStructure.java");
@@ -1167,6 +1167,21 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/MethodWithVararg.kt"); doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/MethodWithVararg.kt");
} }
@TestMetadata("PropertyArrayTypes.kt")
public void testPropertyArrayTypes() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.kt");
}
@TestMetadata("PropertyComplexTypes.kt")
public void testPropertyComplexTypes() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.kt");
}
@TestMetadata("PropertySimpleType.kt")
public void testPropertySimpleType() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/PropertySimpleType.kt");
}
@TestMetadata("compiler/testData/loadJava/kotlinSignature/error") @TestMetadata("compiler/testData/loadJava/kotlinSignature/error")
public static class Error extends AbstractLazyResolveNamespaceComparingTest { public static class Error extends AbstractLazyResolveNamespaceComparingTest {
@TestMetadata("AddingNullability.kt") @TestMetadata("AddingNullability.kt")