From 572173a8f822cf1f60aecbcb8160ac981a8e9bba Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 5 Oct 2012 14:46:59 +0400 Subject: [PATCH] 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 --- .../JavaDescriptorPropertiesResolver.java | 17 +- .../resolve/java/JavaDescriptorResolver.java | 43 +- .../AlternativeFieldSignatureData.java | 69 ++++ .../AlternativeMethodSignatureData.java | 384 +++++------------- ...AlternativeSignatureMismatchException.java | 27 ++ .../ElementAlternativeSignatureData.java | 111 +++++ .../TypeTransformingVisitor.java | 197 +++++++++ .../resolve/java/wrapper/PsiFieldWrapper.java | 10 + .../kotlinSignature/PropertyArrayTypes.java | 38 ++ .../kotlinSignature/PropertyArrayTypes.kt | 9 + .../kotlinSignature/PropertyArrayTypes.txt | 8 + .../kotlinSignature/PropertyComplexTypes.java | 41 ++ .../kotlinSignature/PropertyComplexTypes.kt | 10 + .../kotlinSignature/PropertyComplexTypes.txt | 9 + .../kotlinSignature/PropertySimpleType.java | 34 ++ .../kotlinSignature/PropertySimpleType.kt | 9 + .../kotlinSignature/PropertySimpleType.txt | 8 + .../jvm/compiler/LoadJavaTestGenerated.java | 17 +- ...esolveNamespaceComparingTestGenerated.java | 15 + 19 files changed, 763 insertions(+), 293 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeFieldSignatureData.java create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeSignatureMismatchException.java create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/ElementAlternativeSignatureData.java create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/TypeTransformingVisitor.java create mode 100644 compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.java create mode 100644 compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.kt create mode 100644 compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.txt create mode 100644 compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.java create mode 100644 compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.kt create mode 100644 compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.txt create mode 100644 compiler/testData/loadJava/kotlinSignature/PropertySimpleType.java create mode 100644 compiler/testData/loadJava/kotlinSignature/PropertySimpleType.kt create mode 100644 compiler/testData/loadJava/kotlinSignature/PropertySimpleType.txt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorPropertiesResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorPropertiesResolver.java index 20fc7b7659e..925baaf57a7 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorPropertiesResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorPropertiesResolver.java @@ -27,8 +27,10 @@ import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.OverrideResolver; 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.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.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; @@ -114,7 +116,6 @@ public final class JavaDescriptorPropertiesResolver { } DeclarationDescriptor realOwner = getRealOwner(owner, scopeData, characteristicMember.getMember().isStatic()); - boolean isEnumEntry = DescriptorUtils.isEnumClassObject(realOwner); boolean isPropertyForNamedObject = members.field != null && JvmAbi.INSTANCE_FIELD.equals(members.field.getMember().getName()); PropertyDescriptor propertyDescriptor = new PropertyDescriptor( @@ -182,6 +183,20 @@ public final class JavaDescriptorPropertiesResolver { JetType propertyType = getPropertyType(members, 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( propertyType, typeParameters, diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index f04aebf5c03..ff689c8148e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -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.descriptor.ClassDescriptorFromJvmBytecode; 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.JetClassAnnotation; import org.jetbrains.jet.lang.resolve.java.kt.PsiAnnotationWithFlags; @@ -428,13 +429,13 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes throw new IllegalStateException(); } - AlternativeSignatureData alternativeSignatureData = - new AlternativeSignatureData(constructor, valueParameterDescriptors, null, Collections.emptyList()); - if (!alternativeSignatureData.isNone() && alternativeSignatureData.getError() == null) { - valueParameterDescriptors = alternativeSignatureData.getValueParameters(); + AlternativeMethodSignatureData alternativeMethodSignatureData = + new AlternativeMethodSignatureData(constructor, valueParameterDescriptors, null, Collections.emptyList()); + if (alternativeMethodSignatureData.isAnnotated() && !alternativeMethodSignatureData.hasErrors()) { + valueParameterDescriptors = alternativeMethodSignatureData.getValueParameters(); } - else if (alternativeSignatureData.getError() != null) { - trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, constructorDescriptor, alternativeSignatureData.getError()); + else if (alternativeMethodSignatureData.hasErrors()) { + trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, constructorDescriptor, alternativeMethodSignatureData.getError()); } 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); } - static class ValueParameterDescriptors { + public static class ValueParameterDescriptors { final JetType receiverType; final List descriptors; - ValueParameterDescriptors(@Nullable JetType receiverType, List descriptors) { + public ValueParameterDescriptors(@Nullable JetType receiverType, @NotNull List descriptors) { this.receiverType = receiverType; this.descriptors = descriptors; } + + @Nullable + public JetType getReceiverType() { + return receiverType; + } + + @NotNull + public List getDescriptors() { + return descriptors; + } } private enum JvmMethodParameterKind { @@ -1120,15 +1131,15 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes JetType returnType = makeReturnType(returnPsiType, method, methodTypeVariableResolver); // TODO consider better place for this check - AlternativeSignatureData alternativeSignatureData = - new AlternativeSignatureData(method, valueParameterDescriptors, returnType, methodTypeParameters); - if (!alternativeSignatureData.isNone() && alternativeSignatureData.getError() == null) { - valueParameterDescriptors = alternativeSignatureData.getValueParameters(); - returnType = alternativeSignatureData.getReturnType(); - methodTypeParameters = alternativeSignatureData.getTypeParameters(); + AlternativeMethodSignatureData alternativeMethodSignatureData = + new AlternativeMethodSignatureData(method, valueParameterDescriptors, returnType, methodTypeParameters); + if (alternativeMethodSignatureData.isAnnotated() && !alternativeMethodSignatureData.hasErrors()) { + valueParameterDescriptors = alternativeMethodSignatureData.getValueParameters(); + returnType = alternativeMethodSignatureData.getReturnType(); + methodTypeParameters = alternativeMethodSignatureData.getTypeParameters(); } - else if (alternativeSignatureData.getError() != null) { - trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, functionDescriptorImpl, alternativeSignatureData.getError()); + else if (alternativeMethodSignatureData.hasErrors()) { + trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, functionDescriptorImpl, alternativeMethodSignatureData.getError()); } functionDescriptorImpl.initialize( diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeFieldSignatureData.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeFieldSignatureData.java new file mode 100644 index 00000000000..47802eb118a --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeFieldSignatureData.java @@ -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()); + } + catch (AlternativeSignatureMismatchException e) { + setError(e.getMessage()); + } + } + + @NotNull + public JetType getReturnType() { + checkForErrors(); + return altReturnType; + } + + @Override + public String getSignature() { + return field.getPsiField().getText(); + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeMethodSignatureData.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeMethodSignatureData.java index feb78585d63..676aca2a82c 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeMethodSignatureData.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeMethodSignatureData.java @@ -14,43 +14,41 @@ * 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.util.text.StringUtil; -import com.intellij.psi.PsiErrorElement; +import com.intellij.psi.PsiNamedElement; import com.intellij.psi.PsiSubstitutor; import com.intellij.psi.PsiType; import com.intellij.util.Function; import com.intellij.util.containers.ComparatorUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.asm4.Type; -import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; +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.resolve.AnalyzingUtils; -import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper; import org.jetbrains.jet.lang.resolve.name.Name; -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.lang.types.JetType; 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 * @since 6/5/12 */ -class AlternativeSignatureData { +public class AlternativeMethodSignatureData extends ElementAlternativeSignatureData { private final JetNamedFunction altFunDeclaration; private final PsiMethodWrapper method; - private final boolean none; - private String error; - private JavaDescriptorResolver.ValueParameterDescriptors altValueParameters; private JetType altReturnType; private List altTypeParameters; @@ -58,56 +56,49 @@ class AlternativeSignatureData { private final Map originalToAltTypeParameters = new HashMap(); - AlternativeSignatureData( + public AlternativeMethodSignatureData( @NotNull PsiMethodWrapper method, @NotNull JavaDescriptorResolver.ValueParameterDescriptors valueParameterDescriptors, - @Nullable JetType returnType, - @NotNull List methodTypeParameters) { + @Nullable JetType originalReturnType, + @NotNull List methodTypeParameters + ) { String signature = method.getSignatureAnnotation().signature(); if (signature.isEmpty()) { - none = true; + setAnnotated(false); altFunDeclaration = null; this.method = null; return; } - none = false; + setAnnotated(true); this.method = method; Project project = method.getPsiMethod().getProject(); altFunDeclaration = JetPsiFactory.createFunction(project, signature); - for (TypeParameterDescriptor tp : methodTypeParameters) { - originalToAltTypeParameters.put(tp, TypeParameterDescriptorImpl - .createForFurtherModification(tp.getContainingDeclaration(), tp.getAnnotations(), - tp.isReified(), tp.getVariance(), tp.getName(), tp.getIndex())); + for (TypeParameterDescriptor typeParameter : methodTypeParameters) { + originalToAltTypeParameters.put(typeParameter, + TypeParameterDescriptorImpl.createForFurtherModification( + typeParameter.getContainingDeclaration(), + typeParameter.getAnnotations(), + typeParameter.isReified(), + typeParameter.getVariance(), + typeParameter.getName(), + typeParameter.getIndex())); } try { - checkForSyntaxErrors(); + checkForSyntaxErrors(altFunDeclaration); + checkEqualFunctionNames(altFunDeclaration, method); computeTypeParameters(methodTypeParameters); computeValueParameters(valueParameterDescriptors); - if (returnType != null) { - computeReturnType(returnType); + + if (originalReturnType != null) { + altReturnType = computeReturnType(originalReturnType, altFunDeclaration.getReturnTypeRef(), originalToAltTypeParameters); } } catch (AlternativeSignatureMismatchException e) { - error = 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"); + setError(e.getMessage()); } } @@ -129,86 +120,85 @@ class AlternativeSignatureData { 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) { - List parameterDescriptors = valueParameterDescriptors.descriptors; + List parameterDescriptors = valueParameterDescriptors.getDescriptors(); if (parameterDescriptors.size() != altFunDeclaration.getValueParameters().size()) { - fail("Method signature has %d value parameters, but alternative signature has %d", - parameterDescriptors.size(), altFunDeclaration.getValueParameters().size()); + throw new AlternativeSignatureMismatchException("Method signature has %d value parameters, but alternative signature has %d", + parameterDescriptors.size(), altFunDeclaration.getValueParameters().size()); } List altParamDescriptors = new ArrayList(); for (int i = 0, size = parameterDescriptors.size(); i < size; i++) { - ValueParameterDescriptor pd = parameterDescriptors.get(i); - JetParameter valueParameter = altFunDeclaration.getValueParameters().get(i); + ValueParameterDescriptor originalParameterDescriptor = parameterDescriptors.get(i); + JetParameter annotationValueParameter = altFunDeclaration.getValueParameters().get(i); + //noinspection ConstantConditions - JetTypeElement alternativeTypeElement = valueParameter.getTypeReference().getTypeElement(); + JetTypeElement alternativeTypeElement = annotationValueParameter.getTypeReference().getTypeElement(); + assert alternativeTypeElement != null; + JetType alternativeType; JetType alternativeVarargElementType; - if (pd.getVarargElementType() == null) { - if (valueParameter.isVarArg()) { - fail("Parameter in method signature is not vararg, but in alternative signature it is vararg"); + + JetType originalParamVarargElementType = originalParameterDescriptor.getVarargElementType(); + 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; } else { - if (!valueParameter.isVarArg()) { - fail("Parameter in method signature is vararg, but in alternative signature it is not"); + if (!annotationValueParameter.isVarArg()) { + 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); } - altParamDescriptors.add(new ValueParameterDescriptorImpl(pd.getContainingDeclaration(), pd.getIndex(), pd.getAnnotations(), - pd.getName(), pd.isVar(), alternativeType, pd.declaresDefaultValue(), - alternativeVarargElementType)); + + altParamDescriptors.add(new ValueParameterDescriptorImpl( + 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"); } + altValueParameters = new JavaDescriptorResolver.ValueParameterDescriptors(null, altParamDescriptors); } private void computeTypeParameters(List typeParameters) { - if (typeParameters.size() != altFunDeclaration.getTypeParameters().size()) { - fail("Method signature has %d type parameters, but alternative signature has %d", - typeParameters.size(), altFunDeclaration.getTypeParameters().size()); + throw new AlternativeSignatureMismatchException("Method signature has %d type parameters, but alternative signature has %d", + typeParameters.size(), altFunDeclaration.getTypeParameters().size()); } altTypeParameters = new ArrayList(); + for (int i = 0, size = typeParameters.size(); i < size; i++) { - TypeParameterDescriptor pd = typeParameters.get(i); - TypeParameterDescriptorImpl altParamDescriptor = originalToAltTypeParameters.get(pd); + TypeParameterDescriptor originalTypeParamDescriptor = typeParameters.get(i); + + TypeParameterDescriptorImpl altParamDescriptor = originalToAltTypeParameters.get(originalTypeParamDescriptor); + JetTypeParameter altTypeParameter = altFunDeclaration.getTypeParameters().get(i); + int upperBoundIndex = 0; - for (JetType upperBound : pd.getUpperBounds()) { + for (JetType upperBound : originalTypeParamDescriptor.getUpperBounds()) { JetTypeElement altTypeElement; - JetTypeParameter parameter = altFunDeclaration.getTypeParameters().get(i); + if (upperBoundIndex == 0) { - JetTypeReference extendsBound = parameter.getExtendsBound(); + JetTypeReference extendsBound = altTypeParameter.getExtendsBound(); if (extendsBound == null) { // default upper bound - assert pd.getUpperBounds().size() == 1; + assert originalTypeParamDescriptor.getUpperBounds().size() == 1; altParamDescriptor.addDefaultUpperBound(); break; } @@ -218,18 +208,24 @@ class AlternativeSignatureData { } else { JetTypeConstraint constraint = - findTypeParameterConstraint(altFunDeclaration, pd.getName(), upperBoundIndex); + findTypeParameterConstraint(altFunDeclaration, originalTypeParamDescriptor.getName(), upperBoundIndex); 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 altTypeElement = constraint.getBoundTypeReference().getTypeElement(); } - altParamDescriptor.addUpperBound(computeType(altTypeElement, upperBound)); + + assert (altTypeElement != null); + + altParamDescriptor.addUpperBound(TypeTransformingVisitor.computeType(altTypeElement, upperBound, + originalToAltTypeParameters)); 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(); @@ -237,9 +233,21 @@ class AlternativeSignatureData { } } + @Override + public String getSignature() { + String paramsString = StringUtil.join(method.getPsiMethod().getSignature(PsiSubstitutor.EMPTY).getParameterTypes(), + new Function() { + @Override + public String fun(PsiType psiType) { + return psiType.getPresentableText(); + } + }, ", "); + + return String.format("%s(%s)", altFunDeclaration.getName(), paramsString); + } + @Nullable - private static JetTypeConstraint findTypeParameterConstraint(@NotNull JetFunction function, @NotNull Name typeParameterName, - int index) { + private static JetTypeConstraint findTypeParameterConstraint(@NotNull JetFunction function, @NotNull Name typeParameterName, int index) { if (index != 0) { int currentIndex = 0; for (JetTypeConstraint constraint : function.getTypeConstraints()) { @@ -256,184 +264,10 @@ class AlternativeSignatureData { return null; } - private void checkForSyntaxErrors() { - List syntaxErrors = AnalyzingUtils.getSyntaxErrorRanges(altFunDeclaration); - if (!syntaxErrors.isEmpty()) { - String textSignature = String.format("%s(%s)", method.getName(), - StringUtil.join(method.getPsiMethod().getSignature(PsiSubstitutor.EMPTY).getParameterTypes(), - new Function() { - @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); - } + private static void checkEqualFunctionNames(PsiNamedElement namedElement, PsiMethodWrapper method) { + if (!ComparatorUtil.equalsNullable(method.getName(), namedElement.getName())) { + throw new AlternativeSignatureMismatchException("Function names mismatch, original: %s, alternative: %s", + method.getName(), namedElement.getName()); } - - 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 { - 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 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 altArguments = new ArrayList(); - 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 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); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeSignatureMismatchException.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeSignatureMismatchException.java new file mode 100644 index 00000000000..2e0bf892a36 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeSignatureMismatchException.java @@ -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); + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/ElementAlternativeSignatureData.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/ElementAlternativeSignatureData.java new file mode 100644 index 00000000000..af975546ac2 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/ElementAlternativeSignatureData.java @@ -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 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 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); + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/TypeTransformingVisitor.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/TypeTransformingVisitor.java new file mode 100644 index 00000000000..e46cb928d94 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/TypeTransformingVisitor.java @@ -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 { + private final JetType originalType; + private final Map originalToAltTypeParameters; + + private TypeTransformingVisitor( + JetType originalType, + Map originalToAltTypeParameters + ) { + this.originalType = originalType; + this.originalToAltTypeParameters = Collections.unmodifiableMap(originalToAltTypeParameters); + } + + @NotNull + public static JetType computeType( + @NotNull JetTypeElement alternativeTypeElement, + @NotNull JetType originalType, + @NotNull Map 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 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 altArguments = new ArrayList(); + 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 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); + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/wrapper/PsiFieldWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/wrapper/PsiFieldWrapper.java index ff1be322e84..33427fac480 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/wrapper/PsiFieldWrapper.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/wrapper/PsiFieldWrapper.java @@ -20,6 +20,7 @@ import com.intellij.psi.PsiField; import com.intellij.psi.PsiMember; import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.java.kt.KotlinSignatureAnnotation; /** * @author Stepan Koltsov @@ -41,4 +42,13 @@ public class PsiFieldWrapper extends PsiMemberWrapper { public boolean isAbstract() { return false; } + + private KotlinSignatureAnnotation signatureAnnotation; + @NotNull + public KotlinSignatureAnnotation getSignatureAnnotation() { + if (signatureAnnotation == null) { + signatureAnnotation = KotlinSignatureAnnotation.get(getPsiMember()); + } + return signatureAnnotation; + } } diff --git a/compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.java b/compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.java new file mode 100644 index 00000000000..91714789fa3 --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.java @@ -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 { + @KotlinSignature("fun PropertyArrayTypes(genericTypeParam : T)") + public PropertyArrayTypes(T genericTypeParam) { + // For initializing genericType field in kotlin + } + + @KotlinSignature("var arrayOfArrays : Array>") + public String[][] arrayOfArrays; + + @KotlinSignature("var array : Array") + public String[] array; + + @KotlinSignature("var genericArray : Array") + public T[] genericArray; +} diff --git a/compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.kt b/compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.kt new file mode 100644 index 00000000000..2a8baa3897b --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.kt @@ -0,0 +1,9 @@ +package test + +import java.util.* + +public open class PropertyArrayTypes(p0 : T) : java.lang.Object() { + public var arrayOfArrays : Array> = Array>(0, { Array(0, { "" })}) + public var array : Array = Array(0, { "" }) + public var genericArray : Array = Array(0, { p0 }) +} diff --git a/compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.txt b/compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.txt new file mode 100644 index 00000000000..42bf7d809dc --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/PropertyArrayTypes.txt @@ -0,0 +1,8 @@ +namespace test + +public open class test.PropertyArrayTypes : java.lang.Object { + public final /*constructor*/ fun (/*0*/ p0: T): test.PropertyArrayTypes + public final var array: jet.Array + public final var arrayOfArrays: jet.Array> + public final var genericArray: jet.Array +} diff --git a/compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.java b/compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.java new file mode 100644 index 00000000000..472fd8ade9e --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.java @@ -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 { + @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") + public ArrayList listDefinedGeneric; + + @KotlinSignature("var listGeneric : ArrayList") + public ArrayList listGeneric; + + @KotlinSignature("var listOfGenericList : ArrayList>") + public ArrayList> listOfGenericList; +} diff --git a/compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.kt b/compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.kt new file mode 100644 index 00000000000..f7f5d8dd4a2 --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.kt @@ -0,0 +1,10 @@ +package test + +import java.util.* + +public open class PropertyComplexTypes(p0 : T) : java.lang.Object() { + public var genericType : T = p0 + public var listDefinedGeneric : ArrayList = ArrayList() + public var listGeneric : ArrayList = ArrayList() + public var listOfGenericList : ArrayList> = ArrayList>() +} diff --git a/compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.txt b/compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.txt new file mode 100644 index 00000000000..edcfab88bdd --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/PropertyComplexTypes.txt @@ -0,0 +1,9 @@ +namespace test + +public open class test.PropertyComplexTypes : java.lang.Object { + public final /*constructor*/ fun (/*0*/ p0: T): test.PropertyComplexTypes + public final var genericType: T + public final var listDefinedGeneric: java.util.ArrayList + public final var listGeneric: java.util.ArrayList + public final var listOfGenericList: java.util.ArrayList> +} diff --git a/compiler/testData/loadJava/kotlinSignature/PropertySimpleType.java b/compiler/testData/loadJava/kotlinSignature/PropertySimpleType.java new file mode 100644 index 00000000000..ff819edf2fd --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/PropertySimpleType.java @@ -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; +} diff --git a/compiler/testData/loadJava/kotlinSignature/PropertySimpleType.kt b/compiler/testData/loadJava/kotlinSignature/PropertySimpleType.kt new file mode 100644 index 00000000000..9b83868f41b --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/PropertySimpleType.kt @@ -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 = "" +} diff --git a/compiler/testData/loadJava/kotlinSignature/PropertySimpleType.txt b/compiler/testData/loadJava/kotlinSignature/PropertySimpleType.txt new file mode 100644 index 00000000000..906914c0aa7 --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/PropertySimpleType.txt @@ -0,0 +1,8 @@ +namespace test + +public open class test.PropertySimpleType : java.lang.Object { + public final /*constructor*/ fun (): test.PropertySimpleType + protected final var protectedField: jet.String + public final var publicFieldVal: jet.String + public final var publicFieldVar: jet.String? +} diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java index 0793d47884d..be67df0a048 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java @@ -282,6 +282,21 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { 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") public static class Error extends AbstractLoadJavaTest { @TestMetadata("AddingNullability.java") @@ -327,7 +342,7 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { public void testWrongMethodName() throws Exception { doTest("compiler/testData/loadJava/kotlinSignature/error/WrongMethodName.java"); } - + @TestMetadata("WrongReturnTypeStructure.java") public void testWrongReturnTypeStructure() throws Exception { doTest("compiler/testData/loadJava/kotlinSignature/error/WrongReturnTypeStructure.java"); diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java index da3f892d7b3..77694f100c4 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java @@ -1167,6 +1167,21 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso 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") public static class Error extends AbstractLazyResolveNamespaceComparingTest { @TestMetadata("AddingNullability.kt")