Split JvmDependenciesIndex to several files, move to 'index' package
This commit is contained in:
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndex
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClassFinder
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
|
||||
+1
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndex
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmVirtualFileFinder
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmVirtualFileFinderFactory
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.PsiPackage
|
||||
import com.intellij.psi.impl.file.PsiPackageImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndex
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinCliJavaFileManager
|
||||
|
||||
@@ -74,6 +74,10 @@ import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmContentRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesDynamicCompoundIndex
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndex
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JvmUpdateableDependenciesIndexFactory
|
||||
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
|
||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
|
||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||
@@ -148,7 +152,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
val initialRoots = configuration.getList(JVMConfigurationKeys.CONTENT_ROOTS).classpathRoots()
|
||||
|
||||
// REPL and kapt2 update classpath dynamically
|
||||
val indexFactory = JvmUpdatableDependenciesIndexFactory()
|
||||
val indexFactory = JvmUpdateableDependenciesIndexFactory()
|
||||
|
||||
rootsIndex = indexFactory.makeIndexFor(initialRoots)
|
||||
updateClasspathFromRootsIndex(rootsIndex)
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.cli.jvm.index
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.read
|
||||
import kotlin.concurrent.write
|
||||
|
||||
class JvmDependenciesDynamicCompoundIndex() : JvmDependenciesIndex {
|
||||
private val indices = arrayListOf<JvmDependenciesIndex>()
|
||||
private val lock = ReentrantReadWriteLock()
|
||||
|
||||
fun addIndex(index: JvmDependenciesIndex) {
|
||||
lock.write {
|
||||
indices.add(index)
|
||||
}
|
||||
}
|
||||
|
||||
fun addNewIndexForRoots(roots: Iterable<JavaRoot>): JvmDependenciesIndex? =
|
||||
lock.read {
|
||||
val alreadyIndexed = indexedRoots.toHashSet()
|
||||
val newRoots = roots.filter { !alreadyIndexed.contains(it) }
|
||||
if (newRoots.isEmpty()) null
|
||||
else {
|
||||
val index = JvmDependenciesIndexImpl(newRoots)
|
||||
addIndex(index)
|
||||
index
|
||||
}
|
||||
}
|
||||
|
||||
override val indexedRoots: Sequence<JavaRoot> get() = indices.asSequence().flatMap { it.indexedRoots }
|
||||
|
||||
override fun <T : Any> findClass(
|
||||
classId: ClassId,
|
||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
|
||||
): T? =
|
||||
lock.read {
|
||||
indices.asSequence().mapNotNull { it.findClass(classId, acceptedRootTypes, findClassGivenDirectory) }.firstOrNull()
|
||||
}
|
||||
|
||||
override fun traverseDirectoriesInPackage(
|
||||
packageFqName: FqName,
|
||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
|
||||
) {
|
||||
lock.read {
|
||||
indices.forEach { it.traverseDirectoriesInPackage(packageFqName, acceptedRootTypes, continueSearch) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun collectKnownClassNamesInPackage(packageFqName: FqName): Set<String> = lock.read {
|
||||
indices.flatMapTo(hashSetOf()) { it.collectKnownClassNamesInPackage(packageFqName) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.cli.jvm.index
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.util.*
|
||||
|
||||
interface JvmDependenciesIndex {
|
||||
val indexedRoots: Sequence<JavaRoot>
|
||||
|
||||
fun <T : Any> findClass(
|
||||
classId: ClassId,
|
||||
acceptedRootTypes: Set<JavaRoot.RootType> = JavaRoot.SourceAndBinary,
|
||||
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
|
||||
): T?
|
||||
|
||||
fun traverseDirectoriesInPackage(
|
||||
packageFqName: FqName,
|
||||
acceptedRootTypes: Set<JavaRoot.RootType> = JavaRoot.SourceAndBinary,
|
||||
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
|
||||
)
|
||||
|
||||
fun collectKnownClassNamesInPackage(
|
||||
packageFqName: FqName
|
||||
): Set<String>
|
||||
}
|
||||
|
||||
data class JavaRoot(val file: VirtualFile, val type: RootType, val prefixFqName: FqName? = null) {
|
||||
enum class RootType {
|
||||
SOURCE,
|
||||
BINARY
|
||||
}
|
||||
|
||||
companion object RootTypes {
|
||||
val OnlyBinary: Set<RootType> = EnumSet.of(RootType.BINARY)
|
||||
val SourceAndBinary: Set<RootType> = EnumSet.of(RootType.BINARY, RootType.SOURCE)
|
||||
}
|
||||
}
|
||||
|
||||
interface JvmDependenciesIndexFactory<out T : JvmDependenciesIndex> {
|
||||
fun makeIndexFor(roots: List<JavaRoot>): T
|
||||
}
|
||||
|
||||
class JvmUpdateableDependenciesIndexFactory : JvmDependenciesIndexFactory<JvmDependenciesDynamicCompoundIndex> {
|
||||
override fun makeIndexFor(roots: List<JavaRoot>) = JvmDependenciesDynamicCompoundIndex().apply {
|
||||
addIndex(JvmDependenciesIndexImpl(roots))
|
||||
}
|
||||
}
|
||||
+5
-105
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 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.
|
||||
@@ -14,69 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
package org.jetbrains.kotlin.cli.jvm.index
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.util.containers.IntArrayList
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.util.*
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.read
|
||||
import kotlin.concurrent.write
|
||||
|
||||
data class JavaRoot(val file: VirtualFile, val type: JavaRoot.RootType, val prefixFqName: FqName? = null) {
|
||||
enum class RootType {
|
||||
SOURCE,
|
||||
BINARY
|
||||
}
|
||||
|
||||
companion object RootTypes {
|
||||
val OnlyBinary: Set<RootType> = EnumSet.of(RootType.BINARY)
|
||||
val SourceAndBinary: Set<RootType> = EnumSet.of(RootType.BINARY, RootType.SOURCE)
|
||||
}
|
||||
}
|
||||
|
||||
interface JvmDependenciesIndex {
|
||||
|
||||
val indexedRoots: Sequence<JavaRoot>
|
||||
|
||||
fun <T : Any> findClass(
|
||||
classId: ClassId,
|
||||
acceptedRootTypes: Set<JavaRoot.RootType> = JavaRoot.SourceAndBinary,
|
||||
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
|
||||
): T?
|
||||
|
||||
fun traverseDirectoriesInPackage(
|
||||
packageFqName: FqName,
|
||||
acceptedRootTypes: Set<JavaRoot.RootType> = JavaRoot.SourceAndBinary,
|
||||
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
|
||||
)
|
||||
|
||||
fun collectKnownClassNamesInPackage(
|
||||
packageFqName: FqName
|
||||
): Set<String>
|
||||
}
|
||||
|
||||
interface JvmDependenciesIndexFactory<out T : JvmDependenciesIndex> {
|
||||
fun makeIndexFor(roots: List<JavaRoot>): T
|
||||
}
|
||||
|
||||
class JvmStaticDependenciesIndexFactory : JvmDependenciesIndexFactory<JvmDependenciesIndex> {
|
||||
override fun makeIndexFor(roots: List<JavaRoot>) = JvmDependenciesIndexImpl(roots)
|
||||
}
|
||||
|
||||
class JvmUpdatableDependenciesIndexFactory : JvmDependenciesIndexFactory<JvmDependenciesDynamicCompoundIndex> {
|
||||
override fun makeIndexFor(roots: List<JavaRoot>) = JvmDependenciesDynamicCompoundIndex().apply {
|
||||
addIndex(JvmDependenciesIndexImpl(roots))
|
||||
}
|
||||
}
|
||||
|
||||
// speeds up finding files/classes in classpath/java source roots
|
||||
// NOT THREADSAFE, needs to be adapted/removed if we want compiler to be multithreaded
|
||||
// the main idea of this class is for each package to store roots which contains it to avoid excessive file system traversal
|
||||
class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
||||
|
||||
//these fields are computed based on _roots passed to constructor which are filled in later
|
||||
private val roots: List<JavaRoot> by lazy { _roots.toList() }
|
||||
|
||||
@@ -139,7 +88,7 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
||||
override fun collectKnownClassNamesInPackage(
|
||||
packageFqName: FqName
|
||||
): Set<String> {
|
||||
var result = hashSetOf<String>()
|
||||
val result = hashSetOf<String>()
|
||||
traverseDirectoriesInPackage(packageFqName, continueSearch = {
|
||||
dir, rootType ->
|
||||
|
||||
@@ -322,57 +271,8 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
|
||||
|
||||
object NotFound : SearchResult
|
||||
}
|
||||
}
|
||||
|
||||
class JvmDependenciesDynamicCompoundIndex() : JvmDependenciesIndex {
|
||||
|
||||
private val indices = arrayListOf<JvmDependenciesIndex>()
|
||||
private val lock = ReentrantReadWriteLock()
|
||||
|
||||
fun addIndex(index: JvmDependenciesIndex) {
|
||||
lock.write {
|
||||
indices.add(index)
|
||||
}
|
||||
}
|
||||
|
||||
fun addNewIndexForRoots(roots: Iterable<JavaRoot>): JvmDependenciesIndex? =
|
||||
lock.read {
|
||||
val alreadyIndexed = indexedRoots.toHashSet()
|
||||
val newRoots = roots.filter { !alreadyIndexed.contains(it) }
|
||||
if (newRoots.isEmpty()) null
|
||||
else {
|
||||
val index = JvmDependenciesIndexImpl(newRoots)
|
||||
addIndex(index)
|
||||
index
|
||||
}
|
||||
}
|
||||
|
||||
override val indexedRoots: Sequence<JavaRoot> get() = indices.asSequence().flatMap { it.indexedRoots }
|
||||
|
||||
override fun <T : Any> findClass(
|
||||
classId: ClassId,
|
||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
|
||||
): T? =
|
||||
lock.read {
|
||||
indices.asSequence().mapNotNull { it.findClass(classId, acceptedRootTypes, findClassGivenDirectory) }.firstOrNull()
|
||||
}
|
||||
|
||||
override fun traverseDirectoriesInPackage(
|
||||
packageFqName: FqName,
|
||||
acceptedRootTypes: Set<JavaRoot.RootType>,
|
||||
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
|
||||
) {
|
||||
lock.read {
|
||||
indices.forEach { it.traverseDirectoriesInPackage(packageFqName, acceptedRootTypes, continueSearch) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun collectKnownClassNamesInPackage(packageFqName: FqName): Set<String> = lock.read {
|
||||
indices.flatMapTo(hashSetOf()) { it.collectKnownClassNamesInPackage(packageFqName) }
|
||||
private companion object {
|
||||
fun IntArrayList.lastOrNull() = if (isEmpty) null else get(size() - 1)
|
||||
}
|
||||
}
|
||||
|
||||
private fun IntArrayList.lastOrNull() = if (isEmpty) null else get(size() - 1)
|
||||
private val IntArrayList.indices: IntRange get() = 0..(size() - 1)
|
||||
|
||||
@@ -20,8 +20,12 @@ import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import junit.framework.TestCase
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.*
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCliJavaFileManagerImpl
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndexImpl
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmVirtualFileFinder
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -31,7 +35,6 @@ import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
import java.io.File
|
||||
|
||||
|
||||
class KotlinCliJavaFileManagerTest : KotlinTestWithEnvironment() {
|
||||
private var javaFilesDir: File? = null
|
||||
|
||||
|
||||
Reference in New Issue
Block a user