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:
Ilya Chernikov
2022-02-19 21:07:21 +01:00
committed by teamcity
parent bd60d4b2a6
commit 03cbfea737
45 changed files with 539 additions and 239 deletions
@@ -18,14 +18,9 @@ package org.jetbrains.kotlin.backend.common
import org.jetbrains.kotlin.AbstractKtSourceElement
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.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.util.render
fun CommonBackendContext.reportWarning(message: String, irFile: IrFile?, irElement: IrElement) {
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 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? =
if (startOffset != UNDEFINED_OFFSET) KtOffsetsOnlySourceElement(this.startOffset, this.endOffset)
else null
@@ -285,7 +285,7 @@ fun IrFile.getKtFile(): KtFile? =
fun IrFile.getIoFile(): File? =
when (val fe = fileEntry) {
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 {
@@ -186,7 +186,8 @@ val IrFileEntry.lineStartOffsets: IntArray
class NaiveSourceBasedFileEntryImpl(
override val name: String,
private val lineStartOffsets: IntArray = intArrayOf()
private val lineStartOffsets: IntArray = intArrayOf(),
override val maxOffset: Int = UNDEFINED_OFFSET
) : IrFileEntry {
val lineStartOffsetsAreEmpty: Boolean
get() = lineStartOffsets.isEmpty()
@@ -215,15 +216,19 @@ class NaiveSourceBasedFileEntryImpl(
if (offset == SYNTHETIC_OFFSET) return 0
if (offset < 0) return -1
val lineNumber = getLineNumber(offset)
return offset - lineStartOffsets[lineNumber]
return if (lineNumber < 0) -1 else offset - lineStartOffsets[lineNumber]
}
override val maxOffset: Int
get() = UNDEFINED_OFFSET
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo {
return SourceRangeInfo(name, beginOffset, -1, -1, endOffset, -1, -1)
}
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo =
SourceRangeInfo(
filePath = name,
startOffset = beginOffset,
startLineNumber = getLineNumber(beginOffset),
startColumnNumber = getColumnNumber(beginOffset),
endOffset = endOffset,
endLineNumber = getLineNumber(endOffset),
endColumnNumber = getColumnNumber(endOffset)
)
}
private fun IrClass.getPropertyDeclaration(name: String): IrProperty? {