From 1cdfab761a5ab54dd83f4a20d192cf219de6da27 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 25 Mar 2014 19:08:12 +0400 Subject: [PATCH] Lazy annotation resolution supported --- .../di/InjectorForLazyResolveWithJava.java | 1 + .../di/InjectorForTopDownAnalyzerForJvm.java | 1 + .../jet/di/InjectorForBodyResolve.java | 1 + .../jet/di/InjectorForLazyResolve.java | 1 + .../jetbrains/jet/di/InjectorForMacros.java | 1 + .../di/InjectorForTopDownAnalyzerBasic.java | 1 + .../jet/lang/resolve/AnnotationResolver.java | 42 +++++++++++++++---- .../jet/lang/resolve/BindingContext.java | 5 +-- .../jetbrains/jet/di/InjectorForTests.java | 1 + .../di/InjectorForTopDownAnalyzerForJs.java | 1 + 10 files changed, 44 insertions(+), 11 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java index d96daa3ecb4..5e27587c391 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java @@ -174,6 +174,7 @@ public class InjectorForLazyResolveWithJava { psiBasedMethodSignatureChecker.setExternalSignatureResolver(traceBasedExternalSignatureResolver); annotationResolver.setCallResolver(callResolver); + annotationResolver.setStorageManager(lockBasedStorageManager); callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java index b2dcb5fc294..9191a4154c6 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java @@ -219,6 +219,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly bodyResolver.setTrace(bindingTrace); annotationResolver.setCallResolver(callResolver); + annotationResolver.setStorageManager(storageManager); callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver); diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java index e244531d24e..0b1379de471 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java @@ -120,6 +120,7 @@ public class InjectorForBodyResolve { this.bodyResolver.setTrace(bindingTrace); annotationResolver.setCallResolver(callResolver); + annotationResolver.setStorageManager(storageManager); callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver); diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java index 8f7cae50a74..24dd8f85abd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java @@ -115,6 +115,7 @@ public class InjectorForLazyResolve { this.resolveSession.setTypeResolver(typeResolver); annotationResolver.setCallResolver(callResolver); + annotationResolver.setStorageManager(lockBasedStorageManager); callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver); diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForMacros.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForMacros.java index 0f9767d4526..3972a7799f8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForMacros.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForMacros.java @@ -106,6 +106,7 @@ public class InjectorForMacros { this.expressionTypingComponents.setPlatformToKotlinClassMap(platformToKotlinClassMap); annotationResolver.setCallResolver(callResolver); + annotationResolver.setStorageManager(storageManager); callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver); diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java index f779acabdb3..a2b97b99956 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java @@ -161,6 +161,7 @@ public class InjectorForTopDownAnalyzerBasic { bodyResolver.setTrace(bindingTrace); annotationResolver.setCallResolver(callResolver); + annotationResolver.setStorageManager(storageManager); callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java index f9e65ffd168..19567fbe0c7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -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 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 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 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); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index 23403eb2734..065d8a79300 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -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 ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT = Slices.createSimpleSlice(); - WritableSlice ANNOTATION = - Slices.sliceBuilder().setOpposite(ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT).build(); + WritableSlice ANNOTATION = + Slices.sliceBuilder().setOpposite(ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT).build(); WritableSlice> COMPILE_TIME_VALUE = Slices.createSimpleSlice(); diff --git a/compiler/tests/org/jetbrains/jet/di/InjectorForTests.java b/compiler/tests/org/jetbrains/jet/di/InjectorForTests.java index 447625986a9..4bdb65eb2c4 100644 --- a/compiler/tests/org/jetbrains/jet/di/InjectorForTests.java +++ b/compiler/tests/org/jetbrains/jet/di/InjectorForTests.java @@ -108,6 +108,7 @@ public class InjectorForTests { this.typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver); annotationResolver.setCallResolver(callResolver); + annotationResolver.setStorageManager(storageManager); callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver); diff --git a/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java b/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java index 95e9984dda3..fb72eb478e0 100644 --- a/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java +++ b/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java @@ -161,6 +161,7 @@ public class InjectorForTopDownAnalyzerForJs { bodyResolver.setTrace(bindingTrace); annotationResolver.setCallResolver(callResolver); + annotationResolver.setStorageManager(storageManager); callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver);