Add path to FirFile to pass it to the DiagnosticContext

This commit is contained in:
Ilya Chernikov
2021-09-29 17:58:07 +02:00
parent 1e056a7aa8
commit 5446168770
15 changed files with 31 additions and 14 deletions
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.languageVersionSettings
@@ -84,6 +85,9 @@ abstract class CheckerContext : MutableDiagnosticContext() {
override val languageVersionSettings: LanguageVersionSettings override val languageVersionSettings: LanguageVersionSettings
get() = session.languageVersionSettings get() = session.languageVersionSettings
override val containingFilePath: String?
get() = containingDeclarations.firstOrNull()?.let { (it as? FirFile)?.path }
} }
/** /**
@@ -47,7 +47,7 @@ class LightTree2Fir(
fun buildFirFile(file: File): FirFile { fun buildFirFile(file: File): FirFile {
val code = FileUtil.loadFile(file, CharsetToolkit.UTF8, true) val code = FileUtil.loadFile(file, CharsetToolkit.UTF8, true)
return buildFirFile(code, file.name) return buildFirFile(code, file.name, file.path)
} }
fun buildLightTree(code: String): FlyweightCapableTreeStructure<LighterASTNode> { fun buildLightTree(code: String): FlyweightCapableTreeStructure<LighterASTNode> {
@@ -56,10 +56,10 @@ class LightTree2Fir(
return builder.lightTree return builder.lightTree
} }
fun buildFirFile(code: String, fileName: String): FirFile { fun buildFirFile(code: String, fileName: String, path: String?): FirFile {
val lightTree = buildLightTree(code) val lightTree = buildLightTree(code)
return DeclarationsConverter(session, scopeProvider, lightTree) return DeclarationsConverter(session, scopeProvider, lightTree)
.convertFile(lightTree.root, fileName) .convertFile(lightTree.root, fileName, path)
} }
} }
@@ -84,7 +84,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 = ""): FirFile { fun convertFile(file: LighterASTNode, fileName: String = "", filePath: String?): FirFile {
if (file.tokenType != KT_FILE) { if (file.tokenType != KT_FILE) {
//TODO throw error //TODO throw error
throw Exception() throw Exception()
@@ -118,6 +118,7 @@ class DeclarationsConverter(
origin = FirDeclarationOrigin.Source origin = FirDeclarationOrigin.Source
moduleData = baseModuleData moduleData = baseModuleData
name = fileName name = fileName
path = filePath
this.packageDirective = packageDirective ?: buildPackageDirective { packageFqName = context.packageFqName } this.packageDirective = packageDirective ?: buildPackageDirective { packageFqName = context.packageFqName }
annotations += fileAnnotationList annotations += fileAnnotationList
imports += importList imports += importList
@@ -12,7 +12,6 @@ import com.intellij.testFramework.TestDataPath
import com.intellij.util.PathUtil import com.intellij.util.PathUtil
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.BodyBuildingMode
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
@@ -34,12 +33,12 @@ class TotalKotlinTest : AbstractRawFirBuilderTestCase() {
} }
} }
private fun generateFirFromLightTree(onlyLightTree: Boolean, converter: LightTree2Fir, text: String, fileName: String) { private fun generateFirFromLightTree(onlyLightTree: Boolean, converter: LightTree2Fir, text: String, fileName: String, filePath: String) {
if (onlyLightTree) { if (onlyLightTree) {
val lightTree = converter.buildLightTree(text) val lightTree = converter.buildLightTree(text)
DebugUtil.lightTreeToString(lightTree, false) DebugUtil.lightTreeToString(lightTree, false)
} else { } else {
val firFile = converter.buildFirFile(text, fileName) val firFile = converter.buildFirFile(text, fileName, filePath)
StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString() StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
} }
} }
@@ -59,7 +58,7 @@ class TotalKotlinTest : AbstractRawFirBuilderTestCase() {
path.walkTopDown { path.walkTopDown {
val text = FileUtil.loadFile(it, CharsetToolkit.UTF8, true).trim() val text = FileUtil.loadFile(it, CharsetToolkit.UTF8, true).trim()
time += measureNanoTime { time += measureNanoTime {
generateFirFromLightTree(onlyLightTree, lightTreeConverter, text, it.name) generateFirFromLightTree(onlyLightTree, lightTreeConverter, text, it.name, it.path)
} }
counter++ counter++
@@ -31,7 +31,7 @@ open class LightTree2FirGenerator : TreeGenerator, AbstractRawFirBuilderTestCase
session = FirSessionFactory.createEmptySession(), session = FirSessionFactory.createEmptySession(),
scopeProvider = StubFirScopeProvider scopeProvider = StubFirScopeProvider
) )
val firFile = lightTreeConverter.buildFirFile(text, file.name) val firFile = lightTreeConverter.buildFirFile(text, file.name, file.path)
StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString() StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
} }
@@ -68,7 +68,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
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) val firFileFromLightTree = lightTreeConverter.buildFirFile(text, file.name, file.path)
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
@@ -98,7 +98,7 @@ 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) val firFileFromLightTree = lightTreeConverter.buildFirFile(text, file.name, file.path)
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>")
@@ -907,6 +907,7 @@ open class RawFirBuilder(
moduleData = baseModuleData moduleData = baseModuleData
origin = FirDeclarationOrigin.Source origin = FirDeclarationOrigin.Source
name = file.name name = file.name
path = file.virtualFile?.path
packageDirective = buildPackageDirective { packageDirective = buildPackageDirective {
packageFqName = context.packageFqName packageFqName = context.packageFqName
source = file.packageDirective?.toKtPsiSourceElement() source = file.packageDirective?.toKtPsiSourceElement()
@@ -29,6 +29,7 @@ abstract class FirFile : FirAnnotatedDeclaration() {
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 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)
@@ -39,6 +39,7 @@ 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
override fun build(): FirFile { override fun build(): FirFile {
return FirFileImpl( return FirFileImpl(
@@ -52,6 +53,7 @@ class FirFileBuilder : FirAnnotationContainerBuilder {
imports, imports,
declarations, declarations,
name, name,
path,
) )
} }
@@ -35,6 +35,7 @@ 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?,
) : FirFile() { ) : FirFile() {
override val symbol: FirFileSymbol = FirFileSymbol() override val symbol: FirFileSymbol = FirFileSymbol()
@@ -415,6 +415,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
+fieldList(import).withTransform() +fieldList(import).withTransform()
+declarations.withTransform() +declarations.withTransform()
+stringField("name") +stringField("name")
+stringField("path", nullable = true)
+symbol("FirFileSymbol") +symbol("FirFileSymbol")
} }
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.diagnostics
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
interface DiagnosticContext { interface DiagnosticContext {
val containingFilePath: String?
fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean
val languageVersionSettings: LanguageVersionSettings val languageVersionSettings: LanguageVersionSettings
@@ -11,6 +11,8 @@ import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrDeclaration 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.declarations.name
import org.jetbrains.kotlin.ir.declarations.path
import org.jetbrains.kotlin.ir.util.file import org.jetbrains.kotlin.ir.util.file
class KtDiagnosticReporterWithImplicitIrBasedContext( class KtDiagnosticReporterWithImplicitIrBasedContext(
@@ -36,12 +38,15 @@ class KtDiagnosticReporterWithImplicitIrBasedContext(
val sourceElement = irElement.sourceElement() val sourceElement = irElement.sourceElement()
override fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean { override fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean {
TODO("Not yet implemented") return false
// TODO("Not yet implemented")
} }
override val languageVersionSettings: LanguageVersionSettings override val languageVersionSettings: LanguageVersionSettings
get() = this@KtDiagnosticReporterWithImplicitIrBasedContext.languageVersionSettings get() = this@KtDiagnosticReporterWithImplicitIrBasedContext.languageVersionSettings
override val containingFilePath: String = containingIrFile.path
@OptIn(InternalDiagnosticFactoryMethod::class) @OptIn(InternalDiagnosticFactoryMethod::class)
fun report( fun report(
factory: KtDiagnosticFactory0, factory: KtDiagnosticFactory0,
@@ -131,7 +131,7 @@ 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) val firFile = lightTreeBuilder.buildFirFile(it.text, it.name, it.virtualFilePath)
(session.firProvider as FirProviderImpl).recordFile(firFile) (session.firProvider as FirProviderImpl).recordFile(firFile)
firFile firFile
} }
@@ -142,7 +142,7 @@ class FirResolveBench(val withProgress: Boolean, val listener: BenchListener? =
val code: String val code: String
val time = measureNanoTime { val time = measureNanoTime {
code = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim() code = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim()
firFile = builder.buildFirFile(code, file.name) firFile = builder.buildFirFile(code, file.name, file.path)
(builder.session.firProvider as FirProviderImpl).recordFile(firFile) (builder.session.firProvider as FirProviderImpl).recordFile(firFile)
} }
val after = vmStateSnapshot() val after = vmStateSnapshot()