From 1a9296425051333049c2ad306029619fe2fa0b26 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 22 Apr 2014 18:31:58 +0400 Subject: [PATCH] JavaDescriptorResolver is cached by KotlinResolveCache Accessible via JavaResolveExtension --- .../resolve/java/AnalyzerFacadeForJVM.java | 32 +++++++++++-- .../caches/resolve/JavaResolveExtension.kt | 33 +++++++++++++ .../caches/resolve/KotlinResolveCache.kt | 47 +++++++++++++++---- .../KotlinSignatureAnnotationIntention.java | 6 +-- .../KotlinSignatureInJavaMarkerProvider.java | 6 +-- .../SignatureMarkerProviderTest.java | 16 +++---- .../DecompiledTextConsistencyTest.kt | 15 ++---- 7 files changed, 113 insertions(+), 42 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/caches/resolve/JavaResolveExtension.kt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java index 12815b10d32..d9061046956 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java @@ -54,13 +54,28 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade { new ImportPath("kotlin.*"), new ImportPath("kotlin.io.*")); + public static class JvmSetup extends BasicSetup { + + private final JavaDescriptorResolver javaDescriptorResolver; + + public JvmSetup(@NotNull ResolveSession session, @NotNull JavaDescriptorResolver javaDescriptorResolver) { + super(session); + this.javaDescriptorResolver = javaDescriptorResolver; + } + + @NotNull + public JavaDescriptorResolver getJavaDescriptorResolver() { + return javaDescriptorResolver; + } + } + private AnalyzerFacadeForJVM() { } @NotNull @Override - public Setup createSetup(@NotNull Project fileProject, @NotNull Collection files) { - return new BasicSetup(createLazyResolveSession(fileProject, files, new BindingTraceContext(), true)); + public JvmSetup createSetup(@NotNull Project fileProject, @NotNull Collection files) { + return createSetup(fileProject, files, new BindingTraceContext(), true); } @NotNull @@ -70,6 +85,16 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade { @NotNull BindingTrace trace, boolean addBuiltIns ) { + + return createSetup(project, files, trace, addBuiltIns).getLazyResolveSession(); + } + + private static JvmSetup createSetup( + Project project, + Collection files, + BindingTrace trace, + boolean addBuiltIns + ) { GlobalContextImpl globalContext = ContextPackage.GlobalContext(); DeclarationProviderFactory declarationProviderFactory = @@ -89,8 +114,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade { DependencyKind.BUILT_INS, KotlinBuiltIns.getInstance().getBuiltInsModule().getPackageFragmentProvider()); } - - return resolveWithJava.getResolveSession(); + return new JvmSetup(resolveWithJava.getResolveSession(), resolveWithJava.getJavaDescriptorResolver()); } @NotNull diff --git a/idea/src/org/jetbrains/jet/plugin/caches/resolve/JavaResolveExtension.kt b/idea/src/org/jetbrains/jet/plugin/caches/resolve/JavaResolveExtension.kt new file mode 100644 index 00000000000..e83debb205a --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/caches/resolve/JavaResolveExtension.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2014 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.plugin.caches.resolve + +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver +import org.jetbrains.jet.analyzer.AnalyzerFacade +import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM.JvmSetup +import org.jetbrains.jet.plugin.project.TargetPlatform +import com.intellij.openapi.project.Project + +object JavaResolveExtension : CacheExtension { + override val platform: TargetPlatform = TargetPlatform.JVM + + override fun getData(setup: AnalyzerFacade.Setup): JavaDescriptorResolver { + return (setup as JvmSetup).getJavaDescriptorResolver() + } + + public fun get(project: Project): JavaDescriptorResolver = KotlinCacheService.getInstance(project)[this] +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt b/idea/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt index db762938365..4f91e255c55 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt +++ b/idea/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt @@ -48,12 +48,8 @@ import org.jetbrains.jet.plugin.project.TargetPlatform import org.jetbrains.jet.plugin.project.TargetPlatform.* import org.jetbrains.jet.plugin.project.ResolveSessionForBodies import org.jetbrains.jet.plugin.project.TargetPlatformDetector -import com.google.common.collect.ImmutableMap -import org.jetbrains.jet.lang.resolve.Diagnostics -import org.jetbrains.jet.util.slicedmap.ReadOnlySlice -import org.jetbrains.jet.util.slicedmap.WritableSlice -import org.jetbrains.jet.lang.diagnostics.Diagnostic import java.util.HashSet +import org.jetbrains.jet.analyzer.AnalyzerFacade private val LOG = Logger.getInstance(javaClass()) @@ -75,6 +71,12 @@ fun getAnalysisResultsForElements(elements: Collection): AnalyzeExha return KotlinCacheService.getInstance(element.getProject()).getAnalysisResults(elements) } +private class SessionAndSetup( + val platform: TargetPlatform, + val resolveSessionForBodies: ResolveSessionForBodies, + val setup: AnalyzerFacade.Setup +) + class KotlinCacheService(val project: Project) { class object { fun getInstance(project: Project) = ServiceManager.getService(project, javaClass())!! @@ -84,8 +86,17 @@ class KotlinCacheService(val project: Project) { val allFiles = JetFilesProvider.getInstance(project).allInScope(GlobalSearchScope.allScope(project)) val files = if (syntheticFile == null) allFiles else collectFilesForSyntheticFile(allFiles, syntheticFile) - val resolveSession = AnalyzerFacadeProvider.getAnalyzerFacade(platform).createSetup(project, files).getLazyResolveSession() - CachedValueProvider.Result.create(ResolveSessionForBodies(project, resolveSession), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT) + val setup = AnalyzerFacadeProvider.getAnalyzerFacade(platform).createSetup(project, files) + val resolveSessionForBodies = ResolveSessionForBodies(project, setup.getLazyResolveSession()) + CachedValueProvider.Result.create( + SessionAndSetup( + platform, + resolveSessionForBodies, + setup + ), + PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, + resolveSessionForBodies + ) } private fun collectFilesForSyntheticFile(allFiles: Collection, syntheticFile: JetFile): Collection { @@ -160,16 +171,32 @@ class KotlinCacheService(val project: Project) { val project = jetFile.getProject() return JetFilesProvider.getInstance(project).isFileInScope(jetFile, GlobalSearchScope.allScope(project)) } + + public fun get(extension: CacheExtension): T { + return globalCachesPerPlatform[extension.platform]!![extension] + } +} + +trait CacheExtension { + val platform: TargetPlatform + fun getData(setup: AnalyzerFacade.Setup): T } private class KotlinResolveCache( val project: Project, - val resolveSessionProvider: () -> CachedValueProvider.Result + val resolveSessionProvider: () -> CachedValueProvider.Result ) { - private val resolveSessionCache = SynchronizedCachedValue(project, resolveSessionProvider) + private val setupCache = SynchronizedCachedValue(project, resolveSessionProvider, trackValue = false) - public fun getLazyResolveSession(): ResolveSessionForBodies = resolveSessionCache.getValue() + public fun getLazyResolveSession(): ResolveSessionForBodies = setupCache.getValue().resolveSessionForBodies + + public fun get(extension: CacheExtension): T { + val sessionAndSetup = setupCache.getValue() + assert(extension.platform == sessionAndSetup.platform, + "Extension $extension declares platfrom ${extension.platform} which is incompatible with ${sessionAndSetup.platform}") + return extension.getData(sessionAndSetup.setup) + } private data class Task( val elements: Set diff --git a/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureAnnotationIntention.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureAnnotationIntention.java index 33c76cf375f..cb3e39ffdfb 100644 --- a/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureAnnotationIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureAnnotationIntention.java @@ -33,8 +33,6 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.messages.MessageBusConnection; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.di.InjectorForJavaDescriptorResolver; -import org.jetbrains.jet.di.InjectorForJavaDescriptorResolverUtil; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext; @@ -44,6 +42,7 @@ import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.JetIcons; +import org.jetbrains.jet.plugin.caches.resolve.JavaResolveExtension; import org.jetbrains.jet.renderer.DescriptorRenderer; import org.jetbrains.jet.renderer.DescriptorRendererBuilder; @@ -164,8 +163,7 @@ public class KotlinSignatureAnnotationIntention extends BaseIntentionAction impl @NotNull private static String getDefaultSignature(@NotNull Project project, @NotNull PsiMember psiMember) { BindingTraceContext trace = new BindingTraceContext(); - InjectorForJavaDescriptorResolver injector = InjectorForJavaDescriptorResolverUtil.create(project, trace); - JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver(); + JavaDescriptorResolver javaDescriptorResolver = JavaResolveExtension.instance$.get(project); PsiClass containingClass = psiMember.getContainingClass(); assert containingClass != null; diff --git a/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerProvider.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerProvider.java index 419a1bf2b21..87930c854af 100644 --- a/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerProvider.java @@ -35,8 +35,6 @@ import com.intellij.util.Function; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.di.InjectorForJavaDescriptorResolver; -import org.jetbrains.jet.di.InjectorForJavaDescriptorResolverUtil; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor; @@ -50,6 +48,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.plugin.JetIcons; +import org.jetbrains.jet.plugin.caches.resolve.JavaResolveExtension; import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager; import org.jetbrains.jet.plugin.caches.resolve.KotlinDeclarationsCache; import org.jetbrains.jet.plugin.project.ProjectStructureUtil; @@ -98,9 +97,8 @@ public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider { } BindingTrace trace = createDelegatingTrace(project); - InjectorForJavaDescriptorResolver injector = InjectorForJavaDescriptorResolverUtil.create(project, trace); - JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver(); + JavaDescriptorResolver javaDescriptorResolver = JavaResolveExtension.instance$.get(project); for (PsiElement element : elements) { if (!(element instanceof PsiMember)) { diff --git a/idea/tests/org/jetbrains/jet/plugin/ktSignature/SignatureMarkerProviderTest.java b/idea/tests/org/jetbrains/jet/plugin/ktSignature/SignatureMarkerProviderTest.java index 5420566ed20..0e92ce47b8a 100644 --- a/idea/tests/org/jetbrains/jet/plugin/ktSignature/SignatureMarkerProviderTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/ktSignature/SignatureMarkerProviderTest.java @@ -19,19 +19,19 @@ package org.jetbrains.jet.plugin.ktSignature; import com.intellij.openapi.project.Project; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiFile; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.di.InjectorForJavaDescriptorResolver; -import org.jetbrains.jet.di.InjectorForJavaDescriptorResolverUtil; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.plugin.JetFileType; import org.jetbrains.jet.plugin.JetLightProjectDescriptor; -import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager; -import org.jetbrains.jet.plugin.project.TargetPlatform; +import org.jetbrains.jet.plugin.caches.resolve.JavaResolveExtension; +import org.jetbrains.jet.plugin.caches.resolve.ResolvePackage; public class SignatureMarkerProviderTest extends LightCodeInsightFixtureTestCase { @@ -46,15 +46,13 @@ public class SignatureMarkerProviderTest extends LightCodeInsightFixtureTestCase project = myFixture.getProject(); - myFixture.configureByText(JetFileType.INSTANCE, "val t: Thread? = null"); + PsiFile file = myFixture.configureByText(JetFileType.INSTANCE, "val t: Thread? = null"); PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass("java.lang.Thread", GlobalSearchScope.allScope(project)); - BindingContext context = KotlinCacheManager.getInstance(project).getDeclarationsFromProject(TargetPlatform.JVM).getBindingContext(); + BindingContext context = ResolvePackage.getBindingContext((JetFile) file); ClassDescriptor preResolvedClass = context.get(BindingContext.CLASS, psiClass); - InjectorForJavaDescriptorResolver injector = - InjectorForJavaDescriptorResolverUtil.create(project, KotlinSignatureInJavaMarkerProvider.createDelegatingTrace(project)); - ClassDescriptor reResolvedClass = injector.getJavaDescriptorResolver() + ClassDescriptor reResolvedClass = JavaResolveExtension.instance$.get(project) .resolveClass(new FqName("java.lang.Thread")); assertSame(preResolvedClass, reResolvedClass); diff --git a/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextConsistencyTest.kt b/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextConsistencyTest.kt index ceacdecf4c1..2e4d824c551 100644 --- a/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextConsistencyTest.kt +++ b/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextConsistencyTest.kt @@ -17,22 +17,16 @@ package org.jetbrains.jet.plugin.libraries import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase -import com.intellij.testFramework.LightProjectDescriptor import org.jetbrains.jet.plugin.JetWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.jet.lang.resolve.name.FqName import org.junit.Assert -import org.jetbrains.jet.plugin.JetJdkAndLibraryProjectDescriptor -import org.jetbrains.jet.jvm.compiler.longTest.ResolveDescriptorsFromExternalLibraries -import org.jetbrains.jet.plugin.JetLightProjectDescriptor -import com.intellij.openapi.projectRoots.Sdk import org.jetbrains.jet.plugin.PluginTestCaseBase import org.jetbrains.jet.lang.resolve.java.PackageClassUtils import com.intellij.openapi.project.Project -import org.jetbrains.jet.di.InjectorForJavaDescriptorResolverUtil -import org.jetbrains.jet.lang.resolve.BindingTraceContext import org.jetbrains.jet.lang.descriptors.ClassDescriptor import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor import java.util.Collections +import org.jetbrains.jet.plugin.caches.resolve.JavaResolveExtension public class DecompiledTextConsistencyTest : JetLightCodeInsightFixtureTestCase() { @@ -40,10 +34,9 @@ public class DecompiledTextConsistencyTest : JetLightCodeInsightFixtureTestCase( public fun testConsistencyWithJavaDescriptorResolver() { val packageClassFqName = PackageClassUtils.getPackageClassFqName(STANDARD_LIBRARY_FQNAME) - val kotlinPackageClass = myFixture!!.getJavaFacade()!!.findClass(packageClassFqName.asString())!! + val kotlinPackageClass = myFixture.getJavaFacade()!!.findClass(packageClassFqName.asString())!! val kotlinPackageFile = kotlinPackageClass.getContainingFile()!!.getVirtualFile()!! - val project = getProject()!! - val projectBasedText = buildDecompiledText(kotlinPackageFile, ProjectBasedResolverForDecompiler(project)).text + val projectBasedText = buildDecompiledText(kotlinPackageFile, ProjectBasedResolverForDecompiler(getProject())).text val deserializerForDecompiler = DeserializerForDecompiler(kotlinPackageFile.getParent()!!, STANDARD_LIBRARY_FQNAME) val deserializedText = buildDecompiledText(kotlinPackageFile, deserializerForDecompiler).text Assert.assertEquals(projectBasedText, deserializedText) @@ -58,7 +51,7 @@ public class DecompiledTextConsistencyTest : JetLightCodeInsightFixtureTestCase( } class ProjectBasedResolverForDecompiler(project: Project) : ResolverForDecompiler { - val javaDescriptorResolver = InjectorForJavaDescriptorResolverUtil.create(project, BindingTraceContext()).getJavaDescriptorResolver()!! + val javaDescriptorResolver = JavaResolveExtension[project] override fun resolveClass(classFqName: FqName): ClassDescriptor? { return javaDescriptorResolver.resolveClass(classFqName)