AA: fail-safe path retrieval of source files
Also, apply file extension-based filtering since javaSourceRoots is supposed to refer to either KotlinSourceRoot or JavaSourceRoot.
This commit is contained in:
committed by
Ilya Kirillov
parent
e489c9b549
commit
9e35815ae3
+58
-5
@@ -5,7 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.project.structure.impl
|
||||
|
||||
import com.google.common.io.Files.getFileExtension
|
||||
import com.google.common.io.Files.getNameWithoutExtension
|
||||
import com.intellij.ide.highlighter.JavaFileType
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
@@ -28,6 +30,7 @@ import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
@@ -39,8 +42,9 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
import java.io.IOException
|
||||
import java.nio.file.*
|
||||
import java.nio.file.attribute.BasicFileAttributes
|
||||
|
||||
internal fun TargetPlatform.getAnalyzerServices(): PlatformDependentAnalyzerServices {
|
||||
return when {
|
||||
@@ -52,6 +56,12 @@ internal fun TargetPlatform.getAnalyzerServices(): PlatformDependentAnalyzerServ
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect source file path as [String] from the given source roots in [compilerConfig].
|
||||
*
|
||||
* Such source roots are either [KotlinSourceRoot] or [JavaSourceRoot], and thus
|
||||
* this util collects all `.kt` and `.java` files under source roots.
|
||||
*/
|
||||
internal fun getSourceFilePaths(
|
||||
compilerConfig: CompilerConfiguration,
|
||||
includeDirectoryRoot: Boolean = false,
|
||||
@@ -61,9 +71,7 @@ internal fun getSourceFilePaths(
|
||||
val path = Paths.get(srcRoot)
|
||||
if (Files.isDirectory(path)) {
|
||||
// E.g., project/app/src
|
||||
Files.walk(path)
|
||||
.filter(java.nio.file.Files::isRegularFile)
|
||||
.forEach { add(it.toString()) }
|
||||
collectSourceFilePaths(path, this)
|
||||
if (includeDirectoryRoot) {
|
||||
add(srcRoot)
|
||||
}
|
||||
@@ -75,6 +83,51 @@ internal fun getSourceFilePaths(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect source file path from the given [root] store them in [result].
|
||||
*
|
||||
* E.g., for `project/app/src` as a [root], this will walk the file tree and
|
||||
* collect all `.kt` and `.java` files under that folder.
|
||||
*
|
||||
* Note that this util gracefully skips [IOException] during file tree traversal.
|
||||
*/
|
||||
private fun collectSourceFilePaths(
|
||||
root: Path,
|
||||
result: MutableSet<String>
|
||||
) {
|
||||
// NB: [Files#walk] throws an exception if there is an issue during IO.
|
||||
// With [Files#walkFileTree] with a custom visitor, we can take control of exception handling.
|
||||
Files.walkFileTree(
|
||||
root,
|
||||
object : SimpleFileVisitor<Path>() {
|
||||
override fun preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult {
|
||||
return if (Files.isReadable(dir))
|
||||
FileVisitResult.CONTINUE
|
||||
else
|
||||
FileVisitResult.SKIP_SUBTREE
|
||||
}
|
||||
|
||||
override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
|
||||
if (!Files.isRegularFile(file) || !Files.isReadable(file))
|
||||
return FileVisitResult.CONTINUE
|
||||
val ext = getFileExtension(file.fileName.toString())
|
||||
if (ext == KotlinFileType.EXTENSION || ext == JavaFileType.DEFAULT_EXTENSION) {
|
||||
result.add(file.toString())
|
||||
}
|
||||
return FileVisitResult.CONTINUE
|
||||
}
|
||||
|
||||
override fun visitFileFailed(file: Path, exc: IOException?): FileVisitResult {
|
||||
// TODO: report or log [IOException]?
|
||||
// NB: this intentionally swallows the exception, hence fail-safe.
|
||||
// Skipping subtree doesn't make any sense, since this is not a directory.
|
||||
// Skipping sibling may drop valid file paths afterward, so we just continue.
|
||||
return FileVisitResult.CONTINUE
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
internal inline fun <reified T : PsiFileSystemItem> getPsiFilesFromPaths(
|
||||
project: Project,
|
||||
paths: Collection<String>,
|
||||
|
||||
Reference in New Issue
Block a user