[LL API] Collect syntax errors in 'KtFirCompilerFacility'

^KTIJ-27167 Fixed
This commit is contained in:
Yan Zhulanow
2023-09-22 00:18:31 +09:00
committed by Space Team
parent 141333bdcd
commit 9ef58f2bdb
7 changed files with 53 additions and 8 deletions
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.analysis.api.fir.components
import com.intellij.openapi.progress.ProgressManager
import com.intellij.psi.PsiErrorElement
import org.jetbrains.kotlin.KtRealPsiSourceElement
import org.jetbrains.kotlin.analysis.api.compile.CodeFragmentCapturedValue
import org.jetbrains.kotlin.analysis.api.components.KtCompilationResult
import org.jetbrains.kotlin.analysis.api.components.KtCompilerFacility
@@ -37,14 +39,12 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.constant.EvaluatedConstTracker
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticMarker
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostics
import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.backend.jvm.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.diagnostics.ConeSyntaxDiagnostic
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.pipeline.applyIrGenerationExtensions
import org.jetbrains.kotlin.fir.pipeline.signatureComposerForJvmFir2Ir
@@ -102,6 +102,12 @@ internal class KtFirCompilerFacility(
is KtCompilerTarget.Jvm -> target.classBuilderFactory
}
val syntaxErrors = SyntaxErrorReportingVisitor().also(file::accept).diagnostics
if (syntaxErrors.isNotEmpty()) {
return KtCompilationResult.Failure(syntaxErrors)
}
val mainFirFile = getFullyResolvedFirFile(file)
val frontendDiagnostics = file.collectDiagnosticsForFile(firResolveSession, DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS)
@@ -685,4 +691,20 @@ private class DeclarationRegistrarVisitor(private val consumer: SymbolTable) : I
val signature = symbol.signature ?: return
registrar(signature, { symbol }, { declaration })
}
}
context(KtFirAnalysisSessionComponent)
private class SyntaxErrorReportingVisitor : KtTreeVisitorVoid() {
private val collectedDiagnostics = mutableListOf<KtDiagnostic>()
val diagnostics: List<KtDiagnostic>
get() = Collections.unmodifiableList(collectedDiagnostics)
override fun visitErrorElement(element: PsiErrorElement) {
collectedDiagnostics += ConeSyntaxDiagnostic(element.errorDescription)
.toFirDiagnostics(analysisSession.useSiteSession, KtRealPsiSourceElement(element), callOrAssignmentSource = null)
.map { (it as KtPsiDiagnostic).asKtDiagnostic() }
super.visitErrorElement(element)
}
}
@@ -133,6 +133,12 @@ public class FirIdeNormalAnalysisLibrarySourceModuleCompilerFacilityTestGenerate
runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/simple.kt");
}
@Test
@TestMetadata("syntaxError.kt")
public void testSyntaxError() throws Exception {
runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/syntaxError.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing")
@TestDataPath("$PROJECT_ROOT")
@@ -133,6 +133,12 @@ public class FirIdeNormalAnalysisSourceModuleCompilerFacilityTestGenerated exten
runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/simple.kt");
}
@Test
@TestMetadata("syntaxError.kt")
public void testSyntaxError() throws Exception {
runTest("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/syntaxError.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/capturing")
@TestDataPath("$PROJECT_ROOT")
@@ -104,15 +104,19 @@ abstract class AbstractCompilerFacilityTest : AbstractAnalysisApiBasedTest() {
val target = KtCompilerTarget.Jvm(ClassBuilderFactories.TEST)
val allowedErrorFilter: (KtDiagnostic) -> Boolean = { it.factoryName in ALLOWED_ERRORS }
val actualText = when (val result = compile(ktTargetFile, compilerConfiguration, target, allowedErrorFilter)) {
val result = compile(ktTargetFile, compilerConfiguration, target, allowedErrorFilter)
val actualText = when (result) {
is KtCompilationResult.Failure -> result.errors.joinToString("\n") { dumpDiagnostic(it) }
is KtCompilationResult.Success -> dumpClassFiles(result.output)
}
testServices.assertions.assertEqualsToTestDataFileSibling(actualText)
}
testServices.assertions.assertEqualsToTestDataFileSibling(irCollector.result, extension = ".ir.txt")
if (result is KtCompilationResult.Success) {
testServices.assertions.assertEqualsToTestDataFileSibling(irCollector.result, extension = ".ir.txt")
}
}
}
override fun configureTest(builder: TestConfigurationBuilder) {
@@ -0,0 +1,3 @@
fun foo() {
1.toString()
}}
@@ -0,0 +1,3 @@
fun test() {
<caret>val x = 0
}
@@ -0,0 +1 @@
(30,31) SYNTAX Syntax error: Unexpected symbol.