Move parseFileUtils to incremental-compilation-impl

This commit is contained in:
Alexey Tsvetkov
2018-04-10 15:27:45 +03:00
parent 1442dd6c2b
commit 13ac64b84a
5 changed files with 7 additions and 8 deletions
@@ -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.*
@@ -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
}
}
@@ -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)
}
}