Code cleanup: KotlinPsiChecker
This commit is contained in:
@@ -79,7 +79,7 @@ open class KotlinPsiChecker : Annotator, HighlightRangeExtension {
|
|||||||
return file is KtFile
|
return file is KtFile
|
||||||
}
|
}
|
||||||
|
|
||||||
open protected fun shouldSuppressUnusedParameter(parameter: KtParameter): Boolean = false
|
protected open fun shouldSuppressUnusedParameter(parameter: KtParameter): Boolean = false
|
||||||
|
|
||||||
fun annotateElement(element: PsiElement, holder: AnnotationHolder, diagnostics: Diagnostics) {
|
fun annotateElement(element: PsiElement, holder: AnnotationHolder, diagnostics: Diagnostics) {
|
||||||
val diagnosticsForElement = diagnostics.forElement(element)
|
val diagnosticsForElement = diagnostics.forElement(element)
|
||||||
@@ -92,20 +92,22 @@ open class KotlinPsiChecker : Annotator, HighlightRangeExtension {
|
|||||||
if (diagnosticsForElement.isEmpty()) return
|
if (diagnosticsForElement.isEmpty()) return
|
||||||
|
|
||||||
if (KotlinHighlightingUtil.shouldHighlightErrors(element)) {
|
if (KotlinHighlightingUtil.shouldHighlightErrors(element)) {
|
||||||
ElementAnnotator(element, holder, { param -> shouldSuppressUnusedParameter(param) }).registerDiagnosticsAnnotations(diagnosticsForElement)
|
ElementAnnotator(element, holder) { param ->
|
||||||
|
shouldSuppressUnusedParameter(param)
|
||||||
|
}.registerDiagnosticsAnnotations(diagnosticsForElement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getAfterAnalysisVisitor(holder: AnnotationHolder, bindingContext: BindingContext) = arrayOf(
|
fun getAfterAnalysisVisitor(holder: AnnotationHolder, bindingContext: BindingContext) = arrayOf(
|
||||||
PropertiesHighlightingVisitor(holder, bindingContext),
|
PropertiesHighlightingVisitor(holder, bindingContext),
|
||||||
FunctionsHighlightingVisitor(holder, bindingContext),
|
FunctionsHighlightingVisitor(holder, bindingContext),
|
||||||
VariablesHighlightingVisitor(holder, bindingContext),
|
VariablesHighlightingVisitor(holder, bindingContext),
|
||||||
TypeKindHighlightingVisitor(holder, bindingContext)
|
TypeKindHighlightingVisitor(holder, bindingContext)
|
||||||
)
|
)
|
||||||
|
|
||||||
fun createQuickFixes(diagnostic: Diagnostic): Collection<IntentionAction> =
|
fun createQuickFixes(diagnostic: Diagnostic): Collection<IntentionAction> =
|
||||||
createQuickFixes(listOfNotNull(diagnostic))[diagnostic]
|
createQuickFixes(listOfNotNull(diagnostic))[diagnostic]
|
||||||
|
|
||||||
private val UNRESOLVED_KEY = Key<Unit>("KotlinPsiChecker.UNRESOLVED_KEY")
|
private val UNRESOLVED_KEY = Key<Unit>("KotlinPsiChecker.UNRESOLVED_KEY")
|
||||||
|
|
||||||
@@ -122,10 +124,9 @@ private fun createQuickFixes(similarDiagnostics: Collection<Diagnostic>): MultiM
|
|||||||
val intentionActionsFactories = QuickFixes.getInstance().getActionFactories(factory)
|
val intentionActionsFactories = QuickFixes.getInstance().getActionFactories(factory)
|
||||||
for (intentionActionsFactory in intentionActionsFactories) {
|
for (intentionActionsFactory in intentionActionsFactories) {
|
||||||
val allProblemsActions = intentionActionsFactory.createActionsForAllProblems(similarDiagnostics)
|
val allProblemsActions = intentionActionsFactory.createActionsForAllProblems(similarDiagnostics)
|
||||||
if (!allProblemsActions.isEmpty()) {
|
if (allProblemsActions.isNotEmpty()) {
|
||||||
actions.putValues(first, allProblemsActions)
|
actions.putValues(first, allProblemsActions)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for (diagnostic in similarDiagnostics) {
|
for (diagnostic in similarDiagnostics) {
|
||||||
actions.putValues(diagnostic, intentionActionsFactory.createActions(diagnostic))
|
actions.putValues(diagnostic, intentionActionsFactory.createActions(diagnostic))
|
||||||
}
|
}
|
||||||
@@ -142,12 +143,12 @@ private fun createQuickFixes(similarDiagnostics: Collection<Diagnostic>): MultiM
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun Diagnostic.getRealDiagnosticFactory(): DiagnosticFactory<*> =
|
private fun Diagnostic.getRealDiagnosticFactory(): DiagnosticFactory<*> =
|
||||||
when (factory) {
|
when (factory) {
|
||||||
Errors.PLUGIN_ERROR -> Errors.PLUGIN_ERROR.cast(this).a.factory
|
Errors.PLUGIN_ERROR -> Errors.PLUGIN_ERROR.cast(this).a.factory
|
||||||
Errors.PLUGIN_WARNING -> Errors.PLUGIN_WARNING.cast(this).a.factory
|
Errors.PLUGIN_WARNING -> Errors.PLUGIN_WARNING.cast(this).a.factory
|
||||||
Errors.PLUGIN_INFO -> Errors.PLUGIN_INFO.cast(this).a.factory
|
Errors.PLUGIN_INFO -> Errors.PLUGIN_INFO.cast(this).a.factory
|
||||||
else -> factory
|
else -> factory
|
||||||
}
|
}
|
||||||
|
|
||||||
private object NoDeclarationDescriptorsChecker {
|
private object NoDeclarationDescriptorsChecker {
|
||||||
private val LOG = Logger.getInstance(NoDeclarationDescriptorsChecker::class.java)
|
private val LOG = Logger.getInstance(NoDeclarationDescriptorsChecker::class.java)
|
||||||
@@ -168,9 +169,11 @@ private object NoDeclarationDescriptorsChecker {
|
|||||||
when (type) {
|
when (type) {
|
||||||
is Class<*> -> {
|
is Class<*> -> {
|
||||||
if (DeclarationDescriptor::class.java.isAssignableFrom(type) || KotlinType::class.java.isAssignableFrom(type)) {
|
if (DeclarationDescriptor::class.java.isAssignableFrom(type) || KotlinType::class.java.isAssignableFrom(type)) {
|
||||||
LOG.error("QuickFix class ${field.declaringClass.name} contains field ${field.name} that holds ${type.simpleName}. "
|
LOG.error(
|
||||||
+ "This leads to holding too much memory through this quick-fix instance. "
|
"QuickFix class ${field.declaringClass.name} contains field ${field.name} that holds ${type.simpleName}. "
|
||||||
+ "Possible solution can be wrapping it using KotlinIntentionActionFactoryWithDelegate.")
|
+ "This leads to holding too much memory through this quick-fix instance. "
|
||||||
|
+ "Possible solution can be wrapping it using KotlinIntentionActionFactoryWithDelegate."
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IntentionAction::class.java.isAssignableFrom(type)) {
|
if (IntentionAction::class.java.isAssignableFrom(type)) {
|
||||||
@@ -192,9 +195,11 @@ private object NoDeclarationDescriptorsChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ElementAnnotator(private val element: PsiElement,
|
private class ElementAnnotator(
|
||||||
private val holder: AnnotationHolder,
|
private val element: PsiElement,
|
||||||
private val shouldSuppressUnusedParameter: (KtParameter) -> Boolean) {
|
private val holder: AnnotationHolder,
|
||||||
|
private val shouldSuppressUnusedParameter: (KtParameter) -> Boolean
|
||||||
|
) {
|
||||||
fun registerDiagnosticsAnnotations(diagnostics: Collection<Diagnostic>) {
|
fun registerDiagnosticsAnnotations(diagnostics: Collection<Diagnostic>) {
|
||||||
diagnostics.groupBy { it.factory }.forEach { group -> registerDiagnosticAnnotations(group.value) }
|
diagnostics.groupBy { it.factory }.forEach { group -> registerDiagnosticAnnotations(group.value) }
|
||||||
}
|
}
|
||||||
@@ -220,26 +225,30 @@ private class ElementAnnotator(private val element: PsiElement,
|
|||||||
val reference = referenceExpression.mainReference
|
val reference = referenceExpression.mainReference
|
||||||
if (reference is MultiRangeReference) {
|
if (reference is MultiRangeReference) {
|
||||||
AnnotationPresentationInfo(
|
AnnotationPresentationInfo(
|
||||||
ranges = reference.ranges.map { it.shiftRight(referenceExpression.textOffset) },
|
ranges = reference.ranges.map { it.shiftRight(referenceExpression.textOffset) },
|
||||||
highlightType = ProblemHighlightType.LIKE_UNKNOWN_SYMBOL)
|
highlightType = ProblemHighlightType.LIKE_UNKNOWN_SYMBOL
|
||||||
}
|
)
|
||||||
else {
|
} else {
|
||||||
AnnotationPresentationInfo(ranges, highlightType = ProblemHighlightType.LIKE_UNKNOWN_SYMBOL)
|
AnnotationPresentationInfo(ranges, highlightType = ProblemHighlightType.LIKE_UNKNOWN_SYMBOL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Errors.ILLEGAL_ESCAPE -> AnnotationPresentationInfo(ranges, textAttributes = KotlinHighlightingColors.INVALID_STRING_ESCAPE)
|
Errors.ILLEGAL_ESCAPE -> AnnotationPresentationInfo(
|
||||||
|
ranges, textAttributes = KotlinHighlightingColors.INVALID_STRING_ESCAPE
|
||||||
|
)
|
||||||
|
|
||||||
Errors.REDECLARATION -> AnnotationPresentationInfo(
|
Errors.REDECLARATION -> AnnotationPresentationInfo(
|
||||||
ranges = listOf(diagnostic.textRanges.first()), nonDefaultMessage = "")
|
ranges = listOf(diagnostic.textRanges.first()), nonDefaultMessage = ""
|
||||||
|
)
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
AnnotationPresentationInfo(
|
AnnotationPresentationInfo(
|
||||||
ranges,
|
ranges,
|
||||||
highlightType = if (factory == Errors.INVISIBLE_REFERENCE)
|
highlightType = if (factory == Errors.INVISIBLE_REFERENCE)
|
||||||
ProblemHighlightType.LIKE_UNKNOWN_SYMBOL
|
ProblemHighlightType.LIKE_UNKNOWN_SYMBOL
|
||||||
else
|
else
|
||||||
null)
|
null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,17 +258,17 @@ private class ElementAnnotator(private val element: PsiElement,
|
|||||||
}
|
}
|
||||||
|
|
||||||
AnnotationPresentationInfo(
|
AnnotationPresentationInfo(
|
||||||
ranges,
|
ranges,
|
||||||
textAttributes = when (factory) {
|
textAttributes = when (factory) {
|
||||||
Errors.DEPRECATION -> CodeInsightColors.DEPRECATED_ATTRIBUTES
|
Errors.DEPRECATION -> CodeInsightColors.DEPRECATED_ATTRIBUTES
|
||||||
Errors.UNUSED_ANONYMOUS_PARAMETER -> CodeInsightColors.WEAK_WARNING_ATTRIBUTES
|
Errors.UNUSED_ANONYMOUS_PARAMETER -> CodeInsightColors.WEAK_WARNING_ATTRIBUTES
|
||||||
else -> null
|
else -> null
|
||||||
},
|
},
|
||||||
highlightType = when (factory) {
|
highlightType = when (factory) {
|
||||||
in Errors.UNUSED_ELEMENT_DIAGNOSTICS -> ProblemHighlightType.LIKE_UNUSED_SYMBOL
|
in Errors.UNUSED_ELEMENT_DIAGNOSTICS -> ProblemHighlightType.LIKE_UNUSED_SYMBOL
|
||||||
Errors.UNUSED_ANONYMOUS_PARAMETER -> ProblemHighlightType.WEAK_WARNING
|
Errors.UNUSED_ANONYMOUS_PARAMETER -> ProblemHighlightType.WEAK_WARNING
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Severity.INFO -> AnnotationPresentationInfo(ranges, highlightType = ProblemHighlightType.INFORMATION)
|
Severity.INFO -> AnnotationPresentationInfo(ranges, highlightType = ProblemHighlightType.INFORMATION)
|
||||||
@@ -271,8 +280,7 @@ private class ElementAnnotator(private val element: PsiElement,
|
|||||||
private fun setUpAnnotations(diagnostics: List<Diagnostic>, data: AnnotationPresentationInfo) {
|
private fun setUpAnnotations(diagnostics: List<Diagnostic>, data: AnnotationPresentationInfo) {
|
||||||
val fixesMap = try {
|
val fixesMap = try {
|
||||||
createQuickFixes(diagnostics)
|
createQuickFixes(diagnostics)
|
||||||
}
|
} catch (e: Exception) {
|
||||||
catch (e: Exception) {
|
|
||||||
if (e is ControlFlowException) {
|
if (e is ControlFlowException) {
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
@@ -310,10 +318,10 @@ private class ElementAnnotator(private val element: PsiElement,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class AnnotationPresentationInfo(
|
private class AnnotationPresentationInfo(
|
||||||
val ranges: List<TextRange>,
|
val ranges: List<TextRange>,
|
||||||
val nonDefaultMessage: String? = null,
|
val nonDefaultMessage: String? = null,
|
||||||
val highlightType: ProblemHighlightType? = null,
|
val highlightType: ProblemHighlightType? = null,
|
||||||
val textAttributes: TextAttributesKey? = null
|
val textAttributes: TextAttributesKey? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun create(diagnostic: Diagnostic, range: TextRange, holder: AnnotationHolder): Annotation {
|
fun create(diagnostic: Diagnostic, range: TextRange, holder: AnnotationHolder): Annotation {
|
||||||
@@ -324,8 +332,7 @@ private class AnnotationPresentationInfo(
|
|||||||
Severity.WARNING -> {
|
Severity.WARNING -> {
|
||||||
if (highlightType == ProblemHighlightType.WEAK_WARNING) {
|
if (highlightType == ProblemHighlightType.WEAK_WARNING) {
|
||||||
holder.createWeakWarningAnnotation(range, defaultMessage)
|
holder.createWeakWarningAnnotation(range, defaultMessage)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
holder.createWarningAnnotation(range, defaultMessage)
|
holder.createWarningAnnotation(range, defaultMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -351,8 +358,7 @@ private class AnnotationPresentationInfo(
|
|||||||
val factoryName = diagnostic.factory.name
|
val factoryName = diagnostic.factory.name
|
||||||
message = if (message.startsWith("<html>")) {
|
message = if (message.startsWith("<html>")) {
|
||||||
"<html>[$factoryName] ${message.substring("<html>".length)}"
|
"<html>[$factoryName] ${message.substring("<html>".length)}"
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
"[$factoryName] $message"
|
"[$factoryName] $message"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user