mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
fixed detection of source folder creation
This commit is contained in:
committed by
Sergei Vorobyov
parent
48d798af87
commit
421dc9ace2
+46
-22
@@ -3,11 +3,14 @@ package com.intellij.openapi.externalSystem.service.project.manage
|
||||
|
||||
import com.intellij.ide.projectView.actions.MarkRootActionBase
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.TransactionGuard
|
||||
import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.externalSystem.util.PathPrefixTreeMapImpl
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.util.Computable
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.vfs.*
|
||||
@@ -20,13 +23,12 @@ class SourceFolderManagerImpl(private val project: Project) : SourceFolderManage
|
||||
private var isDisposed = false
|
||||
private val mutex = Any()
|
||||
private val postponedSourceFolderCreator = PostponedSourceFolderCreator()
|
||||
private val sourceFolders = THashMap<String, SourceFolderModel>(FileUtil.PATH_HASHING_STRATEGY)
|
||||
private val sourceFolders = PathPrefixTreeMapImpl<SourceFolderModel>()
|
||||
private val sourceFoldersByModule = THashMap<String, ModuleModel>()
|
||||
|
||||
override fun addSourceFolder(module: Module, url: String, type: JpsModuleSourceRootType<*>) {
|
||||
val sourceFolder = SourceFolderModel(module, type, "")
|
||||
synchronized(mutex) {
|
||||
sourceFolders[url] = sourceFolder
|
||||
sourceFolders[url] = SourceFolderModel(module, url, type, "")
|
||||
val moduleModel = sourceFoldersByModule.getOrPut(module.name) {
|
||||
ModuleModel(module).also {
|
||||
Disposer.register(module, it)
|
||||
@@ -34,6 +36,10 @@ class SourceFolderManagerImpl(private val project: Project) : SourceFolderManage
|
||||
}
|
||||
moduleModel.sourceFolders.add(url)
|
||||
}
|
||||
TransactionGuard.getInstance().submitTransactionLater(this, Runnable {
|
||||
val virtualFileManager = VirtualFileManager.getInstance()
|
||||
virtualFileManager.refreshAndFindFileByUrl(url)
|
||||
})
|
||||
}
|
||||
|
||||
override fun setSourceFolderPackagePrefix(url: String, packagePrefix: String) {
|
||||
@@ -57,42 +63,60 @@ class SourceFolderManagerImpl(private val project: Project) : SourceFolderManage
|
||||
virtualFileManager.removeVirtualFileListener(postponedSourceFolderCreator)
|
||||
}
|
||||
|
||||
private fun remove(url: String): SourceFolderModel? {
|
||||
return synchronized(mutex) {
|
||||
sourceFolders.remove(url)
|
||||
}
|
||||
}
|
||||
|
||||
fun isDisposed() = isDisposed
|
||||
|
||||
fun getSourceFolders(moduleName: String) = synchronized(mutex) {
|
||||
sourceFoldersByModule[moduleName]?.sourceFolders
|
||||
}
|
||||
|
||||
private fun unsafeRemoveSourceFolder(url: String) {
|
||||
val sourceFolder = sourceFolders.remove(url) ?: return
|
||||
val module = sourceFolder.module
|
||||
val moduleModel = sourceFoldersByModule[module.name] ?: return
|
||||
val sourceFolders = moduleModel.sourceFolders
|
||||
sourceFolders.remove(url)
|
||||
if (sourceFolders.isEmpty()) {
|
||||
sourceFoldersByModule.remove(module.name)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class PostponedSourceFolderCreator : VirtualFileListener {
|
||||
override fun fileCreated(event: VirtualFileEvent) {
|
||||
val sourceFoldersToChange = ArrayList<SourceFolderModel>()
|
||||
val virtualFileManager = VirtualFileManager.getInstance()
|
||||
synchronized(mutex) {
|
||||
for (sourceFolder in sourceFolders.getAllDescendants(event.file.url)) {
|
||||
val sourceFolderFile = ExternalSystemApiUtil.doWriteAction(Computable<VirtualFile> {
|
||||
virtualFileManager.refreshAndFindFileByUrl(sourceFolder.url)
|
||||
})
|
||||
if (sourceFolderFile != null && sourceFolderFile.isValid) {
|
||||
sourceFoldersToChange.add(sourceFolder)
|
||||
unsafeRemoveSourceFolder(sourceFolder.url)
|
||||
}
|
||||
}
|
||||
}
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(false, object : DisposeAwareProjectChange(project) {
|
||||
override fun execute() {
|
||||
val sourceFolderUrl = event.file.url
|
||||
val (module, type, packagePrefix) = remove(sourceFolderUrl) ?: return
|
||||
val moduleManager = ModuleRootManager.getInstance(module)
|
||||
val modifiableModuleModel = moduleManager.modifiableModel
|
||||
try {
|
||||
val contentEntry = MarkRootActionBase.findContentEntry(modifiableModuleModel, event.file)
|
||||
if (contentEntry != null) {
|
||||
val sourceFolder = contentEntry.addSourceFolder(sourceFolderUrl, type)
|
||||
sourceFolder.packagePrefix = packagePrefix
|
||||
for ((module, url, type, packagePrefix) in sourceFoldersToChange) {
|
||||
val moduleManager = ModuleRootManager.getInstance(module)
|
||||
val modifiableModuleModel = moduleManager.modifiableModel
|
||||
try {
|
||||
val contentEntry = MarkRootActionBase.findContentEntry(modifiableModuleModel, event.file)
|
||||
if (contentEntry != null) {
|
||||
val sourceFolder = contentEntry.addSourceFolder(url, type)
|
||||
sourceFolder.packagePrefix = packagePrefix
|
||||
}
|
||||
}
|
||||
finally {
|
||||
modifiableModuleModel.commit()
|
||||
}
|
||||
}
|
||||
finally {
|
||||
modifiableModuleModel.commit()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private data class SourceFolderModel(val module: Module, val type: JpsModuleSourceRootType<*>, var packagePrefix: String)
|
||||
private data class SourceFolderModel(val module: Module, val url: String, val type: JpsModuleSourceRootType<*>, var packagePrefix: String)
|
||||
|
||||
private inner class ModuleModel(val module: Module, val sourceFolders: MutableSet<String>) : Disposable {
|
||||
constructor(module: Module) : this(module, THashSet(FileUtil.PATH_HASHING_STRATEGY))
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.externalSystem.util
|
||||
|
||||
/**
|
||||
* [PrefixTreeMap] uses keys, that is specified by the file system paths.
|
||||
* @see PrefixTreeMap
|
||||
*/
|
||||
interface PathPrefixTreeMap<V> : PrefixTreeMap<String, V> {
|
||||
|
||||
/**
|
||||
* @see PrefixTreeMap.get
|
||||
*/
|
||||
operator fun get(path: String): V?
|
||||
|
||||
/**
|
||||
* @see PrefixTreeMap.set
|
||||
*/
|
||||
operator fun set(path: String, value: V): V?
|
||||
|
||||
/**
|
||||
* @see PrefixTreeMap.remove
|
||||
*/
|
||||
fun remove(path: String): V?
|
||||
|
||||
/**
|
||||
* @see PrefixTreeMap.contains
|
||||
*/
|
||||
fun contains(path: String): Boolean
|
||||
|
||||
/**
|
||||
* @see PrefixTreeMap.getAllDescendants
|
||||
*/
|
||||
fun getAllDescendants(path: String): List<V>
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.externalSystem.util
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
|
||||
class PathPrefixTreeMapImpl<V>(
|
||||
private val pathSeparator: String = "/",
|
||||
private val removeLastSlash: Boolean = true
|
||||
) : PathPrefixTreeMap<V>, PrefixTreeMapImpl<String, V>(FileUtil.PATH_HASHING_STRATEGY) {
|
||||
|
||||
override operator fun get(path: String): V? = get(path.toPrefixList())
|
||||
|
||||
override operator fun set(path: String, value: V): V? = set(path.toPrefixList(), value)
|
||||
|
||||
override fun remove(path: String): V? = remove(path.toPrefixList())
|
||||
|
||||
override fun contains(path: String): Boolean = contains(path.toPrefixList())
|
||||
|
||||
override fun getAllDescendants(path: String): List<V> = getAllDescendants(path.toPrefixList())
|
||||
|
||||
private fun String.toPrefixList(): List<String> {
|
||||
val path = if (removeLastSlash) removeSuffix(pathSeparator) else this
|
||||
return path.split(pathSeparator)
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.externalSystem.util
|
||||
|
||||
/**
|
||||
* Map for fast finding values by the prefix of them keys
|
||||
*/
|
||||
interface PrefixTreeMap<K, V> {
|
||||
|
||||
/**
|
||||
* Gets value from the storage by the specified [path]
|
||||
*
|
||||
* @param path is key identificator
|
||||
* @return stored value with the specified [path], null if [path] not found
|
||||
*/
|
||||
operator fun get(path: List<K>): V?
|
||||
|
||||
/**
|
||||
* Sets value in the storage by the specified [path]
|
||||
*
|
||||
* @param path is key identificator
|
||||
* @param value is value to store
|
||||
* @return previous stored value with the specified [path], null if previous [path] not found
|
||||
*/
|
||||
operator fun set(path: List<K>, value: V): V?
|
||||
|
||||
/**
|
||||
* Removes value from the storage by the specified [path]
|
||||
*
|
||||
* @param path is key identificator
|
||||
* @return stored value with the specified [path], null if stored [path] not found
|
||||
*/
|
||||
fun remove(path: List<K>): V?
|
||||
|
||||
/**
|
||||
* Checks existence of [path] in the storage
|
||||
*
|
||||
* @param path is key identificator
|
||||
* @return result of existence checking
|
||||
*/
|
||||
fun contains(path: List<K>): Boolean
|
||||
|
||||
/**
|
||||
* Gets all values with a key, for which [path] is an ancestor
|
||||
*
|
||||
* @param path is key identificator
|
||||
* @return list of stored values, [emptyList] if [path] not found
|
||||
*/
|
||||
fun getAllDescendants(path: List<K>): List<V>
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.externalSystem.util
|
||||
|
||||
import com.intellij.util.containers.FList
|
||||
import gnu.trove.THashMap
|
||||
import gnu.trove.TObjectHashingStrategy
|
||||
|
||||
open class PrefixTreeMapImpl<K, V>(private val strategy: TObjectHashingStrategy<K>? = null) : PrefixTreeMap<K, V> {
|
||||
|
||||
private val root = Node()
|
||||
|
||||
override operator fun get(path: List<K>) = root.get(path.toFList())?.getValue()
|
||||
|
||||
override operator fun set(path: List<K>, value: V) = root.put(path.toFList(), value)
|
||||
|
||||
override fun remove(path: List<K>) = root.remove(path.toFList())
|
||||
|
||||
override fun contains(path: List<K>) = root.contains(path.toFList())
|
||||
|
||||
override fun getAllDescendants(path: List<K>) = root.get(path.toFList())?.getAllDescendants() ?: emptyList()
|
||||
|
||||
private inner class Node {
|
||||
private val children = strategy?.let { THashMap<K, Node>(it) } ?: THashMap()
|
||||
private val isLeaf get() = children.isEmpty
|
||||
private val isInvalid get() = isLeaf && !isPresent
|
||||
private var isPresent: Boolean = false
|
||||
private var value: V? = null
|
||||
|
||||
fun getValue() = value
|
||||
|
||||
fun put(path: FList<K>, value: V): V? {
|
||||
val (head, tail) = path
|
||||
val child = children.getOrPut(head) { Node() }
|
||||
if (tail.isEmpty()) {
|
||||
val previousValue = child.value
|
||||
child.value = value
|
||||
child.isPresent = true
|
||||
return previousValue
|
||||
}
|
||||
else return child.put(tail, value)
|
||||
}
|
||||
|
||||
fun remove(path: FList<K>): V? {
|
||||
val (head, tail) = path
|
||||
val child = children[head] ?: return null
|
||||
if (tail.isEmpty()) {
|
||||
val value = child.value
|
||||
child.value = null
|
||||
child.isPresent = false
|
||||
return value
|
||||
}
|
||||
else {
|
||||
val result = child.remove(tail)
|
||||
if (child.isInvalid) {
|
||||
children.remove(head)
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
fun contains(path: FList<K>): Boolean {
|
||||
val (head, tail) = path
|
||||
val child = children[head] ?: return false
|
||||
return when {
|
||||
tail.isEmpty() -> child.isPresent
|
||||
else -> child.contains(tail)
|
||||
}
|
||||
}
|
||||
|
||||
fun get(path: FList<K>): Node? {
|
||||
val (head, tail) = path
|
||||
val child = children[head] ?: return null
|
||||
return when {
|
||||
tail.isEmpty() -> child
|
||||
else -> child.get(tail)
|
||||
}
|
||||
}
|
||||
|
||||
fun getAllDescendants(): List<V> {
|
||||
val result = children.flatMap { it.value.getAllDescendants() }.toMutableList()
|
||||
value?.let { result.add(it) }
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private operator fun <E> FList<E>.component1() = head
|
||||
|
||||
private operator fun <E> FList<E>.component2() = tail
|
||||
|
||||
private fun <E> List<E>.toFList() = FList.createFromReversed(asReversed())
|
||||
}
|
||||
}
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.externalSystem.service.project.manage
|
||||
|
||||
import com.intellij.openapi.externalSystem.util.PathPrefixTreeMapImpl
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import org.junit.Test
|
||||
|
||||
class PathPrefixTreeMapImplTest : UsefulTestCase() {
|
||||
|
||||
@Test
|
||||
fun `test map filling`() {
|
||||
val map = PathPrefixTreeMapImpl<Int>()
|
||||
map["C://path/to/my/dir3"] = 30
|
||||
map["C://path/to/my/dir4"] = 10
|
||||
map["C://path/to/dir1"] = 11
|
||||
map["C://path/to/dir2"] = 21
|
||||
map["C://path/to/my"] = 43
|
||||
map["C://path"] = 13
|
||||
assertEquals(map["C://path/to/my/dir1"], null)
|
||||
assertEquals(map["C://path/to/my/dir2"], null)
|
||||
assertEquals(map["C://path/to/my/dir3"], 30)
|
||||
assertEquals(map["C://path/to/my/dir4"], 10)
|
||||
assertEquals(map["C://path/to/dir1"], 11)
|
||||
assertEquals(map["C://path/to/dir2"], 21)
|
||||
assertEquals(map["C://path/to/dir3"], null)
|
||||
assertEquals(map["C://path/to/dir4"], null)
|
||||
assertEquals(map["C://path/to/my"], 43)
|
||||
assertEquals(map["C://path"], 13)
|
||||
assertFalse(map.contains("C://path/to/my/dir1"))
|
||||
assertFalse(map.contains("C://path/to/my/dir2"))
|
||||
assertTrue(map.contains("C://path/to/my/dir3"))
|
||||
assertTrue(map.contains("C://path/to/my/dir4"))
|
||||
assertTrue(map.contains("C://path/to/dir1"))
|
||||
assertTrue(map.contains("C://path/to/dir2"))
|
||||
assertFalse(map.contains("C://path/to/dir3"))
|
||||
assertFalse(map.contains("C://path/to/dir4"))
|
||||
assertTrue(map.contains("C://path/to/my"))
|
||||
assertTrue(map.contains("C://path"))
|
||||
map["C://path/to/my/dir1"] = 10
|
||||
map["C://path/to/my/dir2"] = 20
|
||||
map["C://path/to/dir3"] = 30
|
||||
map["C://path/to/dir4"] = 11
|
||||
assertEquals(map["C://path/to/my/dir1"], 10)
|
||||
assertEquals(map["C://path/to/my/dir2"], 20)
|
||||
assertEquals(map["C://path/to/my/dir3"], 30)
|
||||
assertEquals(map["C://path/to/my/dir4"], 10)
|
||||
assertEquals(map["C://path/to/dir1"], 11)
|
||||
assertEquals(map["C://path/to/dir2"], 21)
|
||||
assertEquals(map["C://path/to/dir3"], 30)
|
||||
assertEquals(map["C://path/to/dir4"], 11)
|
||||
assertEquals(map["C://path/to/my"], 43)
|
||||
assertEquals(map["C://path"], 13)
|
||||
assertTrue(map.contains("C://path/to/my/dir1"))
|
||||
assertTrue(map.contains("C://path/to/my/dir2"))
|
||||
assertTrue(map.contains("C://path/to/my/dir3"))
|
||||
assertTrue(map.contains("C://path/to/my/dir4"))
|
||||
assertTrue(map.contains("C://path/to/dir1"))
|
||||
assertTrue(map.contains("C://path/to/dir2"))
|
||||
assertTrue(map.contains("C://path/to/dir3"))
|
||||
assertTrue(map.contains("C://path/to/dir4"))
|
||||
assertTrue(map.contains("C://path/to/my"))
|
||||
assertTrue(map.contains("C://path"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test map removes`() {
|
||||
val map = PathPrefixTreeMapImpl<Int>()
|
||||
map["C://path/to/my/dir1"] = 10
|
||||
map["C://path/to/my/dir2"] = 20
|
||||
map["C://path/to/my/dir3"] = 30
|
||||
map["C://path/to/my/dir4"] = 10
|
||||
map["C://path/to/dir1"] = 11
|
||||
map["C://path/to/dir2"] = 21
|
||||
map["C://path/to/dir3"] = 30
|
||||
map["C://path/to/dir4/"] = 11
|
||||
map["C://path/to/my"] = 43
|
||||
map["C://path"] = 13
|
||||
assertEquals(map["C://path/to/my/dir1"], 10)
|
||||
assertEquals(map["C://path/to/my/dir2"], 20)
|
||||
assertEquals(map["C://path/to/my/dir3"], 30)
|
||||
assertEquals(map["C://path/to/my/dir4"], 10)
|
||||
assertEquals(map["C://path/to/dir1"], 11)
|
||||
assertEquals(map["C://path/to/dir2"], 21)
|
||||
assertEquals(map["C://path/to/dir3"], 30)
|
||||
assertEquals(map["C://path/to/dir4"], 11)
|
||||
assertEquals(map["C://path/to/my"], 43)
|
||||
assertEquals(map["C://path"], 13)
|
||||
assertTrue(map.contains("C://path/to/my/dir1"))
|
||||
assertTrue(map.contains("C://path/to/my/dir2"))
|
||||
assertTrue(map.contains("C://path/to/my/dir3"))
|
||||
assertTrue(map.contains("C://path/to/my/dir4"))
|
||||
assertTrue(map.contains("C://path/to/dir1"))
|
||||
assertTrue(map.contains("C://path/to/dir2"))
|
||||
assertTrue(map.contains("C://path/to/dir3"))
|
||||
assertTrue(map.contains("C://path/to/dir4"))
|
||||
assertTrue(map.contains("C://path/to/my"))
|
||||
assertTrue(map.contains("C://path"))
|
||||
map.remove("C://path/to/my/dir1/")
|
||||
map.remove("C://path/to/my/dir2")
|
||||
map.remove("C://path/to/dir3")
|
||||
map.remove("C://path/to/dir4")
|
||||
assertEquals(map["C://path/to/my/dir1"], null)
|
||||
assertEquals(map["C://path/to/my/dir2"], null)
|
||||
assertEquals(map["C://path/to/my/dir3"], 30)
|
||||
assertEquals(map["C://path/to/my/dir4"], 10)
|
||||
assertEquals(map["C://path/to/dir1"], 11)
|
||||
assertEquals(map["C://path/to/dir2"], 21)
|
||||
assertEquals(map["C://path/to/dir3/"], null)
|
||||
assertEquals(map["C://path/to/dir4"], null)
|
||||
assertEquals(map["C://path/to/my"], 43)
|
||||
assertEquals(map["C://path"], 13)
|
||||
assertFalse(map.contains("C://path/to/my/dir1"))
|
||||
assertFalse(map.contains("C://path/to/my/dir2"))
|
||||
assertTrue(map.contains("C://path/to/my/dir3"))
|
||||
assertTrue(map.contains("C://path/to/my/dir4"))
|
||||
assertTrue(map.contains("C://path/to/dir1"))
|
||||
assertTrue(map.contains("C://path/to/dir2"))
|
||||
assertFalse(map.contains("C://path/to/dir3"))
|
||||
assertFalse(map.contains("C://path/to/dir4"))
|
||||
assertTrue(map.contains("C://path/to/my"))
|
||||
assertTrue(map.contains("C://path"))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `test containing nullable values`() {
|
||||
val map = PathPrefixTreeMapImpl<Int?>()
|
||||
map["C://path/to/my/dir1"] = null
|
||||
map["C://path/to/my/dir2"] = 20
|
||||
map["C://path/to/my/dir3/"] = null
|
||||
map["C://path/to/my/dir4/"] = 10
|
||||
map["C://path/to/dir1"] = null
|
||||
map["C://path/to/dir2"] = 21
|
||||
map["C://path/to/dir3"] = null
|
||||
map["C://path/to/dir4"] = 11
|
||||
map["C://path/to/my"] = 43
|
||||
map["C://path"] = 13
|
||||
assertEquals(map["C://path/to/my/dir1"], null)
|
||||
assertEquals(map["C://path/to/my/dir2"], 20)
|
||||
assertEquals(map["C://path/to/my/dir3"], null)
|
||||
assertEquals(map["C://path/to/my/dir4"], 10)
|
||||
assertEquals(map["C://path/to/dir1"], null)
|
||||
assertEquals(map["C://path/to/dir2"], 21)
|
||||
assertEquals(map["C://path/to/dir3"], null)
|
||||
assertEquals(map["C://path/to/dir4/"], 11)
|
||||
assertEquals(map["C://path/to/my"], 43)
|
||||
assertEquals(map["C://path"], 13)
|
||||
assertTrue(map.contains("C://path/to/my/dir1"))
|
||||
assertTrue(map.contains("C://path/to/my/dir2"))
|
||||
assertTrue(map.contains("C://path/to/my/dir3"))
|
||||
assertTrue(map.contains("C://path/to/my/dir4/"))
|
||||
assertTrue(map.contains("C://path/to/dir1"))
|
||||
assertTrue(map.contains("C://path/to/dir2"))
|
||||
assertTrue(map.contains("C://path/to/dir3"))
|
||||
assertTrue(map.contains("C://path/to/dir4"))
|
||||
assertTrue(map.contains("C://path/to/my"))
|
||||
assertTrue(map.contains("C://path"))
|
||||
map.remove("C://path/to/my/dir1")
|
||||
map.remove("C://path/to/my/dir2")
|
||||
map.remove("C://path/to/dir3")
|
||||
map.remove("C://path/to/dir4")
|
||||
assertEquals(map["C://path/to/my/dir1"], null)
|
||||
assertEquals(map["C://path/to/my/dir2"], null)
|
||||
assertEquals(map["C://path/to/my/dir3"], null)
|
||||
assertEquals(map["C://path/to/my/dir4"], 10)
|
||||
assertEquals(map["C://path/to/dir1/"], null)
|
||||
assertEquals(map["C://path/to/dir2"], 21)
|
||||
assertEquals(map["C://path/to/dir3"], null)
|
||||
assertEquals(map["C://path/to/dir4"], null)
|
||||
assertEquals(map["C://path/to/my"], 43)
|
||||
assertEquals(map["C://path"], 13)
|
||||
assertFalse(map.contains("C://path/to/my/dir1/"))
|
||||
assertFalse(map.contains("C://path/to/my/dir2"))
|
||||
assertTrue(map.contains("C://path/to/my/dir3"))
|
||||
assertTrue(map.contains("C://path/to/my/dir4"))
|
||||
assertTrue(map.contains("C://path/to/dir1"))
|
||||
assertTrue(map.contains("C://path/to/dir2"))
|
||||
assertFalse(map.contains("C://path/to/dir3"))
|
||||
assertFalse(map.contains("C://path/to/dir4"))
|
||||
assertTrue(map.contains("C://path/to/my"))
|
||||
assertTrue(map.contains("C://path"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test get all elements under dir`() {
|
||||
val map = PathPrefixTreeMapImpl<Int?>()
|
||||
map["C://path/to/my/dir1/"] = 10
|
||||
map["C://path/to/my/dir2"] = 20
|
||||
map["C://path/to/my/dir3/"] = 30
|
||||
map["C://path/to/my/dir4"] = 10
|
||||
map["C://path/to/dir1"] = 11
|
||||
map["C://path/to/dir2/"] = 21
|
||||
map["C://path/to/dir3"] = 30
|
||||
map["C://path/to/dir4/"] = 11
|
||||
map["C://path/to/my"] = 43
|
||||
map["C://path"] = 13
|
||||
val underMy = map.getAllDescendants("C://path/to/my").toSet()
|
||||
assertEquals(setOf(10, 20, 30, 10, 43), underMy)
|
||||
val underMyDir = map.getAllDescendants("C://path/to/my/").toSet()
|
||||
assertEquals(setOf(10, 20, 30, 10, 43), underMyDir)
|
||||
val underTo = map.getAllDescendants("C://path/to").toSet()
|
||||
assertEquals(setOf(10, 20, 30, 10, 43, 11, 21, 30, 11, 43), underTo)
|
||||
val underToDir = map.getAllDescendants("C://path/to/").toSet()
|
||||
assertEquals(setOf(10, 20, 30, 10, 43, 11, 21, 30, 11, 43), underToDir)
|
||||
val underPath = map.getAllDescendants("C://path").toSet()
|
||||
assertEquals(setOf(10, 20, 30, 10, 43, 11, 21, 30, 11, 43, 13), underPath)
|
||||
val underProto = map.getAllDescendants("C:/").toSet()
|
||||
assertEquals(setOf(10, 20, 30, 10, 43, 11, 21, 30, 11, 43, 13), underProto)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test usage with unix paths`() {
|
||||
val map = PathPrefixTreeMapImpl<Int?>()
|
||||
map["/path/to/my/dir1/"] = 10
|
||||
map["/path/to/my/dir2"] = 20
|
||||
map["/path/to/my/dir3/"] = 30
|
||||
assertEquals(10, map.remove("/path/to/my/dir1/"))
|
||||
assertEquals(null, map.remove("/path/to/my/dir1/"))
|
||||
map["/path/to/my/dir4"] = 10
|
||||
map["/path/to/dir1"] = 11
|
||||
map["/path/to/dir2/"] = 21
|
||||
assertEquals(11, map.remove("/path/to/dir1/"))
|
||||
map["/path/to/dir3"] = 30
|
||||
assertEquals(10, map.remove("/path/to/my/dir4/"))
|
||||
map["/path/to/dir4/"] = 11
|
||||
assertEquals(null, map.remove("/path"))
|
||||
map["/path/to/my"] = 43
|
||||
map["/path"] = 13
|
||||
assertEquals(13, map.remove("/path"))
|
||||
assertFalse(map.contains("/path/to/my/dir1"))
|
||||
assertTrue(map.contains("/path/to/my/dir2"))
|
||||
assertTrue(map.contains("/path/to/my/dir3"))
|
||||
assertFalse(map.contains("/path/to/my/dir4/"))
|
||||
assertFalse(map.contains("/path/to/dir1"))
|
||||
assertTrue(map.contains("/path/to/dir2/"))
|
||||
assertTrue(map.contains("/path/to/dir3"))
|
||||
assertTrue(map.contains("/path/to/dir4/"))
|
||||
assertTrue(map.contains("/path/to/my"))
|
||||
assertFalse(map.contains("/path"))
|
||||
}
|
||||
}
|
||||
-7
@@ -417,7 +417,6 @@ public class GradleSettingsImportingTest extends GradleImportingTestCase {
|
||||
|
||||
@Test
|
||||
public void testRemovingSourceFolderManagerMemLeaking() throws IOException {
|
||||
refreshRecursively(myProjectRoot);
|
||||
SourceFolderManagerImpl sourceFolderManager = (SourceFolderManagerImpl)SourceFolderManager.getInstance(myProject);
|
||||
String javaSourcePath = FileUtil.toCanonicalPath(myProjectRoot.getPath() + "/java");
|
||||
String javaSourceUrl = VfsUtilCore.pathToUrl(javaSourcePath);
|
||||
@@ -464,9 +463,6 @@ public class GradleSettingsImportingTest extends GradleImportingTestCase {
|
||||
@Ignore // Remove after published plugin ext with package prefix configuration
|
||||
@Test
|
||||
public void testPostponedImportPackagePrefix() throws IOException {
|
||||
refreshRecursively(myProjectRoot);
|
||||
ApplicationManager.getApplication().invokeAndWait(() -> {
|
||||
});
|
||||
createProjectSubFile("src/main/java/Main.java", "");
|
||||
importProject(
|
||||
new GradleBuildScriptBuilderEx()
|
||||
@@ -487,9 +483,6 @@ public class GradleSettingsImportingTest extends GradleImportingTestCase {
|
||||
assertSourceNotExists("project.main", "src/main/kotlin");
|
||||
assertSourceNotExists("project.test", "src/test/java");
|
||||
createProjectSubFile("src/main/kotlin/Main.kt", "");
|
||||
refreshRecursively(myProjectRoot);
|
||||
ApplicationManager.getApplication().invokeAndWait(() -> {
|
||||
});
|
||||
assertSourcePackagePrefix("project.main", "src/main/java", "prefix.package.some");
|
||||
assertSourcePackagePrefix("project.main", "src/main/kotlin", "prefix.package.other");
|
||||
assertSourceNotExists("project.test", "src/test/java");
|
||||
|
||||
Reference in New Issue
Block a user