Unbind general FirDiagnostic from PsiFile & PsiElement
This commit is contained in:
+3
-4
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmBindingContextSlices
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
@@ -154,16 +153,16 @@ class AnalyzerWithCompilerReport(
|
||||
return diagnostic.severity == Severity.ERROR
|
||||
}
|
||||
|
||||
fun reportDiagnostics(unsortedDiagnostics: Diagnostics, reporter: DiagnosticMessageReporter): Boolean {
|
||||
fun reportDiagnostics(unsortedDiagnostics: GenericDiagnostics<*>, reporter: DiagnosticMessageReporter): Boolean {
|
||||
var hasErrors = false
|
||||
val diagnostics = sortedDiagnostics(unsortedDiagnostics.all())
|
||||
val diagnostics = sortedDiagnostics(unsortedDiagnostics.all().filterIsInstance<Diagnostic>())
|
||||
for (diagnostic in diagnostics) {
|
||||
hasErrors = hasErrors or reportDiagnostic(diagnostic, reporter)
|
||||
}
|
||||
return hasErrors
|
||||
}
|
||||
|
||||
fun reportDiagnostics(diagnostics: Diagnostics, messageCollector: MessageCollector): Boolean {
|
||||
fun reportDiagnostics(diagnostics: GenericDiagnostics<*>, messageCollector: MessageCollector): Boolean {
|
||||
val hasErrors = reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector))
|
||||
|
||||
if (diagnostics.any { it.factory == Errors.INCOMPATIBLE_CLASS }) {
|
||||
|
||||
+2
-2
@@ -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))
|
||||
)
|
||||
}
|
||||
|
||||
+2
-2
@@ -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))
|
||||
)
|
||||
}
|
||||
|
||||
+1
-1
@@ -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)
|
||||
}
|
||||
|
||||
+2
-5
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.*
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.PsiJavaModule
|
||||
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
||||
@@ -54,9 +53,7 @@ import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.container.get
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.FirPsiSourceElement
|
||||
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
||||
import org.jetbrains.kotlin.fir.backend.jvm.FirMetadataSerializer
|
||||
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
||||
@@ -72,7 +69,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.CompilerEnvironment
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.SimpleDiagnostics
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.SimpleGenericDiagnostics
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
||||
@@ -343,7 +340,7 @@ object KotlinToJVMBytecodeCompiler {
|
||||
firAnalyzerFacade.runResolution()
|
||||
val firDiagnostics = firAnalyzerFacade.runCheckers().values.flatten()
|
||||
AnalyzerWithCompilerReport.reportDiagnostics(
|
||||
SimpleDiagnostics(firDiagnostics),
|
||||
SimpleGenericDiagnostics(firDiagnostics),
|
||||
environment.messageCollector
|
||||
)
|
||||
performanceManager?.notifyAnalysisFinished()
|
||||
|
||||
+3
-10
@@ -10,13 +10,14 @@ 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.diagnostics.UnboundDiagnostic
|
||||
import org.jetbrains.kotlin.fir.FirLightSourceElement
|
||||
import org.jetbrains.kotlin.fir.FirPsiSourceElement
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
|
||||
// ------------------------------ diagnostics ------------------------------
|
||||
|
||||
sealed class FirDiagnostic<out E : FirSourceElement> : Diagnostic {
|
||||
sealed class FirDiagnostic<out E : FirSourceElement> : UnboundDiagnostic {
|
||||
abstract val element: E
|
||||
abstract override val severity: Severity
|
||||
abstract override val factory: AbstractFirDiagnosticFactory<*, *>
|
||||
@@ -94,16 +95,8 @@ data class FirPsiDiagnosticWithParameters3<P : PsiElement, A : Any, B : Any, C :
|
||||
|
||||
// ------------------------------ light tree diagnostics ------------------------------
|
||||
|
||||
interface FirLightDiagnostic : Diagnostic {
|
||||
interface FirLightDiagnostic : UnboundDiagnostic {
|
||||
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(
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.diagnostics
|
||||
|
||||
interface GenericDiagnostics<T : UnboundDiagnostic> : Iterable<T> {
|
||||
fun all(): Collection<T>
|
||||
|
||||
fun isEmpty(): Boolean = all().isEmpty()
|
||||
|
||||
override fun iterator(): Iterator<T> = all().iterator()
|
||||
}
|
||||
@@ -20,7 +20,7 @@ class ActualDiagnostic constructor(val diagnostic: Diagnostic, override val plat
|
||||
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<*, *>) {
|
||||
|
||||
@@ -2,222 +2,216 @@
|
||||
* Copyright 2010-2018 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.checkers.utils
|
||||
|
||||
package org.jetbrains.kotlin.checkers.utils;
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.util.slicedMap.WritableSlice
|
||||
import java.util.HashMap
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.KtNodeTypes;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallsKt;
|
||||
import org.jetbrains.kotlin.types.ErrorUtils;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
|
||||
object DebugInfoUtil {
|
||||
private val MAY_BE_UNRESOLVED = TokenSet.create(KtTokens.IN_KEYWORD, KtTokens.NOT_IN)
|
||||
private val EXCLUDED = TokenSet.create(
|
||||
KtTokens.COLON,
|
||||
KtTokens.AS_KEYWORD,
|
||||
KtTokens.`AS_SAFE`,
|
||||
KtTokens.IS_KEYWORD,
|
||||
KtTokens.NOT_IS,
|
||||
KtTokens.OROR,
|
||||
KtTokens.ANDAND,
|
||||
KtTokens.EQ,
|
||||
KtTokens.EQEQEQ,
|
||||
KtTokens.EXCLEQEQEQ,
|
||||
KtTokens.ELVIS,
|
||||
KtTokens.EXCLEXCL
|
||||
)
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.kotlin.lexer.KtTokens.*;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||
|
||||
public class DebugInfoUtil {
|
||||
private static final TokenSet MAY_BE_UNRESOLVED = TokenSet.create(IN_KEYWORD, NOT_IN);
|
||||
private static final TokenSet EXCLUDED = TokenSet.create(
|
||||
COLON, AS_KEYWORD, AS_SAFE, IS_KEYWORD, NOT_IS, OROR, ANDAND, EQ, EQEQEQ, EXCLEQEQEQ, ELVIS, EXCLEXCL);
|
||||
|
||||
public abstract static class DebugInfoReporter {
|
||||
|
||||
public void preProcessReference(@NotNull KtReferenceExpression expression) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public abstract void reportElementWithErrorType(@NotNull KtReferenceExpression expression);
|
||||
|
||||
public abstract void reportMissingUnresolved(@NotNull KtReferenceExpression expression);
|
||||
|
||||
public abstract void reportUnresolvedWithTarget(@NotNull KtReferenceExpression expression, @NotNull String target);
|
||||
|
||||
public void reportDynamicCall(@NotNull KtElement element, DeclarationDescriptor declarationDescriptor) { }
|
||||
}
|
||||
|
||||
public static void markDebugAnnotations(
|
||||
@NotNull PsiElement root,
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull DebugInfoReporter debugInfoReporter
|
||||
fun markDebugAnnotations(
|
||||
root: PsiElement,
|
||||
bindingContext: BindingContext,
|
||||
debugInfoReporter: DebugInfoReporter
|
||||
) {
|
||||
Map<KtReferenceExpression, DiagnosticFactory<?>> markedWithErrorElements = new HashMap<>();
|
||||
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
|
||||
DiagnosticFactory<?> factory = diagnostic.getFactory();
|
||||
if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(diagnostic.getFactory())) {
|
||||
markedWithErrorElements.put((KtReferenceExpression) diagnostic.getPsiElement(), factory);
|
||||
}
|
||||
else if (factory == Errors.SUPER_IS_NOT_AN_EXPRESSION
|
||||
|| factory == Errors.SUPER_NOT_AVAILABLE) {
|
||||
KtSuperExpression superExpression = (KtSuperExpression) diagnostic.getPsiElement();
|
||||
markedWithErrorElements.put(superExpression.getInstanceReference(), factory);
|
||||
}
|
||||
else if (factory == Errors.EXPRESSION_EXPECTED_PACKAGE_FOUND) {
|
||||
markedWithErrorElements.put((KtSimpleNameExpression) diagnostic.getPsiElement(), factory);
|
||||
}
|
||||
else if (factory == Errors.UNSUPPORTED) {
|
||||
for (KtReferenceExpression reference : PsiTreeUtil.findChildrenOfType(diagnostic.getPsiElement(),
|
||||
KtReferenceExpression.class)) {
|
||||
markedWithErrorElements.put(reference, factory);
|
||||
val markedWithErrorElements: MutableMap<KtReferenceExpression, DiagnosticFactory<*>?> = HashMap()
|
||||
for (diagnostic in bindingContext.diagnostics) {
|
||||
val factory = diagnostic.factory
|
||||
if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(diagnostic.factory)) {
|
||||
markedWithErrorElements[diagnostic.psiElement as KtReferenceExpression] = factory
|
||||
} else if (factory === Errors.SUPER_IS_NOT_AN_EXPRESSION
|
||||
|| factory === Errors.SUPER_NOT_AVAILABLE
|
||||
) {
|
||||
val superExpression = diagnostic.psiElement as KtSuperExpression
|
||||
markedWithErrorElements[superExpression.instanceReference] = factory
|
||||
} else if (factory === Errors.EXPRESSION_EXPECTED_PACKAGE_FOUND) {
|
||||
markedWithErrorElements[diagnostic.psiElement as KtSimpleNameExpression] = factory
|
||||
} else if (factory === Errors.UNSUPPORTED) {
|
||||
for (reference in PsiTreeUtil.findChildrenOfType(
|
||||
diagnostic.psiElement,
|
||||
KtReferenceExpression::class.java
|
||||
)) {
|
||||
markedWithErrorElements[reference] = factory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
root.acceptChildren(new KtTreeVisitorVoid() {
|
||||
|
||||
@Override
|
||||
public void visitForExpression(@NotNull KtForExpression expression) {
|
||||
KtExpression range = expression.getLoopRange();
|
||||
reportIfDynamicCall(range, range, LOOP_RANGE_ITERATOR_RESOLVED_CALL);
|
||||
reportIfDynamicCall(range, range, LOOP_RANGE_HAS_NEXT_RESOLVED_CALL);
|
||||
reportIfDynamicCall(range, range, LOOP_RANGE_NEXT_RESOLVED_CALL);
|
||||
super.visitForExpression(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitDestructuringDeclaration(@NotNull KtDestructuringDeclaration destructuringDeclaration) {
|
||||
for (KtDestructuringDeclarationEntry entry : destructuringDeclaration.getEntries()) {
|
||||
reportIfDynamicCall(entry, entry, COMPONENT_RESOLVED_CALL);
|
||||
root.acceptChildren(object : KtTreeVisitorVoid() {
|
||||
override fun visitForExpression(expression: KtForExpression) {
|
||||
val range = expression.loopRange
|
||||
if (range != null) {
|
||||
reportIfDynamicCall(range, range, BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL)
|
||||
reportIfDynamicCall(range, range, BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL)
|
||||
reportIfDynamicCall(range, range, BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL)
|
||||
}
|
||||
super.visitDestructuringDeclaration(destructuringDeclaration);
|
||||
super.visitForExpression(expression)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitProperty(@NotNull KtProperty property) {
|
||||
VariableDescriptor descriptor = bindingContext.get(VARIABLE, property);
|
||||
if (descriptor instanceof PropertyDescriptor && property.getDelegate() != null) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||
reportIfDynamicCall(property.getDelegate(), propertyDescriptor, PROVIDE_DELEGATE_RESOLVED_CALL);
|
||||
reportIfDynamicCall(property.getDelegate(), propertyDescriptor.getGetter(), DELEGATED_PROPERTY_RESOLVED_CALL);
|
||||
reportIfDynamicCall(property.getDelegate(), propertyDescriptor.getSetter(), DELEGATED_PROPERTY_RESOLVED_CALL);
|
||||
override fun visitDestructuringDeclaration(destructuringDeclaration: KtDestructuringDeclaration) {
|
||||
for (entry in destructuringDeclaration.entries) {
|
||||
reportIfDynamicCall(entry, entry, BindingContext.COMPONENT_RESOLVED_CALL)
|
||||
}
|
||||
super.visitProperty(property);
|
||||
super.visitDestructuringDeclaration(destructuringDeclaration)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitThisExpression(@NotNull KtThisExpression expression) {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt.getResolvedCall(expression, bindingContext);
|
||||
override fun visitProperty(property: KtProperty) {
|
||||
val descriptor = bindingContext.get(BindingContext.VARIABLE, property)
|
||||
val delegate = property.delegate
|
||||
if (descriptor is PropertyDescriptor && delegate != null) {
|
||||
reportIfDynamicCall(delegate, descriptor, BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL)
|
||||
reportIfDynamicCall(delegate, descriptor.getter, BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL)
|
||||
reportIfDynamicCall(delegate, descriptor.setter, BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL)
|
||||
}
|
||||
super.visitProperty(property)
|
||||
}
|
||||
|
||||
override fun visitThisExpression(expression: KtThisExpression) {
|
||||
val resolvedCall = expression.getResolvedCall(bindingContext)
|
||||
if (resolvedCall != null) {
|
||||
reportIfDynamic(expression, resolvedCall.getResultingDescriptor(), debugInfoReporter);
|
||||
reportIfDynamic(expression, resolvedCall.resultingDescriptor, debugInfoReporter)
|
||||
}
|
||||
super.visitThisExpression(expression);
|
||||
super.visitThisExpression(expression)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(@NotNull KtReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
if (!BindingContextUtils.isExpressionWithValidReference(expression, bindingContext)){
|
||||
return;
|
||||
override fun visitReferenceExpression(expression: KtReferenceExpression) {
|
||||
super.visitReferenceExpression(expression)
|
||||
if (!BindingContextUtils.isExpressionWithValidReference(expression, bindingContext)) {
|
||||
return
|
||||
}
|
||||
IElementType referencedNameElementType = null;
|
||||
if (expression instanceof KtSimpleNameExpression) {
|
||||
KtSimpleNameExpression nameExpression = (KtSimpleNameExpression) expression;
|
||||
IElementType elementType = expression.getNode().getElementType();
|
||||
if (elementType == KtNodeTypes.OPERATION_REFERENCE) {
|
||||
referencedNameElementType = nameExpression.getReferencedNameElementType();
|
||||
var referencedNameElementType: IElementType? = null
|
||||
if (expression is KtSimpleNameExpression) {
|
||||
val elementType = expression.getNode().elementType
|
||||
if (elementType === KtNodeTypes.OPERATION_REFERENCE) {
|
||||
referencedNameElementType = expression.getReferencedNameElementType()
|
||||
if (EXCLUDED.contains(referencedNameElementType)) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
}
|
||||
if (elementType == KtNodeTypes.LABEL ||
|
||||
nameExpression.getReferencedNameElementType() == KtTokens.THIS_KEYWORD) {
|
||||
return;
|
||||
if (elementType === KtNodeTypes.LABEL ||
|
||||
expression.getReferencedNameElementType() === KtTokens.THIS_KEYWORD
|
||||
) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
debugInfoReporter.preProcessReference(expression);
|
||||
|
||||
String target = null;
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, expression);
|
||||
debugInfoReporter.preProcessReference(expression)
|
||||
var target: String? = null
|
||||
val declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression)
|
||||
if (declarationDescriptor != null) {
|
||||
target = declarationDescriptor.toString();
|
||||
|
||||
reportIfDynamic(expression, declarationDescriptor, debugInfoReporter);
|
||||
target = declarationDescriptor.toString()
|
||||
reportIfDynamic(expression, declarationDescriptor, debugInfoReporter)
|
||||
}
|
||||
if (target == null) {
|
||||
PsiElement labelTarget = bindingContext.get(LABEL_TARGET, expression);
|
||||
val labelTarget = bindingContext.get(BindingContext.LABEL_TARGET, expression)
|
||||
if (labelTarget != null) {
|
||||
target = labelTarget.getText();
|
||||
target = labelTarget.text
|
||||
}
|
||||
}
|
||||
if (target == null) {
|
||||
Collection<? extends DeclarationDescriptor> declarationDescriptors =
|
||||
bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, expression);
|
||||
val declarationDescriptors = bindingContext.get(BindingContext.AMBIGUOUS_REFERENCE_TARGET, expression)
|
||||
if (declarationDescriptors != null) {
|
||||
target = "[" + declarationDescriptors.size() + " descriptors]";
|
||||
target = "[" + declarationDescriptors.size + " descriptors]"
|
||||
}
|
||||
}
|
||||
if (target == null) {
|
||||
Collection<? extends PsiElement> labelTargets = bindingContext.get(AMBIGUOUS_LABEL_TARGET, expression);
|
||||
val labelTargets = bindingContext.get(BindingContext.AMBIGUOUS_LABEL_TARGET, expression)
|
||||
if (labelTargets != null) {
|
||||
target = "[" + labelTargets.size() + " elements]";
|
||||
target = "[" + labelTargets.size + " elements]"
|
||||
}
|
||||
}
|
||||
|
||||
if (MAY_BE_UNRESOLVED.contains(referencedNameElementType)) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
boolean resolved = target != null;
|
||||
boolean markedWithError = markedWithErrorElements.containsKey(expression);
|
||||
if (expression instanceof KtArrayAccessExpression &&
|
||||
markedWithErrorElements.containsKey(((KtArrayAccessExpression) expression).getArrayExpression())) {
|
||||
val resolved = target != null
|
||||
var markedWithError = markedWithErrorElements.containsKey(expression)
|
||||
if (expression is KtArrayAccessExpression &&
|
||||
markedWithErrorElements.containsKey(expression.arrayExpression)
|
||||
) {
|
||||
// if 'foo' in 'foo[i]' is unresolved it means 'foo[i]' is unresolved (otherwise 'foo[i]' is marked as 'missing unresolved')
|
||||
markedWithError = true;
|
||||
markedWithError = true
|
||||
}
|
||||
KotlinType expressionType = bindingContext.getType(expression);
|
||||
DiagnosticFactory<?> factory = markedWithErrorElements.get(expression);
|
||||
val expressionType = bindingContext.getType(expression)
|
||||
val factory = markedWithErrorElements[expression]
|
||||
if (declarationDescriptor != null &&
|
||||
(ErrorUtils.isError(declarationDescriptor) || ErrorUtils.containsErrorType(expressionType))) {
|
||||
if (factory != Errors.EXPRESSION_EXPECTED_PACKAGE_FOUND) {
|
||||
debugInfoReporter.reportElementWithErrorType(expression);
|
||||
(ErrorUtils.isError(declarationDescriptor) || ErrorUtils.containsErrorType(expressionType))
|
||||
) {
|
||||
if (factory !== Errors.EXPRESSION_EXPECTED_PACKAGE_FOUND) {
|
||||
debugInfoReporter.reportElementWithErrorType(expression)
|
||||
}
|
||||
}
|
||||
if (resolved && markedWithError) {
|
||||
if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(factory)) {
|
||||
debugInfoReporter.reportUnresolvedWithTarget(expression, target);
|
||||
debugInfoReporter.reportUnresolvedWithTarget(expression, target!!)
|
||||
}
|
||||
}
|
||||
else if (!resolved && !markedWithError) {
|
||||
debugInfoReporter.reportMissingUnresolved(expression);
|
||||
} else if (!resolved && !markedWithError) {
|
||||
debugInfoReporter.reportMissingUnresolved(expression)
|
||||
}
|
||||
}
|
||||
|
||||
private <E extends KtElement, K, D extends CallableDescriptor> boolean reportIfDynamicCall(E element, K key, WritableSlice<K, ResolvedCall<D>> slice) {
|
||||
ResolvedCall<D> resolvedCall = bindingContext.get(slice, key);
|
||||
if (resolvedCall != null) {
|
||||
return reportIfDynamic(element, resolvedCall.getResultingDescriptor(), debugInfoReporter);
|
||||
}
|
||||
return false;
|
||||
private fun <E : KtElement, K, D : CallableDescriptor?> reportIfDynamicCall(
|
||||
element: E,
|
||||
key: K,
|
||||
slice: WritableSlice<K, ResolvedCall<D>>
|
||||
): Boolean {
|
||||
val resolvedCall = bindingContext[slice, key]
|
||||
return if (resolvedCall != null) {
|
||||
reportIfDynamic(element, resolvedCall.resultingDescriptor, debugInfoReporter)
|
||||
} else false
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
private static boolean reportIfDynamic(KtElement element, DeclarationDescriptor declarationDescriptor, DebugInfoReporter debugInfoReporter) {
|
||||
if (declarationDescriptor != null && DynamicCallsKt.isDynamic(declarationDescriptor)) {
|
||||
debugInfoReporter.reportDynamicCall(element, declarationDescriptor);
|
||||
return true;
|
||||
private fun reportIfDynamic(
|
||||
element: KtElement,
|
||||
declarationDescriptor: DeclarationDescriptor?,
|
||||
debugInfoReporter: DebugInfoReporter
|
||||
): Boolean {
|
||||
if (declarationDescriptor != null && declarationDescriptor.isDynamic()) {
|
||||
debugInfoReporter.reportDynamicCall(element, declarationDescriptor)
|
||||
return true
|
||||
}
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DebugInfoReporter {
|
||||
fun preProcessReference(expression: KtReferenceExpression) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
abstract fun reportElementWithErrorType(expression: KtReferenceExpression)
|
||||
abstract fun reportMissingUnresolved(expression: KtReferenceExpression)
|
||||
abstract fun reportUnresolvedWithTarget(expression: KtReferenceExpression, target: String)
|
||||
open fun reportDynamicCall(element: KtElement, declarationDescriptor: DeclarationDescriptor) {}
|
||||
}
|
||||
}
|
||||
@@ -20,5 +20,5 @@ import com.intellij.psi.PsiFile
|
||||
|
||||
interface Diagnostic : UnboundDiagnostic {
|
||||
val psiElement: PsiElement
|
||||
val psiFile: PsiFile?
|
||||
val psiFile: PsiFile
|
||||
}
|
||||
@@ -74,9 +74,6 @@ 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);
|
||||
}
|
||||
|
||||
@@ -92,9 +89,6 @@ 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);
|
||||
}
|
||||
|
||||
@@ -131,11 +125,9 @@ public class DiagnosticUtils {
|
||||
result.sort((d1, d2) -> {
|
||||
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);
|
||||
}
|
||||
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());
|
||||
|
||||
+3
-2
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.config.LanguageVersion;
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||
import org.jetbrains.kotlin.diagnostics.UnboundDiagnostic;
|
||||
import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement;
|
||||
import org.jetbrains.kotlin.resolve.VarianceConflictDiagnosticData;
|
||||
import org.jetbrains.kotlin.types.KotlinTypeKt;
|
||||
@@ -46,7 +47,7 @@ public class DefaultErrorMessages {
|
||||
|
||||
@NotNull
|
||||
@SuppressWarnings("unchecked")
|
||||
public static String render(@NotNull Diagnostic diagnostic) {
|
||||
public static String render(@NotNull UnboundDiagnostic diagnostic) {
|
||||
DiagnosticRenderer renderer = getRendererForDiagnostic(diagnostic);
|
||||
if (renderer != null) {
|
||||
return renderer.render(diagnostic);
|
||||
@@ -55,7 +56,7 @@ public class DefaultErrorMessages {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static DiagnosticRenderer getRendererForDiagnostic(@NotNull Diagnostic diagnostic) {
|
||||
public static DiagnosticRenderer getRendererForDiagnostic(@NotNull UnboundDiagnostic diagnostic) {
|
||||
DiagnosticRenderer<?> renderer = AddToStdlibKt.firstNotNullResult(RENDERER_MAPS, map -> map.get(diagnostic.getFactory()));
|
||||
if (renderer != null)
|
||||
return renderer;
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.diagnostics.*
|
||||
import java.text.MessageFormat
|
||||
|
||||
|
||||
abstract class AbstractDiagnosticWithParametersRenderer<in D : Diagnostic> protected constructor(message: String) : DiagnosticRenderer<D> {
|
||||
abstract class AbstractDiagnosticWithParametersRenderer<in D : UnboundDiagnostic> protected constructor(message: String) : DiagnosticRenderer<D> {
|
||||
private val messageFormat = MessageFormat(message)
|
||||
|
||||
override fun render(diagnostic: D): String {
|
||||
|
||||
@@ -13,81 +13,77 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
package org.jetbrains.kotlin.resolve;
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiErrorElement
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
||||
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import java.lang.IllegalArgumentException
|
||||
import java.lang.StringBuilder
|
||||
import java.util.ArrayList
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiErrorElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink;
|
||||
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils;
|
||||
import org.jetbrains.kotlin.psi.KtElement;
|
||||
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid;
|
||||
import org.jetbrains.kotlin.psi.debugText.DebugTextUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics;
|
||||
object AnalyzingUtils {
|
||||
private const val WRITE_DEBUG_TRACE_NAMES = false
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AnalyzingUtils {
|
||||
private static final boolean WRITE_DEBUG_TRACE_NAMES = false;
|
||||
|
||||
public abstract static class PsiErrorElementVisitor extends KtTreeVisitorVoid {
|
||||
@Override
|
||||
public abstract void visitErrorElement(@NotNull PsiErrorElement element);
|
||||
}
|
||||
|
||||
public static void checkForSyntacticErrors(@NotNull PsiElement root) {
|
||||
root.acceptChildren(new PsiErrorElementVisitor() {
|
||||
@Override
|
||||
public void visitErrorElement(@NotNull PsiErrorElement element) {
|
||||
throw new IllegalArgumentException(element.getErrorDescription() + "; looking at " +
|
||||
element.getNode().getElementType() + " '" +
|
||||
element.getText() + PsiDiagnosticUtils.atLocation(element));
|
||||
@JvmStatic
|
||||
fun checkForSyntacticErrors(root: PsiElement) {
|
||||
root.acceptChildren(object : PsiErrorElementVisitor() {
|
||||
override fun visitErrorElement(element: PsiErrorElement) {
|
||||
throw IllegalArgumentException(
|
||||
element.errorDescription + "; looking at " +
|
||||
element.node.elementType + " '" +
|
||||
element.text + PsiDiagnosticUtils.atLocation(element)
|
||||
)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
public static List<PsiErrorElement> getSyntaxErrorRanges(@NotNull PsiElement root) {
|
||||
List<PsiErrorElement> r = new ArrayList<>();
|
||||
root.acceptChildren(new PsiErrorElementVisitor() {
|
||||
@Override
|
||||
public void visitErrorElement(@NotNull PsiErrorElement element) {
|
||||
r.add(element);
|
||||
|
||||
@JvmStatic
|
||||
fun getSyntaxErrorRanges(root: PsiElement): List<PsiErrorElement> {
|
||||
val r: MutableList<PsiErrorElement> = ArrayList()
|
||||
root.acceptChildren(object : PsiErrorElementVisitor() {
|
||||
override fun visitErrorElement(element: PsiErrorElement) {
|
||||
r.add(element)
|
||||
}
|
||||
});
|
||||
return r;
|
||||
})
|
||||
return r
|
||||
}
|
||||
|
||||
public static void throwExceptionOnErrors(BindingContext bindingContext) {
|
||||
throwExceptionOnErrors(bindingContext.getDiagnostics());
|
||||
fun throwExceptionOnErrors(bindingContext: BindingContext) {
|
||||
throwExceptionOnErrors(bindingContext.diagnostics)
|
||||
}
|
||||
|
||||
public static void throwExceptionOnErrors(Diagnostics diagnostics) {
|
||||
for (Diagnostic diagnostic : diagnostics) {
|
||||
DiagnosticSink.THROW_EXCEPTION.report(diagnostic);
|
||||
fun throwExceptionOnErrors(diagnostics: Diagnostics) {
|
||||
for (diagnostic in diagnostics) {
|
||||
DiagnosticSink.THROW_EXCEPTION.report(diagnostic)
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------------
|
||||
public static String formDebugNameForBindingTrace(@NotNull String debugName, @Nullable Object resolutionSubjectForMessage) {
|
||||
@JvmStatic
|
||||
fun formDebugNameForBindingTrace(debugName: String, resolutionSubjectForMessage: Any?): String {
|
||||
if (WRITE_DEBUG_TRACE_NAMES) {
|
||||
StringBuilder debugInfo = new StringBuilder(debugName);
|
||||
if (resolutionSubjectForMessage instanceof KtElement) {
|
||||
KtElement element = (KtElement) resolutionSubjectForMessage;
|
||||
debugInfo.append(" ").append(DebugTextUtilKt.getDebugText(element));
|
||||
val debugInfo = StringBuilder(debugName)
|
||||
if (resolutionSubjectForMessage is KtElement) {
|
||||
debugInfo.append(" ").append(resolutionSubjectForMessage.getDebugText())
|
||||
//debugInfo.append(" in ").append(element.getContainingFile().getName());
|
||||
debugInfo.append(" in ").append(element.getContainingKtFile().getName()).append(" ").append(element.getTextOffset());
|
||||
debugInfo.append(" in ").append(resolutionSubjectForMessage.containingKtFile.name).append(" ").append(
|
||||
resolutionSubjectForMessage.textOffset
|
||||
)
|
||||
} else if (resolutionSubjectForMessage != null) {
|
||||
debugInfo.append(" ").append(resolutionSubjectForMessage)
|
||||
}
|
||||
else if (resolutionSubjectForMessage != null) {
|
||||
debugInfo.append(" ").append(resolutionSubjectForMessage);
|
||||
}
|
||||
|
||||
return debugInfo.toString();
|
||||
return debugInfo.toString()
|
||||
}
|
||||
|
||||
return "";
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
abstract class PsiErrorElementVisitor : KtTreeVisitorVoid() {
|
||||
abstract override fun visitErrorElement(element: PsiErrorElement)
|
||||
}
|
||||
}
|
||||
@@ -17,25 +17,26 @@
|
||||
package org.jetbrains.kotlin.resolve.diagnostics
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import com.intellij.openapi.util.ModificationTracker
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.GenericDiagnostics
|
||||
|
||||
interface Diagnostics : Iterable<Diagnostic> {
|
||||
interface Diagnostics : GenericDiagnostics<Diagnostic> {
|
||||
//should not be called on readonly views
|
||||
//any Diagnostics object returned by BindingContext#getDiagnostics() should implement this property
|
||||
val modificationTracker: ModificationTracker
|
||||
get() = throw IllegalStateException("Trying to obtain modification tracker for Diagnostics object of class ${this::class.java}")
|
||||
|
||||
fun all(): Collection<Diagnostic>
|
||||
override fun all(): Collection<Diagnostic>
|
||||
|
||||
override fun isEmpty(): Boolean = all().isEmpty()
|
||||
|
||||
override fun iterator(): Iterator<Diagnostic> = all().iterator()
|
||||
|
||||
fun forElement(psiElement: PsiElement): Collection<Diagnostic>
|
||||
|
||||
fun isEmpty(): Boolean = all().isEmpty()
|
||||
|
||||
fun noSuppression(): Diagnostics
|
||||
|
||||
override fun iterator() = all().iterator()
|
||||
|
||||
companion object {
|
||||
val EMPTY: Diagnostics = object : Diagnostics {
|
||||
override fun noSuppression(): Diagnostics = this
|
||||
|
||||
@@ -16,21 +16,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.diagnostics
|
||||
|
||||
import com.intellij.openapi.util.Condition
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import java.util.ArrayList
|
||||
|
||||
class SimpleDiagnostics(diagnostics: Collection<Diagnostic>) : Diagnostics {
|
||||
class SimpleDiagnostics(diagnostics: Collection<Diagnostic>) : SimpleGenericDiagnostics<Diagnostic>(diagnostics), Diagnostics {
|
||||
//copy to prevent external change
|
||||
private val diagnostics = ArrayList(diagnostics)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private val elementsCache = DiagnosticsElementsCache(this, { true })
|
||||
private val elementsCache = DiagnosticsElementsCache(this) { true }
|
||||
|
||||
override fun all() = diagnostics
|
||||
|
||||
override fun forElement(psiElement: PsiElement) = elementsCache.getDiagnostics(psiElement)
|
||||
override fun forElement(psiElement: PsiElement): MutableCollection<Diagnostic> = elementsCache.getDiagnostics(psiElement)
|
||||
|
||||
override fun noSuppression() = this
|
||||
}
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.resolve.diagnostics
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.UnboundDiagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.GenericDiagnostics
|
||||
import java.util.ArrayList
|
||||
|
||||
open class SimpleGenericDiagnostics<T : UnboundDiagnostic>(diagnostics: Collection<T>) : GenericDiagnostics<T> {
|
||||
//copy to prevent external change
|
||||
private val diagnostics = ArrayList(diagnostics)
|
||||
|
||||
override fun all() = diagnostics
|
||||
}
|
||||
+2
-1
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.checkers.diagnostics.TextDiagnostic
|
||||
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
|
||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||
@@ -324,7 +325,7 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() {
|
||||
|
||||
private fun Iterable<FirDiagnostic<*>>.toActualDiagnostic(root: PsiElement): List<ActualDiagnostic> {
|
||||
val result = mutableListOf<ActualDiagnostic>()
|
||||
mapTo(result) {
|
||||
filterIsInstance<Diagnostic>().mapTo(result) {
|
||||
ActualDiagnostic(it, null, true)
|
||||
}
|
||||
for (errorElement in AnalyzingUtils.getSyntaxErrorRanges(root)) {
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ class DiagnosticTestTypeValidator(
|
||||
|
||||
private fun findTestCases(diagnostic: Diagnostic): TestCasesByNumbers {
|
||||
val ranges = diagnostic.textRanges
|
||||
val filename = diagnostic.psiFile!!.name
|
||||
val filename = diagnostic.psiFile.name
|
||||
val foundTestCases = testInfo.cases.byRanges[filename]!!.floorEntry(ranges[0].startOffset)
|
||||
|
||||
if (foundTestCases != null)
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.icons.AllIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||
import org.jetbrains.kotlin.diagnostics.UnboundDiagnostic;
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.*;
|
||||
import org.jetbrains.kotlin.idea.KotlinIdeaAnalysisBundle;
|
||||
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs;
|
||||
@@ -42,7 +43,7 @@ public class IdeErrorMessages {
|
||||
private static final DiagnosticFactoryToRendererMap MAP = new DiagnosticFactoryToRendererMap("IDE");
|
||||
|
||||
@NotNull
|
||||
public static String render(@NotNull Diagnostic diagnostic) {
|
||||
public static String render(@NotNull UnboundDiagnostic diagnostic) {
|
||||
DiagnosticRenderer renderer = MAP.get(diagnostic.getFactory());
|
||||
|
||||
if (renderer != null) {
|
||||
@@ -54,7 +55,7 @@ public class IdeErrorMessages {
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public static boolean hasIdeSpecificMessage(@NotNull Diagnostic diagnostic) {
|
||||
public static boolean hasIdeSpecificMessage(@NotNull UnboundDiagnostic diagnostic) {
|
||||
return MAP.get(diagnostic.getFactory()) != null;
|
||||
}
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW
|
||||
answer.append("// ================\n")
|
||||
for (diagnostic in diagnostics) {
|
||||
answer.append("// Error at ")
|
||||
.append(diagnostic.psiFile?.name)
|
||||
.append(diagnostic.psiFile.name)
|
||||
.append(join(diagnostic.textRanges, ","))
|
||||
.append(": ")
|
||||
.append(DefaultErrorMessages.render(diagnostic))
|
||||
|
||||
@@ -128,7 +128,7 @@ class AddFunctionToSupertypeFix private constructor(
|
||||
val descriptors = generateFunctionsToAdd(function)
|
||||
if (descriptors.isEmpty()) return null
|
||||
|
||||
val project = diagnostic.psiFile!!.project
|
||||
val project = diagnostic.psiFile.project
|
||||
val functionData = descriptors.mapNotNull { createFunctionData(it, project) }
|
||||
if (functionData.isEmpty()) return null
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ class AddPropertyToSupertypeFix private constructor(
|
||||
val descriptors = generatePropertiesToAdd(property)
|
||||
if (descriptors.isEmpty()) return null
|
||||
|
||||
val project = diagnostic.psiFile!!.project
|
||||
val project = diagnostic.psiFile.project
|
||||
val propertyData = descriptors.mapNotNull { createPropertyData(it, property.initializer, project) }
|
||||
if (propertyData.isEmpty()) return null
|
||||
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ import javax.xml.parsers.DocumentBuilderFactory
|
||||
class IdeDiagnosticMessageHolder : DiagnosticMessageHolder {
|
||||
private val diagnostics = arrayListOf<Pair<Diagnostic, String>>()
|
||||
|
||||
override fun report(diagnostic: Diagnostic, file: PsiFile?, render: String) {
|
||||
override fun report(diagnostic: Diagnostic, file: PsiFile, render: String) {
|
||||
diagnostics.add(Pair(diagnostic, render))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user