From 7b945c23134a64b54a1732458a2ffec6eac3f568 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 31 Jul 2013 20:38:47 +0400 Subject: [PATCH] Migrate JavaTypeTransformer from PsiType to JavaType Add more wrapper methods to JavaClassifierType. Inline the utility method adjustTypeUsageWithMutabilityAnnotations to the two places where it was used. Also add JavaAnnotationOwner and change signature of JavaAnnotationResolver to take JavaAnnotationOwner, not PSI --- .../java/kotlinSignature/SignaturesUtil.java | 2 +- .../java/resolver/JavaAnnotationResolver.java | 41 +++++++++++------- .../java/resolver/JavaFunctionResolver.java | 10 ++--- .../java/resolver/JavaPropertyResolver.java | 11 ++--- .../java/resolver/JavaTypeTransformer.java | 42 +++++-------------- .../resolver/JavaValueParameterResolver.java | 15 +++---- .../java/structure/JavaAnnotation.java | 12 ++++-- .../java/structure/JavaAnnotationOwner.java | 36 ++++++++++++++++ .../resolve/java/structure/JavaClass.java | 9 +++- .../java/structure/JavaClassifierType.java | 11 +++++ ...JavaElementCollectionFromPsiArrayUtil.java | 10 +++++ .../java/structure/JavaElementUtil.java | 15 ++++++- .../resolve/java/structure/JavaMember.java | 2 +- .../java/structure/JavaMemberImpl.java | 9 +++- .../java/structure/JavaModifierListOwner.java | 5 --- .../java/structure/JavaValueParameter.java | 17 +++++++- .../ktSignature/KotlinSignatureUtil.java | 9 ++-- 17 files changed, 169 insertions(+), 87 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaAnnotationOwner.java diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesUtil.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesUtil.java index 904ee20c502..0064e58877d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesUtil.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesUtil.java @@ -72,7 +72,7 @@ public class SignaturesUtil { @Nullable public static String getKotlinSignature(@NotNull JavaMember member) { - PsiAnnotation annotation = JavaAnnotationResolver.findAnnotationWithExternal(member.getPsi(), JvmAnnotationNames.KOTLIN_SIGNATURE); + PsiAnnotation annotation = JavaAnnotationResolver.findAnnotationWithExternal(member, JvmAnnotationNames.KOTLIN_SIGNATURE); if (annotation != null) { PsiAnnotationMemberValue attribute = annotation.findAttributeValue(JvmAnnotationNames.KOTLIN_SIGNATURE_VALUE_FIELD_NAME); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaAnnotationResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaAnnotationResolver.java index 401bab0d2a7..c324a979ed2 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaAnnotationResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaAnnotationResolver.java @@ -29,6 +29,8 @@ import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames; import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap; +import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotation; +import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotationOwner; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; @@ -154,25 +156,36 @@ public final class JavaAnnotationResolver { } @Nullable - public static PsiAnnotation findOwnAnnotation(@NotNull PsiModifierListOwner owner, @NotNull JvmClassName name) { - PsiModifierList list = owner.getModifierList(); - if (list != null) { - PsiAnnotation found = list.findAnnotation(name.getFqName().asString()); - if (found != null) { - return found; - } + public static PsiAnnotation findAnnotationWithExternal(@NotNull JavaAnnotationOwner owner, @NotNull JvmClassName name) { + JavaAnnotation annotation = owner.findAnnotation(name.getFqName()); + if (annotation != null) { + return annotation.getPsi(); } - return null; + return findExternalAnnotation(owner.getPsi(), name); + } + + public static boolean hasNotNullAnnotation(@NotNull JavaAnnotationOwner owner) { + return findAnnotationWithExternal(owner, JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION) != null; + } + + public static boolean hasMutableAnnotation(@NotNull JavaAnnotationOwner owner) { + return findAnnotationWithExternal(owner, JvmAnnotationNames.JETBRAINS_MUTABLE_ANNOTATION) != null; + } + + public static boolean hasReadonlyAnnotation(@NotNull JavaAnnotationOwner owner) { + return findAnnotationWithExternal(owner, JvmAnnotationNames.JETBRAINS_READONLY_ANNOTATION) != null; + } + + + @Nullable + public static PsiAnnotation findOwnAnnotation(@NotNull PsiModifierListOwner owner, @NotNull JvmClassName name) { + PsiModifierList list = owner.getModifierList(); + return list == null ? null : list.findAnnotation(name.getFqName().asString()); } @Nullable - public static PsiAnnotation findAnnotationWithExternal(@NotNull PsiModifierListOwner owner, @NotNull JvmClassName name) { - PsiAnnotation annotation = findOwnAnnotation(owner, name); - if (annotation != null) { - return annotation; - } - + public static PsiAnnotation findExternalAnnotation(@NotNull PsiModifierListOwner owner, @NotNull JvmClassName name) { return ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotation(owner, name.getFqName().asString()); } } \ No newline at end of file diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java index 8d0c66fea28..fc75074096c 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java @@ -367,13 +367,13 @@ public final class JavaFunctionResolver { @NotNull JavaMethod method, @NotNull TypeVariableResolver typeVariableResolver ) { - PsiMethod psiMethod = method.getPsi(); - - TypeUsage typeUsage = JavaTypeTransformer.adjustTypeUsageWithMutabilityAnnotations(psiMethod, TypeUsage.MEMBER_SIGNATURE_COVARIANT); + TypeUsage typeUsage = JavaAnnotationResolver.hasReadonlyAnnotation(method) && !JavaAnnotationResolver.hasMutableAnnotation(method) + ? TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT + : TypeUsage.MEMBER_SIGNATURE_COVARIANT; JetType transformedType = typeTransformer.transformToType(returnType, typeUsage, typeVariableResolver); - if (JavaAnnotationResolver.findAnnotationWithExternal(psiMethod, JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION) != null) { - return TypeUtils.makeNullableAsSpecified(transformedType, false); + if (JavaAnnotationResolver.hasNotNullAnnotation(method)) { + return TypeUtils.makeNotNullable(transformedType); } else { return transformedType; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java index 9a5d1c464e5..81fd13f4d5e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java @@ -29,7 +29,6 @@ import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; import org.jetbrains.jet.lang.resolve.java.JavaBindingContext; -import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames; import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver; import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeFieldSignatureData; import org.jetbrains.jet.lang.resolve.java.provider.NamedMembers; @@ -231,14 +230,10 @@ public final class JavaPropertyResolver { private JetType getPropertyType(@NotNull JavaField field, @NotNull TypeVariableResolver typeVariableResolver) { JetType propertyType = typeTransformer.transformToType(field.getType(), typeVariableResolver); - boolean hasNotNullAnnotation = JavaAnnotationResolver.findAnnotationWithExternal( - field.getPsi(), - JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION - ) != null; - - if (hasNotNullAnnotation || isStaticFinalField(field)) { - propertyType = TypeUtils.makeNotNullable(propertyType); + if (JavaAnnotationResolver.hasNotNullAnnotation(field) || isStaticFinalField(field) /* TODO: WTF? */) { + return TypeUtils.makeNotNullable(propertyType); } + return propertyType; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaTypeTransformer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaTypeTransformer.java index 2ae8c09b815..2e0e4a38897 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaTypeTransformer.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaTypeTransformer.java @@ -19,14 +19,11 @@ package org.jetbrains.jet.lang.resolve.java.resolver; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.psi.PsiModifierListOwner; -import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames; import org.jetbrains.jet.lang.resolve.java.TypeUsage; import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver; import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap; @@ -37,10 +34,7 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import javax.inject.Inject; -import java.util.Collections; -import java.util.EnumSet; -import java.util.List; -import java.util.Set; +import java.util.*; import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN_SOURCES; import static org.jetbrains.jet.lang.resolve.java.TypeUsage.*; @@ -198,11 +192,11 @@ public class JavaTypeTransformer { } } else { - PsiType[] psiArguments = classifierType.getPsi().getParameters(); + Collection javaTypeArguments = classifierType.getTypeArguments(); - if (parameters.size() != psiArguments.length) { + if (parameters.size() != javaTypeArguments.size()) { // Most of the time this means there is an error in the Java code - LOG.warn("parameters = " + parameters.size() + ", actual arguments = " + psiArguments.length + + LOG.warn("parameters = " + parameters.size() + ", actual arguments = " + javaTypeArguments.size() + " in " + classifierType.getPresentableText() + "\n fqName: \n" + fqName); for (TypeParameterDescriptor parameter : parameters) { @@ -210,13 +204,13 @@ public class JavaTypeTransformer { } } else { - for (int i = 0; i < parameters.size(); i++) { - PsiType psiArgument = psiArguments[i]; - TypeParameterDescriptor typeParameterDescriptor = parameters.get(i); + int index = 0; + for (JavaType typeArgument : javaTypeArguments) { + TypeParameterDescriptor typeParameterDescriptor = parameters.get(index); + index++; TypeUsage howTheProjectionIsUsed = howThisTypeIsUsed == SUPERTYPE ? SUPERTYPE_ARGUMENT : TYPE_ARGUMENT; - TypeProjection typeProjection = transformToTypeProjection( - JavaType.create(psiArgument), typeParameterDescriptor, typeVariableResolver, + TypeProjection typeProjection = transformToTypeProjection(typeArgument, typeParameterDescriptor, typeVariableResolver, howTheProjectionIsUsed); if (typeProjection.getProjectionKind() == typeParameterDescriptor.getVariance()) { @@ -284,22 +278,6 @@ public class JavaTypeTransformer { // The second option is needed because sometimes we get weird versions of JDK classes in the class path, // such as collections with no generics, so the Java types are not raw, formally, but they don't match with // their Kotlin analogs, so we treat them as raw to avoid exceptions - return classifierType.getPsi().isRaw() || argumentsExpected && classifierType.getPsi().getParameterCount() == 0; - } - - public static TypeUsage adjustTypeUsageWithMutabilityAnnotations(PsiModifierListOwner owner, TypeUsage originalTypeUsage) { - // Overrides type usage in method signature depending on mutability annotation present - EnumSet signatureTypeUsages = - EnumSet.of(TypeUsage.MEMBER_SIGNATURE_COVARIANT, TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT, TypeUsage.MEMBER_SIGNATURE_INVARIANT); - if (!signatureTypeUsages.contains(originalTypeUsage)) { - return originalTypeUsage; - } - if (JavaAnnotationResolver.findAnnotationWithExternal(owner, JvmAnnotationNames.JETBRAINS_MUTABLE_ANNOTATION) != null) { - return TypeUsage.MEMBER_SIGNATURE_COVARIANT; - } - if (JavaAnnotationResolver.findAnnotationWithExternal(owner, JvmAnnotationNames.JETBRAINS_READONLY_ANNOTATION) != null) { - return TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT; - } - return originalTypeUsage; + return classifierType.isRaw() || argumentsExpected && classifierType.getTypeArguments().isEmpty(); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaValueParameterResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaValueParameterResolver.java index 802f52c3ad0..124bbcfa563 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaValueParameterResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaValueParameterResolver.java @@ -16,14 +16,12 @@ package org.jetbrains.jet.lang.resolve.java.resolver; -import com.intellij.psi.PsiAnnotation; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; -import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames; import org.jetbrains.jet.lang.resolve.java.TypeUsage; import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver; import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType; @@ -52,8 +50,9 @@ public final class JavaValueParameterResolver { @NotNull TypeVariableResolver typeVariableResolver, boolean isVararg ) { - TypeUsage typeUsage = JavaTypeTransformer - .adjustTypeUsageWithMutabilityAnnotations(parameter.getPsi(), TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT); + TypeUsage typeUsage = JavaAnnotationResolver.hasMutableAnnotation(parameter) + ? TypeUsage.MEMBER_SIGNATURE_COVARIANT + : TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT; JavaType parameterType = parameter.getType(); @@ -69,12 +68,8 @@ public final class JavaValueParameterResolver { } else { JetType transformedType = typeTransformer.transformToType(parameterType, typeUsage, typeVariableResolver); - if (transformedType.isNullable()) { - PsiAnnotation notNullAnnotation = JavaAnnotationResolver.findAnnotationWithExternal( - parameter.getPsi(), JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION); - if (notNullAnnotation != null) { - transformedType = TypeUtils.makeNotNullable(transformedType); - } + if (transformedType.isNullable() && JavaAnnotationResolver.hasNotNullAnnotation(parameter)) { + transformedType = TypeUtils.makeNotNullable(transformedType); } outType = transformedType; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaAnnotation.java index ed9dbd9cafa..68f38a880ca 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaAnnotation.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaAnnotation.java @@ -19,10 +19,14 @@ package org.jetbrains.jet.lang.resolve.java.structure; import com.intellij.psi.PsiAnnotation; import org.jetbrains.annotations.NotNull; -public class JavaAnnotation { - private final PsiAnnotation psiAnnotation; - +public class JavaAnnotation extends JavaElementImpl { public JavaAnnotation(@NotNull PsiAnnotation psiAnnotation) { - this.psiAnnotation = psiAnnotation; + super(psiAnnotation); + } + + @NotNull + @Override + public PsiAnnotation getPsi() { + return (PsiAnnotation) super.getPsi(); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaAnnotationOwner.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaAnnotationOwner.java new file mode 100644 index 00000000000..183afb44bce --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaAnnotationOwner.java @@ -0,0 +1,36 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.java.structure; + +import com.intellij.psi.PsiModifierListOwner; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.name.FqName; + +import java.util.Collection; + +public interface JavaAnnotationOwner extends JavaElement { + @NotNull + @Override + PsiModifierListOwner getPsi(); + + @NotNull + Collection getAnnotations(); + + @Nullable + JavaAnnotation findAnnotation(@NotNull FqName fqName); +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java index 66dd1a66c9c..db9f02f8c35 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java @@ -33,7 +33,8 @@ import java.util.Collection; import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.*; -public class JavaClass extends JavaClassifier implements JavaNamedElement, JavaTypeParameterListOwner, JavaModifierListOwner { +public class JavaClass extends JavaClassifier + implements JavaNamedElement, JavaTypeParameterListOwner, JavaModifierListOwner, JavaAnnotationOwner { public JavaClass(@NotNull PsiClass psiClass) { super(psiClass); assert !(psiClass instanceof PsiTypeParameter) @@ -161,4 +162,10 @@ public class JavaClass extends JavaClassifier implements JavaNamedElement, JavaT public Collection getAnnotations() { return JavaElementUtil.getAnnotations(this); } + + @Nullable + @Override + public JavaAnnotation findAnnotation(@NotNull FqName fqName) { + return JavaElementUtil.findAnnotation(this, fqName); + } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClassifierType.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClassifierType.java index dfb432eeedb..51d96d9bd41 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClassifierType.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClassifierType.java @@ -27,6 +27,8 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.types; + public class JavaClassifierType extends JavaType { public JavaClassifierType(@NotNull PsiClassType psiClassType) { super(psiClassType); @@ -62,4 +64,13 @@ public class JavaClassifierType extends JavaType { public String getPresentableText() { return getPsi().getPresentableText(); } + + public boolean isRaw() { + return getPsi().isRaw(); + } + + @NotNull + public Collection getTypeArguments() { + return types(getPsi().getParameters()); + } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementCollectionFromPsiArrayUtil.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementCollectionFromPsiArrayUtil.java index 8afaed39419..47e492b96d4 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementCollectionFromPsiArrayUtil.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementCollectionFromPsiArrayUtil.java @@ -88,6 +88,16 @@ import java.util.List; return result; } + @NotNull + public static Collection types(@NotNull PsiType[] types) { + if (types.length == 0) return Collections.emptyList(); + List result = new ArrayList(types.length); + for (PsiType psiType : types) { + result.add(JavaType.create(psiType)); + } + return result; + } + @NotNull public static Collection classifierTypes(@NotNull PsiClassType[] classTypes) { if (classTypes.length == 0) return Collections.emptyList(); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementUtil.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementUtil.java index 3bf0167e759..a5e0ee7b3bb 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementUtil.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementUtil.java @@ -16,12 +16,15 @@ package org.jetbrains.jet.lang.resolve.java.structure; +import com.intellij.psi.PsiAnnotation; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiModifierList; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.Visibilities; import org.jetbrains.jet.lang.descriptors.Visibility; import org.jetbrains.jet.lang.resolve.java.JavaVisibilities; +import org.jetbrains.jet.lang.resolve.name.FqName; import java.util.Collection; import java.util.Collections; @@ -59,11 +62,21 @@ import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectio } @NotNull - public static Collection getAnnotations(@NotNull JavaModifierListOwner owner) { + public static Collection getAnnotations(@NotNull JavaAnnotationOwner owner) { PsiModifierList modifierList = owner.getPsi().getModifierList(); if (modifierList != null) { return annotations(modifierList.getAnnotations()); } return Collections.emptyList(); } + + @Nullable + public static JavaAnnotation findAnnotation(@NotNull JavaAnnotationOwner owner, @NotNull FqName fqName) { + PsiModifierList modifierList = owner.getPsi().getModifierList(); + if (modifierList != null) { + PsiAnnotation psiAnnotation = modifierList.findAnnotation(fqName.asString()); + return psiAnnotation == null ? null : new JavaAnnotation(psiAnnotation); + } + return null; + } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMember.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMember.java index b88e9572a56..174f7d27c1c 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMember.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMember.java @@ -20,7 +20,7 @@ import com.intellij.psi.PsiMember; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public interface JavaMember extends JavaModifierListOwner, JavaNamedElement { +public interface JavaMember extends JavaModifierListOwner, JavaAnnotationOwner, JavaNamedElement { @NotNull @Override PsiMember getPsi(); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMemberImpl.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMemberImpl.java index 9277c7c6ff0..709bbd59a26 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMemberImpl.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMemberImpl.java @@ -21,11 +21,12 @@ import com.intellij.psi.PsiMember; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.Visibility; +import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import java.util.Collection; -public abstract class JavaMemberImpl extends JavaElementImpl implements JavaMember, JavaModifierListOwner { +public abstract class JavaMemberImpl extends JavaElementImpl implements JavaMember { protected JavaMemberImpl(@NotNull PsiMember psiMember) { super(psiMember); } @@ -78,4 +79,10 @@ public abstract class JavaMemberImpl extends JavaElementImpl implements JavaMemb public Collection getAnnotations() { return JavaElementUtil.getAnnotations(this); } + + @Nullable + @Override + public JavaAnnotation findAnnotation(@NotNull FqName fqName) { + return JavaElementUtil.findAnnotation(this, fqName); + } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaModifierListOwner.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaModifierListOwner.java index f508497dab1..9cea32cbd8d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaModifierListOwner.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaModifierListOwner.java @@ -20,8 +20,6 @@ import com.intellij.psi.PsiModifierListOwner; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.Visibility; -import java.util.Collection; - public interface JavaModifierListOwner extends JavaElement { @NotNull @Override @@ -35,7 +33,4 @@ public interface JavaModifierListOwner extends JavaElement { @NotNull Visibility getVisibility(); - - @NotNull - Collection getAnnotations(); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaValueParameter.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaValueParameter.java index 5b5a6e912df..00d6627b333 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaValueParameter.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaValueParameter.java @@ -19,9 +19,12 @@ package org.jetbrains.jet.lang.resolve.java.structure; import com.intellij.psi.PsiParameter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; -public class JavaValueParameter extends JavaElementImpl { +import java.util.Collection; + +public class JavaValueParameter extends JavaElementImpl implements JavaAnnotationOwner { public JavaValueParameter(@NotNull PsiParameter psiParameter) { super(psiParameter); } @@ -32,6 +35,18 @@ public class JavaValueParameter extends JavaElementImpl { return (PsiParameter) super.getPsi(); } + @NotNull + @Override + public Collection getAnnotations() { + return JavaElementUtil.getAnnotations(this); + } + + @Nullable + @Override + public JavaAnnotation findAnnotation(@NotNull FqName fqName) { + return JavaElementUtil.findAnnotation(this, fqName); + } + @Nullable public Name getName() { String name = getPsi().getName(); diff --git a/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureUtil.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureUtil.java index 4b7e4768b6d..94b0e807142 100644 --- a/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureUtil.java @@ -26,11 +26,12 @@ import com.intellij.psi.impl.compiled.ClsElementImpl; import com.intellij.psi.impl.source.SourceTreeToPsiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames; import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver; +import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KOTLIN_SIGNATURE; + class KotlinSignatureUtil { - static final String KOTLIN_SIGNATURE_ANNOTATION = JvmAnnotationNames.KOTLIN_SIGNATURE.getFqName().asString(); + static final String KOTLIN_SIGNATURE_ANNOTATION = KOTLIN_SIGNATURE.getFqName().asString(); private KotlinSignatureUtil() { } @@ -80,7 +81,9 @@ class KotlinSignatureUtil { static PsiAnnotation findKotlinSignatureAnnotation(@NotNull PsiElement element) { if (!(element instanceof PsiModifierListOwner)) return null; PsiModifierListOwner annotationOwner = getAnnotationOwner(element); - PsiAnnotation annotation = JavaAnnotationResolver.findAnnotationWithExternal(annotationOwner, JvmAnnotationNames.KOTLIN_SIGNATURE); + PsiAnnotation ownAnnotation = JavaAnnotationResolver.findOwnAnnotation(annotationOwner, KOTLIN_SIGNATURE); + PsiAnnotation annotation = ownAnnotation != null ? ownAnnotation + : JavaAnnotationResolver.findExternalAnnotation(annotationOwner, KOTLIN_SIGNATURE); if (annotation == null) return null; if (annotation.getParameterList().getAttributes().length == 0) return null; return annotation;