From a8137d1a56d3b0a480ac22e3fa11efd9f10b34f6 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Fri, 13 Jan 2012 03:55:11 +0400 Subject: [PATCH] fix another case of property resolution, refactoring --- .../jet/codegen/FunctionCodegen.java | 2 +- .../codegen/ImplementationBodyCodegen.java | 4 +- .../jetbrains/jet/codegen/JetTypeMapper.java | 14 +- .../jet/codegen/PropertyCodegen.java | 9 +- .../resolve/java/JavaDescriptorResolver.java | 199 ++++++++++++------ .../jet/lang/resolve/java/JvmStdlibNames.java | 1 + .../lang/resolve/java/PsiFieldWrapper.java | 13 ++ .../lang/resolve/java/PsiMemberWrapper.java | 27 +++ .../lang/resolve/java/PsiMethodWrapper.java | 37 ++-- .../resolve/java/kt/JetMethodAnnotation.java | 11 +- .../kt/JetMethodOrPropertyAnnotation.java | 25 +++ .../java/kt/JetPropertyAnnotation.java | 2 +- .../testData/readClass/prop/ExtVarMapPQInt.kt | 7 + .../src/jet/runtime/typeinfo/JetProperty.java | 2 + 14 files changed, 243 insertions(+), 110 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiFieldWrapper.java create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMemberWrapper.java create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodOrPropertyAnnotation.java create mode 100644 compiler/testData/readClass/prop/ExtVarMapPQInt.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 8db55f9de7c..d043a239822 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -94,7 +94,7 @@ public class FunctionCodegen { int start = 0; if(kind != OwnerKind.TRAIT_IMPL) { if (functionDescriptor instanceof PropertyAccessorDescriptor) { - PropertyCodegen.generateJetPropertyAnnotation(mv, propertyTypeSignature); + PropertyCodegen.generateJetPropertyAnnotation(mv, propertyTypeSignature, jvmSignature.getKotlinTypeParameter()); } else if (functionDescriptor instanceof NamedFunctionDescriptor) { if (propertyTypeSignature != null) { throw new IllegalStateException(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 336064107e7..fbbb9cf5279 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -243,7 +243,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JvmPropertyAccessorSignature originalSignature = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION); Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod(); MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null); - PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature()); + PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(), originalSignature.getJvmMethodSignature().getKotlinTypeParameter()); mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true).visitEnd(); if (v.generateCode()) { mv.visitCode(); @@ -267,7 +267,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JvmPropertyAccessorSignature originalSignature2 = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION); Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod(); MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null); - PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature()); + PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(), originalSignature2.getJvmMethodSignature().getKotlinTypeParameter()); mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true).visitEnd(); if (v.generateCode()) { mv.visitCode(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index ce69e28e85c..0837a30cc0b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -519,9 +519,8 @@ public class JetTypeMapper { BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false); - signatureWriter.writeFormalTypeParametersStart(); - signatureWriter.writeFormalTypeParametersEnd(); - + writeFormalTypeParameters(f.getTypeParameters(), signatureWriter); + signatureWriter.writeParametersStart(); final List parameters = f.getValueParameters(); @@ -552,8 +551,7 @@ public class JetTypeMapper { // TODO: do not generate generics if not needed BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, true); - signatureWriter.writeFormalTypeParametersStart(); - signatureWriter.writeFormalTypeParametersEnd(); + writeFormalTypeParameters(descriptor.getTypeParameters(), signatureWriter); signatureWriter.writeParametersStart(); @@ -597,8 +595,7 @@ public class JetTypeMapper { // TODO: generics signature is not always needed BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, true); - signatureWriter.writeFormalTypeParametersStart(); - signatureWriter.writeFormalTypeParametersEnd(); + writeFormalTypeParameters(descriptor.getTypeParameters(), signatureWriter); JetType outType = descriptor.getOutType(); @@ -644,8 +641,7 @@ public class JetTypeMapper { List parameters = descriptor.getOriginal().getValueParameters(); ClassDescriptor classDescriptor = descriptor.getContainingDeclaration(); - signatureWriter.writeFormalTypeParametersStart(); - signatureWriter.writeFormalTypeParametersEnd(); + writeFormalTypeParameters(descriptor.getTypeParameters(), signatureWriter); signatureWriter.writeParametersStart(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index d08e6690f71..8ae216a3055 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -146,7 +146,7 @@ public class PropertyCodegen { final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor(); String getterName = getterName(propertyDescriptor.getName()); MethodVisitor mv = v.newMethod(origin, flags, getterName, descriptor, null, null); - generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature()); + generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(), signature.getJvmMethodSignature().getKotlinTypeParameter()); if (v.generateCode() && (!isTrait || kind instanceof OwnerKind.DelegateKind)) { mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); @@ -169,11 +169,14 @@ public class PropertyCodegen { } } - public static void generateJetPropertyAnnotation(MethodVisitor mv, @NotNull String kotlinType) { + public static void generateJetPropertyAnnotation(MethodVisitor mv, @NotNull String kotlinType, @NotNull String typeParameters) { AnnotationVisitor annotationVisitor = mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true); if (kotlinType.length() > 0) { annotationVisitor.visit(JvmStdlibNames.JET_PROPERTY_TYPE_FIELD, kotlinType); } + if (typeParameters.length() > 0) { + annotationVisitor.visit(JvmStdlibNames.JET_PROPERTY_TYPE_PARAMETERS_FIELD, typeParameters); + } annotationVisitor.visitEnd(); } @@ -200,7 +203,7 @@ public class PropertyCodegen { JvmPropertyAccessorSignature signature = state.getTypeMapper().mapSetterSignature(propertyDescriptor, kind); final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor(); MethodVisitor mv = v.newMethod(origin, flags, setterName(propertyDescriptor.getName()), descriptor, null, null); - generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature()); + generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(), signature.getJvmMethodSignature().getKotlinTypeParameter()); if (v.generateCode() && (!isTrait || kind instanceof OwnerKind.DelegateKind)) { mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); 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 77e3be0c6f5..16dcc83c13a 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 @@ -14,7 +14,6 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiEllipsisType; import com.intellij.psi.PsiField; import com.intellij.psi.PsiJavaFile; -import com.intellij.psi.PsiMember; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiModifierListOwner; @@ -34,11 +33,12 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorImpl; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptorImpl; import org.jetbrains.jet.lang.descriptors.Modality; import org.jetbrains.jet.lang.descriptors.NamedFunctionDescriptorImpl; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptorImpl; @@ -48,7 +48,6 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; -import org.jetbrains.jet.lang.resolve.java.kt.JetMethodAnnotation; import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeConstructorImpl; @@ -160,7 +159,7 @@ public class JavaDescriptorResolver { protected final Map namespaceDescriptorCacheByFqn = Maps.newHashMap(); protected final Map namespaceDescriptorCache = Maps.newHashMap(); - protected final Map typeParameterDescriptorCache = Maps.newHashMap(); + private final Map typeParameterDescriptorCache = Maps.newHashMap(); protected final Map methodDescriptorCache = Maps.newHashMap(); protected final Map fieldDescriptorCache = Maps.newHashMap(); protected final JavaPsiFacade javaFacade; @@ -806,15 +805,15 @@ public class JavaDescriptorResolver { private static class PropertyKey { @NotNull private final String name; - @NotNull - private final PsiType type; - @Nullable - private final PsiType receiverType; + //@NotNull + //private final PsiType type; + //@Nullable + //private final PsiType receiverType; - private PropertyKey(@NotNull String name, @NotNull PsiType type, @Nullable PsiType receiverType) { + private PropertyKey(@NotNull String name /*, @NotNull PsiType type, @Nullable PsiType receiverType */) { this.name = name; - this.type = type; - this.receiverType = receiverType; + //this.type = type; + //this.receiverType = receiverType; } @Override @@ -825,9 +824,9 @@ public class JavaDescriptorResolver { PropertyKey that = (PropertyKey) o; if (!name.equals(that.name)) return false; - if (receiverType != null ? !receiverType.equals(that.receiverType) : that.receiverType != null) - return false; - if (!type.equals(that.type)) return false; + //if (receiverType != null ? !receiverType.equals(that.receiverType) : that.receiverType != null) + // return false; + //if (!type.equals(that.type)) return false; return true; } @@ -835,16 +834,19 @@ public class JavaDescriptorResolver { @Override public int hashCode() { int result = name.hashCode(); - result = 31 * result + type.hashCode(); - result = 31 * result + (receiverType != null ? receiverType.hashCode() : 0); + //result = 31 * result + type.hashCode(); + //result = 31 * result + (receiverType != null ? receiverType.hashCode() : 0); return result; } } private static class MembersForProperty { - private PsiField field; - private PsiMethod setter; - private PsiMethod getter; + private PsiFieldWrapper field; + private PsiMethodWrapper setter; + private PsiMethodWrapper getter; + + private PsiType type; + private PsiType receiverType; } private Map getMembersForProperties(@NotNull PsiClass clazz, boolean staticMembers, boolean kotlin) { @@ -860,8 +862,9 @@ public class JavaDescriptorResolver { } MembersForProperty members = new MembersForProperty(); - members.field = field; - membersMap.put(new PropertyKey(field.getName(), field.getType(), null), members); + members.field = new PsiFieldWrapper(field); + members.type = field.getType(); + membersMap.put(new PropertyKey(field.getName() /*, field.getType(), null*/), members); } } @@ -882,41 +885,49 @@ public class JavaDescriptorResolver { // TODO: some java properties too if (method.getJetProperty().isDefined()) { - PsiType receiverType; - if (method.getParameters().size() == 0) { - receiverType = null; - } else if (method.getParameters().size() == 1) { - if (method.getParameter(0).getJetTypeParameter().isDefined()) { - receiverType = null; - } else { - receiverType = method.getParameter(0).getPsiParameter().getType(); - } - } else if (method.getParameters().size() == 2) { - if (!method.getParameter(1).getJetTypeParameter().isDefined()) { - throw new IllegalStateException(); - } - receiverType = psiMethod.getParameterList().getParameters()[0].getType(); - } else { - throw new IllegalStateException(); - } - + if (psiMethod.getName().equals(JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD)) { continue; } + int i = 0; + + PsiType receiverType; + if (i < method.getParameters().size() && method.getParameter(i).getJetValueParameter().receiver()) { + receiverType = method.getParameter(i).getPsiParameter().getType(); + ++i; + } else { + receiverType = null; + } + + while (i < method.getParameters().size() && method.getParameter(i).getJetTypeParameter().isDefined()) { + // TODO: store is reified + ++i; + } + + if (i != method.getParameters().size()) { + // TODO: report error properly + throw new IllegalStateException(); + } + String propertyName = StringUtil.decapitalize(psiMethod.getName().substring(JvmAbi.GETTER_PREFIX.length())); - PropertyKey key = new PropertyKey(propertyName, psiMethod.getReturnType(), receiverType); + PropertyKey key = new PropertyKey(propertyName /*, psiMethod.getReturnType(), receiverType*/); MembersForProperty members = membersMap.get(key); if (members == null) { members = new MembersForProperty(); membersMap.put(key, members); } - members.getter = psiMethod; + members.getter = new PsiMethodWrapper(psiMethod); + + // TODO: check conflicts with setter + members.type = psiMethod.getReturnType(); + members.receiverType = receiverType; } } else if (psiMethod.getName().startsWith(JvmAbi.SETTER_PREFIX)) { if (method.getJetProperty().isDefined()) { if (psiMethod.getParameterList().getParametersCount() == 0) { + // TODO: report error properly throw new IllegalStateException(); } @@ -940,13 +951,17 @@ public class JavaDescriptorResolver { PsiType propertyType = psiMethod.getParameterList().getParameters()[i].getType(); String propertyName = StringUtil.decapitalize(psiMethod.getName().substring(JvmAbi.SETTER_PREFIX.length())); - PropertyKey key = new PropertyKey(propertyName, propertyType, receiverType); + PropertyKey key = new PropertyKey(propertyName /*, propertyType, receiverType*/); MembersForProperty members = membersMap.get(key); if (members == null) { members = new MembersForProperty(); membersMap.put(key, members); } - members.setter = psiMethod; + members.setter = new PsiMethodWrapper(psiMethod); + + // TODO: check conflicts with getter + members.type = propertyType; + members.receiverType = receiverType; } } } @@ -986,29 +1001,30 @@ public class JavaDescriptorResolver { } Set descriptors = Sets.newHashSet(); - for (Map.Entry entry : getMembersForProperties(psiClass, staticMembers, scopeData.kotlin).entrySet()) { + Map membersForProperties = getMembersForProperties(psiClass, staticMembers, scopeData.kotlin); + for (Map.Entry entry : membersForProperties.entrySet()) { //VariableDescriptor variableDescriptor = fieldDescriptorCache.get(field); //if (variableDescriptor != null) { // return variableDescriptor; //} String propertyName = entry.getKey().name; - PsiType propertyType = entry.getKey().type; - PsiType receiverType = entry.getKey().receiverType; + PsiType propertyType = entry.getValue().type; + PsiType receiverType = entry.getValue().receiverType; MembersForProperty members = entry.getValue(); JetType type = semanticServices.getTypeTransformer().transformToType(propertyType); boolean isFinal; if (members.setter == null && members.getter == null) { - isFinal = members.field.hasModifierProperty(PsiModifier.FINAL); + isFinal = false; } else if (members.getter != null) { - isFinal = members.getter.hasModifierProperty(PsiModifier.FINAL); + isFinal = members.getter.isFinal(); } else if (members.setter != null) { - isFinal = members.setter.hasModifierProperty(PsiModifier.FINAL); + isFinal = members.setter.isFinal(); } else { isFinal = false; } - PsiMember anyMember; + PsiMemberWrapper anyMember; if (members.getter != null) { anyMember = members.getter; } else if (members.field != null) { @@ -1026,25 +1042,66 @@ public class JavaDescriptorResolver { isVar = members.setter != null; } + PropertyDescriptor propertyDescriptor = new PropertyDescriptor( + owner, + Collections.emptyList(), + isFinal && !staticMembers ? Modality.FINAL : Modality.OPEN, // TODO: abstract + resolveVisibilityFromPsiModifiers(anyMember.psiMember), + isVar, + false, + propertyName); + + PropertyGetterDescriptor getterDescriptor = null; + PropertySetterDescriptor setterDescriptor = null; + if (members.getter != null) { + getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, Collections.emptyList(), Modality.OPEN, Visibility.PUBLIC, true, false); + } + if (members.setter != null) { + setterDescriptor = new PropertySetterDescriptor(propertyDescriptor, Collections.emptyList(), Modality.OPEN, Visibility.PUBLIC, true, false); + } + + propertyDescriptor.initialize(getterDescriptor, setterDescriptor); + + final List classTypeParameters; + if (anyMember instanceof PsiMethodWrapper && !anyMember.isStatic()) { + classTypeParameters = ((ClassDescriptor) owner).getTypeConstructor().getParameters(); + } else { + classTypeParameters = new ArrayList(0); + } + TypeParameterListTypeVariableResolver typeVariableResolver = new TypeParameterListTypeVariableResolver(classTypeParameters); + + List typeParameters = new ArrayList(0); + + if (members.setter != null) { + // call ugly code with side effects + typeParameters = resolveMethodTypeParameters(members.setter, propertyDescriptor.getSetter(), typeVariableResolver); + } + if (members.getter != null) { + // call ugly code with side effects + typeParameters = resolveMethodTypeParameters(members.getter, propertyDescriptor.getGetter(), typeVariableResolver); + } + JetType receiverJetType; if (receiverType == null) { receiverJetType = null; } else { receiverJetType = semanticServices.getTypeTransformer().transformToType(receiverType); } - - PropertyDescriptor propertyDescriptor = new PropertyDescriptor( - owner, - Collections.emptyList(), - isFinal && !staticMembers ? Modality.FINAL : Modality.OPEN, // TODO: abstract - resolveVisibilityFromPsiModifiers(anyMember), - isVar, - false, - receiverJetType, + + propertyDescriptor.setType( + type, + typeParameters, DescriptorUtils.getExpectedThisObjectIfNeeded(owner), - propertyName, - type); - semanticServices.getTrace().record(BindingContext.VARIABLE, anyMember, propertyDescriptor); + receiverJetType + ); + if (getterDescriptor != null) { + getterDescriptor.initialize(type); + } + if (setterDescriptor != null) { + // TODO: initialize + } + + semanticServices.getTrace().record(BindingContext.VARIABLE, anyMember.psiMember, propertyDescriptor); //fieldDescriptorCache.put(field, propertyDescriptor); descriptors.add(propertyDescriptor); } @@ -1177,7 +1234,7 @@ public class JavaDescriptorResolver { // TODO: add outer classes TypeParameterListTypeVariableResolver typeVariableResolverForParameters = new TypeParameterListTypeVariableResolver(classTypeParameters); - final List methodTypeParameters = resolveMethodTypeParameters(psiMethod, functionDescriptorImpl, typeVariableResolverForParameters); + final List methodTypeParameters = resolveMethodTypeParameters(new PsiMethodWrapper(psiMethod), functionDescriptorImpl, typeVariableResolverForParameters); class MethodTypeVariableResolver implements TypeVariableResolver { @@ -1217,17 +1274,19 @@ public class JavaDescriptorResolver { return substitutedFunctionDescriptor; } - private List resolveMethodTypeParameters(PsiMethod method, FunctionDescriptorImpl functionDescriptorImpl, TypeVariableResolver classTypeVariableResolver) { - JetMethodAnnotation jetMethodAnnotation = JetMethodAnnotation.get(method); - if (jetMethodAnnotation.typeParameters().length() > 0) { + private List resolveMethodTypeParameters( + @NotNull PsiMethodWrapper method, + @NotNull FunctionDescriptor functionDescriptor, + @NotNull TypeVariableResolver classTypeVariableResolver) { + if (method.getJetMethodOrProperty().typeParameters().length() > 0) { List r = resolveMethodTypeParametersFromJetSignature( - jetMethodAnnotation.typeParameters(), method, functionDescriptorImpl, classTypeVariableResolver); - initializeTypeParameters(method); + method.getJetMethodOrProperty().typeParameters(), method.getPsiMethod(), functionDescriptor, classTypeVariableResolver); + initializeTypeParameters(method.getPsiMethod()); return r; } - List typeParameters = makeUninitializedTypeParameters(functionDescriptorImpl, method.getTypeParameters()); - initializeTypeParameters(method); + List typeParameters = makeUninitializedTypeParameters(functionDescriptor, method.getPsiMethod().getTypeParameters()); + initializeTypeParameters(method.getPsiMethod()); return typeParameters; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmStdlibNames.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmStdlibNames.java index 918c324fc6e..48ac6e69141 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmStdlibNames.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmStdlibNames.java @@ -31,6 +31,7 @@ public class JvmStdlibNames { public static final JvmClassName JET_PROPERTY = new JvmClassName("jet.runtime.typeinfo.JetProperty"); public static final String JET_PROPERTY_TYPE_FIELD = "type"; + public static final String JET_PROPERTY_TYPE_PARAMETERS_FIELD = "typeParameters"; public static final JvmClassName JET_CONSTRUCTOR = new JvmClassName("jet.runtime.typeinfo.JetConstructor"); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiFieldWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiFieldWrapper.java new file mode 100644 index 00000000000..75ad3e13860 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiFieldWrapper.java @@ -0,0 +1,13 @@ +package org.jetbrains.jet.lang.resolve.java; + +import com.intellij.psi.PsiMember; +import org.jetbrains.annotations.NotNull; + +/** + * @author Stepan Koltsov + */ +public class PsiFieldWrapper extends PsiMemberWrapper { + public PsiFieldWrapper(@NotNull PsiMember psiMember) { + super(psiMember); + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMemberWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMemberWrapper.java new file mode 100644 index 00000000000..9e382597382 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMemberWrapper.java @@ -0,0 +1,27 @@ +package org.jetbrains.jet.lang.resolve.java; + +import com.intellij.psi.PsiMember; +import com.intellij.psi.PsiModifier; +import org.jetbrains.annotations.NotNull; + +/** + * @author Stepan Koltsov + */ +public class PsiMemberWrapper { + + @NotNull + protected final PsiMember psiMember; + + public PsiMemberWrapper(@NotNull PsiMember psiMember) { + this.psiMember = psiMember; + } + + public boolean isStatic() { + return psiMember.hasModifierProperty(PsiModifier.STATIC); + } + + public boolean isPrivate() { + return psiMember.hasModifierProperty(PsiModifier.PRIVATE); + } + +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java index c0d5c8c82c0..7fe74364e9b 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java @@ -1,11 +1,13 @@ package org.jetbrains.jet.lang.resolve.java; +import com.intellij.psi.PsiMember; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiParameter; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.resolve.java.kt.JetConstructorAnnotation; import org.jetbrains.jet.lang.resolve.java.kt.JetMethodAnnotation; +import org.jetbrains.jet.lang.resolve.java.kt.JetMethodOrPropertyAnnotation; import org.jetbrains.jet.lang.resolve.java.kt.JetPropertyAnnotation; import java.util.ArrayList; @@ -14,19 +16,17 @@ import java.util.List; /** * @author Stepan Koltsov */ -public class PsiMethodWrapper { - @NotNull - private final PsiMethod psiMethod; +public class PsiMethodWrapper extends PsiMemberWrapper { public PsiMethodWrapper(@NotNull PsiMethod psiMethod) { - this.psiMethod = psiMethod; + super(psiMethod); } private List parameters; @NotNull public List getParameters() { if (parameters == null) { - PsiParameter[] psiParameters = psiMethod.getParameterList().getParameters(); + PsiParameter[] psiParameters = getPsiMethod().getParameterList().getParameters(); parameters = new ArrayList(psiParameters.length); for (int i = 0; i < psiParameters.length; ++i) { parameters.add(new PsiParameterWrapper(psiParameters[i])); @@ -40,19 +40,15 @@ public class PsiMethodWrapper { return getParameters().get(i); } - public boolean isStatic() { - return psiMethod.getModifierList().hasExplicitModifier(PsiModifier.STATIC); - } - - public boolean isPrivate() { - return psiMethod.hasModifierProperty(PsiModifier.PRIVATE); + public boolean isFinal() { + return psiMember.hasModifierProperty(PsiModifier.FINAL); } private JetMethodAnnotation jetMethod; @NotNull public JetMethodAnnotation getJetMethod() { if (jetMethod == null) { - jetMethod = JetMethodAnnotation.get(psiMethod); + jetMethod = JetMethodAnnotation.get(getPsiMethod()); } return jetMethod; } @@ -61,7 +57,7 @@ public class PsiMethodWrapper { @NotNull public JetConstructorAnnotation getJetConstructor() { if (jetConstructor == null) { - jetConstructor = JetConstructorAnnotation.get(psiMethod); + jetConstructor = JetConstructorAnnotation.get(getPsiMethod()); } return jetConstructor; } @@ -70,8 +66,21 @@ public class PsiMethodWrapper { @NotNull public JetPropertyAnnotation getJetProperty() { if (jetProperty == null) { - jetProperty = JetPropertyAnnotation.get(psiMethod); + jetProperty = JetPropertyAnnotation.get(getPsiMethod()); } return jetProperty; } + + public JetMethodOrPropertyAnnotation getJetMethodOrProperty() { + if (getJetMethod().isDefined()) { + return getJetMethod(); + } else { + return getJetProperty(); + } + } + + @NotNull + public PsiMethod getPsiMethod() { + return (PsiMethod) psiMember; + } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodAnnotation.java index 189a744258b..2f4d954e21c 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodAnnotation.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodAnnotation.java @@ -9,21 +9,12 @@ import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; /** * @author Stepan Koltsov */ -public class JetMethodAnnotation extends PsiAnnotationWrapper { +public class JetMethodAnnotation extends JetMethodOrPropertyAnnotation { public JetMethodAnnotation(@Nullable PsiAnnotation psiAnnotation) { super(psiAnnotation); } - private String typeParameters; - @NotNull - public String typeParameters() { - if (typeParameters == null) { - typeParameters = getStringAttribute(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, ""); - } - return typeParameters; - } - private String returnType; @NotNull public String returnType() { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodOrPropertyAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodOrPropertyAnnotation.java new file mode 100644 index 00000000000..e21e5ab0680 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodOrPropertyAnnotation.java @@ -0,0 +1,25 @@ +package org.jetbrains.jet.lang.resolve.java.kt; + +import com.intellij.psi.PsiAnnotation; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; + +/** + * @author Stepan Koltsov + */ +public abstract class JetMethodOrPropertyAnnotation extends PsiAnnotationWrapper { + protected JetMethodOrPropertyAnnotation(@Nullable PsiAnnotation psiAnnotation) { + super(psiAnnotation); + } + + private String typeParameters; + @NotNull + public String typeParameters() { + if (typeParameters == null) { + typeParameters = getStringAttribute(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, ""); + } + return typeParameters; + } + +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetPropertyAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetPropertyAnnotation.java index 945051bbf94..3ca9a0031f7 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetPropertyAnnotation.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetPropertyAnnotation.java @@ -9,7 +9,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; /** * @author Stepan Koltsov */ -public class JetPropertyAnnotation extends PsiAnnotationWrapper { +public class JetPropertyAnnotation extends JetMethodOrPropertyAnnotation { protected JetPropertyAnnotation(@Nullable PsiAnnotation psiAnnotation) { super(psiAnnotation); } diff --git a/compiler/testData/readClass/prop/ExtVarMapPQInt.kt b/compiler/testData/readClass/prop/ExtVarMapPQInt.kt new file mode 100644 index 00000000000..4abab48e497 --- /dev/null +++ b/compiler/testData/readClass/prop/ExtVarMapPQInt.kt @@ -0,0 +1,7 @@ +package test + +import java.util.Map + +var Map.asas: Int + get() = throw Exception() + set(i: Int) = throw Exception() diff --git a/stdlib/src/jet/runtime/typeinfo/JetProperty.java b/stdlib/src/jet/runtime/typeinfo/JetProperty.java index fe187b010bb..2344ebe1fc4 100644 --- a/stdlib/src/jet/runtime/typeinfo/JetProperty.java +++ b/stdlib/src/jet/runtime/typeinfo/JetProperty.java @@ -12,4 +12,6 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) public @interface JetProperty { String type() default ""; + + String typeParameters() default ""; }