Lazy annotation resolution supported

This commit is contained in:
Andrey Breslav
2014-03-25 19:08:12 +04:00
parent bb17adc8d7
commit 1cdfab761a
10 changed files with 44 additions and 11 deletions
@@ -174,6 +174,7 @@ public class InjectorForLazyResolveWithJava {
psiBasedMethodSignatureChecker.setExternalSignatureResolver(traceBasedExternalSignatureResolver);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setStorageManager(lockBasedStorageManager);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
callResolver.setCandidateResolver(candidateResolver);
@@ -219,6 +219,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
bodyResolver.setTrace(bindingTrace);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setStorageManager(storageManager);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
callResolver.setCandidateResolver(candidateResolver);
@@ -120,6 +120,7 @@ public class InjectorForBodyResolve {
this.bodyResolver.setTrace(bindingTrace);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setStorageManager(storageManager);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
callResolver.setCandidateResolver(candidateResolver);
@@ -115,6 +115,7 @@ public class InjectorForLazyResolve {
this.resolveSession.setTypeResolver(typeResolver);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setStorageManager(lockBasedStorageManager);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
callResolver.setCandidateResolver(candidateResolver);
@@ -106,6 +106,7 @@ public class InjectorForMacros {
this.expressionTypingComponents.setPlatformToKotlinClassMap(platformToKotlinClassMap);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setStorageManager(storageManager);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
callResolver.setCandidateResolver(candidateResolver);
@@ -161,6 +161,7 @@ public class InjectorForTopDownAnalyzerBasic {
bodyResolver.setTrace(bindingTrace);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setStorageManager(storageManager);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
callResolver.setCandidateResolver(candidateResolver);
@@ -36,11 +36,14 @@ import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
import org.jetbrains.jet.lang.resolve.constants.ArrayValue;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyAnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyAnnotationsContext;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.storage.StorageManager;
import javax.inject.Inject;
import java.util.ArrayList;
@@ -53,12 +56,18 @@ import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
public class AnnotationResolver {
private CallResolver callResolver;
private StorageManager storageManager;
@Inject
public void setCallResolver(CallResolver callResolver) {
this.callResolver = callResolver;
}
@Inject
public void setStorageManager(StorageManager storageManager) {
this.storageManager = storageManager;
}
@NotNull
public Annotations resolveAnnotationsWithoutArguments(
@NotNull JetScope scope,
@@ -109,13 +118,20 @@ public class AnnotationResolver {
if (annotationEntryElements.isEmpty()) return Annotations.EMPTY;
List<AnnotationDescriptor> result = Lists.newArrayList();
for (JetAnnotationEntry entryElement : annotationEntryElements) {
AnnotationDescriptorImpl descriptor = trace.get(BindingContext.ANNOTATION, entryElement);
AnnotationDescriptor descriptor = trace.get(BindingContext.ANNOTATION, entryElement);
if (descriptor == null) {
descriptor = new AnnotationDescriptorImpl();
descriptor.setAnnotationType(resolveAnnotationType(scope, entryElement, trace));
if (TopDownAnalyzer.LAZY) {
descriptor = new LazyAnnotationDescriptor(
new LazyAnnotationsContext(this, storageManager, scope, trace),
entryElement
);
}
else {
descriptor = new AnnotationDescriptorImpl();
((AnnotationDescriptorImpl) descriptor).setAnnotationType(resolveAnnotationType(scope, entryElement, trace));
}
trace.record(BindingContext.ANNOTATION, entryElement, descriptor);
}
if (shouldResolveArguments) {
resolveAnnotationArguments(entryElement, scope, trace);
}
@@ -205,26 +221,36 @@ public class AnnotationResolver {
@NotNull JetScope scope,
@NotNull BindingTrace trace
) {
AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText();
if (TopDownAnalyzer.LAZY && annotationDescriptor instanceof LazyAnnotationDescriptor) {
((LazyAnnotationDescriptor) annotationDescriptor).forceResolveAllContents();
return;
}
OverloadResolutionResults<FunctionDescriptor> results = resolveAnnotationCall(annotationEntry, scope, trace);
if (results.isSingleResult()) {
AnnotationDescriptorImpl annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText();
resolveAnnotationArguments(annotationDescriptor, results.getResultingCall(), trace);
}
}
public static void resolveAnnotationArguments(
@NotNull AnnotationDescriptorImpl annotationDescriptor,
@NotNull AnnotationDescriptor annotationDescriptor,
@NotNull ResolvedCall<?> resolvedCall,
@NotNull BindingTrace trace
) {
if (TopDownAnalyzer.LAZY && annotationDescriptor instanceof LazyAnnotationDescriptor) {
((LazyAnnotationDescriptor) annotationDescriptor).forceResolveAllContents();
return;
}
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) {
annotationDescriptor.setValueArgument(parameterDescriptor, value);
((AnnotationDescriptorImpl) annotationDescriptor).setValueArgument(parameterDescriptor, value);
}
}
}
@@ -24,7 +24,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptorImpl;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.TailRecursionKind;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
@@ -73,8 +72,8 @@ public interface BindingContext {
};
WritableSlice<AnnotationDescriptor, JetAnnotationEntry> ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT = Slices.createSimpleSlice();
WritableSlice<JetAnnotationEntry, AnnotationDescriptorImpl> ANNOTATION =
Slices.<JetAnnotationEntry, AnnotationDescriptorImpl>sliceBuilder().setOpposite(ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT).build();
WritableSlice<JetAnnotationEntry, AnnotationDescriptor> ANNOTATION =
Slices.<JetAnnotationEntry, AnnotationDescriptor>sliceBuilder().setOpposite(ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT).build();
WritableSlice<JetExpression, CompileTimeConstant<?>> COMPILE_TIME_VALUE = Slices.createSimpleSlice();
@@ -108,6 +108,7 @@ public class InjectorForTests {
this.typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setStorageManager(storageManager);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
callResolver.setCandidateResolver(candidateResolver);
@@ -161,6 +161,7 @@ public class InjectorForTopDownAnalyzerForJs {
bodyResolver.setTrace(bindingTrace);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setStorageManager(storageManager);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
callResolver.setCandidateResolver(candidateResolver);