[LL API] Collect syntax errors in 'KtFirCompilerFacility'
^KTIJ-27167 Fixed
This commit is contained in:
+27
-5
@@ -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)
|
||||
}
|
||||
}
|
||||
+6
@@ -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")
|
||||
|
||||
+6
@@ -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")
|
||||
|
||||
+7
-3
@@ -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) {
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo() {
|
||||
1.toString()
|
||||
}}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
fun test() {
|
||||
<caret>val x = 0
|
||||
}
|
||||
analysis/analysis-api/testData/components/compilerFacility/compilation/codeFragments/syntaxError.txt
Vendored
+1
@@ -0,0 +1 @@
|
||||
(30,31) SYNTAX Syntax error: Unexpected symbol.
|
||||
Reference in New Issue
Block a user