From 76523cc17564c58221add148aaaf4136a1d94711 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 17 Oct 2016 11:35:43 +0300 Subject: [PATCH] Split JvmDependenciesIndex to several files, move to 'index' package --- .../jvm/compiler/JvmCliVirtualFileFinder.kt | 2 + .../JvmCliVirtualFileFinderFactory.kt | 1 + .../compiler/KotlinCliJavaFileManagerImpl.kt | 2 + .../cli/jvm/compiler/KotlinCoreEnvironment.kt | 6 +- .../JvmDependenciesDynamicCompoundIndex.kt | 72 ++++++++++++ .../cli/jvm/index/JvmDependenciesIndex.kt | 64 ++++++++++ .../JvmDependenciesIndexImpl.kt} | 110 +----------------- .../cli/jvm/KotlinCliJavaFileManagerTest.kt | 7 +- 8 files changed, 156 insertions(+), 108 deletions(-) create mode 100644 compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesDynamicCompoundIndex.kt create mode 100644 compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndex.kt rename compiler/cli/src/org/jetbrains/kotlin/cli/jvm/{compiler/JvmDependenciesIndex.kt => index/JvmDependenciesIndexImpl.kt} (74%) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmCliVirtualFileFinder.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmCliVirtualFileFinder.kt index 261b7682fad..7ed52a813a5 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmCliVirtualFileFinder.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmCliVirtualFileFinder.kt @@ -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 diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmCliVirtualFileFinderFactory.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmCliVirtualFileFinderFactory.kt index cdc97fa5487..201e680ed3b 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmCliVirtualFileFinderFactory.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmCliVirtualFileFinderFactory.kt @@ -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 diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCliJavaFileManagerImpl.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCliJavaFileManagerImpl.kt index 4e55acf39f0..7c71f6c0762 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCliJavaFileManagerImpl.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCliJavaFileManagerImpl.kt @@ -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 diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index 80019d189c0..466f9695456 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -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) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesDynamicCompoundIndex.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesDynamicCompoundIndex.kt new file mode 100644 index 00000000000..01537f1a3a9 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesDynamicCompoundIndex.kt @@ -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() + private val lock = ReentrantReadWriteLock() + + fun addIndex(index: JvmDependenciesIndex) { + lock.write { + indices.add(index) + } + } + + fun addNewIndexForRoots(roots: Iterable): 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 get() = indices.asSequence().flatMap { it.indexedRoots } + + override fun findClass( + classId: ClassId, + acceptedRootTypes: Set, + findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T? + ): T? = + lock.read { + indices.asSequence().mapNotNull { it.findClass(classId, acceptedRootTypes, findClassGivenDirectory) }.firstOrNull() + } + + override fun traverseDirectoriesInPackage( + packageFqName: FqName, + acceptedRootTypes: Set, + continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean + ) { + lock.read { + indices.forEach { it.traverseDirectoriesInPackage(packageFqName, acceptedRootTypes, continueSearch) } + } + } + + override fun collectKnownClassNamesInPackage(packageFqName: FqName): Set = lock.read { + indices.flatMapTo(hashSetOf()) { it.collectKnownClassNamesInPackage(packageFqName) } + } +} diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndex.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndex.kt new file mode 100644 index 00000000000..3eb185b9710 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndex.kt @@ -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 + + fun findClass( + classId: ClassId, + acceptedRootTypes: Set = JavaRoot.SourceAndBinary, + findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T? + ): T? + + fun traverseDirectoriesInPackage( + packageFqName: FqName, + acceptedRootTypes: Set = JavaRoot.SourceAndBinary, + continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean + ) + + fun collectKnownClassNamesInPackage( + packageFqName: FqName + ): Set +} + +data class JavaRoot(val file: VirtualFile, val type: RootType, val prefixFqName: FqName? = null) { + enum class RootType { + SOURCE, + BINARY + } + + companion object RootTypes { + val OnlyBinary: Set = EnumSet.of(RootType.BINARY) + val SourceAndBinary: Set = EnumSet.of(RootType.BINARY, RootType.SOURCE) + } +} + +interface JvmDependenciesIndexFactory { + fun makeIndexFor(roots: List): T +} + +class JvmUpdateableDependenciesIndexFactory : JvmDependenciesIndexFactory { + override fun makeIndexFor(roots: List) = JvmDependenciesDynamicCompoundIndex().apply { + addIndex(JvmDependenciesIndexImpl(roots)) + } +} diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmDependenciesIndex.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndexImpl.kt similarity index 74% rename from compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmDependenciesIndex.kt rename to compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndexImpl.kt index 004ba086dce..4ebe97370e5 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmDependenciesIndex.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndexImpl.kt @@ -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 = EnumSet.of(RootType.BINARY) - val SourceAndBinary: Set = EnumSet.of(RootType.BINARY, RootType.SOURCE) - } -} - -interface JvmDependenciesIndex { - - val indexedRoots: Sequence - - fun findClass( - classId: ClassId, - acceptedRootTypes: Set = JavaRoot.SourceAndBinary, - findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T? - ): T? - - fun traverseDirectoriesInPackage( - packageFqName: FqName, - acceptedRootTypes: Set = JavaRoot.SourceAndBinary, - continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean - ) - - fun collectKnownClassNamesInPackage( - packageFqName: FqName - ): Set -} - -interface JvmDependenciesIndexFactory { - fun makeIndexFor(roots: List): T -} - -class JvmStaticDependenciesIndexFactory : JvmDependenciesIndexFactory { - override fun makeIndexFor(roots: List) = JvmDependenciesIndexImpl(roots) -} - -class JvmUpdatableDependenciesIndexFactory : JvmDependenciesIndexFactory { - override fun makeIndexFor(roots: List) = 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): JvmDependenciesIndex { - //these fields are computed based on _roots passed to constructor which are filled in later private val roots: List by lazy { _roots.toList() } @@ -139,7 +88,7 @@ class JvmDependenciesIndexImpl(_roots: List): JvmDependenciesIndex { override fun collectKnownClassNamesInPackage( packageFqName: FqName ): Set { - var result = hashSetOf() + val result = hashSetOf() traverseDirectoriesInPackage(packageFqName, continueSearch = { dir, rootType -> @@ -322,57 +271,8 @@ class JvmDependenciesIndexImpl(_roots: List): JvmDependenciesIndex { object NotFound : SearchResult } -} -class JvmDependenciesDynamicCompoundIndex() : JvmDependenciesIndex { - - private val indices = arrayListOf() - private val lock = ReentrantReadWriteLock() - - fun addIndex(index: JvmDependenciesIndex) { - lock.write { - indices.add(index) - } - } - - fun addNewIndexForRoots(roots: Iterable): 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 get() = indices.asSequence().flatMap { it.indexedRoots } - - override fun findClass( - classId: ClassId, - acceptedRootTypes: Set, - findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T? - ): T? = - lock.read { - indices.asSequence().mapNotNull { it.findClass(classId, acceptedRootTypes, findClassGivenDirectory) }.firstOrNull() - } - - override fun traverseDirectoriesInPackage( - packageFqName: FqName, - acceptedRootTypes: Set, - continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean - ) { - lock.read { - indices.forEach { it.traverseDirectoriesInPackage(packageFqName, acceptedRootTypes, continueSearch) } - } - } - - override fun collectKnownClassNamesInPackage(packageFqName: FqName): Set = 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) - diff --git a/compiler/tests/org/jetbrains/kotlin/cli/jvm/KotlinCliJavaFileManagerTest.kt b/compiler/tests/org/jetbrains/kotlin/cli/jvm/KotlinCliJavaFileManagerTest.kt index 8bcb824bf82..fa088b93f13 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/jvm/KotlinCliJavaFileManagerTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/cli/jvm/KotlinCliJavaFileManagerTest.kt @@ -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