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
This commit is contained in:
Alexander Udalov
2013-07-31 20:38:47 +04:00
parent 732378d837
commit 7b945c2313
17 changed files with 169 additions and 87 deletions
@@ -72,7 +72,7 @@ public class SignaturesUtil {
@Nullable @Nullable
public static String getKotlinSignature(@NotNull JavaMember member) { 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) { if (annotation != null) {
PsiAnnotationMemberValue attribute = annotation.findAttributeValue(JvmAnnotationNames.KOTLIN_SIGNATURE_VALUE_FIELD_NAME); PsiAnnotationMemberValue attribute = annotation.findAttributeValue(JvmAnnotationNames.KOTLIN_SIGNATURE_VALUE_FIELD_NAME);
@@ -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.JvmAnnotationNames;
import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap; 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.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
@@ -154,25 +156,36 @@ public final class JavaAnnotationResolver {
} }
@Nullable @Nullable
public static PsiAnnotation findOwnAnnotation(@NotNull PsiModifierListOwner owner, @NotNull JvmClassName name) { public static PsiAnnotation findAnnotationWithExternal(@NotNull JavaAnnotationOwner owner, @NotNull JvmClassName name) {
PsiModifierList list = owner.getModifierList(); JavaAnnotation annotation = owner.findAnnotation(name.getFqName());
if (list != null) { if (annotation != null) {
PsiAnnotation found = list.findAnnotation(name.getFqName().asString()); return annotation.getPsi();
if (found != null) {
return found;
}
} }
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 @Nullable
public static PsiAnnotation findAnnotationWithExternal(@NotNull PsiModifierListOwner owner, @NotNull JvmClassName name) { public static PsiAnnotation findExternalAnnotation(@NotNull PsiModifierListOwner owner, @NotNull JvmClassName name) {
PsiAnnotation annotation = findOwnAnnotation(owner, name);
if (annotation != null) {
return annotation;
}
return ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotation(owner, name.getFqName().asString()); return ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotation(owner, name.getFqName().asString());
} }
} }
@@ -367,13 +367,13 @@ public final class JavaFunctionResolver {
@NotNull JavaMethod method, @NotNull JavaMethod method,
@NotNull TypeVariableResolver typeVariableResolver @NotNull TypeVariableResolver typeVariableResolver
) { ) {
PsiMethod psiMethod = method.getPsi(); TypeUsage typeUsage = JavaAnnotationResolver.hasReadonlyAnnotation(method) && !JavaAnnotationResolver.hasMutableAnnotation(method)
? TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT
TypeUsage typeUsage = JavaTypeTransformer.adjustTypeUsageWithMutabilityAnnotations(psiMethod, TypeUsage.MEMBER_SIGNATURE_COVARIANT); : TypeUsage.MEMBER_SIGNATURE_COVARIANT;
JetType transformedType = typeTransformer.transformToType(returnType, typeUsage, typeVariableResolver); JetType transformedType = typeTransformer.transformToType(returnType, typeUsage, typeVariableResolver);
if (JavaAnnotationResolver.findAnnotationWithExternal(psiMethod, JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION) != null) { if (JavaAnnotationResolver.hasNotNullAnnotation(method)) {
return TypeUtils.makeNullableAsSpecified(transformedType, false); return TypeUtils.makeNotNullable(transformedType);
} }
else { else {
return transformedType; return transformedType;
@@ -29,7 +29,6 @@ import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.JavaBindingContext; 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.TypeVariableResolver;
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeFieldSignatureData; import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeFieldSignatureData;
import org.jetbrains.jet.lang.resolve.java.provider.NamedMembers; 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) { private JetType getPropertyType(@NotNull JavaField field, @NotNull TypeVariableResolver typeVariableResolver) {
JetType propertyType = typeTransformer.transformToType(field.getType(), typeVariableResolver); JetType propertyType = typeTransformer.transformToType(field.getType(), typeVariableResolver);
boolean hasNotNullAnnotation = JavaAnnotationResolver.findAnnotationWithExternal( if (JavaAnnotationResolver.hasNotNullAnnotation(field) || isStaticFinalField(field) /* TODO: WTF? */) {
field.getPsi(), return TypeUtils.makeNotNullable(propertyType);
JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION
) != null;
if (hasNotNullAnnotation || isStaticFinalField(field)) {
propertyType = TypeUtils.makeNotNullable(propertyType);
} }
return propertyType; return propertyType;
} }
@@ -19,14 +19,11 @@ package org.jetbrains.jet.lang.resolve.java.resolver;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.openapi.diagnostic.Logger; 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.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; 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.TypeUsage;
import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver; import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver;
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap; 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 org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.Collections; import java.util.*;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN_SOURCES; import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN_SOURCES;
import static org.jetbrains.jet.lang.resolve.java.TypeUsage.*; import static org.jetbrains.jet.lang.resolve.java.TypeUsage.*;
@@ -198,11 +192,11 @@ public class JavaTypeTransformer {
} }
} }
else { else {
PsiType[] psiArguments = classifierType.getPsi().getParameters(); Collection<JavaType> 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 // 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); " in " + classifierType.getPresentableText() + "\n fqName: \n" + fqName);
for (TypeParameterDescriptor parameter : parameters) { for (TypeParameterDescriptor parameter : parameters) {
@@ -210,13 +204,13 @@ public class JavaTypeTransformer {
} }
} }
else { else {
for (int i = 0; i < parameters.size(); i++) { int index = 0;
PsiType psiArgument = psiArguments[i]; for (JavaType typeArgument : javaTypeArguments) {
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i); TypeParameterDescriptor typeParameterDescriptor = parameters.get(index);
index++;
TypeUsage howTheProjectionIsUsed = howThisTypeIsUsed == SUPERTYPE ? SUPERTYPE_ARGUMENT : TYPE_ARGUMENT; TypeUsage howTheProjectionIsUsed = howThisTypeIsUsed == SUPERTYPE ? SUPERTYPE_ARGUMENT : TYPE_ARGUMENT;
TypeProjection typeProjection = transformToTypeProjection( TypeProjection typeProjection = transformToTypeProjection(typeArgument, typeParameterDescriptor, typeVariableResolver,
JavaType.create(psiArgument), typeParameterDescriptor, typeVariableResolver,
howTheProjectionIsUsed); howTheProjectionIsUsed);
if (typeProjection.getProjectionKind() == typeParameterDescriptor.getVariance()) { 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, // 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 // 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 // their Kotlin analogs, so we treat them as raw to avoid exceptions
return classifierType.getPsi().isRaw() || argumentsExpected && classifierType.getPsi().getParameterCount() == 0; return classifierType.isRaw() || argumentsExpected && classifierType.getTypeArguments().isEmpty();
}
public static TypeUsage adjustTypeUsageWithMutabilityAnnotations(PsiModifierListOwner owner, TypeUsage originalTypeUsage) {
// Overrides type usage in method signature depending on mutability annotation present
EnumSet<TypeUsage> 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;
} }
} }
@@ -16,14 +16,12 @@
package org.jetbrains.jet.lang.resolve.java.resolver; package org.jetbrains.jet.lang.resolve.java.resolver;
import com.intellij.psi.PsiAnnotation;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; 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.TypeUsage;
import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver; import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver;
import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType; import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType;
@@ -52,8 +50,9 @@ public final class JavaValueParameterResolver {
@NotNull TypeVariableResolver typeVariableResolver, @NotNull TypeVariableResolver typeVariableResolver,
boolean isVararg boolean isVararg
) { ) {
TypeUsage typeUsage = JavaTypeTransformer TypeUsage typeUsage = JavaAnnotationResolver.hasMutableAnnotation(parameter)
.adjustTypeUsageWithMutabilityAnnotations(parameter.getPsi(), TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT); ? TypeUsage.MEMBER_SIGNATURE_COVARIANT
: TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT;
JavaType parameterType = parameter.getType(); JavaType parameterType = parameter.getType();
@@ -69,12 +68,8 @@ public final class JavaValueParameterResolver {
} }
else { else {
JetType transformedType = typeTransformer.transformToType(parameterType, typeUsage, typeVariableResolver); JetType transformedType = typeTransformer.transformToType(parameterType, typeUsage, typeVariableResolver);
if (transformedType.isNullable()) { if (transformedType.isNullable() && JavaAnnotationResolver.hasNotNullAnnotation(parameter)) {
PsiAnnotation notNullAnnotation = JavaAnnotationResolver.findAnnotationWithExternal( transformedType = TypeUtils.makeNotNullable(transformedType);
parameter.getPsi(), JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION);
if (notNullAnnotation != null) {
transformedType = TypeUtils.makeNotNullable(transformedType);
}
} }
outType = transformedType; outType = transformedType;
@@ -19,10 +19,14 @@ package org.jetbrains.jet.lang.resolve.java.structure;
import com.intellij.psi.PsiAnnotation; import com.intellij.psi.PsiAnnotation;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class JavaAnnotation { public class JavaAnnotation extends JavaElementImpl {
private final PsiAnnotation psiAnnotation;
public JavaAnnotation(@NotNull PsiAnnotation psiAnnotation) { public JavaAnnotation(@NotNull PsiAnnotation psiAnnotation) {
this.psiAnnotation = psiAnnotation; super(psiAnnotation);
}
@NotNull
@Override
public PsiAnnotation getPsi() {
return (PsiAnnotation) super.getPsi();
} }
} }
@@ -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<JavaAnnotation> getAnnotations();
@Nullable
JavaAnnotation findAnnotation(@NotNull FqName fqName);
}
@@ -33,7 +33,8 @@ import java.util.Collection;
import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.*; 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) { public JavaClass(@NotNull PsiClass psiClass) {
super(psiClass); super(psiClass);
assert !(psiClass instanceof PsiTypeParameter) assert !(psiClass instanceof PsiTypeParameter)
@@ -161,4 +162,10 @@ public class JavaClass extends JavaClassifier implements JavaNamedElement, JavaT
public Collection<JavaAnnotation> getAnnotations() { public Collection<JavaAnnotation> getAnnotations() {
return JavaElementUtil.getAnnotations(this); return JavaElementUtil.getAnnotations(this);
} }
@Nullable
@Override
public JavaAnnotation findAnnotation(@NotNull FqName fqName) {
return JavaElementUtil.findAnnotation(this, fqName);
}
} }
@@ -27,6 +27,8 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.types;
public class JavaClassifierType extends JavaType { public class JavaClassifierType extends JavaType {
public JavaClassifierType(@NotNull PsiClassType psiClassType) { public JavaClassifierType(@NotNull PsiClassType psiClassType) {
super(psiClassType); super(psiClassType);
@@ -62,4 +64,13 @@ public class JavaClassifierType extends JavaType {
public String getPresentableText() { public String getPresentableText() {
return getPsi().getPresentableText(); return getPsi().getPresentableText();
} }
public boolean isRaw() {
return getPsi().isRaw();
}
@NotNull
public Collection<JavaType> getTypeArguments() {
return types(getPsi().getParameters());
}
} }
@@ -88,6 +88,16 @@ import java.util.List;
return result; return result;
} }
@NotNull
public static Collection<JavaType> types(@NotNull PsiType[] types) {
if (types.length == 0) return Collections.emptyList();
List<JavaType> result = new ArrayList<JavaType>(types.length);
for (PsiType psiType : types) {
result.add(JavaType.create(psiType));
}
return result;
}
@NotNull @NotNull
public static Collection<JavaClassifierType> classifierTypes(@NotNull PsiClassType[] classTypes) { public static Collection<JavaClassifierType> classifierTypes(@NotNull PsiClassType[] classTypes) {
if (classTypes.length == 0) return Collections.emptyList(); if (classTypes.length == 0) return Collections.emptyList();
@@ -16,12 +16,15 @@
package org.jetbrains.jet.lang.resolve.java.structure; package org.jetbrains.jet.lang.resolve.java.structure;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiModifierList; import com.intellij.psi.PsiModifierList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.Visibilities; import org.jetbrains.jet.lang.descriptors.Visibilities;
import org.jetbrains.jet.lang.descriptors.Visibility; import org.jetbrains.jet.lang.descriptors.Visibility;
import org.jetbrains.jet.lang.resolve.java.JavaVisibilities; import org.jetbrains.jet.lang.resolve.java.JavaVisibilities;
import org.jetbrains.jet.lang.resolve.name.FqName;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -59,11 +62,21 @@ import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectio
} }
@NotNull @NotNull
public static Collection<JavaAnnotation> getAnnotations(@NotNull JavaModifierListOwner owner) { public static Collection<JavaAnnotation> getAnnotations(@NotNull JavaAnnotationOwner owner) {
PsiModifierList modifierList = owner.getPsi().getModifierList(); PsiModifierList modifierList = owner.getPsi().getModifierList();
if (modifierList != null) { if (modifierList != null) {
return annotations(modifierList.getAnnotations()); return annotations(modifierList.getAnnotations());
} }
return Collections.emptyList(); 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;
}
} }
@@ -20,7 +20,7 @@ import com.intellij.psi.PsiMember;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public interface JavaMember extends JavaModifierListOwner, JavaNamedElement { public interface JavaMember extends JavaModifierListOwner, JavaAnnotationOwner, JavaNamedElement {
@NotNull @NotNull
@Override @Override
PsiMember getPsi(); PsiMember getPsi();
@@ -21,11 +21,12 @@ import com.intellij.psi.PsiMember;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.Visibility; import org.jetbrains.jet.lang.descriptors.Visibility;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.Collection; 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) { protected JavaMemberImpl(@NotNull PsiMember psiMember) {
super(psiMember); super(psiMember);
} }
@@ -78,4 +79,10 @@ public abstract class JavaMemberImpl extends JavaElementImpl implements JavaMemb
public Collection<JavaAnnotation> getAnnotations() { public Collection<JavaAnnotation> getAnnotations() {
return JavaElementUtil.getAnnotations(this); return JavaElementUtil.getAnnotations(this);
} }
@Nullable
@Override
public JavaAnnotation findAnnotation(@NotNull FqName fqName) {
return JavaElementUtil.findAnnotation(this, fqName);
}
} }
@@ -20,8 +20,6 @@ import com.intellij.psi.PsiModifierListOwner;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.Visibility; import org.jetbrains.jet.lang.descriptors.Visibility;
import java.util.Collection;
public interface JavaModifierListOwner extends JavaElement { public interface JavaModifierListOwner extends JavaElement {
@NotNull @NotNull
@Override @Override
@@ -35,7 +33,4 @@ public interface JavaModifierListOwner extends JavaElement {
@NotNull @NotNull
Visibility getVisibility(); Visibility getVisibility();
@NotNull
Collection<JavaAnnotation> getAnnotations();
} }
@@ -19,9 +19,12 @@ package org.jetbrains.jet.lang.resolve.java.structure;
import com.intellij.psi.PsiParameter; import com.intellij.psi.PsiParameter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; 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) { public JavaValueParameter(@NotNull PsiParameter psiParameter) {
super(psiParameter); super(psiParameter);
} }
@@ -32,6 +35,18 @@ public class JavaValueParameter extends JavaElementImpl {
return (PsiParameter) super.getPsi(); return (PsiParameter) super.getPsi();
} }
@NotNull
@Override
public Collection<JavaAnnotation> getAnnotations() {
return JavaElementUtil.getAnnotations(this);
}
@Nullable
@Override
public JavaAnnotation findAnnotation(@NotNull FqName fqName) {
return JavaElementUtil.findAnnotation(this, fqName);
}
@Nullable @Nullable
public Name getName() { public Name getName() {
String name = getPsi().getName(); String name = getPsi().getName();
@@ -26,11 +26,12 @@ import com.intellij.psi.impl.compiled.ClsElementImpl;
import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver;
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KOTLIN_SIGNATURE;
class KotlinSignatureUtil { 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() { private KotlinSignatureUtil() {
} }
@@ -80,7 +81,9 @@ class KotlinSignatureUtil {
static PsiAnnotation findKotlinSignatureAnnotation(@NotNull PsiElement element) { static PsiAnnotation findKotlinSignatureAnnotation(@NotNull PsiElement element) {
if (!(element instanceof PsiModifierListOwner)) return null; if (!(element instanceof PsiModifierListOwner)) return null;
PsiModifierListOwner annotationOwner = getAnnotationOwner(element); 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 == null) return null;
if (annotation.getParameterList().getAttributes().length == 0) return null; if (annotation.getParameterList().getAttributes().length == 0) return null;
return annotation; return annotation;