Skip to content

Commit

Permalink
Implement common Diagnostic(Factory/Renderer) in related FIR classes
Browse files Browse the repository at this point in the history
  • Loading branch information
mglukhikh committed Nov 26, 2020
1 parent d47e163 commit 1795c4f
Show file tree
Hide file tree
Showing 36 changed files with 232 additions and 350 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ class AnalyzerWithCompilerReport(
psiElement: E, factory: DiagnosticFactory0<E>, val message: String
) : SimpleDiagnostic<E>(psiElement, factory, Severity.ERROR) {

override fun isValid(): Boolean = true
override val isValid: Boolean = true
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ class DefaultDiagnosticReporter(override val messageCollector: MessageCollector)
interface MessageCollectorBasedReporter : DiagnosticMessageReporter {
val messageCollector: MessageCollector

override fun report(diagnostic: Diagnostic, file: PsiFile, render: String) = messageCollector.report(
override fun report(diagnostic: Diagnostic, file: PsiFile?, render: String) = messageCollector.report(
AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity),
render,
MessageUtil.psiFileToMessageLocation(file, file.name, DiagnosticUtils.getLineAndColumnRange(diagnostic))
MessageUtil.psiFileToMessageLocation(file!!, file.name, DiagnosticUtils.getLineAndColumnRange(diagnostic))
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ class DefaultDiagnosticReporter(override val messageCollector: MessageCollector)
interface MessageCollectorBasedReporter : DiagnosticMessageReporter {
val messageCollector: MessageCollector

override fun report(diagnostic: Diagnostic, file: PsiFile, render: String) = messageCollector.report(
override fun report(diagnostic: Diagnostic, file: PsiFile?, render: String) = messageCollector.report(
AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity),
render,
MessageUtil.psiFileToMessageLocation(file, file.name, DiagnosticUtils.getLineAndColumn(diagnostic))
MessageUtil.psiFileToMessageLocation(file!!, file.name, DiagnosticUtils.getLineAndColumn(diagnostic))
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.diagnostics.Diagnostic

interface DiagnosticMessageReporter {
fun report(diagnostic: Diagnostic, file: PsiFile, render: String)
fun report(diagnostic: Diagnostic, file: PsiFile?, render: String)
}
Original file line number Diff line number Diff line change
Expand Up @@ -343,9 +343,7 @@ object KotlinToJVMBytecodeCompiler {
firAnalyzerFacade.runResolution()
val firDiagnostics = firAnalyzerFacade.runCheckers().values.flatten()
AnalyzerWithCompilerReport.reportDiagnostics(
SimpleDiagnostics(
firDiagnostics.map { it.toRegularDiagnostic() }
),
SimpleDiagnostics(firDiagnostics),
environment.messageCollector
)
performanceManager?.notifyAnalysisFinished()
Expand Down Expand Up @@ -429,30 +427,6 @@ object KotlinToJVMBytecodeCompiler {
return writeOutputs(environment, projectConfiguration, chunk, outputs, mainClassFqName)
}

private fun FirDiagnostic<*>.toRegularDiagnostic(): Diagnostic {
val psiSource = element as FirPsiSourceElement<*>
@Suppress("UNCHECKED_CAST")
when (this) {
is FirSimpleDiagnostic ->
return SimpleDiagnostic(
psiSource.psi, factory.psiDiagnosticFactory as DiagnosticFactory0<PsiElement>, severity
)
is FirDiagnosticWithParameters1<*, *> ->
return DiagnosticWithParameters1(
psiSource.psi, this.a, factory.psiDiagnosticFactory as DiagnosticFactory1<PsiElement, Any>, severity
)
is FirDiagnosticWithParameters2<*, *, *> ->
return DiagnosticWithParameters2(
psiSource.psi, this.a, this.b, factory.psiDiagnosticFactory as DiagnosticFactory2<PsiElement, Any, Any>, severity
)
is FirDiagnosticWithParameters3<*, *, *, *> ->
return DiagnosticWithParameters3(
psiSource.psi, this.a, this.b, this.c,
factory.psiDiagnosticFactory as DiagnosticFactory3<PsiElement, Any, Any, Any>, severity
)
}
}

private fun getBuildFilePaths(buildFile: File?, sourceFilePaths: List<String>): List<String> =
if (buildFile == null) sourceFilePaths
else sourceFilePaths.map { path ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
companion object {
fun getRendererForDiagnostic(diagnostic: FirDiagnostic<*>): FirDiagnosticRenderer<*> {
val factory = diagnostic.factory
return MAP[factory] ?: factory.defaultRenderer
return MAP[factory] ?: factory.firRenderer
}

// * - The old FE reports these diagnostics with additional parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

package org.jetbrains.kotlin.fir.analysis.diagnostics

import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.FirLightSourceElement
Expand All @@ -14,10 +16,16 @@ import org.jetbrains.kotlin.fir.FirSourceElement

// ------------------------------ diagnostics ------------------------------

sealed class FirDiagnostic<out E : FirSourceElement> {
sealed class FirDiagnostic<out E : FirSourceElement> : Diagnostic {
abstract val element: E
abstract val severity: Severity
abstract val factory: AbstractFirDiagnosticFactory<*, *>
abstract override val severity: Severity
abstract override val factory: AbstractFirDiagnosticFactory<*, *>

override val textRanges: List<TextRange>
get() = factory.getTextRanges(this)

override val isValid: Boolean
get() = true
}

sealed class FirSimpleDiagnostic<out E : FirSourceElement> : FirDiagnostic<E>() {
Expand All @@ -44,43 +52,36 @@ sealed class FirDiagnosticWithParameters3<out E : FirSourceElement, A : Any, B :

// ------------------------------ psi diagnostics ------------------------------

interface FirPsiDiagnostic<P : PsiElement> {
fun asPsiBasedDiagnostic(): Diagnostic
interface FirPsiDiagnostic<P : PsiElement> : Diagnostic {
val element: FirPsiSourceElement<P>

override val psiElement: PsiElement
get() = element.psi

override val psiFile: PsiFile
get() = psiElement.containingFile
}

data class FirPsiSimpleDiagnostic<P : PsiElement>(
override val element: FirPsiSourceElement<P>,
override val severity: Severity,
override val factory: FirDiagnosticFactory0<FirPsiSourceElement<P>, P>
) : FirSimpleDiagnostic<FirPsiSourceElement<P>>(), FirPsiDiagnostic<P> {
override fun asPsiBasedDiagnostic(): Diagnostic {
return factory.psiDiagnosticFactory.on(element.psi)
}
}
) : FirSimpleDiagnostic<FirPsiSourceElement<P>>(), FirPsiDiagnostic<P>

data class FirPsiDiagnosticWithParameters1<P : PsiElement, A : Any>(
override val element: FirPsiSourceElement<P>,
override val a: A,
override val severity: Severity,
override val factory: FirDiagnosticFactory1<FirPsiSourceElement<P>, P, A>
) : FirDiagnosticWithParameters1<FirPsiSourceElement<P>, A>(), FirPsiDiagnostic<P> {
override fun asPsiBasedDiagnostic(): Diagnostic {
return factory.psiDiagnosticFactory.on(element.psi, a)
}
}
) : FirDiagnosticWithParameters1<FirPsiSourceElement<P>, A>(), FirPsiDiagnostic<P>

data class FirPsiDiagnosticWithParameters2<P : PsiElement, A : Any, B : Any>(
override val element: FirPsiSourceElement<P>,
override val a: A,
override val b: B,
override val severity: Severity,
override val factory: FirDiagnosticFactory2<FirPsiSourceElement<P>, P, A, B>
) : FirDiagnosticWithParameters2<FirPsiSourceElement<P>, A, B>(), FirPsiDiagnostic<P> {
override fun asPsiBasedDiagnostic(): Diagnostic {
return factory.psiDiagnosticFactory.on(element.psi, a, b)
}
}
) : FirDiagnosticWithParameters2<FirPsiSourceElement<P>, A, B>(), FirPsiDiagnostic<P>

data class FirPsiDiagnosticWithParameters3<P : PsiElement, A : Any, B : Any, C : Any>(
override val element: FirPsiSourceElement<P>,
Expand All @@ -89,16 +90,20 @@ data class FirPsiDiagnosticWithParameters3<P : PsiElement, A : Any, B : Any, C :
override val c: C,
override val severity: Severity,
override val factory: FirDiagnosticFactory3<FirPsiSourceElement<P>, P, A, B, C>
) : FirDiagnosticWithParameters3<FirPsiSourceElement<P>, A, B, C>(), FirPsiDiagnostic<P> {
override fun asPsiBasedDiagnostic(): Diagnostic {
return factory.psiDiagnosticFactory.on(element.psi, a, b, c)
}
}
) : FirDiagnosticWithParameters3<FirPsiSourceElement<P>, A, B, C>(), FirPsiDiagnostic<P>

// ------------------------------ light tree diagnostics ------------------------------

interface FirLightDiagnostic {
interface FirLightDiagnostic : Diagnostic {
val element: FirLightSourceElement

override val psiElement: PsiElement
get() {
throw UnsupportedOperationException("Light diagnostic does not hold PSI element")
}

override val psiFile: PsiFile?
get() = null
}

data class FirLightSimpleDiagnostic(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,33 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticRenderer
import org.jetbrains.kotlin.fir.FirLightSourceElement
import org.jetbrains.kotlin.fir.FirPsiSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement

sealed class AbstractFirDiagnosticFactory<out E : FirSourceElement, D : FirDiagnostic<E>>(
val name: String,
val severity: Severity,
override var name: String?,
override val severity: Severity,
val positioningStrategy: LightTreePositioningStrategy,
) {
abstract val psiDiagnosticFactory: DiagnosticFactoryWithPsiElement<*, *>
) : DiagnosticFactory<D>(name, severity) {
abstract val firRenderer: FirDiagnosticRenderer<D>

abstract val defaultRenderer: FirDiagnosticRenderer<*>
override var defaultRenderer: DiagnosticRenderer<D>?
get() = firRenderer
set(_) {
}

fun getTextRanges(diagnostic: FirDiagnostic<*>): List<TextRange> =
positioningStrategy.markDiagnostic(diagnostic)

override fun toString(): String {
return name
}
}

class FirDiagnosticFactory0<E : FirSourceElement, P : PsiElement>(
name: String,
severity: Severity,
override val psiDiagnosticFactory: DiagnosticFactory0<P>,
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory<E, FirSimpleDiagnostic<E>>(name, severity, positioningStrategy) {
companion object {
private val DefaultRenderer = SimpleFirDiagnosticRenderer("")
}

override val defaultRenderer: FirDiagnosticRenderer<*>
get() = DefaultRenderer
override val firRenderer: FirDiagnosticRenderer<FirSimpleDiagnostic<E>> = SimpleFirDiagnosticRenderer("")

fun on(element: E): FirSimpleDiagnostic<E> {
return when (element) {
Expand All @@ -58,18 +52,12 @@ class FirDiagnosticFactory0<E : FirSourceElement, P : PsiElement>(
class FirDiagnosticFactory1<E : FirSourceElement, P : PsiElement, A : Any>(
name: String,
severity: Severity,
override val psiDiagnosticFactory: DiagnosticFactory1<P, A>,
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory<E, FirDiagnosticWithParameters1<E, A>>(name, severity, positioningStrategy) {
companion object {
private val DefaultRenderer = FirDiagnosticWithParameters1Renderer(
"{0}",
FirDiagnosticRenderers.TO_STRING
)
}

override val defaultRenderer: FirDiagnosticRenderer<*>
get() = DefaultRenderer
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters1<E, A>> = FirDiagnosticWithParameters1Renderer(
"{0}",
FirDiagnosticRenderers.TO_STRING
)

fun on(element: E, a: A): FirDiagnosticWithParameters1<E, A> {
return when (element) {
Expand All @@ -85,19 +73,13 @@ class FirDiagnosticFactory1<E : FirSourceElement, P : PsiElement, A : Any>(
class FirDiagnosticFactory2<E : FirSourceElement, P : PsiElement, A : Any, B : Any>(
name: String,
severity: Severity,
override val psiDiagnosticFactory: DiagnosticFactory2<P, A, B>,
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory<E, FirDiagnosticWithParameters2<E, A, B>>(name, severity, positioningStrategy) {
companion object {
private val DefaultRenderer = FirDiagnosticWithParameters2Renderer(
"{0}, {1}",
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING
)
}

override val defaultRenderer: FirDiagnosticRenderer<*>
get() = DefaultRenderer
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters2<E, A, B>> = FirDiagnosticWithParameters2Renderer(
"{0}, {1}",
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING
)

fun on(element: E, a: A, b: B): FirDiagnosticWithParameters2<E, A, B> {
return when (element) {
Expand All @@ -113,20 +95,14 @@ class FirDiagnosticFactory2<E : FirSourceElement, P : PsiElement, A : Any, B : A
class FirDiagnosticFactory3<E : FirSourceElement, P : PsiElement, A : Any, B : Any, C : Any>(
name: String,
severity: Severity,
override val psiDiagnosticFactory: DiagnosticFactory3<P, A, B, C>,
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory<E, FirDiagnosticWithParameters3<E, A, B, C>>(name, severity, positioningStrategy) {
companion object {
private val DefaultRenderer = FirDiagnosticWithParameters3Renderer(
"{0}, {1}, {2}",
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING
)
}

override val defaultRenderer: FirDiagnosticRenderer<*>
get() = DefaultRenderer
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters3<E, A, B, C>> = FirDiagnosticWithParameters3Renderer(
"{0}, {1}, {2}",
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING
)

fun on(element: E, a: A, b: B, c: C): FirDiagnosticWithParameters3<E, A, B, C> {
return when (element) {
Expand All @@ -147,7 +123,9 @@ fun <E : FirSourceElement, P : PsiElement> FirDiagnosticFactory0<E, P>.on(elemen
return element?.let { on(it) }
}

fun <E : FirSourceElement, P : PsiElement, A : Any> FirDiagnosticFactory1<E, P, A>.on(element: E?, a: A): FirDiagnosticWithParameters1<E, A>? {
fun <E : FirSourceElement, P : PsiElement, A : Any> FirDiagnosticFactory1<E, P, A>.on(
element: E?, a: A
): FirDiagnosticWithParameters1<E, A>? {
return element?.let { on(it, a) }
}

Expand Down
Loading

0 comments on commit 1795c4f

Please sign in to comment.