Move parseFileUtils to incremental-compilation-impl
This commit is contained in:
+1
-1
@@ -29,8 +29,8 @@ import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.multiproject.ArtifactChangesProvider
|
||||
import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry
|
||||
import org.jetbrains.kotlin.incremental.parsing.classesFqNames
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.parsing.util.classesFqNames
|
||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2010-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/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.parsing
|
||||
|
||||
import com.intellij.core.CoreApplicationEnvironment
|
||||
import com.intellij.core.CoreProjectEnvironment
|
||||
import com.intellij.lang.MetaLanguage
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.local.CoreLocalFileSystem
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.SingleRootFileViewProvider
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||
import org.jetbrains.kotlin.script.ScriptDefinitionProvider
|
||||
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
fun classesFqNames(files: Set<File>): Set<String> = withPsiSetup {
|
||||
val psiManager = PsiManager.getInstance(project)
|
||||
val fileManager = VirtualFileManager.getInstance()
|
||||
val localFS = fileManager.getFileSystem(StandardFileSystems.FILE_PROTOCOL) as CoreLocalFileSystem
|
||||
|
||||
classesFqNames(files, psiManager, localFS)
|
||||
}
|
||||
|
||||
private fun classesFqNames(files: Collection<File>, psiManager: PsiManager, localFS: CoreLocalFileSystem): Set<String> {
|
||||
val result = HashSet<String>()
|
||||
|
||||
for (file in files) {
|
||||
if (!file.name.endsWith(".kt", ignoreCase = true)) continue
|
||||
|
||||
val virtualFile = localFS.findFileByIoFile(file) ?: continue
|
||||
|
||||
for (psiFile in SingleRootFileViewProvider(psiManager, virtualFile).allFiles) {
|
||||
if (psiFile !is KtFile) continue
|
||||
|
||||
val classes = ArrayDeque<KtClassOrObject>()
|
||||
psiFile.declarations.filterClassesTo(classes)
|
||||
while (classes.isNotEmpty()) {
|
||||
val klass = classes.pollFirst()
|
||||
klass.fqName?.let {
|
||||
result.add(it.asString())
|
||||
}
|
||||
klass.declarations.filterClassesTo(classes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun Collection<KtDeclaration>.filterClassesTo(classes: Deque<KtClassOrObject>) {
|
||||
filterIsInstanceTo<KtClassOrObject, Deque<KtClassOrObject>>(classes)
|
||||
}
|
||||
|
||||
private data class PsiSetup(
|
||||
val applicationEnvironment: CoreApplicationEnvironment,
|
||||
val projectEnvironment: CoreProjectEnvironment,
|
||||
val project: Project,
|
||||
val disposable: Disposable
|
||||
)
|
||||
|
||||
private inline fun <T> withPsiSetup(fn: PsiSetup.() -> T): T {
|
||||
val disposable = Disposer.newDisposable()
|
||||
|
||||
return try {
|
||||
val applicationEnvironment = CoreApplicationEnvironment(disposable, false)
|
||||
val projectEnvironment = CoreProjectEnvironment(disposable, applicationEnvironment)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaLanguage.EP_NAME, MetaLanguage::class.java)
|
||||
applicationEnvironment.registerApplicationService(ScriptDefinitionProvider::class.java,
|
||||
NoopScriptDefinitionProvider()
|
||||
)
|
||||
applicationEnvironment.registerFileType(KotlinFileType.INSTANCE, "kt")
|
||||
applicationEnvironment.registerParserDefinition(KotlinParserDefinition())
|
||||
|
||||
val project = projectEnvironment.project
|
||||
val setup = PsiSetup(applicationEnvironment, projectEnvironment, project, disposable)
|
||||
setup.fn()
|
||||
} finally {
|
||||
Disposer.dispose(disposable)
|
||||
}
|
||||
}
|
||||
|
||||
private class NoopScriptDefinitionProvider : ScriptDefinitionProvider {
|
||||
override fun isScript(fileName: String): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun findScriptDefinition(fileName: String): KotlinScriptDefinition? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2010-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/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.parsing
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
|
||||
class ClassesFqNamesTest {
|
||||
private lateinit var workingDir: File
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
workingDir = FileUtil.createTempDirectory("ClassesFqNamesTest", null)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
workingDir.deleteRecursively()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSingleClass() {
|
||||
doTest(
|
||||
setOf("test.Foo"),
|
||||
"""
|
||||
package test
|
||||
|
||||
class Foo""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMultipleClasses() {
|
||||
doTest(
|
||||
setOf("test.Fizz", "test.Buzz"),
|
||||
"""
|
||||
package test
|
||||
|
||||
class Fizz
|
||||
class Buzz""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInnerClasses() {
|
||||
doTest(
|
||||
setOf("test.Foo", "test.Foo.Fizz", "test.Foo.Buzz"),
|
||||
"""
|
||||
package test
|
||||
|
||||
class Foo {
|
||||
class Fizz
|
||||
class Buzz
|
||||
}""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testObject() {
|
||||
doTest(
|
||||
setOf("test.Foo", "test.Foo.Fizz", "test.Bar", "test.Bar.Buzz"),
|
||||
"""
|
||||
package test
|
||||
|
||||
object Foo {
|
||||
class Fizz
|
||||
}
|
||||
|
||||
class Bar {
|
||||
object Buzz
|
||||
}""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
private fun doTest(expectedClasses: Set<String>, code: String) {
|
||||
val testKt = File(workingDir, "test.kt")
|
||||
testKt.writeText(code)
|
||||
|
||||
val expected = expectedClasses.sorted().joinToString("\n")
|
||||
val actual = classesFqNames(setOf(testKt)).sorted().joinToString("\n")
|
||||
UsefulTestCase.assertEquals(expected, actual)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user