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;