JavaDescriptorResolver: Add resolve for annotation parameters (array, annotation, enum)
Temporary change testData for LoadJavaTest because enums in parameters of annotations in kotlin files is now unsupported
This commit is contained in:
+192
-29
@@ -396,7 +396,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
.getResolverBinaryClassData();
|
.getResolverBinaryClassData();
|
||||||
classDescriptorCache.put(fqName, classData);
|
classDescriptorCache.put(fqName, classData);
|
||||||
classData.classDescriptor.setName(name);
|
classData.classDescriptor.setName(name);
|
||||||
classData.classDescriptor.setAnnotations(resolveAnnotations(psiClass, taskList));
|
|
||||||
|
|
||||||
List<JetType> supertypes = new ArrayList<JetType>();
|
List<JetType> supertypes = new ArrayList<JetType>();
|
||||||
|
|
||||||
@@ -433,6 +432,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
classData.classDescriptor.getBuilder().setClassObjectDescriptor(classObject);
|
classData.classDescriptor.getBuilder().setClassObjectDescriptor(classObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
classData.classDescriptor.setAnnotations(resolveAnnotations(psiClass, taskList));
|
||||||
|
|
||||||
trace.record(BindingContext.CLASS, psiClass, classData.classDescriptor);
|
trace.record(BindingContext.CLASS, psiClass, classData.classDescriptor);
|
||||||
|
|
||||||
return classData;
|
return classData;
|
||||||
@@ -1580,57 +1581,219 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
|||||||
@Nullable
|
@Nullable
|
||||||
private AnnotationDescriptor resolveAnnotation(PsiAnnotation psiAnnotation, @NotNull List<Runnable> taskList) {
|
private AnnotationDescriptor resolveAnnotation(PsiAnnotation psiAnnotation, @NotNull List<Runnable> taskList) {
|
||||||
final AnnotationDescriptor annotation = new AnnotationDescriptor();
|
final AnnotationDescriptor annotation = new AnnotationDescriptor();
|
||||||
|
|
||||||
String qname = psiAnnotation.getQualifiedName();
|
String qname = psiAnnotation.getQualifiedName();
|
||||||
if (qname.startsWith("java.lang.annotation.") || qname.startsWith("jet.runtime.typeinfo.") || qname.equals(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName())) {
|
if (qname == null) {
|
||||||
// TODO
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final ClassDescriptor clazz = resolveClass(new FqName(psiAnnotation.getQualifiedName()), DescriptorSearchRule.INCLUDE_KOTLIN, taskList);
|
// Don't process internal jet annotations and jetbrains NotNull annotations
|
||||||
|
if (qname.startsWith("jet.runtime.typeinfo.") || qname.equals(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
FqName annotationFqName = new FqName(qname);
|
||||||
|
final ClassDescriptor clazz = resolveClass(annotationFqName, DescriptorSearchRule.INCLUDE_KOTLIN, taskList);
|
||||||
if (clazz == null) {
|
if (clazz == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
taskList.add(new Runnable() {
|
taskList.add(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
annotation.setAnnotationType(clazz.getDefaultType());
|
annotation.setAnnotationType(clazz.getDefaultType());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ArrayList<CompileTimeConstant<?>> valueArguments = new ArrayList<CompileTimeConstant<?>>();
|
|
||||||
|
|
||||||
PsiAnnotationParameterList parameterList = psiAnnotation.getParameterList();
|
PsiAnnotationParameterList parameterList = psiAnnotation.getParameterList();
|
||||||
for (PsiNameValuePair psiNameValuePair : parameterList.getAttributes()) {
|
for (PsiNameValuePair psiNameValuePair : parameterList.getAttributes()) {
|
||||||
PsiAnnotationMemberValue value = psiNameValuePair.getValue();
|
PsiAnnotationMemberValue value = psiNameValuePair.getValue();
|
||||||
if (!(value instanceof PsiLiteralExpression)) {
|
String name = psiNameValuePair.getName();
|
||||||
// todo
|
if (name == null) name = "value";
|
||||||
continue;
|
Name identifier = Name.identifier(name);
|
||||||
|
|
||||||
|
CompileTimeConstant compileTimeConst = getCompileTimeConstFromExpression(annotationFqName, identifier, value, taskList);
|
||||||
|
if (compileTimeConst != null) {
|
||||||
|
ValueParameterDescriptor valueParameterDescriptor = getValueParameterDescriptorForAnnotationParameter(identifier, clazz);
|
||||||
|
if (valueParameterDescriptor != null) {
|
||||||
|
annotation.setValueArgument(valueParameterDescriptor, compileTimeConst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Object literalValue = ((PsiLiteralExpression) value).getValue();
|
|
||||||
if (literalValue instanceof String)
|
|
||||||
valueArguments.add(new StringValue((String) literalValue));
|
|
||||||
else if (literalValue instanceof Byte)
|
|
||||||
valueArguments.add(new ByteValue((Byte) literalValue));
|
|
||||||
else if (literalValue instanceof Short)
|
|
||||||
valueArguments.add(new ShortValue((Short) literalValue));
|
|
||||||
else if (literalValue instanceof Character)
|
|
||||||
valueArguments.add(new CharValue((Character) literalValue));
|
|
||||||
else if (literalValue instanceof Integer)
|
|
||||||
valueArguments.add(new IntValue((Integer) literalValue));
|
|
||||||
else if (literalValue instanceof Long)
|
|
||||||
valueArguments.add(new LongValue((Long) literalValue));
|
|
||||||
else if (literalValue instanceof Float)
|
|
||||||
valueArguments.add(new FloatValue((Float) literalValue));
|
|
||||||
else if (literalValue instanceof Double)
|
|
||||||
valueArguments.add(new DoubleValue((Double) literalValue));
|
|
||||||
else if (literalValue == null)
|
|
||||||
valueArguments.add(NullValue.NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
annotation.setValueArguments(valueArguments); // TODO
|
|
||||||
return annotation;
|
return annotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static ValueParameterDescriptor getValueParameterDescriptorForAnnotationParameter(
|
||||||
|
Name argumentName,
|
||||||
|
ClassDescriptor classDescriptor
|
||||||
|
) {
|
||||||
|
Collection<ConstructorDescriptor> constructors = classDescriptor.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)) {
|
||||||
|
return parameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private CompileTimeConstant<?> getCompileTimeConstFromExpression(
|
||||||
|
FqName annotationFqName, Name parameterName,
|
||||||
|
PsiAnnotationMemberValue value, List<Runnable> taskList
|
||||||
|
) {
|
||||||
|
if (value instanceof PsiLiteralExpression) {
|
||||||
|
return getCompileTimeConstFromLiteralExpression((PsiLiteralExpression) value);
|
||||||
|
}
|
||||||
|
// Enum
|
||||||
|
else if (value instanceof PsiReferenceExpression) {
|
||||||
|
return getCompileTimeConstFromReferenceExpression((PsiReferenceExpression) value, taskList);
|
||||||
|
}
|
||||||
|
// Array
|
||||||
|
else if (value instanceof PsiArrayInitializerMemberValue) {
|
||||||
|
return getCompileTimeConstFromArrayExpression(annotationFqName, parameterName, (PsiArrayInitializerMemberValue) value, taskList);
|
||||||
|
}
|
||||||
|
// Annotation
|
||||||
|
else if (value instanceof PsiAnnotation) {
|
||||||
|
return getCompileTimeConstFromAnnotation((PsiAnnotation) value, taskList);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private CompileTimeConstant<?> getCompileTimeConstFromAnnotation(PsiAnnotation value, List<Runnable> taskList) {
|
||||||
|
AnnotationDescriptor annotationDescriptor = resolveAnnotation(value, taskList);
|
||||||
|
if (annotationDescriptor != null) {
|
||||||
|
return new AnnotationValue(annotationDescriptor);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private CompileTimeConstant<?> getCompileTimeConstFromArrayExpression(
|
||||||
|
FqName annotationFqName,
|
||||||
|
Name valueName, PsiArrayInitializerMemberValue value,
|
||||||
|
List<Runnable> taskList
|
||||||
|
) {
|
||||||
|
PsiAnnotationMemberValue[] initializers = value.getInitializers();
|
||||||
|
List<CompileTimeConstant<?>> values = getCompileTimeConstantForArrayValues(annotationFqName, valueName, taskList, initializers);
|
||||||
|
|
||||||
|
ClassDescriptor classDescriptor = resolveClass(annotationFqName, DescriptorSearchRule.INCLUDE_KOTLIN, taskList);
|
||||||
|
|
||||||
|
JetType expectedArrayType = getExpectedArrayType(classDescriptor, valueName);
|
||||||
|
if (expectedArrayType == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new ArrayValue(values, expectedArrayType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<CompileTimeConstant<?>> getCompileTimeConstantForArrayValues(
|
||||||
|
FqName annotationQualifiedName,
|
||||||
|
Name valueName,
|
||||||
|
List<Runnable> 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);
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private JetType getExpectedArrayType(ClassDescriptor clazz, Name argumentName) {
|
||||||
|
Collection<ConstructorDescriptor> constructors = clazz.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)) {
|
||||||
|
return parameter.getType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private CompileTimeConstant<?> getCompileTimeConstFromReferenceExpression(PsiReferenceExpression value, List<Runnable> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
JetScope scope;
|
||||||
|
ClassDescriptor classDescriptor = resolveClass(new FqName(fqName), DescriptorSearchRule.INCLUDE_KOTLIN, taskList);
|
||||||
|
if (classDescriptor == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ClassDescriptor classObjectDescriptor = classDescriptor.getClassObjectDescriptor();
|
||||||
|
if (classObjectDescriptor == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
scope = classObjectDescriptor.getMemberScope(Lists.<TypeProjection>newArrayList());
|
||||||
|
|
||||||
|
Name identifier = Name.identifier(((PsiEnumConstant) resolveElement).getName());
|
||||||
|
Collection<VariableDescriptor> properties = scope.getProperties(identifier);
|
||||||
|
for (VariableDescriptor variableDescriptor : properties) {
|
||||||
|
if (!variableDescriptor.getReceiverParameter().exists()) {
|
||||||
|
return new EnumValue((PropertyDescriptor) variableDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private CompileTimeConstant<?> getCompileTimeConstFromLiteralExpression(PsiLiteralExpression value) {
|
||||||
|
Object literalValue = value.getValue();
|
||||||
|
if (literalValue instanceof String) {
|
||||||
|
return new StringValue((String) literalValue);
|
||||||
|
}
|
||||||
|
else if (literalValue instanceof Byte) {
|
||||||
|
return new ByteValue((Byte) literalValue);
|
||||||
|
}
|
||||||
|
else if (literalValue instanceof Short) {
|
||||||
|
return new ShortValue((Short) literalValue);
|
||||||
|
}
|
||||||
|
else if (literalValue instanceof Character) {
|
||||||
|
return new CharValue((Character) literalValue);
|
||||||
|
}
|
||||||
|
else if (literalValue instanceof Integer) {
|
||||||
|
return new IntValue((Integer) literalValue);
|
||||||
|
}
|
||||||
|
else if (literalValue instanceof Long) {
|
||||||
|
return new LongValue((Long) literalValue);
|
||||||
|
}
|
||||||
|
else if (literalValue instanceof Float) {
|
||||||
|
return new FloatValue((Float) literalValue);
|
||||||
|
}
|
||||||
|
else if (literalValue instanceof Double) {
|
||||||
|
return new DoubleValue((Double) literalValue);
|
||||||
|
}
|
||||||
|
else if (literalValue == null) {
|
||||||
|
return NullValue.NULL;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public List<FunctionDescriptor> resolveMethods(@NotNull ResolverScopeData scopeData) {
|
public List<FunctionDescriptor> resolveMethods(@NotNull ResolverScopeData scopeData) {
|
||||||
|
|
||||||
getResolverScopeData(scopeData);
|
getResolverScopeData(scopeData);
|
||||||
|
|||||||
+6
@@ -45,4 +45,10 @@ public interface AnnotationArgumentVisitor<R, D> {
|
|||||||
R visitStringValue(StringValue value, D data);
|
R visitStringValue(StringValue value, D data);
|
||||||
|
|
||||||
R visitNullValue(NullValue value, D data);
|
R visitNullValue(NullValue value, D data);
|
||||||
|
|
||||||
|
R visitEnumValue(EnumValue value, D data);
|
||||||
|
|
||||||
|
R visitArrayValue(ArrayValue value, D data);
|
||||||
|
|
||||||
|
R visitAnnotationValue(AnnotationValue value, D data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 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.constants;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Natalia Ukhorskaya
|
||||||
|
*/
|
||||||
|
public class AnnotationValue implements CompileTimeConstant<AnnotationDescriptor> {
|
||||||
|
|
||||||
|
private final AnnotationDescriptor value;
|
||||||
|
|
||||||
|
public AnnotationValue(@NotNull AnnotationDescriptor value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public AnnotationDescriptor getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public JetType getType(@NotNull JetStandardLibrary standardLibrary) {
|
||||||
|
return value.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R, D> R accept(AnnotationArgumentVisitor<R, D> visitor, D data) {
|
||||||
|
return visitor.visitAnnotationValue(this, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 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.constants;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Natalia.Ukhorskaya
|
||||||
|
*/
|
||||||
|
public class ArrayValue implements CompileTimeConstant<List<CompileTimeConstant<?>>> {
|
||||||
|
|
||||||
|
private final List<CompileTimeConstant<?>> value;
|
||||||
|
private final JetType type;
|
||||||
|
|
||||||
|
public ArrayValue(@NotNull List<CompileTimeConstant<?>> value, @NotNull JetType type) {
|
||||||
|
this.value = value;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public List<CompileTimeConstant<?>> getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JetType getType(@NotNull JetStandardLibrary standardLibrary) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R, D> R accept(AnnotationArgumentVisitor<R, D> visitor, D data) {
|
||||||
|
return visitor.visitArrayValue(this, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
ArrayValue that = (ArrayValue) o;
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
return that.value == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (Object thisObject : value) {
|
||||||
|
if (!thisObject.equals(that.value.get(i))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hashCode = 0;
|
||||||
|
if (value == null) return hashCode;
|
||||||
|
for (Object o : value) {
|
||||||
|
hashCode += o.hashCode();
|
||||||
|
}
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 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.constants;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Natalia.Ukhorskaya
|
||||||
|
*/
|
||||||
|
public class EnumValue implements CompileTimeConstant<PropertyDescriptor> {
|
||||||
|
|
||||||
|
private final PropertyDescriptor value;
|
||||||
|
|
||||||
|
public EnumValue(@NotNull PropertyDescriptor value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public PropertyDescriptor getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JetType getType(@NotNull JetStandardLibrary standardLibrary) {
|
||||||
|
return value.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R, D> R accept(AnnotationArgumentVisitor<R, D> visitor, D data) {
|
||||||
|
return visitor.visitEnumValue(this, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value.getType() + "." + value.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
EnumValue enumValue = (EnumValue) o;
|
||||||
|
|
||||||
|
return value.equals(enumValue.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return value.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
package annotations;
|
||||||
|
|
||||||
|
import java.lang.String;
|
||||||
|
|
||||||
|
@interface MyAnnotationWithParam {
|
||||||
|
MyAnnotation value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@interface MyAnnotation {
|
||||||
|
String value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@MyAnnotationWithParam(@MyAnnotation("test"))
|
||||||
|
class A {}
|
||||||
|
|
||||||
|
@interface MyAnnotation2 {
|
||||||
|
String[] value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@interface MyAnnotationWithParam2 {
|
||||||
|
MyAnnotation2 value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@MyAnnotationWithParam2(@MyAnnotation2({"test", "test2"}))
|
||||||
|
class B {}
|
||||||
|
|
||||||
|
@interface MyAnnotation3 {
|
||||||
|
String first();
|
||||||
|
String second();
|
||||||
|
}
|
||||||
|
|
||||||
|
@interface MyAnnotationWithParam3 {
|
||||||
|
MyAnnotation3 value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@MyAnnotationWithParam3(@MyAnnotation3(first = "f", second = "s"))
|
||||||
|
class C {}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
package annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target({ElementType.FIELD, ElementType.CONSTRUCTOR})
|
||||||
|
@interface targetAnnotation {
|
||||||
|
String value();
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package annotations;
|
||||||
|
|
||||||
|
import java.lang.String;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@interface MyAnnotation {
|
||||||
|
String[] value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@MyAnnotation({"a", "b", "c"})
|
||||||
|
class A {
|
||||||
|
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package annotations;
|
||||||
|
|
||||||
|
import java.lang.String;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@interface MyAnnotation {
|
||||||
|
String[] value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@MyAnnotation({})
|
||||||
|
class A {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@interface retentionAnnotation {
|
||||||
|
String value();
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package annotations;
|
||||||
|
|
||||||
|
@MyAnnotation(MyEnum.ONE)
|
||||||
|
class MyTest {}
|
||||||
|
|
||||||
|
@interface MyAnnotation {
|
||||||
|
MyEnum value();
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MyEnum {
|
||||||
|
ONE
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package annotations;
|
||||||
|
|
||||||
|
@MyAnnotation(first = "f", second = "s")
|
||||||
|
class MyTest {}
|
||||||
|
|
||||||
|
@interface MyAnnotation {
|
||||||
|
String first();
|
||||||
|
String second() default("s");
|
||||||
|
}
|
||||||
|
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package annotations;
|
||||||
|
|
||||||
|
import annotations.MyEnum;
|
||||||
|
|
||||||
|
@interface MyAnnotation {
|
||||||
|
MyEnum value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@MyAnnotation(MyEnum.ONE)
|
||||||
|
class testClass {}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package annotations
|
||||||
|
|
||||||
|
public enum class MyEnum {
|
||||||
|
ONE
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package annotations;
|
||||||
|
|
||||||
|
@B(@A("test"))
|
||||||
|
@interface A {
|
||||||
|
String value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@B(@A("test"))
|
||||||
|
@interface B {
|
||||||
|
A value();
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package annotations;
|
||||||
|
|
||||||
|
@interface A {
|
||||||
|
B value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@A(@B("test"))
|
||||||
|
@interface B {
|
||||||
|
String value();
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package test;
|
package test;
|
||||||
|
|
||||||
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)
|
//@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)
|
||||||
@AnnotatedAnnotation
|
@AnnotatedAnnotation
|
||||||
public @interface AnnotatedAnnotation {
|
public @interface AnnotatedAnnotation {
|
||||||
}
|
}
|
||||||
|
|||||||
+319
@@ -0,0 +1,319 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 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.jvm.compiler;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
||||||
|
import org.jetbrains.jet.ConfigurationKind;
|
||||||
|
import org.jetbrains.jet.JetTestUtils;
|
||||||
|
import org.jetbrains.jet.TestJdkKind;
|
||||||
|
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||||
|
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
|
||||||
|
import org.jetbrains.jet.lang.BuiltinsScopeExtensionMode;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.constants.AnnotationValue;
|
||||||
|
import org.jetbrains.jet.lang.resolve.constants.ArrayValue;
|
||||||
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||||
|
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||||
|
import org.jetbrains.jet.test.TestCaseWithTmpdir;
|
||||||
|
import org.jetbrains.jet.utils.PathUtil;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver.getValueParameterDescriptorForAnnotationParameter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Natalia Ukhorskaya
|
||||||
|
*/
|
||||||
|
public class AnnotationJavaDescriptorResolverTest extends TestCaseWithTmpdir {
|
||||||
|
|
||||||
|
private static final String PATH = "compiler/testData/javaDescriptorResolver/annotations/";
|
||||||
|
private static final String DEFAULT_PACKAGE = "annotations";
|
||||||
|
|
||||||
|
private JavaDescriptorResolver javaDescriptorResolver;
|
||||||
|
|
||||||
|
public void testCustomAnnotationWithKotlinEnum() throws IOException {
|
||||||
|
File testFile = new File(PATH + "kotlinEnum.kt");
|
||||||
|
|
||||||
|
LoadDescriptorUtil.compileKotlinToDirAndGetAnalyzeExhaust(testFile, tmpdir, myTestRootDisposable);
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder(tmpdir.getAbsolutePath());
|
||||||
|
builder.append(File.pathSeparator);
|
||||||
|
File runtimePath = PathUtil.getDefaultRuntimePath();
|
||||||
|
if (runtimePath != null) {
|
||||||
|
builder.append(runtimePath.getAbsolutePath());
|
||||||
|
builder.append(File.pathSeparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
File annotationsPath = PathUtil.getJdkAnnotationsPath();
|
||||||
|
if (annotationsPath != null) {
|
||||||
|
builder.append(annotationsPath.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
setUpJavaDescriptorResolver();
|
||||||
|
compileJavaFile("customAnnotationWithKotlinEnum.java", builder.toString());
|
||||||
|
|
||||||
|
String annotationTypeName = DEFAULT_PACKAGE + ".MyAnnotation";
|
||||||
|
AnnotationDescriptor annotation = getAnnotationInClassByType("testClass", annotationTypeName);
|
||||||
|
|
||||||
|
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
|
||||||
|
checkSimpleCompileTimeConstant(actualCompileTimeConstant, DEFAULT_PACKAGE + ".MyEnum", "MyEnum.ONE");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCustomAnnotation() throws IOException {
|
||||||
|
setUpJavaDescriptorResolver();
|
||||||
|
compileJavaFile("customAnnotation.java", null);
|
||||||
|
String annotationTypeName = DEFAULT_PACKAGE + ".MyAnnotation";
|
||||||
|
AnnotationDescriptor annotation = getAnnotationInClassByType("MyTest", annotationTypeName);
|
||||||
|
|
||||||
|
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
|
||||||
|
checkSimpleCompileTimeConstant(actualCompileTimeConstant, DEFAULT_PACKAGE + ".MyEnum", "MyEnum.ONE");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCustomAnnotationWithDefaultParameter() throws IOException {
|
||||||
|
setUpJavaDescriptorResolver();
|
||||||
|
compileJavaFile("customAnnotationWithDefaultParameter.java", null);
|
||||||
|
String annotationTypeName = DEFAULT_PACKAGE + ".MyAnnotation";
|
||||||
|
AnnotationDescriptor annotation = getAnnotationInClassByType("MyTest", annotationTypeName);
|
||||||
|
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "first");
|
||||||
|
checkSimpleCompileTimeConstant(actualCompileTimeConstant, "jet.String", "\"f\"");
|
||||||
|
|
||||||
|
actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "second");
|
||||||
|
checkSimpleCompileTimeConstant(actualCompileTimeConstant, "jet.String", "\"s\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAnnotationWithAnnotationInParam() throws IOException {
|
||||||
|
setUpJavaDescriptorResolver();
|
||||||
|
compileJavaFile("annotationWithAnnotationInParam.java", null);
|
||||||
|
String annotationTypeName = DEFAULT_PACKAGE + ".MyAnnotationWithParam";
|
||||||
|
AnnotationDescriptor annotation = getAnnotationInClassByType("A",
|
||||||
|
annotationTypeName);
|
||||||
|
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
|
||||||
|
assert actualCompileTimeConstant instanceof AnnotationValue;
|
||||||
|
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "value",
|
||||||
|
DEFAULT_PACKAGE + ".MyAnnotation", "jet.String", "\"test\"");
|
||||||
|
|
||||||
|
String annotationTypeName2 = DEFAULT_PACKAGE + ".MyAnnotationWithParam2";
|
||||||
|
AnnotationDescriptor annotation2 = getAnnotationInClassByType("B", annotationTypeName2);
|
||||||
|
actualCompileTimeConstant = getCompileTimeConstant(annotation2, annotationTypeName2, "value");
|
||||||
|
assert actualCompileTimeConstant instanceof AnnotationValue;
|
||||||
|
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "value",
|
||||||
|
DEFAULT_PACKAGE + ".MyAnnotation2", "jet.Array<jet.String?>?", "[\"test\", \"test2\"]");
|
||||||
|
|
||||||
|
String annotationTypeName3 = DEFAULT_PACKAGE + ".MyAnnotationWithParam3";
|
||||||
|
AnnotationDescriptor annotation3 = getAnnotationInClassByType("C", annotationTypeName3);
|
||||||
|
|
||||||
|
actualCompileTimeConstant = getCompileTimeConstant(annotation3, annotationTypeName3, "value");
|
||||||
|
assert actualCompileTimeConstant instanceof AnnotationValue;
|
||||||
|
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "first",
|
||||||
|
DEFAULT_PACKAGE + ".MyAnnotation3", "jet.String", "\"f\"");
|
||||||
|
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "second",
|
||||||
|
DEFAULT_PACKAGE + ".MyAnnotation3", "jet.String", "\"s\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRecursiveAnnotation() throws IOException {
|
||||||
|
setUpJavaDescriptorResolver();
|
||||||
|
compileJavaFile("recursiveAnnotation.java", null);
|
||||||
|
String annotationTypeName = DEFAULT_PACKAGE + ".B";
|
||||||
|
AnnotationDescriptor annotation = getAnnotationInClassByType("A", annotationTypeName);
|
||||||
|
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
|
||||||
|
assert actualCompileTimeConstant instanceof AnnotationValue;
|
||||||
|
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "value",
|
||||||
|
DEFAULT_PACKAGE + ".A", "jet.String", "\"test\"");
|
||||||
|
|
||||||
|
AnnotationDescriptor annotation2 = getAnnotationInClassByType("B", annotationTypeName);
|
||||||
|
actualCompileTimeConstant = getCompileTimeConstant(annotation2, annotationTypeName, "value");
|
||||||
|
assert actualCompileTimeConstant instanceof AnnotationValue;
|
||||||
|
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "value",
|
||||||
|
DEFAULT_PACKAGE + ".A", "jet.String", "\"test\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRecursiveAnnotation2() throws IOException {
|
||||||
|
setUpJavaDescriptorResolver();
|
||||||
|
compileJavaFile("recursiveAnnotation2.java", null);
|
||||||
|
String annotationTypeName = DEFAULT_PACKAGE + ".A";
|
||||||
|
AnnotationDescriptor annotation = getAnnotationInClassByType("B", annotationTypeName);
|
||||||
|
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
|
||||||
|
assert actualCompileTimeConstant instanceof AnnotationValue;
|
||||||
|
checkAnnotationCompileTimeConstant((AnnotationValue) actualCompileTimeConstant, "value",
|
||||||
|
DEFAULT_PACKAGE + ".B", "jet.String", "\"test\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAnnotationWithEnumInParam() throws IOException {
|
||||||
|
setUpJavaDescriptorResolver();
|
||||||
|
compileJavaFile("annotationWithEnumInParam.java", null);
|
||||||
|
String annotationTypeName = "java.lang.annotation.Retention";
|
||||||
|
AnnotationDescriptor annotation = getAnnotationInClassByType("retentionAnnotation", annotationTypeName);
|
||||||
|
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
|
||||||
|
checkSimpleCompileTimeConstant(actualCompileTimeConstant, "java.lang.annotation.RetentionPolicy", "RetentionPolicy.RUNTIME");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAnnotationWithArrayOfEnumInParam() throws IOException {
|
||||||
|
setUpJavaDescriptorResolver();
|
||||||
|
compileJavaFile("annotationWithArrayOfEnumInParam.java", null);
|
||||||
|
String annotationTypeName = "java.lang.annotation.Target";
|
||||||
|
AnnotationDescriptor annotation = getAnnotationInClassByType("targetAnnotation", annotationTypeName);
|
||||||
|
assertEquals("Number of arguments is incorrect", 1, annotation.getAllValueArguments().size());
|
||||||
|
String[] values = new String[] {"ElementType.FIELD", "ElementType.CONSTRUCTOR"};
|
||||||
|
|
||||||
|
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
|
||||||
|
assert actualCompileTimeConstant instanceof ArrayValue;
|
||||||
|
checkArrayCompileTimeConstant((ArrayValue) actualCompileTimeConstant, "jet.Array<java.lang.annotation.ElementType?>?",
|
||||||
|
"java.lang.annotation.ElementType", values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAnnotationWithArrayOfStringInParam() throws IOException {
|
||||||
|
setUpJavaDescriptorResolver();
|
||||||
|
compileJavaFile("annotationWithArrayOfStringInParam.java", null);
|
||||||
|
String annotationTypeName = DEFAULT_PACKAGE + ".MyAnnotation";
|
||||||
|
AnnotationDescriptor annotation = getAnnotationInClassByType("A", annotationTypeName);
|
||||||
|
assertEquals("Number of arguments is incorrect", 1, annotation.getAllValueArguments().size());
|
||||||
|
String[] values = new String[] {"\"a\"", "\"b\"", "\"c\""};
|
||||||
|
|
||||||
|
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
|
||||||
|
assert actualCompileTimeConstant instanceof ArrayValue;
|
||||||
|
checkArrayCompileTimeConstant((ArrayValue) actualCompileTimeConstant, "jet.Array<jet.String?>?", "jet.String", values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAnnotationWithEmptyArrayInParam() throws IOException {
|
||||||
|
setUpJavaDescriptorResolver();
|
||||||
|
compileJavaFile("annotationWithEmptyArrayInParam.java", null);
|
||||||
|
String annotationTypeName = DEFAULT_PACKAGE + ".MyAnnotation";
|
||||||
|
AnnotationDescriptor annotation = getAnnotationInClassByType("A", annotationTypeName);
|
||||||
|
|
||||||
|
assertEquals("Number of arguments is incorrect", 1, annotation.getAllValueArguments().size());
|
||||||
|
String[] values = new String[] {};
|
||||||
|
|
||||||
|
CompileTimeConstant<?> actualCompileTimeConstant = getCompileTimeConstant(annotation, annotationTypeName, "value");
|
||||||
|
assert actualCompileTimeConstant instanceof ArrayValue;
|
||||||
|
checkArrayCompileTimeConstant((ArrayValue) actualCompileTimeConstant, "jet.Array<jet.String?>?", "jet.String", values);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void compileJavaFile(@NotNull String fileRelativePath, @Nullable String classPath)
|
||||||
|
throws IOException {
|
||||||
|
File javaFile = new File(PATH + fileRelativePath);
|
||||||
|
assertNotNull(javaFile);
|
||||||
|
List<String> options = new ArrayList<String>();
|
||||||
|
options.add("-d");
|
||||||
|
options.add(tmpdir.getPath());
|
||||||
|
if (classPath != null) {
|
||||||
|
options.add("-cp");
|
||||||
|
options.add(classPath);
|
||||||
|
}
|
||||||
|
JetTestUtils.compileJavaFiles(Collections.singleton(javaFile), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpJavaDescriptorResolver() {
|
||||||
|
JetCoreEnvironment jetCoreEnvironment =
|
||||||
|
new JetCoreEnvironment(myTestRootDisposable, CompileCompilerDependenciesTest.compilerConfigurationForTests(
|
||||||
|
ConfigurationKind.JDK_ONLY, TestJdkKind.MOCK_JDK, JetTestUtils.getAnnotationsJar(), tmpdir));
|
||||||
|
|
||||||
|
InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(BuiltinsScopeExtensionMode.ALL,
|
||||||
|
jetCoreEnvironment.getProject());
|
||||||
|
javaDescriptorResolver = injector.getJavaDescriptorResolver();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void compareJetTypeWithClass(@NotNull JetType actualType, @NotNull String expectedType) {
|
||||||
|
assertEquals(expectedType, DescriptorRenderer.TEXT.renderType(actualType));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private CompileTimeConstant<?> getCompileTimeConstant(
|
||||||
|
@NotNull AnnotationDescriptor annotationDescriptor,
|
||||||
|
@NotNull String annotationType,
|
||||||
|
@NotNull String parameterName
|
||||||
|
) {
|
||||||
|
ValueParameterDescriptor valueParameterDescriptor = getValueParameterDescriptor(annotationType, parameterName);
|
||||||
|
CompileTimeConstant<?> actualCompileTimeValue = annotationDescriptor.getValueArgument(valueParameterDescriptor);
|
||||||
|
assertNotNull(actualCompileTimeValue);
|
||||||
|
return actualCompileTimeValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private ValueParameterDescriptor getValueParameterDescriptor(@NotNull String annotationTypeName, @NotNull String parameterName) {
|
||||||
|
ClassDescriptor clazz = javaDescriptorResolver.resolveClass(new FqName(annotationTypeName));
|
||||||
|
assertNotNull("Cannot resolve class with name " + annotationTypeName, clazz);
|
||||||
|
ValueParameterDescriptor valueParameterDescriptor =
|
||||||
|
getValueParameterDescriptorForAnnotationParameter(Name.identifier(parameterName), clazz);
|
||||||
|
assertNotNull("Cannot resolve value parameter for " + parameterName, valueParameterDescriptor);
|
||||||
|
return valueParameterDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private AnnotationDescriptor getAnnotationInClassByType(@NotNull String className, @NotNull String type) throws IOException {
|
||||||
|
ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(new FqName(DEFAULT_PACKAGE + "." + className));
|
||||||
|
assertNotNull("Cannot resolve class with name " + className, classDescriptor);
|
||||||
|
List<AnnotationDescriptor> annotations = classDescriptor.getAnnotations();
|
||||||
|
assertEquals(annotations.size(), 1);
|
||||||
|
for (AnnotationDescriptor annotation : annotations) {
|
||||||
|
if (type.endsWith(annotation.getType().toString())) {
|
||||||
|
compareJetTypeWithClass(annotation.getType(), type);
|
||||||
|
return annotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fail("Cannot find annotation for class " + className + ", type " + type);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkSimpleCompileTimeConstant(@NotNull CompileTimeConstant<?> actual, @NotNull String expectedType, @NotNull String expectedValue) {
|
||||||
|
assertEquals(expectedValue, actual.toString());
|
||||||
|
compareJetTypeWithClass(actual.getType(JetStandardLibrary.getInstance()), expectedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAnnotationCompileTimeConstant(
|
||||||
|
@NotNull AnnotationValue actual,
|
||||||
|
@NotNull String parameterName,
|
||||||
|
@NotNull String expectedType,
|
||||||
|
@NotNull String expectedParameterType,
|
||||||
|
@NotNull String expectedParameterValue
|
||||||
|
) {
|
||||||
|
compareJetTypeWithClass(actual.getType(JetStandardLibrary.getInstance()), expectedType);
|
||||||
|
CompileTimeConstant<?> innerAnnotation = getCompileTimeConstant(actual.getValue(), expectedType, parameterName);
|
||||||
|
checkSimpleCompileTimeConstant(innerAnnotation, expectedParameterType, expectedParameterValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkArrayCompileTimeConstant(
|
||||||
|
@NotNull ArrayValue actual,
|
||||||
|
@NotNull String expectedType,
|
||||||
|
@NotNull String expectedArgumentType,
|
||||||
|
@NotNull String[] expectedValues
|
||||||
|
) {
|
||||||
|
JetType actualType = actual.getType(JetStandardLibrary.getInstance());
|
||||||
|
compareJetTypeWithClass(actualType, expectedType);
|
||||||
|
|
||||||
|
List<CompileTimeConstant<?>> arrayValuesCompileTimeConst = actual.getValue();
|
||||||
|
|
||||||
|
assertEquals("Number of arguments is incorrect", expectedValues.length, arrayValuesCompileTimeConst.size());
|
||||||
|
int i = 0;
|
||||||
|
for (CompileTimeConstant<?> constant : arrayValuesCompileTimeConst) {
|
||||||
|
checkSimpleCompileTimeConstant(constant, expectedArgumentType, expectedValues[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user