FIR LT: add syntax error reporting to LT2Fir

use it in the new pipeline
This commit is contained in:
Ilya Chernikov
2021-12-29 22:08:21 +01:00
committed by teamcity
parent 2689ebf455
commit 9e32188938
21 changed files with 98 additions and 40 deletions
@@ -69,6 +69,7 @@ object FirDiagnosticToKtDiagnosticConverterRenderer : AbstractDiagnosticsDataCla
override val defaultImports = listOf( override val defaultImports = listOf(
"org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic", "org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic",
"org.jetbrains.kotlin.fir.builder.FirSyntaxErrors",
"org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors", "org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors",
"org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors", "org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors",
) )
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.KtPsiSourceElement
import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
import org.jetbrains.kotlin.fir.builder.FirSyntaxErrors
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
@@ -93,12 +94,6 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token, token,
) )
} }
add(FirErrors.SYNTAX) { firDiagnostic ->
SyntaxImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.OTHER_ERROR) { firDiagnostic -> add(FirErrors.OTHER_ERROR) { firDiagnostic ->
OtherErrorImpl( OtherErrorImpl(
firDiagnostic as KtPsiDiagnostic, firDiagnostic as KtPsiDiagnostic,
@@ -102,10 +102,6 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val error: String abstract val error: String
} }
abstract class Syntax : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = Syntax::class
}
abstract class OtherError : KtFirDiagnostic<PsiElement>() { abstract class OtherError : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = OtherError::class override val diagnosticClass get() = OtherError::class
} }
@@ -105,11 +105,6 @@ internal class NewInferenceErrorImpl(
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.NewInferenceError(), KtAbstractFirDiagnostic<PsiElement> ) : KtFirDiagnostic.NewInferenceError(), KtAbstractFirDiagnostic<PsiElement>
internal class SyntaxImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.Syntax(), KtAbstractFirDiagnostic<PsiElement>
internal class OtherErrorImpl( internal class OtherErrorImpl(
override val firDiagnostic: KtPsiDiagnostic, override val firDiagnostic: KtPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.codegen.ClassBuilderFactories
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
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.DependencyListForCliModule import org.jetbrains.kotlin.fir.DependencyListForCliModule
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
@@ -123,6 +124,7 @@ fun compileModulesUsingFrontendIrAndLightTree(
compilerEnvironment, compilerEnvironment,
emptyList(), emptyList(),
null, null,
diagnosticsReporter
) )
// TODO: consider what to do if many modules has main classes // TODO: consider what to do if many modules has main classes
if (mainClassFqName == null && moduleConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) { if (mainClassFqName == null && moduleConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) {
@@ -224,6 +226,7 @@ fun compileModuleToAnalyzedFir(
environment: ModuleCompilerEnvironment, environment: ModuleCompilerEnvironment,
previousStepsSymbolProviders: List<FirSymbolProvider>, previousStepsSymbolProviders: List<FirSymbolProvider>,
incrementalExcludesScope: AbstractProjectFileSearchScope?, incrementalExcludesScope: AbstractProjectFileSearchScope?,
diagnosticsReporter: DiagnosticReporter
): ModuleCompilerAnalyzedOutput { ): ModuleCompilerAnalyzedOutput {
var sourcesScope = environment.projectEnvironment.getSearchScopeByIoFiles(input.platformSources) //!! var sourcesScope = environment.projectEnvironment.getSearchScopeByIoFiles(input.platformSources) //!!
val sessionProvider = FirProjectSessionProvider() val sessionProvider = FirProjectSessionProvider()
@@ -270,8 +273,8 @@ fun compileModuleToAnalyzedFir(
} }
// raw fir // raw fir
val commonRawFir = commonSession?.buildFirViaLightTree(input.commonSources) val commonRawFir = commonSession?.buildFirViaLightTree(input.commonSources, diagnosticsReporter)
val rawFir = session.buildFirViaLightTree(input.platformSources) val rawFir = session.buildFirViaLightTree(input.platformSources, diagnosticsReporter)
// resolution // resolution
commonSession?.apply { commonSession?.apply {
+1
View File
@@ -8,6 +8,7 @@ plugins {
dependencies { dependencies {
api(project(":compiler:fir:providers")) api(project(":compiler:fir:providers"))
api(project(":compiler:fir:semantics")) api(project(":compiler:fir:semantics"))
api(project(":compiler:fir:raw-fir:raw-fir.common"))
implementation(project(":compiler:frontend.common")) implementation(project(":compiler:frontend.common"))
implementation(project(":compiler:frontend.common-psi")) implementation(project(":compiler:frontend.common-psi"))
implementation(project(":compiler:psi")) implementation(project(":compiler:psi"))
@@ -52,7 +52,6 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
} }
val Miscellaneous by object : DiagnosticGroup("Miscellaneous") { val Miscellaneous by object : DiagnosticGroup("Miscellaneous") {
val SYNTAX by error<PsiElement>()
val OTHER_ERROR by error<PsiElement>() val OTHER_ERROR by error<PsiElement>()
} }
@@ -111,7 +111,6 @@ object FirErrors {
val NEW_INFERENCE_ERROR by error1<PsiElement, String>() val NEW_INFERENCE_ERROR by error1<PsiElement, String>()
// Miscellaneous // Miscellaneous
val SYNTAX by error0<PsiElement>()
val OTHER_ERROR by error0<PsiElement>() val OTHER_ERROR by error0<PsiElement>()
// General syntax // General syntax
@@ -473,7 +473,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_NOT_INI
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_CALL_FROM_PUBLIC_INLINE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_CALL_FROM_PUBLIC_INLINE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_IS_NOT_AN_EXPRESSION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_IS_NOT_AN_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_NOT_AVAILABLE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_NOT_AVAILABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SYNTAX
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TAILREC_ON_VIRTUAL_MEMBER_ERROR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TAILREC_ON_VIRTUAL_MEMBER_ERROR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TAIL_RECURSION_IN_TRY_IS_NOT_SUPPORTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.THROWABLE_TYPE_MISMATCH import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.THROWABLE_TYPE_MISMATCH
@@ -586,7 +585,6 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
map.put(NEW_INFERENCE_ERROR, "New inference error [{0}]", STRING) map.put(NEW_INFERENCE_ERROR, "New inference error [{0}]", STRING)
// Miscellaneous // Miscellaneous
map.put(SYNTAX, "Syntax error")
map.put(OTHER_ERROR, "Unknown (other) error") map.put(OTHER_ERROR, "Unknown (other) error")
// General syntax // General syntax
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isLocalMember import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isLocalMember
import org.jetbrains.kotlin.fir.analysis.getChild import org.jetbrains.kotlin.fir.analysis.getChild
import org.jetbrains.kotlin.fir.builder.FirSyntaxErrors
import org.jetbrains.kotlin.fir.declarations.utils.isInfix import org.jetbrains.kotlin.fir.declarations.utils.isInfix
import org.jetbrains.kotlin.fir.declarations.utils.isOperator import org.jetbrains.kotlin.fir.declarations.utils.isOperator
import org.jetbrains.kotlin.fir.diagnostics.* import org.jetbrains.kotlin.fir.diagnostics.*
@@ -386,7 +387,7 @@ private val NewConstraintError.upperConeType: ConeKotlinType get() = upperType a
private fun ConeSimpleDiagnostic.getFactory(source: KtSourceElement): KtDiagnosticFactory0 { private fun ConeSimpleDiagnostic.getFactory(source: KtSourceElement): KtDiagnosticFactory0 {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return when (kind) { return when (kind) {
DiagnosticKind.Syntax -> FirErrors.SYNTAX DiagnosticKind.Syntax -> FirSyntaxErrors.SYNTAX
DiagnosticKind.ReturnNotAllowed -> FirErrors.RETURN_NOT_ALLOWED DiagnosticKind.ReturnNotAllowed -> FirErrors.RETURN_NOT_ALLOWED
DiagnosticKind.NotAFunctionLabel -> FirErrors.NOT_A_FUNCTION_LABEL DiagnosticKind.NotAFunctionLabel -> FirErrors.NOT_A_FUNCTION_LABEL
DiagnosticKind.UnresolvedLabel -> FirErrors.UNRESOLVED_LABEL DiagnosticKind.UnresolvedLabel -> FirErrors.UNRESOLVED_LABEL
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.pipeline package org.jetbrains.kotlin.fir.pipeline
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
import org.jetbrains.kotlin.fir.builder.RawFirBuilder import org.jetbrains.kotlin.fir.builder.RawFirBuilder
@@ -16,10 +17,10 @@ import org.jetbrains.kotlin.fir.session.sourcesToPathsMapper
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import java.io.File import java.io.File
fun FirSession.buildFirViaLightTree(files: Collection<File>): List<FirFile> { fun FirSession.buildFirViaLightTree(files: Collection<File>, diagnosticsReporter: DiagnosticReporter? = null): List<FirFile> {
val firProvider = (firProvider as FirProviderImpl) val firProvider = (firProvider as FirProviderImpl)
val sourcesToPathsMapper = sourcesToPathsMapper val sourcesToPathsMapper = sourcesToPathsMapper
val builder = LightTree2Fir(this, firProvider.kotlinScopeProvider) val builder = LightTree2Fir(this, firProvider.kotlinScopeProvider, diagnosticsReporter)
return files.map { return files.map {
builder.buildFirFile(it).also { firFile -> builder.buildFirFile(it).also { firFile ->
firProvider.recordFile(firFile) firProvider.recordFile(firFile)
@@ -17,9 +17,9 @@ import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.cli.common.toBooleanLenient import org.jetbrains.kotlin.cli.common.toBooleanLenient
import org.jetbrains.kotlin.cli.jvm.compiler.* import org.jetbrains.kotlin.cli.jvm.compiler.*
import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
import org.jetbrains.kotlin.fir.analysis.collectors.FirDiagnosticsCollector import org.jetbrains.kotlin.fir.analysis.collectors.FirDiagnosticsCollector
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.builder.PsiHandlingMode 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
@@ -149,7 +149,7 @@ class FirResolveModularizedTotalKotlinTest : AbstractModularizedTest() {
val firProvider = session.firProvider as FirProviderImpl val firProvider = session.firProvider as FirProviderImpl
val firFiles = if (USE_LIGHT_TREE) { val firFiles = if (USE_LIGHT_TREE) {
val lightTree2Fir = LightTree2Fir(session, firProvider.kotlinScopeProvider) val lightTree2Fir = LightTree2Fir(session, firProvider.kotlinScopeProvider, diagnosticsReporter = null)
val allSourceFiles = moduleData.sources.flatMap { val allSourceFiles = moduleData.sources.flatMap {
if (it.isDirectory) { if (it.isDirectory) {
@@ -10,8 +10,13 @@ import com.intellij.lang.impl.PsiBuilderFactoryImpl
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.openapi.vfs.CharsetToolkit
import com.intellij.util.diff.FlyweightCapableTreeStructure import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.diagnostics.DiagnosticContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.lightTree.converter.DeclarationsConverter import org.jetbrains.kotlin.fir.lightTree.converter.DeclarationsConverter
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.lexer.KotlinLexer import org.jetbrains.kotlin.lexer.KotlinLexer
@@ -22,7 +27,8 @@ import java.nio.file.Path
class LightTree2Fir( class LightTree2Fir(
val session: FirSession, val session: FirSession,
private val scopeProvider: FirScopeProvider private val scopeProvider: FirScopeProvider,
private val diagnosticsReporter: DiagnosticReporter? = null
) { ) {
companion object { companion object {
private val parserDefinition = KotlinParserDefinition() private val parserDefinition = KotlinParserDefinition()
@@ -66,9 +72,18 @@ class LightTree2Fir(
fun buildFirFile(code: String, fileName: String, path: 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(
.convertFile(lightTree.root, fileName, path) session, scopeProvider, lightTree, diagnosticsReporter = diagnosticsReporter,
diagnosticContext = makeDiagnosticContext(path)
).convertFile(lightTree.root, fileName, path)
} }
private fun makeDiagnosticContext(path: String?) =
if (diagnosticsReporter == null) null else object : DiagnosticContext {
override val containingFilePath = path
override val languageVersionSettings: LanguageVersionSettings get() = session.languageVersionSettings
override fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean = false
}
} }
data class LightTreeFile( data class LightTreeFile(
@@ -10,9 +10,8 @@ import com.intellij.openapi.util.Ref
import com.intellij.psi.TokenType import com.intellij.psi.TokenType
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 org.jetbrains.kotlin.ElementTypeUtils.isExpression
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.* import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.ElementTypeUtils.isExpression
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.builder.BaseFirBuilder import org.jetbrains.kotlin.fir.builder.BaseFirBuilder
import org.jetbrains.kotlin.fir.builder.Context import org.jetbrains.kotlin.fir.builder.Context
@@ -32,6 +31,8 @@ abstract class BaseConverter(
protected val implicitType = buildImplicitTypeRef() protected val implicitType = buildImplicitTypeRef()
protected open fun reportSyntaxError(node: LighterASTNode) {}
override fun LighterASTNode.toFirSourceElement(kind: KtFakeSourceElementKind?): KtLightSourceElement { override fun LighterASTNode.toFirSourceElement(kind: KtFakeSourceElementKind?): KtLightSourceElement {
val startOffset = offset + tree.getStartOffset(this) val startOffset = offset + tree.getStartOffset(this)
val endOffset = offset + tree.getEndOffset(this) val endOffset = offset + tree.getEndOffset(this)
@@ -183,6 +184,10 @@ abstract class BaseConverter(
if (kid == null) break if (kid == null) break
val tokenType = kid.tokenType val tokenType = kid.tokenType
if (COMMENTS.contains(tokenType) || tokenType == WHITE_SPACE || tokenType == SEMICOLON || tokenType in skipTokens) continue if (COMMENTS.contains(tokenType) || tokenType == WHITE_SPACE || tokenType == SEMICOLON || tokenType in skipTokens) continue
if (tokenType == TokenType.ERROR_ELEMENT) {
reportSyntaxError(kid)
continue
}
f(kid) f(kid)
} }
} }
@@ -195,6 +200,10 @@ abstract class BaseConverter(
if (kid == null) break if (kid == null) break
val tokenType = kid.tokenType val tokenType = kid.tokenType
if (COMMENTS.contains(tokenType) || tokenType == WHITE_SPACE || tokenType == SEMICOLON) continue if (COMMENTS.contains(tokenType) || tokenType == WHITE_SPACE || tokenType == SEMICOLON) continue
if (tokenType == TokenType.ERROR_ELEMENT) {
reportSyntaxError(kid)
continue
}
f(kid, container) f(kid, container)
} }
@@ -19,6 +19,9 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
import org.jetbrains.kotlin.diagnostics.DiagnosticContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.builder.* import org.jetbrains.kotlin.fir.builder.*
import org.jetbrains.kotlin.fir.contracts.FirContractDescription import org.jetbrains.kotlin.fir.contracts.FirContractDescription
@@ -59,7 +62,9 @@ class DeclarationsConverter(
private val baseScopeProvider: FirScopeProvider, private val baseScopeProvider: FirScopeProvider,
tree: FlyweightCapableTreeStructure<LighterASTNode>, tree: FlyweightCapableTreeStructure<LighterASTNode>,
@set:PrivateForInline override var offset: Int = 0, @set:PrivateForInline override var offset: Int = 0,
context: Context<LighterASTNode> = Context() context: Context<LighterASTNode> = Context(),
private val diagnosticsReporter: DiagnosticReporter? = null,
private val diagnosticContext: DiagnosticContext? = null
) : BaseConverter(session, tree, context) { ) : BaseConverter(session, tree, context) {
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
@@ -75,6 +80,10 @@ class DeclarationsConverter(
private val expressionConverter = ExpressionsConverter(session, tree, this, context) private val expressionConverter = ExpressionsConverter(session, tree, this, context)
override fun reportSyntaxError(node: LighterASTNode) {
diagnosticsReporter?.reportOn(node.toFirSourceElement(), FirSyntaxErrors.SYNTAX, diagnosticContext!!)
}
/** /**
* [org.jetbrains.kotlin.parsing.KotlinParsing.parseFile] * [org.jetbrains.kotlin.parsing.KotlinParsing.parseFile]
* [org.jetbrains.kotlin.parsing.KotlinParsing.parsePreamble] * [org.jetbrains.kotlin.parsing.KotlinParsing.parsePreamble]
@@ -1694,7 +1703,8 @@ class DeclarationsConverter(
val blockTree = LightTree2Fir.buildLightTreeBlockExpression(block.asText) val blockTree = LightTree2Fir.buildLightTreeBlockExpression(block.asText)
return DeclarationsConverter( return DeclarationsConverter(
baseSession, baseScopeProvider, blockTree, offset = offset + tree.getStartOffset(block), context baseSession, baseScopeProvider, blockTree, offset = offset + tree.getStartOffset(block), context,
diagnosticsReporter, diagnosticContext
).convertBlockExpression(blockTree.root) ).convertBlockExpression(blockTree.root)
} }
@@ -20,7 +20,8 @@ abstract class AbstractLightTree2FirConverterTestCase : AbstractRawFirBuilderTes
fun doTest(filePath: String) { fun doTest(filePath: String) {
val firFile = LightTree2Fir( val firFile = LightTree2Fir(
session = FirSessionFactory.createEmptySession(), session = FirSessionFactory.createEmptySession(),
scopeProvider = StubFirScopeProvider scopeProvider = StubFirScopeProvider,
diagnosticsReporter = null
).buildFirFile(Paths.get(filePath)) ).buildFirFile(Paths.get(filePath))
val firDump = firFile.render(mode = FirRenderer.RenderMode.WithDeclarationAttributes) val firDump = firFile.render(mode = FirRenderer.RenderMode.WithDeclarationAttributes)
@@ -50,7 +50,8 @@ class TotalKotlinTest : AbstractRawFirBuilderTestCase() {
val lightTreeConverter = LightTree2Fir( val lightTreeConverter = LightTree2Fir(
session = FirSessionFactory.createEmptySession(), session = FirSessionFactory.createEmptySession(),
scopeProvider = StubFirScopeProvider scopeProvider = StubFirScopeProvider,
diagnosticsReporter = null
) )
if (onlyLightTree) println("LightTree generation") else println("Fir from LightTree converter") if (onlyLightTree) println("LightTree generation") else println("Fir from LightTree converter")
@@ -57,7 +57,8 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
private fun compareAll() { private fun compareAll() {
val lightTreeConverter = LightTree2Fir( val lightTreeConverter = LightTree2Fir(
session = FirSessionFactory.createEmptySession(), session = FirSessionFactory.createEmptySession(),
scopeProvider = StubFirScopeProvider scopeProvider = StubFirScopeProvider,
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 = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim()
@@ -78,7 +79,8 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
fun testCompareDiagnostics() { fun testCompareDiagnostics() {
val lightTreeConverter = LightTree2Fir( val lightTreeConverter = LightTree2Fir(
session = FirSessionFactory.createEmptySession(), session = FirSessionFactory.createEmptySession(),
scopeProvider = StubFirScopeProvider scopeProvider = StubFirScopeProvider,
diagnosticsReporter = null
) )
compareBase("compiler/testData/diagnostics/tests", withTestData = true) { file -> compareBase("compiler/testData/diagnostics/tests", withTestData = true) { file ->
if (file.name.endsWith(".fir.kt")) { if (file.name.endsWith(".fir.kt")) {
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2021 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.fir.builder
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
import org.jetbrains.kotlin.diagnostics.error0
import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
object FirSyntaxErrors {
val SYNTAX by error0<PsiElement>()
init {
RootDiagnosticRendererFactory.registerFactory(FirSyntaxErrorsDefaultMessages)
}
}
@Suppress("unused")
object FirSyntaxErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
override val MAP = KtDiagnosticFactoryToRendererMap("FIR").also { map ->
map.put(FirSyntaxErrors.SYNTAX, "Syntax error")
}
}
@@ -211,6 +211,7 @@ class IncrementalFirJvmCompilerRunner(
compilerEnvironment, compilerEnvironment,
emptyList(), emptyList(),
incrementalExcludesScope, incrementalExcludesScope,
diagnosticsReporter
) )
// TODO: consider what to do if many compilations find a main class // TODO: consider what to do if many compilations find a main class
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.diagnostics.rendering.Renderers import org.jetbrains.kotlin.diagnostics.rendering.Renderers
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.builder.FirSyntaxErrors
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirProperty
@@ -90,7 +91,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
) )
) return@flatMap emptyList() ) return@flatMap emptyList()
// SYNTAX errors will be reported later // SYNTAX errors will be reported later
if (diagnostic.factory == FirErrors.SYNTAX) return@flatMap emptyList() if (diagnostic.factory == FirSyntaxErrors.SYNTAX) return@flatMap emptyList()
if (!diagnostic.isValid) return@flatMap emptyList() if (!diagnostic.isValid) return@flatMap emptyList()
diagnostic.toMetaInfos( diagnostic.toMetaInfos(
file, file,
@@ -114,7 +115,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
) { ) {
val metaInfos = if (firFile.psi != null) { val metaInfos = if (firFile.psi != null) {
AnalyzingUtils.getSyntaxErrorRanges(firFile.psi!!).flatMap { AnalyzingUtils.getSyntaxErrorRanges(firFile.psi!!).flatMap {
FirErrors.SYNTAX.on(KtRealPsiSourceElement(it), positioningStrategy = null) FirSyntaxErrors.SYNTAX.on(KtRealPsiSourceElement(it), positioningStrategy = null)
.toMetaInfos( .toMetaInfos(
testFile, testFile,
globalMetadataInfoHandler1 = globalMetadataInfoHandler, globalMetadataInfoHandler1 = globalMetadataInfoHandler,
@@ -124,7 +125,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
} }
} else { } else {
collectLightTreeSyntaxErrors(firFile).flatMap { sourceElement -> collectLightTreeSyntaxErrors(firFile).flatMap { sourceElement ->
FirErrors.SYNTAX.on(sourceElement, positioningStrategy = null) FirSyntaxErrors.SYNTAX.on(sourceElement, positioningStrategy = null)
.toMetaInfos( .toMetaInfos(
testFile, testFile,
globalMetadataInfoHandler1 = globalMetadataInfoHandler, globalMetadataInfoHandler1 = globalMetadataInfoHandler,