Migrate JavaAnnotationResolver from PSI to JavaElement
Create a bunch of annotation argument classes, which serve as wrappers over PsiAnnotationMemberValue class, but also have a Name
This commit is contained in:
+5
-9
@@ -78,20 +78,16 @@ public final class DescriptorResolverUtils {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ValueParameterDescriptor getValueParameterDescriptorForAnnotationParameter(
|
||||
Name argumentName,
|
||||
ClassDescriptor classDescriptor
|
||||
) {
|
||||
Collection<ConstructorDescriptor> constructors = classDescriptor.getConstructors();
|
||||
public static ValueParameterDescriptor getAnnotationParameterByName(@NotNull Name name, @NotNull ClassDescriptor annotationClass) {
|
||||
Collection<ConstructorDescriptor> constructors = annotationClass.getConstructors();
|
||||
assert constructors.size() == 1 : "Annotation class descriptor must have only one constructor";
|
||||
List<ValueParameterDescriptor> valueParameters = constructors.iterator().next().getValueParameters();
|
||||
|
||||
for (ValueParameterDescriptor parameter : valueParameters) {
|
||||
Name parameterName = parameter.getName();
|
||||
if (parameterName.equals(argumentName)) {
|
||||
for (ValueParameterDescriptor parameter : constructors.iterator().next().getValueParameters()) {
|
||||
if (parameter.getName().equals(name)) {
|
||||
return parameter;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -20,6 +20,7 @@ import jet.KotlinClass;
|
||||
import jet.KotlinPackage;
|
||||
import jet.runtime.typeinfo.KotlinSignature;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.rt.annotation.AssertInvisibleInResolver;
|
||||
|
||||
public final class JvmAnnotationNames {
|
||||
@@ -39,7 +40,7 @@ public final class JvmAnnotationNames {
|
||||
|
||||
public static final JvmClassName KOTLIN_SIGNATURE = JvmClassName.byClass(KotlinSignature.class);
|
||||
|
||||
public static final String KOTLIN_SIGNATURE_VALUE_FIELD_NAME = "value";
|
||||
public static final Name KOTLIN_SIGNATURE_VALUE_FIELD_NAME = Name.identifier("value");
|
||||
|
||||
public static final JvmClassName JETBRAINS_NOT_NULL_ANNOTATION = JvmClassName.byClass(NotNull.class);
|
||||
|
||||
|
||||
+7
-7
@@ -18,9 +18,6 @@ package org.jetbrains.jet.lang.resolve.java.kotlinSignature;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiAnnotationMemberValue;
|
||||
import com.intellij.psi.PsiLiteralExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
@@ -28,6 +25,9 @@ import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotation;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotationArgument;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaLiteralAnnotationArgument;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaMember;
|
||||
import org.jetbrains.jet.lang.types.TypeConstructor;
|
||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||
@@ -72,12 +72,12 @@ public class SignaturesUtil {
|
||||
|
||||
@Nullable
|
||||
public static String getKotlinSignature(@NotNull JavaMember member) {
|
||||
PsiAnnotation annotation = JavaAnnotationResolver.findAnnotationWithExternal(member, JvmAnnotationNames.KOTLIN_SIGNATURE);
|
||||
JavaAnnotation annotation = JavaAnnotationResolver.findAnnotationWithExternal(member, JvmAnnotationNames.KOTLIN_SIGNATURE);
|
||||
|
||||
if (annotation != null) {
|
||||
PsiAnnotationMemberValue attribute = annotation.findAttributeValue(JvmAnnotationNames.KOTLIN_SIGNATURE_VALUE_FIELD_NAME);
|
||||
if (attribute instanceof PsiLiteralExpression) {
|
||||
Object value = ((PsiLiteralExpression) attribute).getValue();
|
||||
JavaAnnotationArgument argument = annotation.findArgument(JvmAnnotationNames.KOTLIN_SIGNATURE_VALUE_FIELD_NAME);
|
||||
if (argument instanceof JavaLiteralAnnotationArgument) {
|
||||
Object value = ((JavaLiteralAnnotationArgument) argument).getValue();
|
||||
if (value instanceof String) {
|
||||
return StringUtil.unescapeStringCharacters((String) value);
|
||||
}
|
||||
|
||||
+5
-5
@@ -33,9 +33,9 @@ import org.jetbrains.jet.lang.resolve.constants.StringValue;
|
||||
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
|
||||
import org.jetbrains.jet.lang.resolve.java.TypeUsage;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
|
||||
@@ -110,11 +110,11 @@ public class JavaToKotlinClassMap extends JavaToKotlinClassMapBuilder implements
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static AnnotationDescriptor getAnnotationDescriptorForJavaLangDeprecated(@NotNull ClassDescriptor classDescriptor) {
|
||||
private static AnnotationDescriptor getAnnotationDescriptorForJavaLangDeprecated(@NotNull ClassDescriptor annotationClass) {
|
||||
AnnotationDescriptor annotation = new AnnotationDescriptor();
|
||||
annotation.setAnnotationType(classDescriptor.getDefaultType());
|
||||
ValueParameterDescriptor value =
|
||||
DescriptorResolverUtils.getValueParameterDescriptorForAnnotationParameter(Name.identifier("value"), classDescriptor);
|
||||
annotation.setAnnotationType(annotationClass.getDefaultType());
|
||||
ValueParameterDescriptor value = DescriptorResolverUtils.getAnnotationParameterByName(
|
||||
JavaAnnotationResolver.DEFAULT_ANNOTATION_MEMBER_NAME, annotationClass);
|
||||
assert value != null : "jet.deprecated must have one parameter called value";
|
||||
annotation.setValueArgument(value, new StringValue("Deprecated in Java"));
|
||||
return annotation;
|
||||
|
||||
+1
-1
@@ -217,7 +217,7 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
|
||||
|
||||
private void setArgumentValueByName(@NotNull String name, @NotNull CompileTimeConstant<?> argumentValue) {
|
||||
ValueParameterDescriptor parameter =
|
||||
DescriptorResolverUtils.getValueParameterDescriptorForAnnotationParameter(Name.identifier(name), annotationClass);
|
||||
DescriptorResolverUtils.getAnnotationParameterByName(Name.identifier(name), annotationClass);
|
||||
if (parameter != null) {
|
||||
annotation.setValueArgument(parameter, argumentValue);
|
||||
}
|
||||
|
||||
+45
-49
@@ -16,9 +16,10 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.java.resolver;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiModifierList;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
@@ -30,18 +31,21 @@ 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.JavaAnnotationArgument;
|
||||
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;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN_SOURCES;
|
||||
|
||||
public final class JavaAnnotationResolver {
|
||||
public static final Name DEFAULT_ANNOTATION_MEMBER_NAME = Name.identifier("value");
|
||||
|
||||
private JavaClassResolver classResolver;
|
||||
private JavaCompileTimeConstResolver compileTimeConstResolver;
|
||||
|
||||
@@ -59,20 +63,20 @@ public final class JavaAnnotationResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<AnnotationDescriptor> resolveAnnotations(@NotNull PsiModifierListOwner owner, @NotNull PostponedTasks tasks) {
|
||||
PsiAnnotation[] psiAnnotations = getAllAnnotations(owner);
|
||||
List<AnnotationDescriptor> r = Lists.newArrayListWithCapacity(psiAnnotations.length);
|
||||
for (PsiAnnotation psiAnnotation : psiAnnotations) {
|
||||
AnnotationDescriptor annotation = resolveAnnotation(psiAnnotation, tasks);
|
||||
public List<AnnotationDescriptor> resolveAnnotations(@NotNull JavaAnnotationOwner owner, @NotNull PostponedTasks tasks) {
|
||||
Collection<JavaAnnotation> annotations = getAnnotationsWithExternal(owner);
|
||||
List<AnnotationDescriptor> result = new ArrayList<AnnotationDescriptor>(annotations.size());
|
||||
for (JavaAnnotation javaAnnotation : annotations) {
|
||||
AnnotationDescriptor annotation = resolveAnnotation(javaAnnotation, tasks);
|
||||
if (annotation != null) {
|
||||
r.add(annotation);
|
||||
result.add(annotation);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<AnnotationDescriptor> resolveAnnotations(@NotNull PsiModifierListOwner owner) {
|
||||
public List<AnnotationDescriptor> resolveAnnotations(@NotNull JavaAnnotationOwner owner) {
|
||||
PostponedTasks postponedTasks = new PostponedTasks();
|
||||
List<AnnotationDescriptor> annotations = resolveAnnotations(owner, postponedTasks);
|
||||
postponedTasks.performTasks();
|
||||
@@ -80,30 +84,28 @@ public final class JavaAnnotationResolver {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AnnotationDescriptor resolveAnnotation(PsiAnnotation psiAnnotation, @NotNull PostponedTasks postponedTasks) {
|
||||
public AnnotationDescriptor resolveAnnotation(@NotNull JavaAnnotation javaAnnotation, @NotNull PostponedTasks postponedTasks) {
|
||||
final AnnotationDescriptor annotation = new AnnotationDescriptor();
|
||||
String qname = psiAnnotation.getQualifiedName();
|
||||
if (qname == null) {
|
||||
FqName fqName = javaAnnotation.getFqName();
|
||||
if (fqName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Don't process internal jet annotations and jetbrains NotNull annotations
|
||||
if (qname.startsWith("jet.runtime.typeinfo.")
|
||||
|| qname.equals(JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().asString())
|
||||
|| qname.equals(JvmAnnotationNames.KOTLIN_CLASS.getFqName().asString())
|
||||
|| qname.equals(JvmAnnotationNames.KOTLIN_PACKAGE.getFqName().asString())
|
||||
if (fqName.asString().startsWith("jet.runtime.typeinfo.")
|
||||
|| fqName.equals(JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION.getFqName())
|
||||
|| fqName.equals(JvmAnnotationNames.KOTLIN_CLASS.getFqName())
|
||||
|| fqName.equals(JvmAnnotationNames.KOTLIN_PACKAGE.getFqName())
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FqName annotationFqName = new FqName(qname);
|
||||
|
||||
AnnotationDescriptor mappedClassDescriptor = JavaToKotlinClassMap.getInstance().mapToAnnotationClass(annotationFqName);
|
||||
AnnotationDescriptor mappedClassDescriptor = JavaToKotlinClassMap.getInstance().mapToAnnotationClass(fqName);
|
||||
if (mappedClassDescriptor != null) {
|
||||
return mappedClassDescriptor;
|
||||
}
|
||||
|
||||
final ClassDescriptor annotationClass = classResolver.resolveClass(annotationFqName, INCLUDE_KOTLIN_SOURCES, postponedTasks);
|
||||
final ClassDescriptor annotationClass = classResolver.resolveClass(fqName, INCLUDE_KOTLIN_SOURCES, postponedTasks);
|
||||
if (annotationClass == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -116,22 +118,15 @@ public final class JavaAnnotationResolver {
|
||||
});
|
||||
|
||||
|
||||
PsiAnnotationParameterList parameterList = psiAnnotation.getParameterList();
|
||||
for (PsiNameValuePair psiNameValuePair : parameterList.getAttributes()) {
|
||||
PsiAnnotationMemberValue value = psiNameValuePair.getValue();
|
||||
String name = psiNameValuePair.getName();
|
||||
if (name == null) name = "value";
|
||||
Name identifier = Name.identifier(name);
|
||||
for (JavaAnnotationArgument argument : javaAnnotation.getArguments()) {
|
||||
CompileTimeConstant value = compileTimeConstResolver.resolveAnnotationArgument(fqName, argument, postponedTasks);
|
||||
if (value == null) continue;
|
||||
|
||||
if (value == null) return null;
|
||||
CompileTimeConstant compileTimeConst =
|
||||
compileTimeConstResolver.getCompileTimeConstFromExpression(annotationFqName, identifier, value, postponedTasks);
|
||||
if (compileTimeConst != null) {
|
||||
ValueParameterDescriptor valueParameterDescriptor =
|
||||
DescriptorResolverUtils.getValueParameterDescriptorForAnnotationParameter(identifier, annotationClass);
|
||||
if (valueParameterDescriptor != null) {
|
||||
annotation.setValueArgument(valueParameterDescriptor, compileTimeConst);
|
||||
}
|
||||
Name name = argument.getName();
|
||||
ValueParameterDescriptor descriptor = DescriptorResolverUtils.getAnnotationParameterByName(
|
||||
name == null ? DEFAULT_ANNOTATION_MEMBER_NAME : name, annotationClass);
|
||||
if (descriptor != null) {
|
||||
annotation.setValueArgument(descriptor, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,30 +134,31 @@ public final class JavaAnnotationResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiAnnotation[] getAllAnnotations(@NotNull PsiModifierListOwner owner) {
|
||||
List<PsiAnnotation> result = new ArrayList<PsiAnnotation>();
|
||||
private static Collection<JavaAnnotation> getAnnotationsWithExternal(@NotNull JavaAnnotationOwner owner) {
|
||||
List<JavaAnnotation> result = new ArrayList<JavaAnnotation>();
|
||||
|
||||
PsiModifierList list = owner.getModifierList();
|
||||
if (list != null) {
|
||||
result.addAll(Arrays.asList(list.getAnnotations()));
|
||||
}
|
||||
result.addAll(owner.getAnnotations());
|
||||
|
||||
PsiAnnotation[] externalAnnotations = ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotations(owner);
|
||||
PsiAnnotation[] externalAnnotations =
|
||||
ExternalAnnotationsManager.getInstance(owner.getPsi().getProject()).findExternalAnnotations(owner.getPsi());
|
||||
if (externalAnnotations != null) {
|
||||
result.addAll(Arrays.asList(externalAnnotations));
|
||||
for (PsiAnnotation annotation : externalAnnotations) {
|
||||
result.add(new JavaAnnotation(annotation));
|
||||
}
|
||||
}
|
||||
|
||||
return result.toArray(new PsiAnnotation[result.size()]);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiAnnotation findAnnotationWithExternal(@NotNull JavaAnnotationOwner owner, @NotNull JvmClassName name) {
|
||||
public static JavaAnnotation findAnnotationWithExternal(@NotNull JavaAnnotationOwner owner, @NotNull JvmClassName name) {
|
||||
JavaAnnotation annotation = owner.findAnnotation(name.getFqName());
|
||||
if (annotation != null) {
|
||||
return annotation.getPsi();
|
||||
return annotation;
|
||||
}
|
||||
|
||||
return findExternalAnnotation(owner.getPsi(), name);
|
||||
PsiAnnotation externalAnnotation = findExternalAnnotation(owner.getPsi(), name);
|
||||
return externalAnnotation == null ? null : new JavaAnnotation(externalAnnotation);
|
||||
}
|
||||
|
||||
public static boolean hasNotNullAnnotation(@NotNull JavaAnnotationOwner owner) {
|
||||
|
||||
+3
-5
@@ -22,7 +22,6 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -327,12 +326,11 @@ public final class JavaClassResolver {
|
||||
classDescriptor.getBuilder().setClassObjectDescriptor(classObjectDescriptor);
|
||||
}
|
||||
|
||||
PsiClass psiClass = javaClass.getPsi();
|
||||
classDescriptor.setAnnotations(annotationResolver.resolveAnnotations(psiClass, taskList));
|
||||
classDescriptor.setAnnotations(annotationResolver.resolveAnnotations(javaClass, taskList));
|
||||
|
||||
trace.record(BindingContext.CLASS, psiClass, classDescriptor);
|
||||
trace.record(BindingContext.CLASS, javaClass.getPsi(), classDescriptor);
|
||||
|
||||
JavaMethod samInterfaceMethod = SingleAbstractMethodUtils.getSamInterfaceMethod(javaClass, psiClass.getProject());
|
||||
JavaMethod samInterfaceMethod = SingleAbstractMethodUtils.getSamInterfaceMethod(javaClass, javaClass.getPsi().getProject());
|
||||
if (samInterfaceMethod != null) {
|
||||
SimpleFunctionDescriptor abstractMethod = resolveFunctionOfSamInterface(samInterfaceMethod, classDescriptor);
|
||||
classDescriptor.setFunctionTypeForSamInterface(SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(abstractMethod));
|
||||
|
||||
+58
-74
@@ -16,20 +16,19 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.java.resolver;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.constants.*;
|
||||
import org.jetbrains.jet.lang.resolve.constants.StringValue;
|
||||
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.*;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
@@ -38,6 +37,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getEnumEntriesScope;
|
||||
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN_SOURCES;
|
||||
|
||||
public final class JavaCompileTimeConstResolver {
|
||||
@@ -58,103 +58,87 @@ public final class JavaCompileTimeConstResolver {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompileTimeConstant<?> getCompileTimeConstFromExpression(
|
||||
FqName annotationFqName, Name parameterName,
|
||||
PsiAnnotationMemberValue value, PostponedTasks postponedTasks
|
||||
public CompileTimeConstant<?> resolveAnnotationArgument(
|
||||
@NotNull FqName annotationFqName,
|
||||
@NotNull JavaAnnotationArgument argument,
|
||||
@NotNull PostponedTasks postponedTasks
|
||||
) {
|
||||
if (value instanceof PsiLiteralExpression) {
|
||||
return resolveCompileTimeConstantValue(((PsiLiteralExpression) value).getValue(), null);
|
||||
if (argument instanceof JavaLiteralAnnotationArgument) {
|
||||
return resolveCompileTimeConstantValue(((JavaLiteralAnnotationArgument) argument).getValue(), null);
|
||||
}
|
||||
// Enum
|
||||
else if (value instanceof PsiReferenceExpression) {
|
||||
return getCompileTimeConstFromReferenceExpression((PsiReferenceExpression) value, postponedTasks);
|
||||
else if (argument instanceof JavaReferenceAnnotationArgument) {
|
||||
return resolveFromReference(((JavaReferenceAnnotationArgument) argument).resolve(), postponedTasks);
|
||||
}
|
||||
// Array
|
||||
else if (value instanceof PsiArrayInitializerMemberValue) {
|
||||
return getCompileTimeConstFromArrayExpression(annotationFqName, parameterName, (PsiArrayInitializerMemberValue) value,
|
||||
postponedTasks);
|
||||
else if (argument instanceof JavaArrayAnnotationArgument) {
|
||||
Name argumentName = argument.getName();
|
||||
return resolveFromArray(
|
||||
annotationFqName,
|
||||
argumentName == null ? JavaAnnotationResolver.DEFAULT_ANNOTATION_MEMBER_NAME : argumentName,
|
||||
((JavaArrayAnnotationArgument) argument).getElements(),
|
||||
postponedTasks
|
||||
);
|
||||
}
|
||||
// Annotation
|
||||
else if (value instanceof PsiAnnotation) {
|
||||
return getCompileTimeConstFromAnnotation((PsiAnnotation) value, postponedTasks);
|
||||
else if (argument instanceof JavaAnnotationAsAnnotationArgument) {
|
||||
return resolveFromAnnotation(((JavaAnnotationAsAnnotationArgument) argument).getAnnotation(), postponedTasks);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private CompileTimeConstant<?> getCompileTimeConstFromAnnotation(PsiAnnotation value, PostponedTasks taskList) {
|
||||
AnnotationDescriptor annotationDescriptor = annotationResolver.resolveAnnotation(value, taskList);
|
||||
if (annotationDescriptor != null) {
|
||||
return new AnnotationValue(annotationDescriptor);
|
||||
}
|
||||
return null;
|
||||
private CompileTimeConstant<?> resolveFromAnnotation(@NotNull JavaAnnotation value, @NotNull PostponedTasks taskList) {
|
||||
AnnotationDescriptor descriptor = annotationResolver.resolveAnnotation(value, taskList);
|
||||
return descriptor == null ? null : new AnnotationValue(descriptor);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private CompileTimeConstant<?> getCompileTimeConstFromArrayExpression(
|
||||
FqName annotationFqName,
|
||||
Name valueName, PsiArrayInitializerMemberValue value,
|
||||
PostponedTasks taskList
|
||||
private CompileTimeConstant<?> resolveFromArray(
|
||||
@NotNull FqName annotationFqName,
|
||||
@NotNull Name argumentName,
|
||||
@NotNull Collection<JavaAnnotationArgument> elements,
|
||||
@NotNull PostponedTasks taskList
|
||||
) {
|
||||
PsiAnnotationMemberValue[] initializers = value.getInitializers();
|
||||
List<CompileTimeConstant<?>> values = getCompileTimeConstantForArrayValues(annotationFqName, valueName, taskList, initializers);
|
||||
|
||||
ClassDescriptor classDescriptor = classResolver.resolveClass(annotationFqName, INCLUDE_KOTLIN_SOURCES, taskList);
|
||||
ClassDescriptor annotationClass = classResolver.resolveClass(annotationFqName, INCLUDE_KOTLIN_SOURCES, taskList);
|
||||
if (annotationClass == null) return null;
|
||||
|
||||
//TODO: nullability issues
|
||||
ValueParameterDescriptor valueParameterDescriptor =
|
||||
DescriptorResolverUtils.getValueParameterDescriptorForAnnotationParameter(valueName, classDescriptor);
|
||||
if (valueParameterDescriptor == null) {
|
||||
return null;
|
||||
}
|
||||
JetType expectedArrayType = valueParameterDescriptor.getType();
|
||||
return new ArrayValue(values, expectedArrayType);
|
||||
}
|
||||
ValueParameterDescriptor valueParameter = DescriptorResolverUtils.getAnnotationParameterByName(argumentName, annotationClass);
|
||||
if (valueParameter == null) return null;
|
||||
|
||||
private List<CompileTimeConstant<?>> getCompileTimeConstantForArrayValues(
|
||||
FqName annotationQualifiedName,
|
||||
Name valueName,
|
||||
PostponedTasks taskList,
|
||||
PsiAnnotationMemberValue[] initializers
|
||||
) {
|
||||
List<CompileTimeConstant<?>> values = new ArrayList<CompileTimeConstant<?>>();
|
||||
for (PsiAnnotationMemberValue initializer : initializers) {
|
||||
CompileTimeConstant<?> compileTimeConstant =
|
||||
getCompileTimeConstFromExpression(annotationQualifiedName, valueName, initializer, taskList);
|
||||
if (compileTimeConstant == null) {
|
||||
compileTimeConstant = NullValue.NULL;
|
||||
}
|
||||
values.add(compileTimeConstant);
|
||||
List<CompileTimeConstant<?>> values = new ArrayList<CompileTimeConstant<?>>(elements.size());
|
||||
for (JavaAnnotationArgument argument : elements) {
|
||||
CompileTimeConstant<?> value = resolveAnnotationArgument(annotationFqName, argument, taskList);
|
||||
values.add(value == null ? NullValue.NULL : value);
|
||||
}
|
||||
return values;
|
||||
|
||||
return new ArrayValue(values, valueParameter.getType());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private CompileTimeConstant<?> getCompileTimeConstFromReferenceExpression(PsiReferenceExpression value, PostponedTasks taskList) {
|
||||
PsiElement resolveElement = value.resolve();
|
||||
if (resolveElement instanceof PsiEnumConstant) {
|
||||
PsiElement psiElement = resolveElement.getParent();
|
||||
if (psiElement instanceof PsiClass) {
|
||||
PsiClass psiClass = (PsiClass) psiElement;
|
||||
String fqName = psiClass.getQualifiedName();
|
||||
if (fqName == null) {
|
||||
return null;
|
||||
}
|
||||
private CompileTimeConstant<?> resolveFromReference(@Nullable JavaElement element, @NotNull PostponedTasks taskList) {
|
||||
if (!(element instanceof JavaField)) return null;
|
||||
|
||||
ClassDescriptor classDescriptor = classResolver.resolveClass(new FqName(fqName), INCLUDE_KOTLIN_SOURCES, taskList);
|
||||
if (classDescriptor == null) return null;
|
||||
JetScope scope = DescriptorUtils.getEnumEntriesScope(classDescriptor);
|
||||
JavaField field = (JavaField) element;
|
||||
if (!field.isEnumEntry()) return null;
|
||||
|
||||
Name identifier = Name.identifier(((PsiEnumConstant) resolveElement).getName());
|
||||
Collection<VariableDescriptor> properties = scope.getProperties(identifier);
|
||||
for (VariableDescriptor variableDescriptor : properties) {
|
||||
if (variableDescriptor.getReceiverParameter() == null) {
|
||||
return new EnumValue((PropertyDescriptor) variableDescriptor);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
JavaClass javaClass = field.getContainingClass();
|
||||
if (javaClass == null) return null;
|
||||
|
||||
FqName fqName = javaClass.getFqName();
|
||||
if (fqName == null) return null;
|
||||
|
||||
ClassDescriptor enumClass = classResolver.resolveClass(fqName, INCLUDE_KOTLIN_SOURCES, taskList);
|
||||
if (enumClass == null) return null;
|
||||
|
||||
for (VariableDescriptor variableDescriptor : getEnumEntriesScope(enumClass).getProperties(field.getName())) {
|
||||
if (variableDescriptor.getReceiverParameter() == null) {
|
||||
return new EnumValue((PropertyDescriptor) variableDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -203,4 +187,4 @@ public final class JavaCompileTimeConstResolver {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -118,7 +118,7 @@ public final class JavaFunctionResolver {
|
||||
|
||||
SimpleFunctionDescriptorImpl functionDescriptorImpl = new SimpleFunctionDescriptorImpl(
|
||||
ownerDescriptor,
|
||||
annotationResolver.resolveAnnotations(psiMethod),
|
||||
annotationResolver.resolveAnnotations(method),
|
||||
method.getName(),
|
||||
CallableMemberDescriptor.Kind.DECLARATION
|
||||
);
|
||||
|
||||
+1
-1
@@ -175,7 +175,7 @@ public final class JavaPropertyResolver {
|
||||
@NotNull JavaField field,
|
||||
boolean isVar
|
||||
) {
|
||||
List<AnnotationDescriptor> annotations = annotationResolver.resolveAnnotations(field.getPsi());
|
||||
List<AnnotationDescriptor> annotations = annotationResolver.resolveAnnotations(field);
|
||||
Visibility visibility = field.getVisibility();
|
||||
|
||||
if (field.isEnumEntry()) {
|
||||
|
||||
+25
@@ -17,7 +17,15 @@
|
||||
package org.jetbrains.jet.lang.resolve.java.structure;
|
||||
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiAnnotationMemberValue;
|
||||
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;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.namedAnnotationArguments;
|
||||
|
||||
public class JavaAnnotation extends JavaElementImpl {
|
||||
public JavaAnnotation(@NotNull PsiAnnotation psiAnnotation) {
|
||||
@@ -29,4 +37,21 @@ public class JavaAnnotation extends JavaElementImpl {
|
||||
public PsiAnnotation getPsi() {
|
||||
return (PsiAnnotation) super.getPsi();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JavaAnnotationArgument findArgument(@NotNull Name name) {
|
||||
PsiAnnotationMemberValue attribute = getPsi().findAttributeValue(name.asString());
|
||||
return attribute == null ? null : JavaAnnotationArgument.create(attribute, name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<JavaAnnotationArgument> getArguments() {
|
||||
return namedAnnotationArguments(getPsi().getParameterList().getAttributes());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FqName getFqName() {
|
||||
String qualifiedName = getPsi().getQualifiedName();
|
||||
return qualifiedName == null ? null : new FqName(qualifiedName);
|
||||
}
|
||||
}
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
public abstract class JavaAnnotationArgument extends JavaElementImpl {
|
||||
private final Name name;
|
||||
|
||||
protected JavaAnnotationArgument(@NotNull PsiAnnotationMemberValue psiAnnotationMemberValue, @Nullable Name name) {
|
||||
super(psiAnnotationMemberValue);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiAnnotationMemberValue getPsi() {
|
||||
return (PsiAnnotationMemberValue) super.getPsi();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JavaAnnotationArgument create(@NotNull PsiAnnotationMemberValue argument, @Nullable Name name) {
|
||||
if (argument instanceof PsiLiteralExpression) {
|
||||
return new JavaLiteralAnnotationArgument((PsiLiteralExpression) argument, name);
|
||||
}
|
||||
else if (argument instanceof PsiReferenceExpression) {
|
||||
return new JavaReferenceAnnotationArgument((PsiReferenceExpression) argument, name);
|
||||
}
|
||||
else if (argument instanceof PsiArrayInitializerMemberValue) {
|
||||
return new JavaArrayAnnotationArgument((PsiArrayInitializerMemberValue) argument, name);
|
||||
}
|
||||
else if (argument instanceof PsiAnnotation) {
|
||||
return new JavaAnnotationAsAnnotationArgument((PsiAnnotation) argument, name);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unsupported annotation argument type: " + argument);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Name getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.PsiAnnotation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
public class JavaAnnotationAsAnnotationArgument extends JavaAnnotationArgument {
|
||||
protected JavaAnnotationAsAnnotationArgument(@NotNull PsiAnnotation psiAnnotation, @Nullable Name name) {
|
||||
super(psiAnnotation, name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiAnnotation getPsi() {
|
||||
return (PsiAnnotation) super.getPsi();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JavaAnnotation getAnnotation() {
|
||||
return new JavaAnnotation(getPsi());
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.PsiArrayInitializerMemberValue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.namelessAnnotationArguments;
|
||||
|
||||
public class JavaArrayAnnotationArgument extends JavaAnnotationArgument {
|
||||
protected JavaArrayAnnotationArgument(@NotNull PsiArrayInitializerMemberValue psiArrayInitializerMemberValue, @Nullable Name name) {
|
||||
super(psiArrayInitializerMemberValue, name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiArrayInitializerMemberValue getPsi() {
|
||||
return (PsiArrayInitializerMemberValue) super.getPsi();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<JavaAnnotationArgument> getElements() {
|
||||
return namelessAnnotationArguments(getPsi().getInitializers());
|
||||
}
|
||||
}
|
||||
+24
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.java.structure;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -117,4 +118,27 @@ import java.util.List;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<JavaAnnotationArgument> namelessAnnotationArguments(@NotNull PsiAnnotationMemberValue[] memberValues) {
|
||||
if (memberValues.length == 0) return Collections.emptyList();
|
||||
List<JavaAnnotationArgument> result = new ArrayList<JavaAnnotationArgument>(memberValues.length);
|
||||
for (PsiAnnotationMemberValue psiAnnotationMemberValue : memberValues) {
|
||||
result.add(JavaAnnotationArgument.create(psiAnnotationMemberValue, null));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<JavaAnnotationArgument> namedAnnotationArguments(@NotNull PsiNameValuePair[] nameValuePairs) {
|
||||
if (nameValuePairs.length == 0) return Collections.emptyList();
|
||||
List<JavaAnnotationArgument> result = new ArrayList<JavaAnnotationArgument>(nameValuePairs.length);
|
||||
for (PsiNameValuePair pair : nameValuePairs) {
|
||||
String name = pair.getName();
|
||||
PsiAnnotationMemberValue value = pair.getValue();
|
||||
assert value != null : "Annotation argument value cannot be null: " + name;
|
||||
result.add(JavaAnnotationArgument.create(value, name == null ? null : Name.identifier(name)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.PsiLiteralExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
public class JavaLiteralAnnotationArgument extends JavaAnnotationArgument {
|
||||
protected JavaLiteralAnnotationArgument(@NotNull PsiLiteralExpression psiLiteralExpression, @Nullable Name name) {
|
||||
super(psiLiteralExpression, name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiLiteralExpression getPsi() {
|
||||
return (PsiLiteralExpression) super.getPsi();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object getValue() {
|
||||
return getPsi().getValue();
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.PsiElement;
|
||||
import com.intellij.psi.PsiEnumConstant;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiReferenceExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
public class JavaReferenceAnnotationArgument extends JavaAnnotationArgument {
|
||||
protected JavaReferenceAnnotationArgument(@NotNull PsiReferenceExpression psiReferenceExpression, @Nullable Name name) {
|
||||
super(psiReferenceExpression, name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReferenceExpression getPsi() {
|
||||
return (PsiReferenceExpression) super.getPsi();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JavaElement resolve() {
|
||||
PsiReferenceExpression expression = getPsi();
|
||||
PsiElement element = expression.resolve();
|
||||
if (element instanceof PsiEnumConstant) {
|
||||
return new JavaField((PsiField) element);
|
||||
}
|
||||
// TODO: other types of references
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user