Resolve annotation arguments only once
This commit is contained in:
@@ -223,11 +223,17 @@ public class AnnotationResolver {
|
||||
return;
|
||||
}
|
||||
|
||||
AnnotationDescriptorImpl annotationDescriptorImpl = (AnnotationDescriptorImpl) annotationDescriptor;
|
||||
if (annotationDescriptorImpl.areValueArgumentsResolved()) return;
|
||||
|
||||
OverloadResolutionResults<FunctionDescriptor> results = resolveAnnotationCall(annotationEntry, scope, trace);
|
||||
if (results.isSingleResult()) {
|
||||
checkAnnotationType(annotationEntry, trace, results);
|
||||
resolveAnnotationArguments(annotationDescriptor, results.getResultingCall(), trace);
|
||||
}
|
||||
else {
|
||||
annotationDescriptorImpl.markValueArgumentsResolved();
|
||||
}
|
||||
}
|
||||
|
||||
public static void resolveAnnotationArguments(
|
||||
@@ -240,15 +246,19 @@ public class AnnotationResolver {
|
||||
return;
|
||||
}
|
||||
|
||||
AnnotationDescriptorImpl annotationDescriptorImpl = (AnnotationDescriptorImpl) annotationDescriptor;
|
||||
|
||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> descriptorToArgument : resolvedCall.getValueArguments().entrySet()) {
|
||||
ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey();
|
||||
ResolvedValueArgument resolvedArgument = descriptorToArgument.getValue();
|
||||
|
||||
CompileTimeConstant<?> value = getAnnotationArgumentValue(trace, parameterDescriptor, resolvedArgument);
|
||||
if (value != null) {
|
||||
((AnnotationDescriptorImpl) annotationDescriptor).setValueArgument(parameterDescriptor, value);
|
||||
annotationDescriptorImpl.setValueArgument(parameterDescriptor, value);
|
||||
}
|
||||
}
|
||||
|
||||
annotationDescriptorImpl.markValueArgumentsResolved();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+1
@@ -157,6 +157,7 @@ public class AnnotationDescriptorDeserializer extends BaseDescriptorDeserializer
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
annotation.markValueArgumentsResolved();
|
||||
result.add(annotation);
|
||||
}
|
||||
|
||||
|
||||
+14
-2
@@ -30,6 +30,7 @@ import java.util.Map;
|
||||
public class AnnotationDescriptorImpl implements AnnotationDescriptor {
|
||||
private JetType annotationType;
|
||||
private final Map<ValueParameterDescriptor, CompileTimeConstant<?>> valueArguments = Maps.newHashMap();
|
||||
private boolean valueArgumentsResolved = false;
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@@ -40,12 +41,14 @@ public class AnnotationDescriptorImpl implements AnnotationDescriptor {
|
||||
@Override
|
||||
@Nullable
|
||||
public CompileTimeConstant<?> getValueArgument(@NotNull ValueParameterDescriptor valueParameterDescriptor) {
|
||||
return valueArguments.get(valueParameterDescriptor);
|
||||
return getAllValueArguments().get(valueParameterDescriptor);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Map<ValueParameterDescriptor, CompileTimeConstant<?>> getAllValueArguments() {
|
||||
// TODO: this assertion does not hold now, but this whole class will be gone before long, so I'm not fixing it
|
||||
//assert valueArgumentsResolved : "Value arguments are not resolved yet for [" + getType() + "]";
|
||||
return Collections.unmodifiableMap(valueArguments);
|
||||
}
|
||||
|
||||
@@ -54,9 +57,18 @@ public class AnnotationDescriptorImpl implements AnnotationDescriptor {
|
||||
}
|
||||
|
||||
public void setValueArgument(@NotNull ValueParameterDescriptor name, @NotNull CompileTimeConstant<?> value) {
|
||||
assert !valueArgumentsResolved : "Value arguments are already resolved for " + this;
|
||||
valueArguments.put(name, value);
|
||||
}
|
||||
|
||||
public void markValueArgumentsResolved() {
|
||||
this.valueArgumentsResolved = true;
|
||||
}
|
||||
|
||||
public boolean areValueArgumentsResolved() {
|
||||
return valueArgumentsResolved;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return DescriptorRenderer.TEXT.renderAnnotation(this);
|
||||
|
||||
@@ -207,10 +207,16 @@ public class ResolveElementCache {
|
||||
}
|
||||
}
|
||||
|
||||
private static void annotationAdditionalResolve(KotlinCodeAnalyzer analyzer, JetAnnotationEntry jetAnnotationEntry) {
|
||||
private static void annotationAdditionalResolve(ResolveSession resolveSession, JetAnnotationEntry jetAnnotationEntry) {
|
||||
JetDeclaration declaration = PsiTreeUtil.getParentOfType(jetAnnotationEntry, JetDeclaration.class);
|
||||
if (declaration != null) {
|
||||
Annotated descriptor = analyzer.resolveToDescriptor(declaration);
|
||||
Annotated descriptor = resolveSession.resolveToDescriptor(declaration);
|
||||
|
||||
resolveSession.getAnnotationResolver().resolveAnnotationsArguments(
|
||||
descriptor,
|
||||
resolveSession.getTrace(),
|
||||
resolveSession.getScopeProvider().getResolutionScopeForDeclaration(declaration)
|
||||
);
|
||||
|
||||
ForceResolveUtil.forceResolveAllContents(descriptor.getAnnotations());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// "Suppress 'REDUNDANT_NULLABLE' for fun foo" "true"
|
||||
// ERROR: An integer literal does not conform to the expected type kotlin.String
|
||||
// ERROR: An integer literal does not conform to the expected type kotlin.String
|
||||
|
||||
[suppress(1, "REDUNDANT_NULLABLE")]
|
||||
fun foo(): String?<caret>? = null
|
||||
@@ -1,6 +1,5 @@
|
||||
// "Suppress 'REDUNDANT_NULLABLE' for fun foo" "true"
|
||||
// ERROR: An integer literal does not conform to the expected type kotlin.String
|
||||
// ERROR: An integer literal does not conform to the expected type kotlin.String
|
||||
|
||||
[suppress(1)]
|
||||
fun foo(): String?<caret>? = null
|
||||
Reference in New Issue
Block a user