Implement common Diagnostic(Factory/Renderer) in related FIR classes

This commit is contained in:
Mikhail Glukhikh
2020-11-17 12:22:13 +03:00
parent d47e16331c
commit 1795c4f3e5
36 changed files with 232 additions and 350 deletions
@@ -17,10 +17,10 @@ class ActualDiagnostic constructor(val diagnostic: Diagnostic, override val plat
TextDiagnostic.InferenceCompatibility.OLD
override val name: String
get() = diagnostic.factory.name
get() = diagnostic.factory.name!!
val file: PsiFile
get() = diagnostic.psiFile
get() = diagnostic.psiFile!!
override fun compareTo(other: AbstractTestDiagnostic): Int {
return if (this.diagnostic is DiagnosticWithParameters1<*, *> && other is ActualDiagnostic && other.diagnostic is DiagnosticWithParameters1<*, *>) {
@@ -21,28 +21,16 @@ class SyntaxErrorDiagnostic(errorElement: PsiErrorElement) : AbstractDiagnosticF
SyntaxErrorDiagnosticFactory.INSTANCE
)
open class AbstractDiagnosticForTests(private val element: PsiElement, private val factory: DiagnosticFactory<*>) : Diagnostic {
override fun getFactory(): DiagnosticFactory<*> {
return factory
}
open class AbstractDiagnosticForTests(override val psiElement: PsiElement, override val factory: DiagnosticFactory<*>) : Diagnostic {
override val severity: Severity
get() = Severity.ERROR
override fun getSeverity(): Severity {
return Severity.ERROR
}
override val textRanges: List<TextRange>
get() = listOf(psiElement.textRange)
override fun getPsiElement(): PsiElement {
return element
}
override val psiFile: PsiFile
get() = psiElement.containingFile
override fun getTextRanges(): List<TextRange> {
return listOf(element.textRange)
}
override fun getPsiFile(): PsiFile {
return element.containingFile
}
override fun isValid(): Boolean {
return true
}
override val isValid: Boolean
get() = true
}
@@ -17,10 +17,12 @@ import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
class DebugInfoDiagnosticFactory0 : DiagnosticFactory0<PsiElement>,
class DebugInfoDiagnosticFactory0 private constructor(
private val privateName: String,
severity: Severity = Severity.ERROR
) : DiagnosticFactory0<PsiElement>(severity, PositioningStrategies.DEFAULT),
DebugInfoDiagnosticFactory {
private val name: String
override val withExplicitDefinitionOnly: Boolean
override val withExplicitDefinitionOnly: Boolean = false
override fun createDiagnostic(
expression: KtExpression,
@@ -32,22 +34,9 @@ class DebugInfoDiagnosticFactory0 : DiagnosticFactory0<PsiElement>,
return DebugInfoDiagnostic(expression, this)
}
private constructor(name: String, severity: Severity = Severity.ERROR) : super(severity, PositioningStrategies.DEFAULT) {
this.name = name
this.withExplicitDefinitionOnly = false
}
private constructor(name: String, severity: Severity, withExplicitDefinitionOnly: Boolean) : super(
severity,
PositioningStrategies.DEFAULT
) {
this.name = name
this.withExplicitDefinitionOnly = withExplicitDefinitionOnly
}
override fun getName(): String {
return "DEBUG_INFO_$name"
}
override var name: String?
get() = "DEBUG_INFO_$privateName"
set(_) {}
companion object {
val SMARTCAST = DebugInfoDiagnosticFactory0("SMARTCAST", Severity.INFO)
@@ -19,11 +19,11 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
class DebugInfoDiagnosticFactory1 : DiagnosticFactory1<PsiElement, String>,
DebugInfoDiagnosticFactory {
private val name: String
private val privateName: String
override fun getName(): String {
return "DEBUG_INFO_$name"
}
override var name: String?
get() = "DEBUG_INFO_$privateName"
set(_) {}
override val withExplicitDefinitionOnly: Boolean
@@ -33,8 +33,8 @@ class DebugInfoDiagnosticFactory1 : DiagnosticFactory1<PsiElement, String>,
dataFlowValueFactory: DataFlowValueFactory?,
languageVersionSettings: LanguageVersionSettings?,
moduleDescriptor: ModuleDescriptorImpl?
) = when (name) {
EXPRESSION_TYPE.name -> {
) = when (privateName) {
EXPRESSION_TYPE.privateName -> {
val (type, dataFlowTypes) = CheckerTestUtil.getTypeInfo(
expression,
bindingContext,
@@ -45,23 +45,23 @@ class DebugInfoDiagnosticFactory1 : DiagnosticFactory1<PsiElement, String>,
this.on(expression, Renderers.renderExpressionType(type, dataFlowTypes))
}
CALL.name -> {
CALL.privateName -> {
val (fqName, typeCall) = CheckerTestUtil.getCallDebugInfo(expression, bindingContext)
this.on(expression, Renderers.renderCallInfo(fqName, typeCall))
}
else -> throw NotImplementedError("Creation diagnostic '$name' isn't supported.")
}
protected constructor(name: String, severity: Severity) : super(severity, PositioningStrategies.DEFAULT) {
this.name = name
private constructor(name: String, severity: Severity) : super(severity, PositioningStrategies.DEFAULT) {
this.privateName = name
this.withExplicitDefinitionOnly = false
}
protected constructor(name: String, severity: Severity, withExplicitDefinitionOnly: Boolean) : super(
private constructor(name: String, severity: Severity, withExplicitDefinitionOnly: Boolean) : super(
severity,
PositioningStrategies.DEFAULT
) {
this.name = name
this.privateName = name
this.withExplicitDefinitionOnly = withExplicitDefinitionOnly
}
@@ -10,9 +10,9 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
import org.jetbrains.kotlin.diagnostics.Severity
class SyntaxErrorDiagnosticFactory private constructor() : DiagnosticFactory<SyntaxErrorDiagnostic>(Severity.ERROR) {
override fun getName(): String {
return "SYNTAX"
}
override var name: String?
get() = "SYNTAX"
set(_) {}
companion object {
val INSTANCE = SyntaxErrorDiagnosticFactory()
@@ -24,6 +24,6 @@ interface Diagnostic {
val severity: Severity
val psiElement: PsiElement
val textRanges: List<TextRange>
val psiFile: PsiFile
val psiFile: PsiFile?
val isValid: Boolean
}
@@ -24,7 +24,6 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
@@ -75,6 +74,9 @@ public class DiagnosticUtils {
List<TextRange> textRanges = diagnostic.getTextRanges();
if (textRanges.isEmpty()) return PsiDiagnosticUtils.LineAndColumn.NONE;
TextRange firstRange = firstRange(textRanges);
if (file == null) {
return PsiDiagnosticUtils.LineAndColumn.NONE;
}
return getLineAndColumnInPsiFile(file, firstRange);
}
@@ -90,6 +92,9 @@ public class DiagnosticUtils {
List<TextRange> textRanges = diagnostic.getTextRanges();
if (textRanges.isEmpty()) return PsiDiagnosticUtils.LineAndColumnRange.NONE;
TextRange firstRange = firstRange(textRanges);
if (file == null) {
return PsiDiagnosticUtils.LineAndColumnRange.NONE;
}
return getLineAndColumnRangeInPsiFile(file, firstRange);
}
@@ -124,9 +129,13 @@ public class DiagnosticUtils {
public static List<Diagnostic> sortedDiagnostics(@NotNull Collection<Diagnostic> diagnostics) {
List<Diagnostic> result = Lists.newArrayList(diagnostics);
result.sort((d1, d2) -> {
String path1 = d1.getPsiFile().getViewProvider().getVirtualFile().getPath();
String path2 = d2.getPsiFile().getViewProvider().getVirtualFile().getPath();
if (!path1.equals(path2)) return path1.compareTo(path2);
PsiFile file1 = d1.getPsiFile();
PsiFile file2 = d2.getPsiFile();
if (file1 != null && file2 != null) {
String path1 = file1.getViewProvider().getVirtualFile().getPath();
String path2 = file2.getViewProvider().getVirtualFile().getPath();
if (!path1.equals(path2)) return path1.compareTo(path2);
}
TextRange range1 = firstRange(d1.getTextRanges());
TextRange range2 = firstRange(d2.getTextRanges());
@@ -164,7 +164,7 @@ abstract class KotlinSuppressCache {
companion object {
private fun getDiagnosticSuppressKey(diagnostic: Diagnostic): String =
diagnostic.factory.name.toLowerCase()
diagnostic.factory.name!!.toLowerCase()
private fun isSuppressedByStrings(key: String, strings: Set<String>, severity: Severity): Boolean =
severity == Severity.WARNING && "warnings" in strings || key in strings