Implement LibraryDependenciesCache
This commit is contained in:
@@ -22,7 +22,11 @@
|
|||||||
<item name='com.intellij.openapi.roots.OrderEnumerator com.intellij.openapi.roots.OrderEnumerator recursively()'>
|
<item name='com.intellij.openapi.roots.OrderEnumerator com.intellij.openapi.roots.OrderEnumerator recursively()'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
<item
|
<item
|
||||||
|
name='com.intellij.openapi.roots.OrderEnumerator com.intellij.openapi.roots.OrderEnumerator satisfying(com.intellij.openapi.util.Condition<com.intellij.openapi.roots.OrderEntry>)'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
name='com.intellij.openapi.roots.ProjectFileIndex.SERVICE com.intellij.openapi.roots.ProjectFileIndex getInstance(com.intellij.openapi.project.Project)'>
|
name='com.intellij.openapi.roots.ProjectFileIndex.SERVICE com.intellij.openapi.roots.ProjectFileIndex getInstance(com.intellij.openapi.project.Project)'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
|
import com.intellij.openapi.roots.libraries.Library
|
||||||
|
import com.intellij.util.containers.MultiMap
|
||||||
|
import com.intellij.psi.util.CachedValuesManager
|
||||||
|
import com.intellij.psi.util.CachedValueProvider
|
||||||
|
import com.intellij.openapi.roots.ProjectRootModificationTracker
|
||||||
|
import com.intellij.openapi.module.ModuleManager
|
||||||
|
import com.intellij.openapi.roots.ModuleRootManager
|
||||||
|
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||||
|
import com.intellij.openapi.roots.OrderEntry
|
||||||
|
import com.intellij.openapi.roots.ModuleOrderEntry
|
||||||
|
import com.intellij.openapi.util.Condition
|
||||||
|
import java.util.LinkedHashSet
|
||||||
|
import com.intellij.openapi.roots.RootPolicy
|
||||||
|
import org.jetbrains.jet.utils.addIfNotNull
|
||||||
|
import com.intellij.openapi.projectRoots.Sdk
|
||||||
|
import com.intellij.openapi.roots.JdkOrderEntry
|
||||||
|
import com.intellij.openapi.roots.ModuleSourceOrderEntry
|
||||||
|
|
||||||
|
public class LibraryDependenciesCache(private val project: Project) {
|
||||||
|
|
||||||
|
//NOTE: used LibraryRuntimeClasspathScope as reference
|
||||||
|
public fun getLibrariesAndSdksUsedWith(library: Library): Pair<List<Library>, List<Sdk>> {
|
||||||
|
val processedModules = LinkedHashSet<Module>()
|
||||||
|
val condition = Condition<OrderEntry>() { orderEntry ->
|
||||||
|
if (orderEntry is ModuleOrderEntry) {
|
||||||
|
val module = orderEntry.getModule()
|
||||||
|
module != null && module !in processedModules
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val libraries = LinkedHashSet<Library>()
|
||||||
|
val sdks = LinkedHashSet<Sdk>()
|
||||||
|
|
||||||
|
fun collectLibrariesAndSdksAcrossDependencies(module: Module) {
|
||||||
|
if (!processedModules.add(module)) return
|
||||||
|
|
||||||
|
ModuleRootManager.getInstance(module).orderEntries().recursively().satisfying(condition).process(object : RootPolicy<Unit>() {
|
||||||
|
override fun visitModuleSourceOrderEntry(moduleSourceOrderEntry: ModuleSourceOrderEntry?, value: Unit?): Unit? {
|
||||||
|
processedModules.addIfNotNull(moduleSourceOrderEntry?.getOwnerModule())
|
||||||
|
return Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun visitLibraryOrderEntry(libraryOrderEntry: LibraryOrderEntry?, value: Unit?): Unit? {
|
||||||
|
libraries.addIfNotNull(libraryOrderEntry?.getLibrary())
|
||||||
|
return Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitJdkOrderEntry(jdkOrderEntry: JdkOrderEntry?, value: Unit?): Unit? {
|
||||||
|
sdks.addIfNotNull(jdkOrderEntry?.getJdk())
|
||||||
|
return Unit
|
||||||
|
}
|
||||||
|
}, Unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
getLibraryUsageIndex().modulesLibraryIsUsedIn[library].forEach { module -> collectLibrariesAndSdksAcrossDependencies(module) }
|
||||||
|
|
||||||
|
return Pair(libraries.toList(), sdks.toList())
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun getLibraryUsageIndex(): LibraryUsageIndex {
|
||||||
|
return CachedValuesManager.getManager(project).getCachedValue(project) {
|
||||||
|
CachedValueProvider.Result(LibraryUsageIndex(), ProjectRootModificationTracker.getInstance(project))
|
||||||
|
}!!
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class LibraryUsageIndex {
|
||||||
|
val modulesLibraryIsUsedIn: MultiMap<Library, Module> = MultiMap.createSet();
|
||||||
|
{
|
||||||
|
ModuleManager.getInstance(project).getModules().forEach {
|
||||||
|
module ->
|
||||||
|
ModuleRootManager.getInstance(module).getOrderEntries().forEach {
|
||||||
|
entry ->
|
||||||
|
if (entry is LibraryOrderEntry) {
|
||||||
|
val library = entry.getLibrary()
|
||||||
|
if (library != null) {
|
||||||
|
modulesLibraryIsUsedIn.putValue(library, module)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user