FIR LT: Introduce source file abstraction, carry it from parsing to IR
along with source lines mapping, allows to "emulate" usage of the PSI files which allows to extract source file and line mapping info on every stage from source element. It makes sense to use this mapping for the error reporting too.
This commit is contained in:
+1
-1
@@ -8,8 +8,8 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirModuleResolveState
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirModuleResolveState
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDiagnosticsForFile
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDiagnosticsForFile
|
||||||
import org.jetbrains.kotlin.fir.analysis.AbstractFirAnalyzerFacade
|
|
||||||
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
||||||
|
import org.jetbrains.kotlin.fir.AbstractFirAnalyzerFacade
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
|
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
|
|||||||
+90
-1
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.cli.common.fir
|
package org.jetbrains.kotlin.cli.common.fir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.SequentialFilePositionFinder
|
|
||||||
import org.jetbrains.kotlin.cli.common.messages.*
|
import org.jetbrains.kotlin.cli.common.messages.*
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||||
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
||||||
@@ -13,7 +12,9 @@ import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic
|
|||||||
import org.jetbrains.kotlin.diagnostics.Severity
|
import org.jetbrains.kotlin.diagnostics.Severity
|
||||||
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
|
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
||||||
|
import java.io.Closeable
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
|
||||||
object FirDiagnosticsCompilerResultsReporter {
|
object FirDiagnosticsCompilerResultsReporter {
|
||||||
fun reportToMessageCollector(
|
fun reportToMessageCollector(
|
||||||
@@ -55,6 +56,7 @@ object FirDiagnosticsCompilerResultsReporter {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
// TODO: bring KtSourceFile and KtSourceFileLinesMapping here and rewrite reporting via it to avoid code duplication
|
||||||
// NOTE: SequentialPositionFinder relies on the ascending order of the input offsets, so the code relies
|
// NOTE: SequentialPositionFinder relies on the ascending order of the input offsets, so the code relies
|
||||||
// on the the appropriate sorting above
|
// on the the appropriate sorting above
|
||||||
// Also the end offset is ignored, as it is irrelevant for the CLI reporting
|
// Also the end offset is ignored, as it is irrelevant for the CLI reporting
|
||||||
@@ -133,3 +135,90 @@ object FirDiagnosticsCompilerResultsReporter {
|
|||||||
fun BaseDiagnosticsCollector.reportToMessageCollector(messageCollector: MessageCollector, renderDiagnosticName: Boolean) {
|
fun BaseDiagnosticsCollector.reportToMessageCollector(messageCollector: MessageCollector, renderDiagnosticName: Boolean) {
|
||||||
FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(this, messageCollector, renderDiagnosticName)
|
FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(this, messageCollector, renderDiagnosticName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class KtSourceFilePos(val line: Int, val column: Int, val lineContent: String?) {
|
||||||
|
|
||||||
|
// NOTE: This method is used for presenting positions to the user
|
||||||
|
override fun toString(): String = if (line < 0) "(offset: $column line unknown)" else "($line,$column)"
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val NONE = KtSourceFilePos(-1, -1, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SequentialFilePositionFinder(file: File) : Closeable {
|
||||||
|
|
||||||
|
private var reader: InputStreamReader = file.reader(/* TODO: select proper charset */)
|
||||||
|
|
||||||
|
private var currentLineContent: String? = null
|
||||||
|
private val buffer = CharArray(255)
|
||||||
|
private var bufLength = -1
|
||||||
|
private var bufPos = 0
|
||||||
|
private var endOfStream = false
|
||||||
|
private var skipNextLf = false
|
||||||
|
|
||||||
|
private var charsRead = 0
|
||||||
|
private var currentLine = 0
|
||||||
|
|
||||||
|
// assuming that if called multiple times, calls should be sorted by ascending offset
|
||||||
|
fun findNextPosition(offset: Int, withLineContents: Boolean = true): KtSourceFilePos {
|
||||||
|
assert(offset >= charsRead - (currentLineContent?.length ?: 0))
|
||||||
|
|
||||||
|
fun posInCurrentLine(): KtSourceFilePos? {
|
||||||
|
val col = offset - (charsRead - currentLineContent!!.length - 1)/* beginning of line offset */ + 1 /* col is 1-based */
|
||||||
|
return if (col <= currentLineContent!!.length)
|
||||||
|
KtSourceFilePos(currentLine, col, if (withLineContents) currentLineContent else null)
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset < charsRead) {
|
||||||
|
return posInCurrentLine()!!
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (currentLineContent == null) {
|
||||||
|
currentLineContent = readNextLine()
|
||||||
|
}
|
||||||
|
|
||||||
|
posInCurrentLine()?.let { return@findNextPosition it }
|
||||||
|
|
||||||
|
if (endOfStream) return KtSourceFilePos(-1, offset, if (withLineContents) currentLineContent else null)
|
||||||
|
|
||||||
|
currentLineContent = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readNextLine() = buildString {
|
||||||
|
while (true) {
|
||||||
|
if (bufPos >= bufLength) {
|
||||||
|
bufLength = reader.read(buffer)
|
||||||
|
bufPos = 0
|
||||||
|
if (bufLength < 0) {
|
||||||
|
endOfStream = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val c = buffer[bufPos++]
|
||||||
|
charsRead++
|
||||||
|
when {
|
||||||
|
c == '\n' && skipNextLf -> {
|
||||||
|
skipNextLf = false
|
||||||
|
}
|
||||||
|
c == '\n' || c == '\r' -> {
|
||||||
|
currentLine++
|
||||||
|
skipNextLf = c == '\r'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
append(c)
|
||||||
|
skipNextLf = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
reader.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+28
-8
@@ -7,12 +7,17 @@ package org.jetbrains.kotlin.cli.jvm.compiler
|
|||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.vfs.StandardFileSystems
|
import com.intellij.openapi.vfs.StandardFileSystems
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager
|
import com.intellij.openapi.vfs.VirtualFileManager
|
||||||
import com.intellij.openapi.vfs.VirtualFileSystem
|
import com.intellij.openapi.vfs.VirtualFileSystem
|
||||||
import com.intellij.psi.PsiElementFinder
|
import com.intellij.psi.PsiElementFinder
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.search.ProjectScope
|
import com.intellij.psi.search.ProjectScope
|
||||||
|
import org.jetbrains.kotlin.KtIoFileSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtPsiSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtVirtualFileSourceFile
|
||||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
@@ -65,16 +70,33 @@ open class VfsBasedProjectEnvironment(
|
|||||||
psiFinderExtensionPoint.registerExtension(FirJavaElementFinder(firSession, project), project)
|
psiFinderExtensionPoint.registerExtension(FirJavaElementFinder(firSession, project), project)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun List<VirtualFile>.toSearchScope(allowOutOfProjectRoots: Boolean) =
|
||||||
|
takeIf { it.isNotEmpty() }
|
||||||
|
?.let {
|
||||||
|
if (allowOutOfProjectRoots) GlobalSearchScope.filesWithLibrariesScope(project, it)
|
||||||
|
else GlobalSearchScope.filesWithoutLibrariesScope(project, it)
|
||||||
|
}
|
||||||
|
?: GlobalSearchScope.EMPTY_SCOPE
|
||||||
|
|
||||||
override fun getSearchScopeByIoFiles(files: Iterable<File>, allowOutOfProjectRoots: Boolean): AbstractProjectFileSearchScope =
|
override fun getSearchScopeByIoFiles(files: Iterable<File>, allowOutOfProjectRoots: Boolean): AbstractProjectFileSearchScope =
|
||||||
PsiBasedProjectFileSearchScope(
|
PsiBasedProjectFileSearchScope(
|
||||||
files
|
files
|
||||||
.mapNotNull { localFileSystem.findFileByPath(it.absolutePath) }
|
.mapNotNull { localFileSystem.findFileByPath(it.absolutePath) }
|
||||||
.toList()
|
.toSearchScope(allowOutOfProjectRoots)
|
||||||
.takeIf { it.isNotEmpty() }
|
)
|
||||||
?.let {
|
|
||||||
if (allowOutOfProjectRoots) GlobalSearchScope.filesWithLibrariesScope(project, it)
|
override fun getSearchScopeBySourceFiles(files: Iterable<KtSourceFile>, allowOutOfProjectRoots: Boolean): AbstractProjectFileSearchScope =
|
||||||
else GlobalSearchScope.filesWithoutLibrariesScope(project, it)
|
PsiBasedProjectFileSearchScope(
|
||||||
} ?: GlobalSearchScope.EMPTY_SCOPE
|
files
|
||||||
|
.mapNotNull {
|
||||||
|
when (it) {
|
||||||
|
is KtPsiSourceFile -> it.psiFile.virtualFile
|
||||||
|
is KtVirtualFileSourceFile -> it.virtualFile
|
||||||
|
is KtIoFileSourceFile -> localFileSystem.findFileByPath(it.file.absolutePath)
|
||||||
|
else -> null // TODO: find out whether other use cases should be supported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.toSearchScope(allowOutOfProjectRoots)
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun getSearchScopeByDirectories(directories: Iterable<File>): AbstractProjectFileSearchScope =
|
override fun getSearchScopeByDirectories(directories: Iterable<File>): AbstractProjectFileSearchScope =
|
||||||
@@ -108,8 +130,6 @@ open class VfsBasedProjectEnvironment(
|
|||||||
fileSearchScope: AbstractProjectFileSearchScope
|
fileSearchScope: AbstractProjectFileSearchScope
|
||||||
) = FirJavaFacade(firSession, baseModuleData, project.createJavaClassFinder(fileSearchScope.asPsiSearchScope()))
|
) = FirJavaFacade(firSession, baseModuleData, project.createJavaClassFinder(fileSearchScope.asPsiSearchScope()))
|
||||||
|
|
||||||
override fun getFileText(filePath: String): String? =
|
|
||||||
localFileSystem.findFileByPath(filePath)?.inputStream?.reader(Charsets.UTF_8)?.readText()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun AbstractProjectFileSearchScope.asPsiSearchScope() =
|
private fun AbstractProjectFileSearchScope.asPsiSearchScope() =
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import com.intellij.openapi.vfs.VirtualFileSystem
|
|||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.util.io.URLUtil
|
import com.intellij.util.io.URLUtil
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtVirtualFileSourceFile
|
||||||
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl
|
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl
|
||||||
@@ -105,13 +107,12 @@ fun compileModulesUsingFrontendIrAndLightTree(
|
|||||||
val moduleConfiguration = compilerConfiguration.copy().applyModuleProperties(module, buildFile).apply {
|
val moduleConfiguration = compilerConfiguration.copy().applyModuleProperties(module, buildFile).apply {
|
||||||
addAll(JVMConfigurationKeys.FRIEND_PATHS, module.getFriendPaths())
|
addAll(JVMConfigurationKeys.FRIEND_PATHS, module.getFriendPaths())
|
||||||
}
|
}
|
||||||
val platformSources = linkedSetOf<File>()
|
val platformSources = linkedSetOf<KtSourceFile>()
|
||||||
val commonSources = linkedSetOf<File>()
|
val commonSources = linkedSetOf<KtSourceFile>()
|
||||||
|
|
||||||
// !!
|
// !!
|
||||||
compilerConfiguration.kotlinSourceRoots.forAllFiles(compilerConfiguration, projectEnvironment.project) { virtualFile, isCommon ->
|
compilerConfiguration.kotlinSourceRoots.forAllFiles(compilerConfiguration, projectEnvironment.project) { virtualFile, isCommon ->
|
||||||
val file = File(virtualFile.canonicalPath ?: virtualFile.path)
|
val file = KtVirtualFileSourceFile(virtualFile)
|
||||||
if (!file.isFile) error("TODO: better error: file not found $virtualFile")
|
|
||||||
if (isCommon) commonSources.add(file)
|
if (isCommon) commonSources.add(file)
|
||||||
else platformSources.add(file)
|
else platformSources.add(file)
|
||||||
}
|
}
|
||||||
@@ -261,14 +262,14 @@ fun compileModuleToAnalyzedFir(
|
|||||||
diagnosticsReporter: DiagnosticReporter,
|
diagnosticsReporter: DiagnosticReporter,
|
||||||
performanceManager: CommonCompilerPerformanceManager?
|
performanceManager: CommonCompilerPerformanceManager?
|
||||||
): ModuleCompilerAnalyzedOutput {
|
): ModuleCompilerAnalyzedOutput {
|
||||||
var sourcesScope = environment.projectEnvironment.getSearchScopeByIoFiles(input.platformSources) //!!
|
var sourcesScope = environment.projectEnvironment.getSearchScopeBySourceFiles(input.platformSources)
|
||||||
val sessionProvider = FirProjectSessionProvider()
|
val sessionProvider = FirProjectSessionProvider()
|
||||||
val extendedAnalysisMode = input.configuration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS)
|
val extendedAnalysisMode = input.configuration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS)
|
||||||
|
|
||||||
val commonSession = runIf(
|
val commonSession = runIf(
|
||||||
input.commonSources.isNotEmpty() && input.configuration.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
|
input.commonSources.isNotEmpty() && input.configuration.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
|
||||||
) {
|
) {
|
||||||
val commonSourcesScope = environment.projectEnvironment.getSearchScopeByIoFiles(input.commonSources) //!!
|
val commonSourcesScope = environment.projectEnvironment.getSearchScopeBySourceFiles(input.commonSources)
|
||||||
sourcesScope -= commonSourcesScope
|
sourcesScope -= commonSourcesScope
|
||||||
createSession(
|
createSession(
|
||||||
"${input.targetId.name}-common",
|
"${input.targetId.name}-common",
|
||||||
@@ -310,12 +311,11 @@ fun compileModuleToAnalyzedFir(
|
|||||||
// raw fir
|
// raw fir
|
||||||
val commonRawFir = commonSession?.buildFirViaLightTree(
|
val commonRawFir = commonSession?.buildFirViaLightTree(
|
||||||
input.commonSources,
|
input.commonSources,
|
||||||
environment.projectEnvironment,
|
|
||||||
diagnosticsReporter,
|
diagnosticsReporter,
|
||||||
countFilesAndLines
|
countFilesAndLines
|
||||||
)
|
)
|
||||||
val rawFir =
|
val rawFir =
|
||||||
session.buildFirViaLightTree(input.platformSources, environment.projectEnvironment, diagnosticsReporter, countFilesAndLines)
|
session.buildFirViaLightTree(input.platformSources, diagnosticsReporter, countFilesAndLines)
|
||||||
|
|
||||||
// resolution
|
// resolution
|
||||||
commonSession?.apply {
|
commonSession?.apply {
|
||||||
|
|||||||
+3
-2
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.cli.jvm.compiler.pipeline
|
package org.jetbrains.kotlin.cli.jvm.compiler.pipeline
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl
|
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
@@ -27,9 +28,9 @@ import java.io.File
|
|||||||
data class ModuleCompilerInput(
|
data class ModuleCompilerInput(
|
||||||
val targetId: TargetId,
|
val targetId: TargetId,
|
||||||
val commonPlatform: TargetPlatform,
|
val commonPlatform: TargetPlatform,
|
||||||
val commonSources: Collection<File>,
|
val commonSources: Collection<KtSourceFile>,
|
||||||
val platform: TargetPlatform,
|
val platform: TargetPlatform,
|
||||||
val platformSources: Collection<File>,
|
val platformSources: Collection<KtSourceFile>,
|
||||||
val configuration: CompilerConfiguration,
|
val configuration: CompilerConfiguration,
|
||||||
val friendFirModules: Collection<FirModuleData> = emptyList()
|
val friendFirModules: Collection<FirModuleData> = emptyList()
|
||||||
)
|
)
|
||||||
|
|||||||
+1
-1
@@ -87,7 +87,7 @@ abstract class CheckerContext : MutableDiagnosticContext() {
|
|||||||
get() = session.languageVersionSettings
|
get() = session.languageVersionSettings
|
||||||
|
|
||||||
override val containingFilePath: String?
|
override val containingFilePath: String?
|
||||||
get() = containingDeclarations.firstOrNull()?.let { (it as? FirFile)?.path }
|
get() = containingDeclarations.firstOrNull()?.let { (it as? FirFile)?.sourceFile?.path }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.pipeline
|
package org.jetbrains.kotlin.fir.pipeline
|
||||||
|
|
||||||
import com.intellij.openapi.util.text.StringUtilRt
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.builder.PsiHandlingMode
|
import org.jetbrains.kotlin.fir.builder.PsiHandlingMode
|
||||||
@@ -14,15 +14,12 @@ import org.jetbrains.kotlin.fir.declarations.FirFile
|
|||||||
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
|
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
||||||
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
|
|
||||||
import org.jetbrains.kotlin.fir.session.sourcesToPathsMapper
|
import org.jetbrains.kotlin.fir.session.sourcesToPathsMapper
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import java.io.File
|
import org.jetbrains.kotlin.readSourceFileWithMapping
|
||||||
import java.io.FileNotFoundException
|
|
||||||
|
|
||||||
fun FirSession.buildFirViaLightTree(
|
fun FirSession.buildFirViaLightTree(
|
||||||
files: Collection<File>,
|
files: Collection<KtSourceFile>,
|
||||||
projectEnvironment: AbstractProjectEnvironment,
|
|
||||||
diagnosticsReporter: DiagnosticReporter? = null,
|
diagnosticsReporter: DiagnosticReporter? = null,
|
||||||
reportFilesAndLines: ((Int, Int) -> Unit)? = null
|
reportFilesAndLines: ((Int, Int) -> Unit)? = null
|
||||||
): List<FirFile> {
|
): List<FirFile> {
|
||||||
@@ -32,14 +29,15 @@ fun FirSession.buildFirViaLightTree(
|
|||||||
val shouldCountLines = (reportFilesAndLines != null)
|
val shouldCountLines = (reportFilesAndLines != null)
|
||||||
var linesCount = 0
|
var linesCount = 0
|
||||||
val firFiles = files.map { file ->
|
val firFiles = files.map { file ->
|
||||||
val text = projectEnvironment.getFileText(file.absolutePath) ?: throw FileNotFoundException(file.path)
|
val (code, linesMapping) = file.getContentsAsStream().reader(Charsets.UTF_8).use {
|
||||||
val code = StringUtilRt.convertLineSeparators(text)
|
it.readSourceFileWithMapping()
|
||||||
if (shouldCountLines) {
|
|
||||||
linesCount += code.count { it == '\n' } // assuming converted line separators
|
|
||||||
}
|
}
|
||||||
builder.buildFirFile(code, file.name, file.path).also { firFile ->
|
if (shouldCountLines) {
|
||||||
|
linesCount += linesMapping.lastOffset
|
||||||
|
}
|
||||||
|
builder.buildFirFile(code, file, linesMapping).also { firFile ->
|
||||||
firProvider.recordFile(firFile)
|
firProvider.recordFile(firFile)
|
||||||
sourcesToPathsMapper.registerFileSource(firFile.source!!, file.path)
|
sourcesToPathsMapper.registerFileSource(firFile.source!!, file.path ?: file.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reportFilesAndLines?.invoke(files.count(), linesCount)
|
reportFilesAndLines?.invoke(files.count(), linesCount)
|
||||||
|
|||||||
+3
-2
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.session.environment
|
package org.jetbrains.kotlin.fir.session.environment
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.java.FirJavaFacade
|
import org.jetbrains.kotlin.fir.java.FirJavaFacade
|
||||||
@@ -49,6 +50,8 @@ interface AbstractProjectEnvironment {
|
|||||||
|
|
||||||
fun getSearchScopeByIoFiles(files: Iterable<File>, allowOutOfProjectRoots: Boolean = false): AbstractProjectFileSearchScope
|
fun getSearchScopeByIoFiles(files: Iterable<File>, allowOutOfProjectRoots: Boolean = false): AbstractProjectFileSearchScope
|
||||||
|
|
||||||
|
fun getSearchScopeBySourceFiles(files: Iterable<KtSourceFile>, allowOutOfProjectRoots: Boolean = false): AbstractProjectFileSearchScope
|
||||||
|
|
||||||
fun getSearchScopeByDirectories(directories: Iterable<File>): AbstractProjectFileSearchScope
|
fun getSearchScopeByDirectories(directories: Iterable<File>): AbstractProjectFileSearchScope
|
||||||
|
|
||||||
fun getSearchScopeForProjectLibraries(): AbstractProjectFileSearchScope
|
fun getSearchScopeForProjectLibraries(): AbstractProjectFileSearchScope
|
||||||
@@ -60,6 +63,4 @@ interface AbstractProjectEnvironment {
|
|||||||
baseModuleData: FirModuleData,
|
baseModuleData: FirModuleData,
|
||||||
fileSearchScope: AbstractProjectFileSearchScope
|
fileSearchScope: AbstractProjectFileSearchScope
|
||||||
): FirJavaFacade
|
): FirJavaFacade
|
||||||
|
|
||||||
fun getFileText(filePath: String): String?
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.backend
|
package org.jetbrains.kotlin.fir.backend
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtPsiSourceFileLinesMapping
|
||||||
|
import org.jetbrains.kotlin.KtSourceFileLinesMappingFromLineStartOffsets
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||||
import org.jetbrains.kotlin.backend.common.ir.BuiltinSymbolsBase
|
import org.jetbrains.kotlin.backend.common.ir.BuiltinSymbolsBase
|
||||||
@@ -167,7 +169,18 @@ class Fir2IrConverter(
|
|||||||
private fun registerFileAndClasses(file: FirFile, moduleFragment: IrModuleFragment) {
|
private fun registerFileAndClasses(file: FirFile, moduleFragment: IrModuleFragment) {
|
||||||
val fileEntry = when (file.origin) {
|
val fileEntry = when (file.origin) {
|
||||||
FirDeclarationOrigin.Source ->
|
FirDeclarationOrigin.Source ->
|
||||||
file.psi?.let { PsiIrFileEntry(it as KtFile) } ?: NaiveSourceBasedFileEntryImpl(file.path ?: file.name, intArrayOf(0))
|
file.psi?.let { PsiIrFileEntry(it as KtFile) }
|
||||||
|
?: when (val linesMapping = file.sourceFileLinesMapping) {
|
||||||
|
is KtSourceFileLinesMappingFromLineStartOffsets ->
|
||||||
|
NaiveSourceBasedFileEntryImpl(
|
||||||
|
file.sourceFile?.path ?: file.sourceFile?.name ?: file.name,
|
||||||
|
linesMapping.lineStartOffsets,
|
||||||
|
linesMapping.lastOffset
|
||||||
|
)
|
||||||
|
is KtPsiSourceFileLinesMapping -> PsiIrFileEntry(linesMapping.psiFile)
|
||||||
|
else ->
|
||||||
|
NaiveSourceBasedFileEntryImpl(file.sourceFile?.path ?: file.sourceFile?.name ?: file.name)
|
||||||
|
}
|
||||||
FirDeclarationOrigin.Synthetic -> NaiveSourceBasedFileEntryImpl(file.name)
|
FirDeclarationOrigin.Synthetic -> NaiveSourceBasedFileEntryImpl(file.name)
|
||||||
else -> error("Unsupported file origin: ${file.origin}")
|
else -> error("Unsupported file origin: ${file.origin}")
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-23
@@ -7,9 +7,10 @@ package org.jetbrains.kotlin.fir.lightTree
|
|||||||
|
|
||||||
import com.intellij.lang.LighterASTNode
|
import com.intellij.lang.LighterASTNode
|
||||||
import com.intellij.lang.impl.PsiBuilderFactoryImpl
|
import com.intellij.lang.impl.PsiBuilderFactoryImpl
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
|
||||||
import com.intellij.openapi.vfs.CharsetToolkit
|
|
||||||
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||||
|
import org.jetbrains.kotlin.KtIoFileSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtSourceFileLinesMapping
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticContext
|
import org.jetbrains.kotlin.diagnostics.DiagnosticContext
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
|||||||
import org.jetbrains.kotlin.lexer.KotlinLexer
|
import org.jetbrains.kotlin.lexer.KotlinLexer
|
||||||
import org.jetbrains.kotlin.parsing.KotlinLightParser
|
import org.jetbrains.kotlin.parsing.KotlinLightParser
|
||||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||||
|
import org.jetbrains.kotlin.readSourceFileWithMapping
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
@@ -46,7 +48,7 @@ class LightTree2Fir(
|
|||||||
return builder.lightTree
|
return builder.lightTree
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildLightTree(code: String): FlyweightCapableTreeStructure<LighterASTNode> {
|
fun buildLightTree(code: CharSequence): FlyweightCapableTreeStructure<LighterASTNode> {
|
||||||
val builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, makeLexer(), code)
|
val builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, makeLexer(), code)
|
||||||
KotlinLightParser.parse(builder)
|
KotlinLightParser.parse(builder)
|
||||||
return builder.lightTree
|
return builder.lightTree
|
||||||
@@ -58,25 +60,25 @@ class LightTree2Fir(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun buildFirFile(file: File): FirFile {
|
fun buildFirFile(file: File): FirFile {
|
||||||
val code = FileUtil.loadFile(file, CharsetToolkit.UTF8, true)
|
val sourceFile = KtIoFileSourceFile(file)
|
||||||
return buildFirFile(code, file.name, file.path)
|
val (code, linesMapping) = with(file.inputStream().reader(Charsets.UTF_8)) {
|
||||||
|
this.readSourceFileWithMapping()
|
||||||
|
}
|
||||||
|
return buildFirFile(code, sourceFile, linesMapping)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildFirFile(lightTreeFile: LightTreeFile): FirFile = with(lightTreeFile) {
|
fun buildFirFile(
|
||||||
|
lightTree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||||
|
sourceFile: KtSourceFile,
|
||||||
|
linesMapping: KtSourceFileLinesMapping
|
||||||
|
): FirFile =
|
||||||
DeclarationsConverter(
|
DeclarationsConverter(
|
||||||
session, scopeProvider, lightTree, diagnosticsReporter = diagnosticsReporter,
|
session, scopeProvider, lightTree, diagnosticsReporter = diagnosticsReporter,
|
||||||
diagnosticContext = makeDiagnosticContext(path)
|
diagnosticContext = makeDiagnosticContext(sourceFile.path)
|
||||||
).convertFile(lightTree.root, fileName, path)
|
).convertFile(lightTree.root, sourceFile, linesMapping)
|
||||||
}
|
|
||||||
|
|
||||||
fun buildFirFile(code: String, fileName: String, path: String?): FirFile {
|
fun buildFirFile(code: CharSequence, sourceFile: KtSourceFile, linesMapping: KtSourceFileLinesMapping): FirFile =
|
||||||
val lightTree = buildLightTree(code)
|
buildFirFile(buildLightTree(code), sourceFile, linesMapping)
|
||||||
|
|
||||||
return DeclarationsConverter(
|
|
||||||
session, scopeProvider, lightTree, diagnosticsReporter = diagnosticsReporter,
|
|
||||||
diagnosticContext = makeDiagnosticContext(path)
|
|
||||||
).convertFile(lightTree.root, fileName, path)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun makeDiagnosticContext(path: String?) =
|
private fun makeDiagnosticContext(path: String?) =
|
||||||
if (diagnosticsReporter == null) null else object : DiagnosticContext {
|
if (diagnosticsReporter == null) null else object : DiagnosticContext {
|
||||||
@@ -86,9 +88,3 @@ class LightTree2Fir(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class LightTreeFile(
|
|
||||||
val lightTree: FlyweightCapableTreeStructure<LighterASTNode>,
|
|
||||||
val fileName: String,
|
|
||||||
val path: String?
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -88,7 +88,7 @@ class DeclarationsConverter(
|
|||||||
* [org.jetbrains.kotlin.parsing.KotlinParsing.parseFile]
|
* [org.jetbrains.kotlin.parsing.KotlinParsing.parseFile]
|
||||||
* [org.jetbrains.kotlin.parsing.KotlinParsing.parsePreamble]
|
* [org.jetbrains.kotlin.parsing.KotlinParsing.parsePreamble]
|
||||||
*/
|
*/
|
||||||
fun convertFile(file: LighterASTNode, fileName: String = "", filePath: String?): FirFile {
|
fun convertFile(file: LighterASTNode, sourceFile: KtSourceFile, linesMapping: KtSourceFileLinesMapping): FirFile {
|
||||||
if (file.tokenType != KT_FILE) {
|
if (file.tokenType != KT_FILE) {
|
||||||
//TODO throw error
|
//TODO throw error
|
||||||
throw Exception()
|
throw Exception()
|
||||||
@@ -123,8 +123,9 @@ class DeclarationsConverter(
|
|||||||
source = file.toFirSourceElement()
|
source = file.toFirSourceElement()
|
||||||
origin = FirDeclarationOrigin.Source
|
origin = FirDeclarationOrigin.Source
|
||||||
moduleData = baseModuleData
|
moduleData = baseModuleData
|
||||||
name = fileName
|
name = sourceFile.name
|
||||||
path = filePath
|
this.sourceFile = sourceFile
|
||||||
|
this.sourceFileLinesMapping = linesMapping
|
||||||
this.packageDirective = packageDirective ?: buildPackageDirective { packageFqName = context.packageFqName }
|
this.packageDirective = packageDirective ?: buildPackageDirective { packageFqName = context.packageFqName }
|
||||||
annotations += fileAnnotationList
|
annotations += fileAnnotationList
|
||||||
imports += importList
|
imports += importList
|
||||||
|
|||||||
+14
-4
@@ -10,11 +10,15 @@ import com.intellij.openapi.vfs.CharsetToolkit
|
|||||||
import com.intellij.psi.impl.DebugUtil
|
import com.intellij.psi.impl.DebugUtil
|
||||||
import com.intellij.testFramework.TestDataPath
|
import com.intellij.testFramework.TestDataPath
|
||||||
import com.intellij.util.PathUtil
|
import com.intellij.util.PathUtil
|
||||||
|
import org.jetbrains.kotlin.KtIoFileSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtSourceFileLinesMapping
|
||||||
import org.jetbrains.kotlin.fir.FirRenderer
|
import org.jetbrains.kotlin.fir.FirRenderer
|
||||||
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
|
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
|
||||||
import org.jetbrains.kotlin.fir.builder.StubFirScopeProvider
|
import org.jetbrains.kotlin.fir.builder.StubFirScopeProvider
|
||||||
import org.jetbrains.kotlin.fir.session.FirSessionFactory
|
import org.jetbrains.kotlin.fir.session.FirSessionFactory
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.readSourceFileWithMapping
|
||||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
|
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -33,12 +37,15 @@ class TotalKotlinTest : AbstractRawFirBuilderTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateFirFromLightTree(onlyLightTree: Boolean, converter: LightTree2Fir, text: String, fileName: String, filePath: String) {
|
private fun generateFirFromLightTree(
|
||||||
|
onlyLightTree: Boolean, converter: LightTree2Fir,
|
||||||
|
text: CharSequence, sourceFile: KtSourceFile, linesMapping: KtSourceFileLinesMapping
|
||||||
|
) {
|
||||||
if (onlyLightTree) {
|
if (onlyLightTree) {
|
||||||
val lightTree = LightTree2Fir.buildLightTree(text)
|
val lightTree = LightTree2Fir.buildLightTree(text)
|
||||||
DebugUtil.lightTreeToString(lightTree, false)
|
DebugUtil.lightTreeToString(lightTree, false)
|
||||||
} else {
|
} else {
|
||||||
val firFile = converter.buildFirFile(text, fileName, filePath)
|
val firFile = converter.buildFirFile(text, sourceFile, linesMapping)
|
||||||
StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
|
StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,9 +64,12 @@ class TotalKotlinTest : AbstractRawFirBuilderTestCase() {
|
|||||||
if (onlyLightTree) println("LightTree generation") else println("Fir from LightTree converter")
|
if (onlyLightTree) println("LightTree generation") else println("Fir from LightTree converter")
|
||||||
println("BASE PATH: $path")
|
println("BASE PATH: $path")
|
||||||
path.walkTopDown {
|
path.walkTopDown {
|
||||||
val text = FileUtil.loadFile(it, CharsetToolkit.UTF8, true).trim()
|
val sourceFile = KtIoFileSourceFile(it)
|
||||||
|
val (code, linesMapping) = with(it.inputStream().reader(Charsets.UTF_8)) {
|
||||||
|
this.readSourceFileWithMapping()
|
||||||
|
}
|
||||||
time += measureNanoTime {
|
time += measureNanoTime {
|
||||||
generateFirFromLightTree(onlyLightTree, lightTreeConverter, text, it.name, it.path)
|
generateFirFromLightTree(onlyLightTree, lightTreeConverter, code, sourceFile, linesMapping)
|
||||||
}
|
}
|
||||||
|
|
||||||
counter++
|
counter++
|
||||||
|
|||||||
+15
-4
@@ -10,6 +10,8 @@ import com.intellij.openapi.vfs.CharsetToolkit
|
|||||||
import com.intellij.testFramework.TestDataPath
|
import com.intellij.testFramework.TestDataPath
|
||||||
import com.intellij.util.PathUtil
|
import com.intellij.util.PathUtil
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
|
import org.jetbrains.kotlin.KtInMemoryTextSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtIoFileSourceFile
|
||||||
import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.Companion.DIAGNOSTIC_IN_TESTDATA_PATTERN
|
import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.Companion.DIAGNOSTIC_IN_TESTDATA_PATTERN
|
||||||
import org.jetbrains.kotlin.fir.FirRenderer
|
import org.jetbrains.kotlin.fir.FirRenderer
|
||||||
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
|
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
|
||||||
@@ -19,7 +21,9 @@ import org.jetbrains.kotlin.fir.lightTree.walkTopDown
|
|||||||
import org.jetbrains.kotlin.fir.lightTree.walkTopDownWithTestData
|
import org.jetbrains.kotlin.fir.lightTree.walkTopDownWithTestData
|
||||||
import org.jetbrains.kotlin.fir.session.FirSessionFactory
|
import org.jetbrains.kotlin.fir.session.FirSessionFactory
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.readSourceFileWithMapping
|
||||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
|
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
|
||||||
|
import org.jetbrains.kotlin.toSourceLinesMapping
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -61,15 +65,17 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
|
|||||||
diagnosticsReporter = null
|
diagnosticsReporter = null
|
||||||
)
|
)
|
||||||
compareBase(System.getProperty("user.dir"), withTestData = false) { file ->
|
compareBase(System.getProperty("user.dir"), withTestData = false) { file ->
|
||||||
val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim()
|
val (text, linesMapping) = with(file.inputStream().reader(Charsets.UTF_8)) {
|
||||||
|
this.readSourceFileWithMapping()
|
||||||
|
}
|
||||||
|
|
||||||
//psi
|
//psi
|
||||||
val ktFile = createPsiFile(FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.path)), text) as KtFile
|
val ktFile = createPsiFile(FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.path)), text.toString().trim()) as KtFile
|
||||||
val firFileFromPsi = ktFile.toFirFile()
|
val firFileFromPsi = ktFile.toFirFile()
|
||||||
val treeFromPsi = StringBuilder().also { FirRenderer(it).visitFile(firFileFromPsi) }.toString()
|
val treeFromPsi = StringBuilder().also { FirRenderer(it).visitFile(firFileFromPsi) }.toString()
|
||||||
|
|
||||||
//light tree
|
//light tree
|
||||||
val firFileFromLightTree = lightTreeConverter.buildFirFile(text, file.name, file.path)
|
val firFileFromLightTree = lightTreeConverter.buildFirFile(text, KtIoFileSourceFile(file), linesMapping)
|
||||||
val treeFromLightTree = StringBuilder().also { FirRenderer(it).visitFile(firFileFromLightTree) }.toString()
|
val treeFromLightTree = StringBuilder().also { FirRenderer(it).visitFile(firFileFromLightTree) }.toString()
|
||||||
|
|
||||||
return@compareBase treeFromLightTree == treeFromPsi
|
return@compareBase treeFromLightTree == treeFromPsi
|
||||||
@@ -100,7 +106,12 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
|
|||||||
.replace("<Unsupported LValue.*?>".toRegex(), "<Unsupported LValue>")
|
.replace("<Unsupported LValue.*?>".toRegex(), "<Unsupported LValue>")
|
||||||
|
|
||||||
//light tree
|
//light tree
|
||||||
val firFileFromLightTree = lightTreeConverter.buildFirFile(text, file.name, file.path)
|
val firFileFromLightTree =
|
||||||
|
lightTreeConverter.buildFirFile(
|
||||||
|
text,
|
||||||
|
KtInMemoryTextSourceFile(file.name, file.path, text),
|
||||||
|
text.toSourceLinesMapping()
|
||||||
|
)
|
||||||
val treeFromLightTree = StringBuilder().also { FirRenderer(it).visitFile(firFileFromLightTree) }.toString()
|
val treeFromLightTree = StringBuilder().also { FirRenderer(it).visitFile(firFileFromLightTree) }.toString()
|
||||||
.replace("<Unsupported LValue.*?>".toRegex(), "<Unsupported LValue>")
|
.replace("<Unsupported LValue.*?>".toRegex(), "<Unsupported LValue>")
|
||||||
|
|
||||||
|
|||||||
@@ -911,7 +911,8 @@ open class RawFirBuilder(
|
|||||||
moduleData = baseModuleData
|
moduleData = baseModuleData
|
||||||
origin = FirDeclarationOrigin.Source
|
origin = FirDeclarationOrigin.Source
|
||||||
name = file.name
|
name = file.name
|
||||||
path = file.virtualFile?.path
|
sourceFile = KtPsiSourceFile(file)
|
||||||
|
sourceFileLinesMapping = KtPsiSourceFileLinesMapping(file)
|
||||||
packageDirective = buildPackageDirective {
|
packageDirective = buildPackageDirective {
|
||||||
packageFqName = context.packageFqName
|
packageFqName = context.packageFqName
|
||||||
source = file.packageDirective?.toKtPsiSourceElement()
|
source = file.packageDirective?.toKtPsiSourceElement()
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.fir.declarations
|
package org.jetbrains.kotlin.fir.declarations
|
||||||
|
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtSourceFileLinesMapping
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
import org.jetbrains.kotlin.fir.FirPackageDirective
|
import org.jetbrains.kotlin.fir.FirPackageDirective
|
||||||
@@ -29,7 +31,8 @@ abstract class FirFile : FirDeclaration() {
|
|||||||
abstract val imports: List<FirImport>
|
abstract val imports: List<FirImport>
|
||||||
abstract val declarations: List<FirDeclaration>
|
abstract val declarations: List<FirDeclaration>
|
||||||
abstract val name: String
|
abstract val name: String
|
||||||
abstract val path: String?
|
abstract val sourceFile: KtSourceFile?
|
||||||
|
abstract val sourceFileLinesMapping: KtSourceFileLinesMapping?
|
||||||
abstract override val symbol: FirFileSymbol
|
abstract override val symbol: FirFileSymbol
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitFile(this, data)
|
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitFile(this, data)
|
||||||
|
|||||||
+6
-2
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.fir.declarations.builder
|
|||||||
|
|
||||||
import kotlin.contracts.*
|
import kotlin.contracts.*
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtSourceFileLinesMapping
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
import org.jetbrains.kotlin.fir.FirPackageDirective
|
import org.jetbrains.kotlin.fir.FirPackageDirective
|
||||||
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
||||||
@@ -39,7 +41,8 @@ class FirFileBuilder : FirAnnotationContainerBuilder {
|
|||||||
val imports: MutableList<FirImport> = mutableListOf()
|
val imports: MutableList<FirImport> = mutableListOf()
|
||||||
val declarations: MutableList<FirDeclaration> = mutableListOf()
|
val declarations: MutableList<FirDeclaration> = mutableListOf()
|
||||||
lateinit var name: String
|
lateinit var name: String
|
||||||
var path: String? = null
|
var sourceFile: KtSourceFile? = null
|
||||||
|
var sourceFileLinesMapping: KtSourceFileLinesMapping? = null
|
||||||
|
|
||||||
override fun build(): FirFile {
|
override fun build(): FirFile {
|
||||||
return FirFileImpl(
|
return FirFileImpl(
|
||||||
@@ -53,7 +56,8 @@ class FirFileBuilder : FirAnnotationContainerBuilder {
|
|||||||
imports,
|
imports,
|
||||||
declarations,
|
declarations,
|
||||||
name,
|
name,
|
||||||
path,
|
sourceFile,
|
||||||
|
sourceFileLinesMapping,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.fir.declarations.impl
|
package org.jetbrains.kotlin.fir.declarations.impl
|
||||||
|
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtSourceFileLinesMapping
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
import org.jetbrains.kotlin.fir.FirPackageDirective
|
import org.jetbrains.kotlin.fir.FirPackageDirective
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
@@ -35,7 +37,8 @@ internal class FirFileImpl(
|
|||||||
override val imports: MutableList<FirImport>,
|
override val imports: MutableList<FirImport>,
|
||||||
override val declarations: MutableList<FirDeclaration>,
|
override val declarations: MutableList<FirDeclaration>,
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val path: String?,
|
override val sourceFile: KtSourceFile?,
|
||||||
|
override val sourceFileLinesMapping: KtSourceFileLinesMapping?,
|
||||||
) : FirFile() {
|
) : FirFile() {
|
||||||
override val symbol: FirFileSymbol = FirFileSymbol()
|
override val symbol: FirFileSymbol = FirFileSymbol()
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -415,7 +415,8 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
|||||||
+fieldList(import).withTransform()
|
+fieldList(import).withTransform()
|
||||||
+declarations.withTransform()
|
+declarations.withTransform()
|
||||||
+stringField("name")
|
+stringField("name")
|
||||||
+stringField("path", nullable = true)
|
+field("sourceFile", sourceFileType, nullable = true)
|
||||||
|
+field("sourceFileLinesMapping", sourceFileLinesMappingType, nullable = true)
|
||||||
+symbol("FirFileSymbol")
|
+symbol("FirFileSymbol")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.fir.tree.generator
|
package org.jetbrains.kotlin.fir.tree.generator
|
||||||
|
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtSourceFileLinesMapping
|
||||||
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
@@ -23,6 +25,8 @@ import org.jetbrains.kotlin.types.SmartcastStability
|
|||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
val sourceElementType = type(KtSourceElement::class)
|
val sourceElementType = type(KtSourceElement::class)
|
||||||
|
val sourceFileType = type(KtSourceFile::class)
|
||||||
|
val sourceFileLinesMappingType = type(KtSourceFileLinesMapping::class)
|
||||||
val jumpTargetType = type("fir", "FirTarget")
|
val jumpTargetType = type("fir", "FirTarget")
|
||||||
val constKindType = type("types", "ConstantValueKind")
|
val constKindType = type("types", "ConstantValueKind")
|
||||||
val operationType = type("fir.expressions", "FirOperation")
|
val operationType = type("fir.expressions", "FirOperation")
|
||||||
|
|||||||
@@ -14,9 +14,6 @@ import com.intellij.psi.PsiFile
|
|||||||
import com.intellij.psi.PsiWhiteSpace
|
import com.intellij.psi.PsiWhiteSpace
|
||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||||
import java.io.Closeable
|
|
||||||
import java.io.File
|
|
||||||
import java.io.InputStreamReader
|
|
||||||
|
|
||||||
sealed class KtSourceElementKind
|
sealed class KtSourceElementKind
|
||||||
|
|
||||||
@@ -444,90 +441,3 @@ inline fun LighterASTNode.toKtLightSourceElement(
|
|||||||
endOffset: Int = this.endOffset
|
endOffset: Int = this.endOffset
|
||||||
): KtLightSourceElement = KtLightSourceElement(this, startOffset, endOffset, tree, kind)
|
): KtLightSourceElement = KtLightSourceElement(this, startOffset, endOffset, tree, kind)
|
||||||
|
|
||||||
|
|
||||||
class KtSourceFilePosition(val line: Int, val column: Int, val lineContent: String?) {
|
|
||||||
|
|
||||||
// NOTE: This method is used for presenting positions to the user
|
|
||||||
override fun toString(): String = if (line < 0) "(offset: $column line unknown)" else "($line,$column)"
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val NONE = KtSourceFilePosition(-1, -1, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SequentialFilePositionFinder(file: File) : Closeable {
|
|
||||||
|
|
||||||
private var reader: InputStreamReader = file.reader(/* TODO: select proper charset */)
|
|
||||||
|
|
||||||
private var currentLineContent: String? = null
|
|
||||||
private val buffer = CharArray(255)
|
|
||||||
private var bufLength = -1
|
|
||||||
private var bufPos = 0
|
|
||||||
private var endOfStream = false
|
|
||||||
private var skipNextLf = false
|
|
||||||
|
|
||||||
private var charsRead = 0
|
|
||||||
private var currentLine = 0
|
|
||||||
|
|
||||||
// assuming that if called multiple times, calls should be sorted by ascending offset
|
|
||||||
fun findNextPosition(offset: Int, withLineContents: Boolean = true): KtSourceFilePosition {
|
|
||||||
assert(offset >= charsRead - (currentLineContent?.length ?: 0))
|
|
||||||
|
|
||||||
fun posInCurrentLine(): KtSourceFilePosition? {
|
|
||||||
val col = offset - (charsRead - currentLineContent!!.length - 1)/* beginning of line offset */ + 1 /* col is 1-based */
|
|
||||||
return if (col <= currentLineContent!!.length)
|
|
||||||
KtSourceFilePosition(currentLine, col, if (withLineContents) currentLineContent else null)
|
|
||||||
else null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset < charsRead) {
|
|
||||||
return posInCurrentLine()!!
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (currentLineContent == null) {
|
|
||||||
currentLineContent = readNextLine()
|
|
||||||
}
|
|
||||||
|
|
||||||
posInCurrentLine()?.let { return@findNextPosition it }
|
|
||||||
|
|
||||||
if (endOfStream) return KtSourceFilePosition(-1, offset, if (withLineContents) currentLineContent else null)
|
|
||||||
|
|
||||||
currentLineContent = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun readNextLine() = buildString {
|
|
||||||
while (true) {
|
|
||||||
if (bufPos >= bufLength) {
|
|
||||||
bufLength = reader.read(buffer)
|
|
||||||
bufPos = 0
|
|
||||||
if (bufLength < 0) {
|
|
||||||
endOfStream = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val c = buffer[bufPos++]
|
|
||||||
charsRead++
|
|
||||||
when {
|
|
||||||
c == '\n' && skipNextLf -> {
|
|
||||||
skipNextLf = false
|
|
||||||
}
|
|
||||||
c == '\n' || c == '\r' -> {
|
|
||||||
currentLine++
|
|
||||||
skipNextLf = c == '\r'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
append(c)
|
|
||||||
skipNextLf = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun close() {
|
|
||||||
reader.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.io.FileUtilRt
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.io.File
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
interface KtSourceFile {
|
||||||
|
val name: String
|
||||||
|
val path: String?
|
||||||
|
|
||||||
|
fun getContentsAsStream(): InputStream
|
||||||
|
}
|
||||||
|
|
||||||
|
class KtPsiSourceFile(val psiFile: PsiFile) : KtSourceFile {
|
||||||
|
override val name: String
|
||||||
|
get() = psiFile.name
|
||||||
|
|
||||||
|
override val path: String?
|
||||||
|
get() = psiFile.virtualFile?.path
|
||||||
|
|
||||||
|
override fun getContentsAsStream(): InputStream = psiFile.virtualFile.inputStream
|
||||||
|
}
|
||||||
|
|
||||||
|
class KtVirtualFileSourceFile(val virtualFile: VirtualFile) : KtSourceFile {
|
||||||
|
override val name: String
|
||||||
|
get() = virtualFile.name
|
||||||
|
|
||||||
|
override val path: String
|
||||||
|
get() = virtualFile.path
|
||||||
|
|
||||||
|
override fun getContentsAsStream(): InputStream = virtualFile.inputStream
|
||||||
|
}
|
||||||
|
|
||||||
|
class KtIoFileSourceFile(val file: File) : KtSourceFile {
|
||||||
|
override val name: String
|
||||||
|
get() = file.name
|
||||||
|
override val path: String
|
||||||
|
get() = FileUtilRt.toSystemIndependentName(file.path)
|
||||||
|
|
||||||
|
override fun getContentsAsStream(): InputStream = file.inputStream()
|
||||||
|
}
|
||||||
|
|
||||||
|
class KtInMemoryTextSourceFile(
|
||||||
|
override val name: String,
|
||||||
|
override val path: String?,
|
||||||
|
val text: CharSequence
|
||||||
|
) : KtSourceFile {
|
||||||
|
override fun getContentsAsStream(): InputStream = ByteArrayInputStream(text.toString().toByteArray())
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import com.intellij.openapi.editor.Document
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
|
||||||
|
interface KtSourceFileLinesMapping {
|
||||||
|
fun getLineStartOffset(line: Int): Int
|
||||||
|
fun getLineAndColumnByOffset(offset: Int): Pair<Int, Int>
|
||||||
|
fun getLineByOffset(offset: Int): Int
|
||||||
|
|
||||||
|
val lastOffset: Int
|
||||||
|
val linesCount: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
class KtPsiSourceFileLinesMapping(val psiFile: PsiFile) : KtSourceFileLinesMapping {
|
||||||
|
private val document: Document? by lazy { psiFile.viewProvider.document }
|
||||||
|
|
||||||
|
override fun getLineStartOffset(line: Int): Int =
|
||||||
|
document?.getLineStartOffset(line) ?: -1
|
||||||
|
|
||||||
|
override fun getLineAndColumnByOffset(offset: Int): Pair<Int, Int> =
|
||||||
|
document?.let {
|
||||||
|
val lineNumber = it.getLineNumber(offset)
|
||||||
|
val lineStartOffset = it.getLineStartOffset(lineNumber)
|
||||||
|
lineNumber to offset - lineStartOffset
|
||||||
|
} ?: (-1 to -1)
|
||||||
|
|
||||||
|
override fun getLineByOffset(offset: Int): Int =
|
||||||
|
document?.getLineNumber(offset) ?: -1
|
||||||
|
|
||||||
|
override val lastOffset: Int
|
||||||
|
get() = document?.textLength ?: -1
|
||||||
|
|
||||||
|
override val linesCount: Int
|
||||||
|
get() = document?.lineCount ?: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
open class KtSourceFileLinesMappingFromLineStartOffsets(
|
||||||
|
val lineStartOffsets: IntArray, override val lastOffset: Int
|
||||||
|
) : KtSourceFileLinesMapping {
|
||||||
|
override fun getLineStartOffset(line: Int): Int = lineStartOffsets[line]
|
||||||
|
|
||||||
|
override fun getLineAndColumnByOffset(offset: Int): Pair<Int, Int> {
|
||||||
|
val lineNumber = getLineByOffset(offset)
|
||||||
|
if (lineNumber < 0) return -1 to -1
|
||||||
|
val lineStartOffset = lineStartOffsets[lineNumber]
|
||||||
|
return lineNumber to offset - lineStartOffset
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLineByOffset(offset: Int): Int {
|
||||||
|
val index = lineStartOffsets.binarySearch(offset)
|
||||||
|
return if (index >= 0) index else -index - 2
|
||||||
|
}
|
||||||
|
|
||||||
|
override val linesCount: Int
|
||||||
|
get() = lineStartOffsets.size
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads file contents from reader, converts line separators and calculates source lines to file offsets mapping
|
||||||
|
*
|
||||||
|
* Returns KtSourceFileLinesMapping and char sequence (StringBuilder to avoid premature copying) containing converted text
|
||||||
|
* The separators are converted similarly to the com.intellij.openapi.util.text.StringUtilRt algorithms
|
||||||
|
*/
|
||||||
|
fun InputStreamReader.readSourceFileWithMapping(): Pair<CharSequence, KtSourceFileLinesMapping> {
|
||||||
|
val buffer = CharArray(255)
|
||||||
|
var bufLength = -1
|
||||||
|
var bufPos = 0
|
||||||
|
var skipNextLf = false
|
||||||
|
|
||||||
|
var charsRead = 0
|
||||||
|
|
||||||
|
val lineOffsets = mutableListOf(0) // TODO: consider using implicit first line offset (needs to be handled properly in IR)
|
||||||
|
val sb = StringBuilder()
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (bufPos >= bufLength) {
|
||||||
|
bufLength = read(buffer)
|
||||||
|
bufPos = 0
|
||||||
|
if (bufLength < 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val c = buffer[bufPos++]
|
||||||
|
charsRead++
|
||||||
|
when {
|
||||||
|
c == '\n' && skipNextLf -> {
|
||||||
|
lineOffsets[lineOffsets.size - 1] = charsRead
|
||||||
|
skipNextLf = false
|
||||||
|
}
|
||||||
|
c == '\n' || c == '\r' -> {
|
||||||
|
sb.append('\n')
|
||||||
|
lineOffsets.add(charsRead)
|
||||||
|
skipNextLf = c == '\r'
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
sb.append(c)
|
||||||
|
skipNextLf = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb to KtSourceFileLinesMappingFromLineStartOffsets(lineOffsets.toIntArray(), charsRead)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts source lines to offsets mapping from text
|
||||||
|
*
|
||||||
|
* intended for using mainly in tests, so no care is taken about performance or possible corner cases
|
||||||
|
*/
|
||||||
|
fun CharSequence.toSourceLinesMapping(): KtSourceFileLinesMapping {
|
||||||
|
val lineOffsets = mutableListOf(0)
|
||||||
|
var offset = 0
|
||||||
|
for (c in this) {
|
||||||
|
offset++
|
||||||
|
if (c == '\n') lineOffsets.add(offset)
|
||||||
|
}
|
||||||
|
return KtSourceFileLinesMappingFromLineStartOffsets(lineOffsets.toIntArray(), offset)
|
||||||
|
}
|
||||||
+16
-9
@@ -8,6 +8,9 @@ package org.jetbrains.kotlin.incremental
|
|||||||
import com.intellij.ide.highlighter.JavaFileType
|
import com.intellij.ide.highlighter.JavaFileType
|
||||||
import com.intellij.openapi.util.Disposer
|
import com.intellij.openapi.util.Disposer
|
||||||
import com.intellij.psi.PsiJavaModule
|
import com.intellij.psi.PsiJavaModule
|
||||||
|
import org.jetbrains.kotlin.KtIoFileSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtVirtualFileSourceFile
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl
|
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl
|
||||||
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
||||||
@@ -99,7 +102,7 @@ class IncrementalFirJvmCompilerRunner(
|
|||||||
val moduleName = args.moduleName ?: JvmProtoBufUtil.DEFAULT_MODULE_NAME
|
val moduleName = args.moduleName ?: JvmProtoBufUtil.DEFAULT_MODULE_NAME
|
||||||
val targetId = TargetId(moduleName, "java-production") // TODO: get rid of magic constant
|
val targetId = TargetId(moduleName, "java-production") // TODO: get rid of magic constant
|
||||||
|
|
||||||
val dirtySources = linkedSetOf<File>().apply { addAll(sourcesToCompile) }
|
val dirtySources = linkedSetOf<KtSourceFile>().apply { sourcesToCompile.forEach { add(KtIoFileSourceFile(it)) } }
|
||||||
|
|
||||||
// TODO: probably shoudl be passed along with sourcesToCompile
|
// TODO: probably shoudl be passed along with sourcesToCompile
|
||||||
// TODO: file path normalization
|
// TODO: file path normalization
|
||||||
@@ -175,12 +178,11 @@ class IncrementalFirJvmCompilerRunner(
|
|||||||
createProjectEnvironment(configuration, rootDisposable, EnvironmentConfigFiles.JVM_CONFIG_FILES, messageCollector)
|
createProjectEnvironment(configuration, rootDisposable, EnvironmentConfigFiles.JVM_CONFIG_FILES, messageCollector)
|
||||||
|
|
||||||
// -sources
|
// -sources
|
||||||
val allPlatformSourceFiles = linkedSetOf<File>() // TODO: get from caller
|
val allPlatformSourceFiles = linkedSetOf<KtSourceFile>() // TODO: get from caller
|
||||||
val allCommonSourceFiles = linkedSetOf<File>()
|
val allCommonSourceFiles = linkedSetOf<KtSourceFile>()
|
||||||
|
|
||||||
configuration.kotlinSourceRoots.forAllFiles(configuration, projectEnvironment.project) { virtualFile, isCommon ->
|
configuration.kotlinSourceRoots.forAllFiles(configuration, projectEnvironment.project) { virtualFile, isCommon ->
|
||||||
val file = File(virtualFile.canonicalPath ?: virtualFile.path)
|
val file = KtVirtualFileSourceFile(virtualFile)
|
||||||
if (!file.isFile) error("TODO: better error: file not found $virtualFile")
|
|
||||||
if (isCommon) allCommonSourceFiles.add(file)
|
if (isCommon) allCommonSourceFiles.add(file)
|
||||||
else allPlatformSourceFiles.add(file)
|
else allPlatformSourceFiles.add(file)
|
||||||
}
|
}
|
||||||
@@ -203,8 +205,8 @@ class IncrementalFirJvmCompilerRunner(
|
|||||||
|
|
||||||
val compilerInput = ModuleCompilerInput(
|
val compilerInput = ModuleCompilerInput(
|
||||||
targetId,
|
targetId,
|
||||||
CommonPlatforms.defaultCommonPlatform, dirtySources.filter { it in allCommonSourceFiles },
|
CommonPlatforms.defaultCommonPlatform, allCommonSourceFiles.filter { dirtySources.any { df -> df.path == it.path } },
|
||||||
JvmPlatforms.unspecifiedJvmPlatform, dirtySources.filter { it in allPlatformSourceFiles },
|
JvmPlatforms.unspecifiedJvmPlatform, allPlatformSourceFiles.filter { dirtySources.any { df -> df.path == it.path } },
|
||||||
configuration
|
configuration
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -227,7 +229,10 @@ class IncrementalFirJvmCompilerRunner(
|
|||||||
mainClassFqName = findMainClass(analysisResults.fir)
|
mainClassFqName = findMainClass(analysisResults.fir)
|
||||||
}
|
}
|
||||||
|
|
||||||
allCompiledSources.addAll(dirtySources)
|
// TODO: switch the whole IC to KtSourceFile instead of FIle
|
||||||
|
dirtySources.forEach {
|
||||||
|
allCompiledSources.add(File(it.path!!))
|
||||||
|
}
|
||||||
|
|
||||||
if (diagnosticsReporter.hasErrors) {
|
if (diagnosticsReporter.hasErrors) {
|
||||||
diagnosticsReporter.reportToMessageCollector(messageCollector, renderDiagnosticName)
|
diagnosticsReporter.reportToMessageCollector(messageCollector, renderDiagnosticName)
|
||||||
@@ -250,7 +255,9 @@ class IncrementalFirJvmCompilerRunner(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
caches.inputsCache.removeOutputForSourceFiles(newDirtySources)
|
caches.inputsCache.removeOutputForSourceFiles(newDirtySources)
|
||||||
dirtySources.addAll(newDirtySources)
|
newDirtySources.forEach {
|
||||||
|
dirtySources.add(KtIoFileSourceFile(it))
|
||||||
|
}
|
||||||
projectEnvironment.localFileSystem.refresh(false)
|
projectEnvironment.localFileSystem.refresh(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,14 +18,9 @@ package org.jetbrains.kotlin.backend.common
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.AbstractKtSourceElement
|
import org.jetbrains.kotlin.AbstractKtSourceElement
|
||||||
import org.jetbrains.kotlin.KtOffsetsOnlySourceElement
|
import org.jetbrains.kotlin.KtOffsetsOnlySourceElement
|
||||||
import org.jetbrains.kotlin.KtRealPsiSourceElement
|
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
|
||||||
import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.util.render
|
|
||||||
|
|
||||||
fun CommonBackendContext.reportWarning(message: String, irFile: IrFile?, irElement: IrElement) {
|
fun CommonBackendContext.reportWarning(message: String, irFile: IrFile?, irElement: IrElement) {
|
||||||
report(irElement, irFile, message, false)
|
report(irElement, irFile, message, false)
|
||||||
@@ -37,12 +32,6 @@ fun <E> MutableList<E>.pop() = this.removeAt(size - 1)
|
|||||||
|
|
||||||
fun <E> MutableList<E>.peek(): E? = if (size == 0) null else this[size - 1]
|
fun <E> MutableList<E>.peek(): E? = if (size == 0) null else this[size - 1]
|
||||||
|
|
||||||
fun findKtSourceElement(irElement: IrElement, irDeclaration: IrDeclaration): KtSourceElement {
|
|
||||||
val psiElement = PsiSourceManager.findPsiElement(irElement, irDeclaration)
|
|
||||||
?: throw AssertionError("No PsiElement found for '${irElement.render()}'")
|
|
||||||
return KtRealPsiSourceElement(psiElement)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrElement.sourceElement(): AbstractKtSourceElement? =
|
fun IrElement.sourceElement(): AbstractKtSourceElement? =
|
||||||
if (startOffset != UNDEFINED_OFFSET) KtOffsetsOnlySourceElement(this.startOffset, this.endOffset)
|
if (startOffset != UNDEFINED_OFFSET) KtOffsetsOnlySourceElement(this.startOffset, this.endOffset)
|
||||||
else null
|
else null
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ fun IrFile.getKtFile(): KtFile? =
|
|||||||
fun IrFile.getIoFile(): File? =
|
fun IrFile.getIoFile(): File? =
|
||||||
when (val fe = fileEntry) {
|
when (val fe = fileEntry) {
|
||||||
is PsiIrFileEntry -> fe.psiFile.virtualFile?.path?.let(::File)
|
is PsiIrFileEntry -> fe.psiFile.virtualFile?.path?.let(::File)
|
||||||
else -> File(fe.name).takeIf { it.exists() }
|
else -> File(fe.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun IrElement.hasChild(crossinline block: (IrElement) -> Boolean): Boolean {
|
inline fun IrElement.hasChild(crossinline block: (IrElement) -> Boolean): Boolean {
|
||||||
|
|||||||
@@ -186,7 +186,8 @@ val IrFileEntry.lineStartOffsets: IntArray
|
|||||||
|
|
||||||
class NaiveSourceBasedFileEntryImpl(
|
class NaiveSourceBasedFileEntryImpl(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
private val lineStartOffsets: IntArray = intArrayOf()
|
private val lineStartOffsets: IntArray = intArrayOf(),
|
||||||
|
override val maxOffset: Int = UNDEFINED_OFFSET
|
||||||
) : IrFileEntry {
|
) : IrFileEntry {
|
||||||
val lineStartOffsetsAreEmpty: Boolean
|
val lineStartOffsetsAreEmpty: Boolean
|
||||||
get() = lineStartOffsets.isEmpty()
|
get() = lineStartOffsets.isEmpty()
|
||||||
@@ -215,15 +216,19 @@ class NaiveSourceBasedFileEntryImpl(
|
|||||||
if (offset == SYNTHETIC_OFFSET) return 0
|
if (offset == SYNTHETIC_OFFSET) return 0
|
||||||
if (offset < 0) return -1
|
if (offset < 0) return -1
|
||||||
val lineNumber = getLineNumber(offset)
|
val lineNumber = getLineNumber(offset)
|
||||||
return offset - lineStartOffsets[lineNumber]
|
return if (lineNumber < 0) -1 else offset - lineStartOffsets[lineNumber]
|
||||||
}
|
}
|
||||||
|
|
||||||
override val maxOffset: Int
|
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo =
|
||||||
get() = UNDEFINED_OFFSET
|
SourceRangeInfo(
|
||||||
|
filePath = name,
|
||||||
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo {
|
startOffset = beginOffset,
|
||||||
return SourceRangeInfo(name, beginOffset, -1, -1, endOffset, -1, -1)
|
startLineNumber = getLineNumber(beginOffset),
|
||||||
}
|
startColumnNumber = getColumnNumber(beginOffset),
|
||||||
|
endOffset = endOffset,
|
||||||
|
endLineNumber = getLineNumber(endOffset),
|
||||||
|
endColumnNumber = getColumnNumber(endOffset)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrClass.getPropertyDeclaration(name: String): IrProperty? {
|
private fun IrClass.getPropertyDeclaration(name: String): IrProperty? {
|
||||||
|
|||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* 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.sourceFiles
|
||||||
|
|
||||||
|
import com.intellij.lang.LighterASTNode
|
||||||
|
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtSourceFileLinesMapping
|
||||||
|
|
||||||
|
data class LightTreeFile(
|
||||||
|
val lightTree: FlyweightCapableTreeStructure<LighterASTNode>,
|
||||||
|
val sourceFile: KtSourceFile,
|
||||||
|
val linesMapping: KtSourceFileLinesMapping
|
||||||
|
)
|
||||||
+7
-4
@@ -6,11 +6,13 @@
|
|||||||
package org.jetbrains.kotlin.test.services
|
package org.jetbrains.kotlin.test.services
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.KtInMemoryTextSourceFile
|
||||||
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
|
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
|
||||||
import org.jetbrains.kotlin.fir.lightTree.LightTreeFile
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.sourceFiles.LightTreeFile
|
||||||
import org.jetbrains.kotlin.test.model.TestFile
|
import org.jetbrains.kotlin.test.model.TestFile
|
||||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||||
|
import org.jetbrains.kotlin.toSourceLinesMapping
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
abstract class SourceFilePreprocessor(val testServices: TestServices) {
|
abstract class SourceFilePreprocessor(val testServices: TestServices) {
|
||||||
@@ -101,9 +103,10 @@ fun SourceFileProvider.getKtFilesForSourceFiles(testFiles: Collection<TestFile>,
|
|||||||
|
|
||||||
fun SourceFileProvider.getLightTreeKtFileForSourceFile(testFile: TestFile): LightTreeFile {
|
fun SourceFileProvider.getLightTreeKtFileForSourceFile(testFile: TestFile): LightTreeFile {
|
||||||
val shortName = testFile.name.substringAfterLast('/').substringAfterLast('\\')
|
val shortName = testFile.name.substringAfterLast('/').substringAfterLast('\\')
|
||||||
val file = getRealFileForSourceFile(testFile)
|
val sourceFile = KtInMemoryTextSourceFile(shortName, "/$shortName", getContentOfSourceFile(testFile))
|
||||||
val lightTree = LightTree2Fir.buildLightTree(file.readText())
|
val linesMapping = sourceFile.text.toSourceLinesMapping()
|
||||||
return LightTreeFile(lightTree, shortName, "/$shortName") // emulating behavior of KtTestUtil.createFile so path looks the same in testdata
|
val lightTree = LightTree2Fir.buildLightTree(sourceFile.text)
|
||||||
|
return LightTreeFile(lightTree, sourceFile, linesMapping)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun SourceFileProvider.getLightTreeFilesForSourceFiles(testFiles: Collection<TestFile>): Map<TestFile, LightTreeFile> {
|
fun SourceFileProvider.getLightTreeFilesForSourceFiles(testFiles: Collection<TestFile>): Map<TestFile, LightTreeFile> {
|
||||||
|
|||||||
+2
-1
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.test.backend.classic
|
package org.jetbrains.kotlin.test.backend.classic
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtPsiSourceFile
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||||
import org.jetbrains.kotlin.codegen.DefaultCodegenFactory
|
import org.jetbrains.kotlin.codegen.DefaultCodegenFactory
|
||||||
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
|
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
|
||||||
@@ -46,7 +47,7 @@ class ClassicJvmBackendFacade(
|
|||||||
javaCompilerFacade.compileJavaFiles(module, configuration, generationState.factory)
|
javaCompilerFacade.compileJavaFiles(module, configuration, generationState.factory)
|
||||||
return BinaryArtifacts.Jvm(
|
return BinaryArtifacts.Jvm(
|
||||||
generationState.factory,
|
generationState.factory,
|
||||||
psiFiles.map { SourceFileInfo(it, JvmFileClassUtil.getFileClassInfoNoResolve(it)) }
|
psiFiles.map { SourceFileInfo(KtPsiSourceFile(it), JvmFileClassUtil.getFileClassInfoNoResolve(it)) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -14,7 +14,10 @@ import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||||
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
|
import org.jetbrains.kotlin.ir.util.dump
|
||||||
|
import org.jetbrains.kotlin.ir.util.dumpTreesFromLineNumber
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl
|
import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl
|
||||||
@@ -46,7 +49,7 @@ class IrTextDumpHandler(testServices: TestServices) : AbstractIrHandler(testServ
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun List<IrFile>.groupWithTestFiles(module: TestModule): List<Pair<TestFile?, IrFile>> = mapNotNull { irFile ->
|
fun List<IrFile>.groupWithTestFiles(module: TestModule): List<Pair<TestFile?, IrFile>> = mapNotNull { irFile ->
|
||||||
val name = irFile.fileEntry.name.removePrefix("/")
|
val name = File(irFile.fileEntry.name).name
|
||||||
val testFile = module.files.firstOrNull { it.name == name }
|
val testFile = module.files.firstOrNull { it.name == name }
|
||||||
testFile to irFile
|
testFile to irFile
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -61,7 +61,7 @@ open class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(t
|
|||||||
val classLoader = createAndVerifyClassLoader(module, info.classFileFactory, reportProblems)
|
val classLoader = createAndVerifyClassLoader(module, info.classFileFactory, reportProblems)
|
||||||
try {
|
try {
|
||||||
for (fileInfo in fileInfos) {
|
for (fileInfo in fileInfos) {
|
||||||
if (fileContainsBoxMethod(fileInfo.file)) {
|
if (fileContainsBoxMethod(fileInfo.sourceFile)) {
|
||||||
boxMethodFound = true
|
boxMethodFound = true
|
||||||
callBoxMethodAndCheckResultWithCleanup(
|
callBoxMethodAndCheckResultWithCleanup(
|
||||||
fileInfo.info,
|
fileInfo.info,
|
||||||
|
|||||||
+3
-2
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.test.services.TestServices
|
|||||||
import org.jetbrains.kotlin.test.services.moduleStructure
|
import org.jetbrains.kotlin.test.services.moduleStructure
|
||||||
import org.jetbrains.kotlin.test.utils.MultiModuleInfoDumper
|
import org.jetbrains.kotlin.test.utils.MultiModuleInfoDumper
|
||||||
import org.jetbrains.kotlin.test.utils.withExtension
|
import org.jetbrains.kotlin.test.utils.withExtension
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class SMAPDumpHandler(testServices: TestServices) : JvmBinaryArtifactHandler(testServices) {
|
class SMAPDumpHandler(testServices: TestServices) : JvmBinaryArtifactHandler(testServices) {
|
||||||
companion object {
|
companion object {
|
||||||
@@ -39,7 +40,7 @@ class SMAPDumpHandler(testServices: TestServices) : JvmBinaryArtifactHandler(tes
|
|||||||
val originalFileNames = module.files.map { it.name }
|
val originalFileNames = module.files.map { it.name }
|
||||||
|
|
||||||
val compiledSmaps = CommonSMAPTestUtil.extractSMAPFromClasses(info.classFileFactory.getClassFiles()).mapNotNull {
|
val compiledSmaps = CommonSMAPTestUtil.extractSMAPFromClasses(info.classFileFactory.getClassFiles()).mapNotNull {
|
||||||
val name = it.sourceFile.removePrefix("/")
|
val name = File(it.sourceFile).name
|
||||||
val index = originalFileNames.indexOf(name)
|
val index = originalFileNames.indexOf(name)
|
||||||
val testFile = module.files[index]
|
val testFile = module.files[index]
|
||||||
if (NO_SMAP_DUMP in testFile.directives) return@mapNotNull null
|
if (NO_SMAP_DUMP in testFile.directives) return@mapNotNull null
|
||||||
@@ -57,7 +58,7 @@ class SMAPDumpHandler(testServices: TestServices) : JvmBinaryArtifactHandler(tes
|
|||||||
|
|
||||||
dumper.builderForModule(module).apply {
|
dumper.builderForModule(module).apply {
|
||||||
for (source in compiledData.values) {
|
for (source in compiledData.values) {
|
||||||
appendLine("// FILE: ${source.sourceFile.removePrefix("/")}")
|
appendLine("// FILE: ${File(source.sourceFile).name}")
|
||||||
appendLine(source.smap ?: "")
|
appendLine(source.smap ?: "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.test.backend.ir
|
package org.jetbrains.kotlin.test.backend.ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
||||||
import org.jetbrains.kotlin.codegen.CodegenFactory
|
import org.jetbrains.kotlin.codegen.CodegenFactory
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
@@ -35,7 +36,8 @@ sealed class IrBackendInput : ResultingArtifact.BackendInput<IrBackendInput>() {
|
|||||||
data class JvmIrBackendInput(
|
data class JvmIrBackendInput(
|
||||||
val state: GenerationState,
|
val state: GenerationState,
|
||||||
val codegenFactory: JvmIrCodegenFactory,
|
val codegenFactory: JvmIrCodegenFactory,
|
||||||
val backendInput: JvmIrCodegenFactory.JvmIrBackendInput
|
val backendInput: JvmIrCodegenFactory.JvmIrBackendInput,
|
||||||
|
val sourceFiles: List<KtSourceFile>
|
||||||
) : IrBackendInput() {
|
) : IrBackendInput() {
|
||||||
override val irModuleFragment: IrModuleFragment
|
override val irModuleFragment: IrModuleFragment
|
||||||
get() = backendInput.irModuleFragment
|
get() = backendInput.irModuleFragment
|
||||||
|
|||||||
+11
-5
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.test.backend.ir
|
package org.jetbrains.kotlin.test.backend.ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtPsiSourceFile
|
||||||
import org.jetbrains.kotlin.backend.common.BackendException
|
import org.jetbrains.kotlin.backend.common.BackendException
|
||||||
import org.jetbrains.kotlin.backend.jvm.MultifileFacadeFileEntry
|
import org.jetbrains.kotlin.backend.jvm.MultifileFacadeFileEntry
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.getFileClassInfoFromIrFile
|
import org.jetbrains.kotlin.backend.jvm.lower.getFileClassInfoFromIrFile
|
||||||
@@ -21,7 +22,6 @@ import org.jetbrains.kotlin.test.model.SourceFileInfo
|
|||||||
import org.jetbrains.kotlin.test.model.TestModule
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class JvmIrBackendFacade(
|
class JvmIrBackendFacade(
|
||||||
testServices: TestServices
|
testServices: TestServices
|
||||||
@@ -48,14 +48,20 @@ class JvmIrBackendFacade(
|
|||||||
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||||
javaCompilerFacade.compileJavaFiles(module, configuration, state.factory)
|
javaCompilerFacade.compileJavaFiles(module, configuration, state.factory)
|
||||||
|
|
||||||
fun sourceFileInfos(irFile: IrFile, allowNestedMultifileFacades: Boolean): List<SourceFileInfo<*>> =
|
fun sourceFileInfos(irFile: IrFile, allowNestedMultifileFacades: Boolean): List<SourceFileInfo> =
|
||||||
when (val fileEntry = irFile.fileEntry) {
|
when (val fileEntry = irFile.fileEntry) {
|
||||||
is PsiIrFileEntry -> {
|
is PsiIrFileEntry -> {
|
||||||
listOf(SourceFileInfo(fileEntry.psiFile, JvmFileClassUtil.getFileClassInfoNoResolve(fileEntry.psiFile as KtFile)))
|
listOf(
|
||||||
|
SourceFileInfo(
|
||||||
|
KtPsiSourceFile(fileEntry.psiFile),
|
||||||
|
JvmFileClassUtil.getFileClassInfoNoResolve(fileEntry.psiFile as KtFile)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
is NaiveSourceBasedFileEntryImpl -> {
|
is NaiveSourceBasedFileEntryImpl -> {
|
||||||
val file = File(fileEntry.name)
|
val sourceFile = inputArtifact.sourceFiles.find { it.path == fileEntry.name }
|
||||||
listOf(SourceFileInfo(file, getFileClassInfoFromIrFile(irFile, file.name)))
|
if (sourceFile == null) emptyList() // synthetic files, like CoroutineHelpers.kt, are ignored here
|
||||||
|
else listOf(SourceFileInfo(sourceFile, getFileClassInfoFromIrFile(irFile, sourceFile.name)))
|
||||||
}
|
}
|
||||||
is MultifileFacadeFileEntry -> {
|
is MultifileFacadeFileEntry -> {
|
||||||
if (!allowNestedMultifileFacades) error("nested multi-file facades are not allowed")
|
if (!allowNestedMultifileFacades) error("nested multi-file facades are not allowed")
|
||||||
|
|||||||
+2
-1
@@ -64,7 +64,8 @@ class ClassicFrontend2IrConverter(
|
|||||||
return IrBackendInput.JvmIrBackendInput(
|
return IrBackendInput.JvmIrBackendInput(
|
||||||
state,
|
state,
|
||||||
codegenFactory,
|
codegenFactory,
|
||||||
codegenFactory.convertToIr(CodegenFactory.IrConversionInput.fromGenerationStateAndFiles(state, psiFiles.values))
|
codegenFactory.convertToIr(CodegenFactory.IrConversionInput.fromGenerationStateAndFiles(state, psiFiles.values)),
|
||||||
|
emptyList()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -50,6 +50,7 @@ class Fir2IrResultsConverter(
|
|||||||
|
|
||||||
// TODO: handle fir from light tree
|
// TODO: handle fir from light tree
|
||||||
val ktFiles = inputArtifact.firFiles.values.mapNotNull { it.psi as KtFile? }
|
val ktFiles = inputArtifact.firFiles.values.mapNotNull { it.psi as KtFile? }
|
||||||
|
val sourceFiles = inputArtifact.firFiles.values.mapNotNull { it.sourceFile }
|
||||||
|
|
||||||
// Create and initialize the module and its dependencies
|
// Create and initialize the module and its dependencies
|
||||||
val project = compilerConfigurationProvider.getProject(module)
|
val project = compilerConfigurationProvider.getProject(module)
|
||||||
@@ -82,7 +83,8 @@ class Fir2IrResultsConverter(
|
|||||||
extensions,
|
extensions,
|
||||||
FirJvmBackendExtension(inputArtifact.session, components),
|
FirJvmBackendExtension(inputArtifact.session, components),
|
||||||
notifyCodegenStart = {},
|
notifyCodegenStart = {},
|
||||||
)
|
),
|
||||||
|
sourceFiles
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.VfsBasedProjectEnvironment
|
|||||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||||
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
|
import org.jetbrains.kotlin.fir.FirAnalyzerFacade
|
||||||
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
import org.jetbrains.kotlin.fir.moduleData
|
||||||
|
|||||||
+2
-2
@@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.test.frontend.fir
|
package org.jetbrains.kotlin.test.frontend.fir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.AbstractFirAnalyzerFacade
|
||||||
|
import org.jetbrains.kotlin.fir.FirAnalyzerFacade
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.analysis.AbstractFirAnalyzerFacade
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.test.model.FrontendKinds
|
import org.jetbrains.kotlin.test.model.FrontendKinds
|
||||||
import org.jetbrains.kotlin.test.model.ResultingArtifact
|
import org.jetbrains.kotlin.test.model.ResultingArtifact
|
||||||
|
|||||||
+4
-3
@@ -5,19 +5,20 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.test.model
|
package org.jetbrains.kotlin.test.model
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
import org.jetbrains.kotlin.codegen.ClassFileFactory
|
import org.jetbrains.kotlin.codegen.ClassFileFactory
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo
|
||||||
import org.jetbrains.kotlin.ir.backend.js.CompilerResult
|
import org.jetbrains.kotlin.ir.backend.js.CompilerResult
|
||||||
import org.jetbrains.kotlin.js.facade.TranslationResult
|
import org.jetbrains.kotlin.js.facade.TranslationResult
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class SourceFileInfo<F>(
|
class SourceFileInfo(
|
||||||
val file: F,
|
val sourceFile: KtSourceFile,
|
||||||
val info: JvmFileClassInfo
|
val info: JvmFileClassInfo
|
||||||
)
|
)
|
||||||
|
|
||||||
object BinaryArtifacts {
|
object BinaryArtifacts {
|
||||||
class Jvm(val classFileFactory: ClassFileFactory, val fileInfos: Collection<SourceFileInfo<*>>) : ResultingArtifact.Binary<Jvm>() {
|
class Jvm(val classFileFactory: ClassFileFactory, val fileInfos: Collection<SourceFileInfo>) : ResultingArtifact.Binary<Jvm>() {
|
||||||
override val kind: BinaryKind<Jvm>
|
override val kind: BinaryKind<Jvm>
|
||||||
get() = ArtifactKinds.Jvm
|
get() = ArtifactKinds.Jvm
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-5
@@ -6,6 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.test.services.sourceProviders
|
package org.jetbrains.kotlin.test.services.sourceProviders
|
||||||
|
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
|
import org.jetbrains.kotlin.KtPsiSourceFile
|
||||||
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.REQUIRES_SEPARATE_PROCESS
|
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.REQUIRES_SEPARATE_PROCESS
|
||||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JDK_KIND
|
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JDK_KIND
|
||||||
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
|
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
|
||||||
@@ -39,11 +41,12 @@ open class MainFunctionForBlackBoxTestsSourceProvider(testServices: TestServices
|
|||||||
return containsBoxMethod(file.originalContent)
|
return containsBoxMethod(file.originalContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> fileContainsBoxMethod(file: T): Boolean =
|
fun fileContainsBoxMethod(sourceFile: KtSourceFile): Boolean =
|
||||||
when (file) {
|
when (sourceFile) {
|
||||||
is PsiFile -> containsBoxMethod(file.text)
|
is KtPsiSourceFile -> containsBoxMethod(sourceFile.psiFile.text)
|
||||||
is File -> containsBoxMethod(file.readText())
|
else -> with(sourceFile.getContentsAsStream().reader(Charsets.UTF_8)) {
|
||||||
else -> error("Unknown file type: $file")
|
containsBoxMethod(this.readText())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun containsBoxMethod(fileContent: String): Boolean {
|
fun containsBoxMethod(fileContent: String): Boolean {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.codegen.inline.GENERATE_SMAP
|
|||||||
import org.jetbrains.kotlin.test.KotlinBaseTest
|
import org.jetbrains.kotlin.test.KotlinBaseTest
|
||||||
import org.jetbrains.kotlin.test.util.JUnit4Assertions
|
import org.jetbrains.kotlin.test.util.JUnit4Assertions
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
|
import java.io.File
|
||||||
import java.io.StringReader
|
import java.io.StringReader
|
||||||
|
|
||||||
object SMAPTestUtil {
|
object SMAPTestUtil {
|
||||||
@@ -62,7 +63,7 @@ object SMAPTestUtil {
|
|||||||
}.associateBy { it.sourceFile }
|
}.associateBy { it.sourceFile }
|
||||||
|
|
||||||
for (source in sourceData) {
|
for (source in sourceData) {
|
||||||
val ktFileName = "/" + source.sourceFile
|
val ktFileName = "/" + File(source.sourceFile).name
|
||||||
.replace(".smap-nonseparate-compilation", ".kt")
|
.replace(".smap-nonseparate-compilation", ".kt")
|
||||||
.replace(".smap-separate-compilation", ".kt")
|
.replace(".smap-separate-compilation", ".kt")
|
||||||
.replace(".smap", ".kt")
|
.replace(".smap", ".kt")
|
||||||
|
|||||||
+8
-1
@@ -11,6 +11,7 @@ import com.intellij.openapi.vfs.VirtualFileManager
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiElementFinder
|
import com.intellij.psi.PsiElementFinder
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.KtInMemoryTextSourceFile
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||||
import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest
|
import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest
|
||||||
@@ -46,6 +47,7 @@ import org.jetbrains.kotlin.psi.KtFile
|
|||||||
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||||
|
import org.jetbrains.kotlin.toSourceLinesMapping
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() {
|
abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() {
|
||||||
@@ -133,7 +135,12 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() {
|
|||||||
if (useLightTree) {
|
if (useLightTree) {
|
||||||
val lightTreeBuilder = LightTree2Fir(session, firProvider.kotlinScopeProvider)
|
val lightTreeBuilder = LightTree2Fir(session, firProvider.kotlinScopeProvider)
|
||||||
ktFiles.mapTo(firFiles) {
|
ktFiles.mapTo(firFiles) {
|
||||||
val firFile = lightTreeBuilder.buildFirFile(it.text, it.name, it.virtualFilePath)
|
val firFile =
|
||||||
|
lightTreeBuilder.buildFirFile(
|
||||||
|
it.text,
|
||||||
|
KtInMemoryTextSourceFile(it.name, it.virtualFilePath, it.text),
|
||||||
|
it.text.toSourceLinesMapping()
|
||||||
|
)
|
||||||
(session.firProvider as FirProviderImpl).recordFile(firFile)
|
(session.firProvider as FirProviderImpl).recordFile(firFile)
|
||||||
firFile
|
firFile
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.intellij.openapi.util.io.FileUtil
|
|||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.openapi.vfs.CharsetToolkit
|
import com.intellij.openapi.vfs.CharsetToolkit
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.KtIoFileSourceFile
|
||||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic
|
||||||
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.fir.types.*
|
|||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
|
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
import org.jetbrains.kotlin.readSourceFileWithMapping
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.sumByLong
|
import org.jetbrains.kotlin.utils.addToStdlib.sumByLong
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
@@ -139,16 +141,18 @@ class FirResolveBench(val withProgress: Boolean, val listener: BenchListener? =
|
|||||||
return files.map { file ->
|
return files.map { file ->
|
||||||
val before = vmStateSnapshot()
|
val before = vmStateSnapshot()
|
||||||
val firFile: FirFile
|
val firFile: FirFile
|
||||||
val code: String
|
|
||||||
val time = measureNanoTime {
|
val time = measureNanoTime {
|
||||||
code = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim()
|
val sourceFile = KtIoFileSourceFile(file)
|
||||||
firFile = builder.buildFirFile(code, file.name, file.path)
|
val (code, linesMapping) = with(file.inputStream().reader(Charsets.UTF_8)) {
|
||||||
|
this.readSourceFileWithMapping()
|
||||||
|
}
|
||||||
|
totalLines += linesMapping.linesCount
|
||||||
|
firFile = builder.buildFirFile(code, sourceFile, linesMapping)
|
||||||
(builder.session.firProvider as FirProviderImpl).recordFile(firFile)
|
(builder.session.firProvider as FirProviderImpl).recordFile(firFile)
|
||||||
}
|
}
|
||||||
val after = vmStateSnapshot()
|
val after = vmStateSnapshot()
|
||||||
val diff = after - before
|
val diff = after - before
|
||||||
recordTime(builder::class, diff, time)
|
recordTime(builder::class, diff, time)
|
||||||
totalLines += StringUtil.countNewLines(code)
|
|
||||||
firFile
|
firFile
|
||||||
}.also {
|
}.also {
|
||||||
listener?.after(builder::class)
|
listener?.after(builder::class)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
|||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
|
import org.jetbrains.kotlin.fir.FirAnalyzerFacade
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
|
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
|
||||||
import org.jetbrains.kotlin.fir.createSessionForTests
|
import org.jetbrains.kotlin.fir.createSessionForTests
|
||||||
|
|||||||
+5
-7
@@ -1,17 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.fir.analysis
|
package org.jetbrains.kotlin.fir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||||
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.collectors.FirDiagnosticsCollector
|
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
||||||
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.collectors.FirDiagnosticsCollector
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
|
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
|
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.Fir2IrJvmSpecialAnnotationSymbolProvider
|
import org.jetbrains.kotlin.fir.backend.jvm.Fir2IrJvmSpecialAnnotationSymbolProvider
|
||||||
@@ -21,8 +20,6 @@ import org.jetbrains.kotlin.fir.builder.PsiHandlingMode
|
|||||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
|
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
|
||||||
import org.jetbrains.kotlin.fir.lightTree.LightTreeFile
|
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
||||||
@@ -31,6 +28,7 @@ import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmDescriptorMangler
|
|||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
|
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
|
||||||
|
import org.jetbrains.kotlin.sourceFiles.LightTreeFile
|
||||||
|
|
||||||
abstract class AbstractFirAnalyzerFacade {
|
abstract class AbstractFirAnalyzerFacade {
|
||||||
abstract val scopeSession: ScopeSession
|
abstract val scopeSession: ScopeSession
|
||||||
@@ -63,7 +61,7 @@ class FirAnalyzerFacade(
|
|||||||
firFiles = if (useLightTree) {
|
firFiles = if (useLightTree) {
|
||||||
val builder = LightTree2Fir(session, firProvider.kotlinScopeProvider)
|
val builder = LightTree2Fir(session, firProvider.kotlinScopeProvider)
|
||||||
lightTreeFiles.map {
|
lightTreeFiles.map {
|
||||||
builder.buildFirFile(it).also { firFile ->
|
builder.buildFirFile(it.lightTree, it.sourceFile, it.linesMapping).also { firFile ->
|
||||||
firProvider.recordFile(firFile)
|
firProvider.recordFile(firFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user