Optimize PluginDeclarationProviderFactory.getStubBasedPackageMemberDeclarationProvider
Add cache for fast package exists check in specific module #KT-16850 fixed
This commit is contained in:
@@ -58,7 +58,8 @@ object JvmAnalyzerFacade : AnalyzerFacade<JvmPlatformParameters>() {
|
|||||||
val project = moduleContext.project
|
val project = moduleContext.project
|
||||||
val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory(
|
val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory(
|
||||||
project, moduleContext.storageManager, syntheticFiles,
|
project, moduleContext.storageManager, syntheticFiles,
|
||||||
if (moduleInfo.isLibrary) GlobalSearchScope.EMPTY_SCOPE else moduleContentScope
|
if (moduleInfo.isLibrary) GlobalSearchScope.EMPTY_SCOPE else moduleContentScope,
|
||||||
|
moduleInfo
|
||||||
)
|
)
|
||||||
|
|
||||||
val moduleClassResolver = ModuleClassResolverImpl { javaClass ->
|
val moduleClassResolver = ModuleClassResolverImpl { javaClass ->
|
||||||
|
|||||||
@@ -101,7 +101,8 @@ object DefaultAnalyzerFacade : AnalyzerFacade<PlatformAnalysisParameters>() {
|
|||||||
val project = moduleContext.project
|
val project = moduleContext.project
|
||||||
val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory(
|
val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory(
|
||||||
project, moduleContext.storageManager, syntheticFiles,
|
project, moduleContext.storageManager, syntheticFiles,
|
||||||
if (moduleInfo.isLibrary) GlobalSearchScope.EMPTY_SCOPE else moduleContentScope
|
if (moduleInfo.isLibrary) GlobalSearchScope.EMPTY_SCOPE else moduleContentScope,
|
||||||
|
moduleInfo
|
||||||
)
|
)
|
||||||
|
|
||||||
val trace = CodeAnalyzerInitializer.getInstance(project).createTrace()
|
val trace = CodeAnalyzerInitializer.getInstance(project).createTrace()
|
||||||
|
|||||||
+3
-1
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.resolve.lazy.declarations
|
|||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.utils.sure
|
import org.jetbrains.kotlin.utils.sure
|
||||||
@@ -29,7 +30,8 @@ class CliDeclarationProviderFactoryService(private val sourceFiles: Collection<K
|
|||||||
project: Project,
|
project: Project,
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
syntheticFiles: Collection<KtFile>,
|
syntheticFiles: Collection<KtFile>,
|
||||||
filesScope: GlobalSearchScope
|
filesScope: GlobalSearchScope,
|
||||||
|
moduleInfo: ModuleInfo
|
||||||
): DeclarationProviderFactory {
|
): DeclarationProviderFactory {
|
||||||
val allFiles = ArrayList<KtFile>()
|
val allFiles = ArrayList<KtFile>()
|
||||||
sourceFiles.filterTo(allFiles) {
|
sourceFiles.filterTo(allFiles) {
|
||||||
|
|||||||
+6
-3
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project
|
|||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -31,7 +32,8 @@ abstract class DeclarationProviderFactoryService {
|
|||||||
project: Project,
|
project: Project,
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
syntheticFiles: Collection<KtFile>,
|
syntheticFiles: Collection<KtFile>,
|
||||||
filesScope: GlobalSearchScope
|
filesScope: GlobalSearchScope,
|
||||||
|
moduleInfo: ModuleInfo
|
||||||
): DeclarationProviderFactory
|
): DeclarationProviderFactory
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -39,10 +41,11 @@ abstract class DeclarationProviderFactoryService {
|
|||||||
project: Project,
|
project: Project,
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
syntheticFiles: Collection<KtFile>,
|
syntheticFiles: Collection<KtFile>,
|
||||||
filesScope: GlobalSearchScope
|
filesScope: GlobalSearchScope,
|
||||||
|
moduleInfo: ModuleInfo
|
||||||
): DeclarationProviderFactory {
|
): DeclarationProviderFactory {
|
||||||
return ServiceManager.getService(project, DeclarationProviderFactoryService::class.java)!!
|
return ServiceManager.getService(project, DeclarationProviderFactoryService::class.java)!!
|
||||||
.create(project, storageManager, syntheticFiles, filteringScope(syntheticFiles, filesScope))
|
.create(project, storageManager, syntheticFiles, filteringScope(syntheticFiles, filesScope), moduleInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun filteringScope(syntheticFiles: Collection<KtFile>, baseScope: GlobalSearchScope): GlobalSearchScope {
|
private fun filteringScope(syntheticFiles: Collection<KtFile>, baseScope: GlobalSearchScope): GlobalSearchScope {
|
||||||
|
|||||||
@@ -51,7 +51,11 @@ object JsAnalyzerFacade : AnalyzerFacade<PlatformAnalysisParameters>() {
|
|||||||
val (syntheticFiles, moduleContentScope) = moduleContent
|
val (syntheticFiles, moduleContentScope) = moduleContent
|
||||||
val project = moduleContext.project
|
val project = moduleContext.project
|
||||||
val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory(
|
val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory(
|
||||||
project, moduleContext.storageManager, syntheticFiles, if (moduleInfo.isLibrary) GlobalSearchScope.EMPTY_SCOPE else moduleContentScope
|
project,
|
||||||
|
moduleContext.storageManager,
|
||||||
|
syntheticFiles,
|
||||||
|
if (moduleInfo.isLibrary) GlobalSearchScope.EMPTY_SCOPE else moduleContentScope,
|
||||||
|
moduleInfo
|
||||||
)
|
)
|
||||||
|
|
||||||
val languageVersionSettings = LanguageSettingsProvider.getInstance(project).getLanguageVersionSettings(moduleInfo, project)
|
val languageVersionSettings = LanguageSettingsProvider.getInstance(project).getLanguageVersionSettings(moduleInfo, project)
|
||||||
|
|||||||
+124
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 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.caches
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.util.Key
|
||||||
|
import com.intellij.openapi.util.Ref
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.openapi.vfs.VirtualFileManager
|
||||||
|
import com.intellij.openapi.vfs.newvfs.BulkFileListener
|
||||||
|
import com.intellij.openapi.vfs.newvfs.events.*
|
||||||
|
import com.intellij.psi.impl.PsiTreeChangeEventImpl
|
||||||
|
import com.intellij.psi.impl.PsiTreeChangePreprocessor
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.util.containers.ContainerUtil
|
||||||
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.ModuleSourceInfo
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.getModuleInfoByVirtualFile
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.getNullableModuleInfo
|
||||||
|
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi.KtPackageDirective
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||||
|
import java.util.concurrent.ConcurrentMap
|
||||||
|
|
||||||
|
class KotlinPackageContentModificationListener(
|
||||||
|
private val project: Project
|
||||||
|
) {
|
||||||
|
init {
|
||||||
|
val connection = project.messageBus.connect()
|
||||||
|
|
||||||
|
val scope = GlobalSearchScope.projectScope(project)
|
||||||
|
|
||||||
|
connection.subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener.Adapter() {
|
||||||
|
override fun before(events: MutableList<out VFileEvent>) = onEvents(events) { it is VFileDeleteEvent || it is VFileMoveEvent }
|
||||||
|
override fun after(events: List<VFileEvent>) = onEvents(events) { it is VFileMoveEvent || it is VFileCreateEvent || it is VFileCopyEvent }
|
||||||
|
|
||||||
|
fun onEvents(events: List<VFileEvent>, filter: (VFileEvent) -> Boolean) = events.asSequence()
|
||||||
|
.filter(filter)
|
||||||
|
.map { it.file }
|
||||||
|
.filterNotNull()
|
||||||
|
.filter { it in scope }
|
||||||
|
.forEach { file ->
|
||||||
|
PerModulePackageCacheService.notifyPackageChange(file, project)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KotlinPackageStatementPsiTreeChangePreprocessor : PsiTreeChangePreprocessor {
|
||||||
|
override fun treeChanged(event: PsiTreeChangeEventImpl) {
|
||||||
|
val file = event.file as? KtFile ?: return
|
||||||
|
|
||||||
|
when (event.code) {
|
||||||
|
PsiTreeChangeEventImpl.PsiEventType.CHILD_ADDED, PsiTreeChangeEventImpl.PsiEventType.CHILD_MOVED, PsiTreeChangeEventImpl.PsiEventType.CHILD_REPLACED, PsiTreeChangeEventImpl.PsiEventType.CHILD_REMOVED -> {
|
||||||
|
val child = event.child ?: return
|
||||||
|
if (child.getParentOfType<KtPackageDirective>(false) != null)
|
||||||
|
PerModulePackageCacheService.notifyPackageChange(file)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PerModulePackageCacheService {
|
||||||
|
|
||||||
|
val cache = ContainerUtil.createConcurrentWeakMap<ModuleInfo, Ref<ConcurrentMap<FqName, Boolean>>>()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
val PER_MODULE_PACKAGE_CACHE = Key.create<ConcurrentMap<ModuleInfo, Ref<ConcurrentMap<FqName, Boolean>>>>("per_module_package_cache")
|
||||||
|
|
||||||
|
internal fun notifyPackageChange(file: KtFile): Unit {
|
||||||
|
(file.getNullableModuleInfo() as? ModuleSourceInfo)?.let { onChangeInModuleSource(it, file.project) }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun onChangeInModuleSource(moduleSourceInfo: ModuleSourceInfo, project: Project) = with(getInstance(project)) {
|
||||||
|
cache[moduleSourceInfo]?.set(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun notifyPackageChange(file: VirtualFile, project: Project): Unit {
|
||||||
|
(getModuleInfoByVirtualFile(project, file) as? ModuleSourceInfo)?.let { onChangeInModuleSource(it, project) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getInstance(project: Project): PerModulePackageCacheService = ServiceManager.getService(project, PerModulePackageCacheService::class.java)
|
||||||
|
|
||||||
|
fun packageExists(packageFqName: FqName, moduleInfo: ModuleSourceInfo, project: Project): Boolean = with(getInstance(project)) {
|
||||||
|
val module = moduleInfo.module
|
||||||
|
|
||||||
|
// Module own cache is a view on global cache. Since global cache based on WeakReferences when module
|
||||||
|
// gets disposed this soft map will be disposed too, leading to drop soft refs on ModuleInfo's, and then to
|
||||||
|
// disposing global cache entry
|
||||||
|
val moduleOwnCache = module.getUserData(PerModulePackageCacheService.PER_MODULE_PACKAGE_CACHE) ?: run {
|
||||||
|
ContainerUtil.createConcurrentSoftMap<ModuleInfo, Ref<ConcurrentMap<FqName, Boolean>>>()
|
||||||
|
.apply { module.putUserData(PerModulePackageCacheService.PER_MODULE_PACKAGE_CACHE, this) }
|
||||||
|
}
|
||||||
|
val cached = moduleOwnCache.getOrPut(moduleInfo) { cache.getOrPut(moduleInfo) { Ref() } }
|
||||||
|
.apply { if (isNull) set(ContainerUtil.createConcurrentSoftMap<FqName, Boolean>()) }
|
||||||
|
.get()
|
||||||
|
|
||||||
|
|
||||||
|
return cached.getOrPut(packageFqName) {
|
||||||
|
PackageIndexUtil.packageExists(packageFqName, moduleInfo.contentScope(), project)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,6 +53,32 @@ class KotlinSourceFilterScope private constructor(
|
|||||||
"cls=$includeClassFiles script=$includeScriptDependencies)"
|
"cls=$includeClassFiles script=$includeScriptDependencies)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other?.javaClass != javaClass) return false
|
||||||
|
if (!super.equals(other)) return false
|
||||||
|
|
||||||
|
other as KotlinSourceFilterScope
|
||||||
|
|
||||||
|
if (includeProjectSourceFiles != other.includeProjectSourceFiles) return false
|
||||||
|
if (includeLibrarySourceFiles != other.includeLibrarySourceFiles) return false
|
||||||
|
if (includeClassFiles != other.includeClassFiles) return false
|
||||||
|
if (includeScriptDependencies != other.includeScriptDependencies) return false
|
||||||
|
if (project != other.project) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = super.hashCode()
|
||||||
|
result = 31 * result + includeProjectSourceFiles.hashCode()
|
||||||
|
result = 31 * result + includeLibrarySourceFiles.hashCode()
|
||||||
|
result = 31 * result + includeClassFiles.hashCode()
|
||||||
|
result = 31 * result + includeScriptDependencies.hashCode()
|
||||||
|
result = 31 * result + project.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun sourcesAndLibraries(delegate: GlobalSearchScope, project: Project) = create(delegate, true, true, true, true, project)
|
fun sourcesAndLibraries(delegate: GlobalSearchScope, project: Project) = create(delegate, true, true, true, true, project)
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
|
|
||||||
object PackageIndexUtil {
|
object PackageIndexUtil {
|
||||||
@JvmStatic fun getSubPackageFqNames(
|
@JvmStatic fun getSubPackageFqNames(
|
||||||
packageFqName: FqName,
|
packageFqName: FqName,
|
||||||
@@ -48,6 +49,7 @@ object PackageIndexUtil {
|
|||||||
searchScope: GlobalSearchScope,
|
searchScope: GlobalSearchScope,
|
||||||
project: Project
|
project: Project
|
||||||
): Boolean {
|
): Boolean {
|
||||||
|
|
||||||
val subpackagesIndex = SubpackagesIndexService.getInstance(project)
|
val subpackagesIndex = SubpackagesIndexService.getInstance(project)
|
||||||
if (!subpackagesIndex.packageExists(packageFqName)) {
|
if (!subpackagesIndex.packageExists(packageFqName)) {
|
||||||
return false
|
return false
|
||||||
|
|||||||
+13
-2
@@ -18,6 +18,9 @@ package org.jetbrains.kotlin.idea.stubindex.resolve
|
|||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
|
import org.jetbrains.kotlin.idea.caches.PerModulePackageCacheService
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.ModuleSourceInfo
|
||||||
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
||||||
import org.jetbrains.kotlin.idea.stubindex.SubpackagesIndexService
|
import org.jetbrains.kotlin.idea.stubindex.SubpackagesIndexService
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -30,7 +33,8 @@ class PluginDeclarationProviderFactory(
|
|||||||
private val project: Project,
|
private val project: Project,
|
||||||
private val indexedFilesScope: GlobalSearchScope,
|
private val indexedFilesScope: GlobalSearchScope,
|
||||||
private val storageManager: StorageManager,
|
private val storageManager: StorageManager,
|
||||||
private val nonIndexedFiles: Collection<KtFile>
|
private val nonIndexedFiles: Collection<KtFile>,
|
||||||
|
private val moduleInfo: ModuleInfo
|
||||||
) : AbstractDeclarationProviderFactory(storageManager) {
|
) : AbstractDeclarationProviderFactory(storageManager) {
|
||||||
private val fileBasedDeclarationProviderFactory = FileBasedDeclarationProviderFactory(storageManager, nonIndexedFiles)
|
private val fileBasedDeclarationProviderFactory = FileBasedDeclarationProviderFactory(storageManager, nonIndexedFiles)
|
||||||
|
|
||||||
@@ -49,8 +53,15 @@ class PluginDeclarationProviderFactory(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun packageExists(name: FqName): Boolean {
|
||||||
|
return if (moduleInfo is ModuleSourceInfo)
|
||||||
|
PerModulePackageCacheService.packageExists(name, moduleInfo, project)
|
||||||
|
else
|
||||||
|
PackageIndexUtil.packageExists(name, indexedFilesScope, project)
|
||||||
|
}
|
||||||
|
|
||||||
private fun getStubBasedPackageMemberDeclarationProvider(name: FqName): PackageMemberDeclarationProvider? {
|
private fun getStubBasedPackageMemberDeclarationProvider(name: FqName): PackageMemberDeclarationProvider? {
|
||||||
if (!PackageIndexUtil.packageExists(name, indexedFilesScope, project)) return null
|
if (!packageExists(name)) return null
|
||||||
|
|
||||||
return StubBasedPackageMemberDeclarationProvider(name, project, indexedFilesScope)
|
return StubBasedPackageMemberDeclarationProvider(name, project, indexedFilesScope)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.stubindex.resolve
|
|||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||||
@@ -30,7 +31,8 @@ class PluginDeclarationProviderFactoryService : DeclarationProviderFactoryServic
|
|||||||
project: Project,
|
project: Project,
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
syntheticFiles: Collection<KtFile>,
|
syntheticFiles: Collection<KtFile>,
|
||||||
filesScope: GlobalSearchScope
|
filesScope: GlobalSearchScope,
|
||||||
|
moduleInfo: ModuleInfo
|
||||||
): DeclarationProviderFactory =
|
): DeclarationProviderFactory =
|
||||||
PluginDeclarationProviderFactory(project, KotlinSourceFilterScope.sources(filesScope, project), storageManager, syntheticFiles)
|
PluginDeclarationProviderFactory(project, KotlinSourceFilterScope.sources(filesScope, project), storageManager, syntheticFiles, moduleInfo)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 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.core.util
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.util.CachedValue
|
||||||
|
import com.intellij.psi.util.CachedValueProvider
|
||||||
|
import com.intellij.psi.util.CachedValuesManager
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
operator fun <T> CachedValue<T>.getValue(o: Any, property: KProperty<*>): T = value
|
||||||
|
|
||||||
|
fun <T> CachedValue(project: Project, trackValue: Boolean = false, provider: () -> CachedValueProvider.Result<T>) =
|
||||||
|
CachedValuesManager.getManager(project).createCachedValue(provider, trackValue)
|
||||||
@@ -40,6 +40,9 @@
|
|||||||
<component>
|
<component>
|
||||||
<implementation-class>org.jetbrains.kotlin.idea.project.KotlinCodeBlockModificationListener</implementation-class>
|
<implementation-class>org.jetbrains.kotlin.idea.project.KotlinCodeBlockModificationListener</implementation-class>
|
||||||
</component>
|
</component>
|
||||||
|
<component>
|
||||||
|
<implementation-class>org.jetbrains.kotlin.idea.caches.KotlinPackageContentModificationListener</implementation-class>
|
||||||
|
</component>
|
||||||
</project-components>
|
</project-components>
|
||||||
|
|
||||||
<application-components>
|
<application-components>
|
||||||
@@ -311,6 +314,8 @@
|
|||||||
<projectService serviceInterface="org.jetbrains.kotlin.idea.kdoc.SampleResolutionService"
|
<projectService serviceInterface="org.jetbrains.kotlin.idea.kdoc.SampleResolutionService"
|
||||||
serviceImplementation="org.jetbrains.kotlin.idea.kdoc.IdeSampleResolutionService"/>
|
serviceImplementation="org.jetbrains.kotlin.idea.kdoc.IdeSampleResolutionService"/>
|
||||||
|
|
||||||
|
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.PerModulePackageCacheService"/>
|
||||||
|
|
||||||
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
|
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
|
||||||
|
|
||||||
<internalFileTemplate name="Kotlin File"/>
|
<internalFileTemplate name="Kotlin File"/>
|
||||||
@@ -454,6 +459,8 @@
|
|||||||
language="kotlin"
|
language="kotlin"
|
||||||
implementation="org.jetbrains.kotlin.idea.references.KotlinDefaultAnnotationMethodImplicitReferenceContributor"/>
|
implementation="org.jetbrains.kotlin.idea.references.KotlinDefaultAnnotationMethodImplicitReferenceContributor"/>
|
||||||
|
|
||||||
|
<psi.treeChangePreprocessor implementation="org.jetbrains.kotlin.idea.caches.KotlinPackageStatementPsiTreeChangePreprocessor"/>
|
||||||
|
|
||||||
<renamePsiElementProcessor id="KotlinClass"
|
<renamePsiElementProcessor id="KotlinClass"
|
||||||
implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinClassProcessor"
|
implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinClassProcessor"
|
||||||
order="first"/>
|
order="first"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user