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 049f4b27329..007f591bb4b 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 @@ -121,7 +121,22 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ return findClassInPsiFile(classNameWithInnerClasses, file) } - override fun knownClassNamesInPackage(packageFqName: FqName) = index.collectKnownClassNamesInPackage(packageFqName) + override fun knownClassNamesInPackage(packageFqName: FqName): Set { + val result = hashSetOf() + index.traverseDirectoriesInPackage(packageFqName, continueSearch = { + dir, _ -> + + for (child in dir.children) { + if (child.extension == "class" || child.extension == "java") { + result.add(child.nameWithoutExtension) + } + } + + true + }) + + return result + } companion object { private val LOG = Logger.getInstance(KotlinCliJavaFileManagerImpl::class.java) 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 index 01537f1a3a9..43adf655d0c 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesDynamicCompoundIndex.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesDynamicCompoundIndex.kt @@ -23,7 +23,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock import kotlin.concurrent.read import kotlin.concurrent.write -class JvmDependenciesDynamicCompoundIndex() : JvmDependenciesIndex { +class JvmDependenciesDynamicCompoundIndex : JvmDependenciesIndex { private val indices = arrayListOf() private val lock = ReentrantReadWriteLock() @@ -36,13 +36,9 @@ class JvmDependenciesDynamicCompoundIndex() : JvmDependenciesIndex { fun addNewIndexForRoots(roots: Iterable): JvmDependenciesIndex? = lock.read { val alreadyIndexed = indexedRoots.toHashSet() - val newRoots = roots.filter { !alreadyIndexed.contains(it) } + val newRoots = roots.filter { root -> root !in alreadyIndexed } if (newRoots.isEmpty()) null - else { - val index = JvmDependenciesIndexImpl(newRoots) - addIndex(index) - index - } + else JvmDependenciesIndexImpl(newRoots).also(this::addIndex) } override val indexedRoots: Sequence get() = indices.asSequence().flatMap { it.indexedRoots } @@ -51,22 +47,15 @@ class JvmDependenciesDynamicCompoundIndex() : JvmDependenciesIndex { classId: ClassId, acceptedRootTypes: Set, findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T? - ): T? = - lock.read { - indices.asSequence().mapNotNull { it.findClass(classId, acceptedRootTypes, findClassGivenDirectory) }.firstOrNull() - } + ): 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) } + ) = lock.read { + indices.forEach { it.traverseDirectoriesInPackage(packageFqName, acceptedRootTypes, continueSearch) } } } 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 index 3eb185b9710..c7b3ab3087f 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndex.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndex.kt @@ -35,10 +35,6 @@ interface JvmDependenciesIndex { 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) { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndexImpl.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndexImpl.kt index f817df9cee3..b755445f0e6 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndexImpl.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndexImpl.kt @@ -39,24 +39,21 @@ class JvmDependenciesIndexImpl(_roots: List): JvmDependenciesIndex { private class Cache { private val innerPackageCaches = HashMap() - operator fun get(name: String) = innerPackageCaches.getOrPut(name) { Cache() } + operator fun get(name: String) = innerPackageCaches.getOrPut(name, ::Cache) // indices of roots that are known to contain this package // if this list contains [1, 3, 5] then roots with indices 1, 3 and 5 are known to contain this package, 2 and 4 are known not to (no information about roots 6 or higher) // if this list contains maxIndex that means that all roots containing this package are known - val rootIndices = IntArrayList() + val rootIndices = IntArrayList(2) } // root "Cache" object corresponds to DefaultPackage which exists in every root. Roots with non-default fqname are also listed here but // they will be ignored on requests with invalid fqname prefix. private val rootCache: Cache by lazy { - with(Cache()) { - roots.indices.forEach { - rootIndices.add(it) - } + Cache().apply { + roots.indices.forEach(rootIndices::add) rootIndices.add(maxIndex) rootIndices.trimToSize() - this } } @@ -72,7 +69,7 @@ class JvmDependenciesIndexImpl(_roots: List): JvmDependenciesIndex { acceptedRootTypes: Set, findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T? ): T? { - return search(FindClassRequest(classId, acceptedRootTypes)) { dir, rootType -> + return findClassCached(classId, acceptedRootTypes) { dir, rootType -> val found = findClassGivenDirectory(dir, rootType) HandleResult(found, continueSearch = found == null) } @@ -88,73 +85,51 @@ class JvmDependenciesIndexImpl(_roots: List): JvmDependenciesIndex { } } - override fun collectKnownClassNamesInPackage( - packageFqName: FqName - ): Set { - val result = hashSetOf() - traverseDirectoriesInPackage(packageFqName, continueSearch = { - dir, _ -> - - for (child in dir.children) { - if (child.extension != "class" && child.extension != "java") continue - result.add(child.nameWithoutExtension) - } - - true - }) - - return result - } - private data class HandleResult(val result: T?, val continueSearch: Boolean) - private fun search( - request: SearchRequest, + private fun findClassCached( + classId: ClassId, + acceptedRootTypes: Set, handler: (VirtualFile, JavaRoot.RootType) -> HandleResult ): T? { // make a decision based on information saved from last class search - if (request !is FindClassRequest || lastClassSearch?.first?.classId != request.classId) { - return doSearch(request, handler) + if (lastClassSearch?.first?.classId != classId) { + return search(FindClassRequest(classId, acceptedRootTypes), handler) } - + val (cachedRequest, cachedResult) = lastClassSearch!! return when (cachedResult) { is SearchResult.NotFound -> { - val limitedRootTypes = request.acceptedRootTypes.toHashSet() - limitedRootTypes.removeAll(cachedRequest.acceptedRootTypes) + val limitedRootTypes = acceptedRootTypes - cachedRequest.acceptedRootTypes if (limitedRootTypes.isEmpty()) { null } else { - doSearch(FindClassRequest(request.classId, limitedRootTypes), handler) + search(FindClassRequest(classId, limitedRootTypes), handler) } } is SearchResult.Found -> { - if (cachedRequest.acceptedRootTypes == request.acceptedRootTypes) { + if (cachedRequest.acceptedRootTypes == acceptedRootTypes) { handler(cachedResult.packageDirectory, cachedResult.root.type).result } else { - doSearch(request, handler) + search(FindClassRequest(classId, acceptedRootTypes), handler) } } } } - private fun doSearch(request: SearchRequest, handler: (VirtualFile, JavaRoot.RootType) -> HandleResult): T? { - val findClassRequest = request as? FindClassRequest - - fun found(packageDirectory: VirtualFile, root: JavaRoot, result: T): T { - if (findClassRequest != null) { - lastClassSearch = Pair(findClassRequest, SearchResult.Found(packageDirectory, root)) + private fun search(request: SearchRequest, handler: (VirtualFile, JavaRoot.RootType) -> HandleResult): T? { + fun found(packageDirectory: VirtualFile, root: JavaRoot, result: T): T = result.also { + if (request is FindClassRequest) { + lastClassSearch = Pair(request, SearchResult.Found(packageDirectory, root)) } - return result } - fun notFound(): T? { - if (findClassRequest != null) { - lastClassSearch = Pair(findClassRequest, SearchResult.NotFound) + fun notFound(): T? = null.also { + if (request is FindClassRequest) { + lastClassSearch = Pair(request, SearchResult.NotFound) } - return null } fun handle(root: JavaRoot, targetDirInRoot: VirtualFile): T? { @@ -197,7 +172,7 @@ class JvmDependenciesIndexImpl(_roots: List): JvmDependenciesIndex { return notFound() } - // try to find a target directory corresponding to package represented by packagesPath in a given root reprenting by index + // try to find a target directory corresponding to package represented by packagesPath in a given root represented by index // possibly filling "Cache" objects with new information private fun travelPath(rootIndex: Int, packagesPath: List, fillCachesAfter: Int, cachesPath: List): VirtualFile? { if (rootIndex >= maxIndex) {