Resolve annotations in annotation arguments
This commit is contained in:
@@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
|||||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
|
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||||
|
import org.jetbrains.jet.lang.resolve.constants.AnnotationValue;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.ArrayValue;
|
import org.jetbrains.jet.lang.resolve.constants.ArrayValue;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.EnumValue;
|
import org.jetbrains.jet.lang.resolve.constants.EnumValue;
|
||||||
@@ -173,27 +174,34 @@ public class AnnotationResolver {
|
|||||||
) {
|
) {
|
||||||
OverloadResolutionResults<FunctionDescriptor> results = resolveAnnotationCall(annotationEntry, scope, trace);
|
OverloadResolutionResults<FunctionDescriptor> results = resolveAnnotationCall(annotationEntry, scope, trace);
|
||||||
if (results.isSuccess()) {
|
if (results.isSuccess()) {
|
||||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> descriptorToArgument :
|
AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
|
||||||
results.getResultingCall().getValueArguments().entrySet()) {
|
assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText();
|
||||||
AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
|
resolveAnnotationArgument(annotationDescriptor, results.getResultingCall(), trace);
|
||||||
assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey();
|
private void resolveAnnotationArgument(
|
||||||
|
@NotNull AnnotationDescriptor annotationDescriptor,
|
||||||
|
@NotNull ResolvedCall<? extends CallableDescriptor> call,
|
||||||
|
@NotNull BindingTrace trace
|
||||||
|
) {
|
||||||
|
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> descriptorToArgument :
|
||||||
|
call.getValueArguments().entrySet()) {
|
||||||
|
ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey();
|
||||||
|
|
||||||
JetType varargElementType = parameterDescriptor.getVarargElementType();
|
JetType varargElementType = parameterDescriptor.getVarargElementType();
|
||||||
List<CompileTimeConstant<?>> constants = resolveValueArguments(descriptorToArgument.getValue(), parameterDescriptor.getType(), trace);
|
List<CompileTimeConstant<?>> constants = resolveValueArguments(descriptorToArgument.getValue(), parameterDescriptor.getType(), trace);
|
||||||
if (varargElementType == null) {
|
if (varargElementType == null) {
|
||||||
for (CompileTimeConstant<?> constant : constants) {
|
for (CompileTimeConstant<?> constant : constants) {
|
||||||
annotationDescriptor.setValueArgument(parameterDescriptor, constant);
|
annotationDescriptor.setValueArgument(parameterDescriptor, constant);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
JetType arrayType = KotlinBuiltIns.getInstance().getPrimitiveArrayJetTypeByPrimitiveJetType(varargElementType);
|
else {
|
||||||
if (arrayType == null) {
|
JetType arrayType = KotlinBuiltIns.getInstance().getPrimitiveArrayJetTypeByPrimitiveJetType(varargElementType);
|
||||||
arrayType = KotlinBuiltIns.getInstance().getArrayType(varargElementType);
|
if (arrayType == null) {
|
||||||
}
|
arrayType = KotlinBuiltIns.getInstance().getArrayType(varargElementType);
|
||||||
annotationDescriptor.setValueArgument(parameterDescriptor, new ArrayValue(constants, arrayType));
|
|
||||||
}
|
}
|
||||||
|
annotationDescriptor.setValueArgument(parameterDescriptor, new ArrayValue(constants, arrayType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,7 +218,7 @@ public class AnnotationResolver {
|
|||||||
if (argumentExpression != null) {
|
if (argumentExpression != null) {
|
||||||
CompileTimeConstant<?> constant = resolveAnnotationArgument(argumentExpression, expectedType, trace);
|
CompileTimeConstant<?> constant = resolveAnnotationArgument(argumentExpression, expectedType, trace);
|
||||||
if (constant != null) {
|
if (constant != null) {
|
||||||
constants.add(constant);
|
constants.add(constant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,8 +292,8 @@ public class AnnotationResolver {
|
|||||||
ResolvedCall<? extends CallableDescriptor> call =
|
ResolvedCall<? extends CallableDescriptor> call =
|
||||||
trace.getBindingContext().get(BindingContext.RESOLVED_CALL, (expression).getCalleeExpression());
|
trace.getBindingContext().get(BindingContext.RESOLVED_CALL, (expression).getCalleeExpression());
|
||||||
if (call != null) {
|
if (call != null) {
|
||||||
|
CallableDescriptor resultingDescriptor = call.getResultingDescriptor();
|
||||||
if (AnnotationUtils.isArrayMethodCall(call)) {
|
if (AnnotationUtils.isArrayMethodCall(call)) {
|
||||||
CallableDescriptor resultingDescriptor = call.getResultingDescriptor();
|
|
||||||
JetType type = resultingDescriptor.getValueParameters().iterator().next().getVarargElementType();
|
JetType type = resultingDescriptor.getValueParameters().iterator().next().getVarargElementType();
|
||||||
List<CompileTimeConstant<?>> arguments = Lists.newArrayList();
|
List<CompileTimeConstant<?>> arguments = Lists.newArrayList();
|
||||||
for (ResolvedValueArgument descriptorToArgument : call.getValueArguments().values()) {
|
for (ResolvedValueArgument descriptorToArgument : call.getValueArguments().values()) {
|
||||||
@@ -293,6 +301,17 @@ public class AnnotationResolver {
|
|||||||
}
|
}
|
||||||
return new ArrayValue(arguments, resultingDescriptor.getReturnType());
|
return new ArrayValue(arguments, resultingDescriptor.getReturnType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resultingDescriptor instanceof ConstructorDescriptor) {
|
||||||
|
JetType constructorReturnType = resultingDescriptor.getReturnType();
|
||||||
|
assert constructorReturnType != null : "Constructor should have return type";
|
||||||
|
if (DescriptorUtils.isAnnotationClass(constructorReturnType.getConstructor().getDeclarationDescriptor())) {
|
||||||
|
AnnotationDescriptor descriptor = new AnnotationDescriptor();
|
||||||
|
descriptor.setAnnotationType(constructorReturnType);
|
||||||
|
resolveAnnotationArgument(descriptor, call, trace);
|
||||||
|
return new AnnotationValue(descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ annotation class AnnIntVararg(vararg a: Int)
|
|||||||
annotation class AnnStringVararg(vararg a: String)
|
annotation class AnnStringVararg(vararg a: String)
|
||||||
annotation class AnnStringArray(a: Array<String>)
|
annotation class AnnStringArray(a: Array<String>)
|
||||||
annotation class AnnArrayOfEnum(a: Array<MyEnum>)
|
annotation class AnnArrayOfEnum(a: Array<MyEnum>)
|
||||||
|
annotation class AnnAnn(a: AnnInt)
|
||||||
|
|
||||||
enum class MyEnum {
|
enum class MyEnum {
|
||||||
A
|
A
|
||||||
|
|||||||
+6
@@ -113,6 +113,12 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture {
|
|||||||
doTest(content, expectedAnnotation);
|
doTest(content, expectedAnnotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAnnotationAnnotation() throws Exception {
|
||||||
|
String content = getContent("AnnAnn(AnnInt(1))");
|
||||||
|
String expectedAnnotation = "AnnAnn[a = AnnInt[a = 1.toInt()]: test.AnnInt]";
|
||||||
|
doTest(content, expectedAnnotation);
|
||||||
|
}
|
||||||
|
|
||||||
private void doTest(@NotNull String content, @NotNull String expectedAnnotation) {
|
private void doTest(@NotNull String content, @NotNull String expectedAnnotation) {
|
||||||
NamespaceDescriptor test = getNamespaceDescriptor(content);
|
NamespaceDescriptor test = getNamespaceDescriptor(content);
|
||||||
ClassDescriptor myClass = getClassDescriptor(test, "MyClass");
|
ClassDescriptor myClass = getClassDescriptor(test, "MyClass");
|
||||||
|
|||||||
Reference in New Issue
Block a user