Drop BuiltInsReferenceResolver

This commit is contained in:
Pavel V. Talanov
2015-12-10 14:28:53 +03:00
parent 3f0d71411e
commit 0099c10e4e
7 changed files with 2 additions and 296 deletions
@@ -20,7 +20,6 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.decompiler.navigation.findDecompiledDeclaration
import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.utils.addToStdlib.sequenceOfLazyValues
@@ -46,7 +45,7 @@ public object DescriptorToSourceUtilsIde {
// therefore we put both source declaration and decompiled declaration to stream, and afterwards we filter it in getAllDeclarations
sequenceOfLazyValues(
{ DescriptorToSourceUtils.getSourceFromDescriptor(effectiveReferenced) },
{ BuiltInsReferenceResolver.resolveBuiltInSymbol(project, effectiveReferenced) ?: findDecompiledDeclaration(project, effectiveReferenced) }
{ findDecompiledDeclaration(project, effectiveReferenced) }
)
}.filterNotNull()
}
@@ -1,247 +0,0 @@
/*
* Copyright 2010-2015 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.kotlin.idea.references
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.progress.NonCancelableSection
import com.intellij.openapi.progress.impl.CoreProgressManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.StartupManager
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiManager
import com.intellij.util.PathUtil
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.context.MutableModuleContextImpl
import org.jetbrains.kotlin.context.ProjectContextImpl
import org.jetbrains.kotlin.context.SimpleGlobalContext
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.frontend.di.createLazyResolveSession
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.createModule
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies
import org.jetbrains.kotlin.storage.ExceptionTracker
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.ObservableStorageManager
import org.jetbrains.kotlin.storage.StorageManager
import java.io.File
import java.net.URL
public class BuiltInsReferenceResolver(val project: Project, val startupManager: StartupManager) {
@Volatile private var moduleDescriptor: ModuleDescriptor? = null
@Volatile public var builtInsSources: Set<KtFile>? = null
private set
@Volatile private var builtinsPackageFragment: PackageFragmentDescriptor? = null
init {
startupManager.runWhenProjectIsInitialized { initialize() }
}
private fun initialize() {
assert(moduleDescriptor == null) { "Attempt to initialize twice" }
val jetBuiltInsFiles = getBuiltInsKtFiles()
runReadAction {
val tracker = object : ExceptionTracker() {
override fun handleException(throwable: Throwable): RuntimeException {
throw RuntimeException("No exceptions expected in ${BuiltInsReferenceResolver::class.simpleName}", throwable)
}
}
val storageManager = NonCancelableStorageManager(LockBasedStorageManager.createWithExceptionHandling(tracker))
val globalContext = SimpleGlobalContext(storageManager, tracker)
val projectContext = ProjectContextImpl(project, globalContext)
val module = TargetPlatform.Default.createModule(Name.special("<built-ins resolver module>"), projectContext.storageManager)
val newModuleContext = MutableModuleContextImpl(module, projectContext)
newModuleContext.setDependencies(newModuleContext.module)
val declarationFactory = FileBasedDeclarationProviderFactory(newModuleContext.storageManager, jetBuiltInsFiles)
val resolveSession = createLazyResolveSession(
newModuleContext,
declarationFactory, BindingTraceContext(),
TargetPlatform.Default)
newModuleContext.initializeModuleContents(resolveSession.getPackageFragmentProvider())
val packageView = newModuleContext.module.getPackage(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME)
val fragments = packageView.fragments
this@BuiltInsReferenceResolver.moduleDescriptor = newModuleContext.module
builtinsPackageFragment = fragments.single()
builtInsSources = jetBuiltInsFiles
}
}
private fun getBuiltInsKtFiles(): Set<KtFile> {
return getBuiltInsDirUrls().flatMapTo(hashSetOf<KtFile>()) { getBuiltInSourceFiles(it) }
}
private fun getBuiltInSourceFiles(url: URL): Set<KtFile> {
val fromUrl = VfsUtilCore.convertFromUrl(url)
val vf = VirtualFileManager.getInstance().findFileByUrl(fromUrl)
assert(vf != null) { "Virtual file not found by URL: $url" }
val psiDirectory = PsiManager.getInstance(project).findDirectory(vf!!)
assert(psiDirectory != null) { "No PsiDirectory for $vf" }
return psiDirectory!!.getFiles().filterIsInstance<KtFile>().toHashSet()
}
private fun findCurrentDescriptorForMember(originalDescriptor: MemberDescriptor): DeclarationDescriptor? {
val containingDeclaration = findCurrentDescriptor(originalDescriptor.getContainingDeclaration())
val memberScope = getMemberScope(containingDeclaration) ?: return null
val renderedOriginal = DescriptorRenderer.FQ_NAMES_IN_TYPES.render(originalDescriptor)
val descriptors = if (originalDescriptor is ConstructorDescriptor && containingDeclaration is ClassDescriptor) {
containingDeclaration.getConstructors()
}
else {
memberScope.getContributedDescriptors()
}
return descriptors.firstOrNull { renderedOriginal == DescriptorRenderer.FQ_NAMES_IN_TYPES.render(it) }
}
private fun findCurrentDescriptor(originalDescriptor: DeclarationDescriptor): DeclarationDescriptor? = when(originalDescriptor) {
is ClassDescriptor -> moduleDescriptor!!.findClassAcrossModuleDependencies(originalDescriptor.classId)
is PackageFragmentDescriptor -> {
if (KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME == originalDescriptor.fqName)
builtinsPackageFragment
else
null
}
is MemberDescriptor -> findCurrentDescriptorForMember(originalDescriptor)
else -> null
}
companion object {
private val BUILT_INS_COMPILABLE_SRC_DIR = File("core/builtins/src", KotlinBuiltIns.BUILT_INS_PACKAGE_NAME.asString())
private val builtInDirUrls = getBuiltInsDirUrls().map { VfsUtilCore.convertFromUrl(it) }
public fun getInstance(project: Project): BuiltInsReferenceResolver =
ServiceManager.getService(project, BuiltInsReferenceResolver::class.java)
private fun isFromBuiltinModule(originalDescriptor: DeclarationDescriptor): Boolean {
// TODO This is optimization only
// It should be rewritten by checking declarationDescriptor.getSource(), when the latter returns something non-trivial for builtins.
val containingModule = originalDescriptor.module
return containingModule.builtIns.builtInsModule == containingModule
}
public fun resolveBuiltInSymbol(project: Project, declarationDescriptor: DeclarationDescriptor): PsiElement? {
if (!isFromBuiltinModule(declarationDescriptor)) {
return null
}
val resolver = getInstance(project)
if (resolver.moduleDescriptor == null) {
return null
}
val descriptor = resolver.findCurrentDescriptor(declarationDescriptor)
if (descriptor != null) {
return DescriptorToSourceUtils.getSourceFromDescriptor(descriptor)
}
return null
}
public fun isFromBuiltIns(element: PsiElement): Boolean {
val url = element.getContainingFile()?.getVirtualFile()?.getUrl()
return url != null && VfsUtilCore.isUnder(url, builtInDirUrls)
}
private fun getMemberScope(parent: DeclarationDescriptor?): MemberScope? = when(parent) {
is ClassDescriptor -> parent.getDefaultType().getMemberScope()
is PackageFragmentDescriptor -> parent.getMemberScope()
else -> null
}
public fun getBuiltInsDirUrls(): Set<URL> {
val defaultBuiltIns = LightClassUtil.builtInsDirUrl
// In production, the above URL is enough as it contains sources for both native and compilable built-ins
// (it's simply the "kotlin" directory in kotlin-plugin.jar)
// But in tests, sources of built-ins are not added to the classpath automatically, so we manually specify URLs for both:
// LightClassUtil.getBuiltInsDirUrl() does so for native built-ins and the code below for compilable built-ins
if (ApplicationManager.getApplication().isUnitTestMode) {
return setOf(defaultBuiltIns, BUILT_INS_COMPILABLE_SRC_DIR.toURI().toURL())
}
return setOf(defaultBuiltIns)
}
public fun refreshBuiltIns() {
getBuiltInsDirUrls().forEach { url ->
val fromUrl = VfsUtilCore.convertFromUrl(url)
val vf = VirtualFileManager.getInstance().findFileByUrl(fromUrl)
assert(vf != null) { "Virtual file not found by URL: $url" }
// Refreshing VFS: in case the plugin jar was updated, the caches may hold the old value
vf!!.getChildren()
vf.refresh(true, true)
PathUtil.getLocalFile(vf).refresh(true, true)
}
}
}
}
class NonCancelableStorageManager(val delegate: StorageManager) : ObservableStorageManager(delegate) {
override val <V> (() -> V).observable: () -> V get() = {
runNonCancelable { this@observable() }
}
override val <K, V> ((K) -> V).observable: (K) -> V get() = { p ->
runNonCancelable { this@observable(p) }
}
private inline fun <T> runNonCancelable(crossinline call: () -> T) : T {
if (CoreProgressManager.getInstance().progressIndicator is NonCancelableSection) {
return call()
}
var result: Any? = null
CoreProgressManager.getInstance().executeNonCancelableSection {
result = call()
}
@Suppress("UNCHECKED_CAST")
return result as T
}
}
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils;
import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver;
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.*;
@@ -89,7 +88,7 @@ public class QuickFixUtil {
}
public static boolean canModifyElement(@NotNull PsiElement element) {
return element.isWritable() && !BuiltInsReferenceResolver.Companion.isFromBuiltIns(element);
return element.isWritable();
}
@Nullable
@@ -34,7 +34,6 @@ import org.jetbrains.kotlin.idea.caches.resolve.LibraryModificationTracker
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProvider
import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile
import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver
import org.jetbrains.kotlin.psi.KtFile
import java.util.*
@@ -85,8 +84,6 @@ public fun closeAndDeleteProject(): Unit =
ApplicationManager.getApplication().runWriteAction() { LightPlatformTestCase.closeAndDeleteProject() }
public fun unInvalidateBuiltinsAndStdLib(project: Project, runnable: RunnableWithException) {
val builtInsSources = BuiltInsReferenceResolver.getInstance(project).builtInsSources!!
val stdLibViewProviders = HashSet<KotlinDecompiledFileViewProvider>()
val vFileToViewProviderMap = ((PsiManager.getInstance(project) as PsiManagerEx).fileManager as FileManagerImpl).vFileToViewProviderMap
for ((file, viewProvider) in vFileToViewProviderMap) {
@@ -104,7 +101,6 @@ public fun unInvalidateBuiltinsAndStdLib(project: Project, runnable: RunnableWit
field.set(file, false)
}
builtInsSources.forEach { unInvalidateFile(it) }
stdLibViewProviders.forEach {
it.allFiles.forEach { unInvalidateFile(it as KtDecompiledFile) }
vFileToViewProviderMap.set(it.virtualFile, it)
-4
View File
@@ -270,9 +270,6 @@
<projectService serviceInterface="org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade"
serviceImplementation="org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade"/>
<projectService serviceInterface="org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver"
serviceImplementation="org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver"/>
<projectService serviceInterface="org.jetbrains.kotlin.idea.caches.resolve.ClsJavaStubByVirtualFileCache"
serviceImplementation="org.jetbrains.kotlin.idea.caches.resolve.ClsJavaStubByVirtualFileCache"/>
@@ -488,7 +485,6 @@
<highlightUsagesHandlerFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightExitPointsHandlerFactory"/>
<findUsagesHandlerFactory implementation="org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory"/>
<usageTypeProvider implementation="org.jetbrains.kotlin.idea.findUsages.KotlinUsageTypeProvider"/>
<useScopeEnlarger implementation="org.jetbrains.kotlin.idea.findUsages.BuiltInsUseScopeEnlarger"/>
<refactoring.safeDeleteProcessor
id="kotlinProcessor"
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.idea.caches.JarUserDataManager;
import org.jetbrains.kotlin.idea.debugger.filter.DebuggerFiltersUtilKt;
import org.jetbrains.kotlin.idea.decompiler.classFile.HasCompiledKotlinInJar;
import org.jetbrains.kotlin.idea.framework.KotlinJavaScriptLibraryDetectionUtil;
import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver;
import org.jetbrains.kotlin.utils.PathUtil;
import java.io.File;
@@ -56,8 +55,6 @@ public class PluginStartupComponent implements ApplicationComponent {
JarUserDataManager.INSTANCE$.register(KotlinJavaScriptLibraryDetectionUtil.HasKotlinJSMetadataInJar.INSTANCE$);
JarUserDataManager.INSTANCE$.register(HasCompiledKotlinInJar.INSTANCE$);
BuiltInsReferenceResolver.Companion.refreshBuiltIns();
DebuggerFiltersUtilKt.addKotlinStdlibDebugFilterIfNeeded();
UpdateChecker.getDisabledToUpdatePlugins().add("org.jetbrains.kotlin");
@@ -1,34 +0,0 @@
/*
* Copyright 2010-2015 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.kotlin.idea.findUsages
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.psi.PsiElement
import com.intellij.psi.search.ProjectScope
import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.UseScopeEnlarger
import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver
import org.jetbrains.kotlin.psi.KtElement
public class BuiltInsUseScopeEnlarger : UseScopeEnlarger() {
override fun getAdditionalUseScope(element: PsiElement): SearchScope? {
if (element is KtElement && BuiltInsReferenceResolver.isFromBuiltIns(element)) {
return ProjectScope.getAllScope(element.getProject())
}
return null
}
}