Allow to suppress warnings at file level

This commit is contained in:
Nikolay Krasko
2015-12-07 21:11:26 +03:00
committed by Nikolay Krasko
parent 712d2bdec0
commit aff83087a3
24 changed files with 192 additions and 22 deletions
@@ -57,20 +57,29 @@ fun createSuppressWarningActions(element: PsiElement, severity: Severity, suppre
var current: PsiElement? = element
var suppressAtStatementAllowed = true
while (current != null) {
if (current is KtDeclaration && current !is KtDestructuringDeclaration) {
val declaration = current
val kind = DeclarationKindDetector.detect(declaration)
if (kind != null) {
actions.add(KotlinSuppressIntentionAction(declaration, suppressionKey, kind))
when {
current is KtDeclaration && current !is KtDestructuringDeclaration -> {
val declaration = current
val kind = DeclarationKindDetector.detect(declaration)
if (kind != null) {
actions.add(KotlinSuppressIntentionAction(declaration, suppressionKey, kind))
}
suppressAtStatementAllowed = false
}
suppressAtStatementAllowed = false
}
else if (current is KtExpression && suppressAtStatementAllowed) {
// Add suppress action at first statement
if (current.parent is KtBlockExpression || current.parent is KtDestructuringDeclaration) {
val kind = if (current.parent is KtBlockExpression) "statement" else "initializer"
current is KtExpression && suppressAtStatementAllowed -> {
// Add suppress action at first statement
if (current.parent is KtBlockExpression || current.parent is KtDestructuringDeclaration) {
val kind = if (current.parent is KtBlockExpression) "statement" else "initializer"
actions.add(KotlinSuppressIntentionAction(current, suppressionKey,
AnnotationHostKind(kind, "", true)))
suppressAtStatementAllowed = false
}
}
current is KtFile -> {
actions.add(KotlinSuppressIntentionAction(current, suppressionKey,
AnnotationHostKind(kind, "", true)))
AnnotationHostKind("file", current.name, true)))
suppressAtStatementAllowed = false
}
}
@@ -25,13 +25,21 @@ import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.util.PsiPrecedences
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.replaceFileAnnotationList
import org.jetbrains.kotlin.resolve.BindingContext
public class KotlinSuppressIntentionAction(
private val suppressAt: KtExpression,
class KotlinSuppressIntentionAction private constructor(
private val suppressAt: PsiElement,
private val suppressKey: String,
private val kind: AnnotationHostKind
) : SuppressIntentionAction() {
constructor(suppressAt: KtExpression,
suppressKey: String,
kind: AnnotationHostKind) : this(suppressAt as PsiElement, suppressKey, kind)
constructor(suppressAt: KtFile,
suppressKey: String,
kind: AnnotationHostKind) : this(suppressAt as PsiElement, suppressKey, kind)
override fun getFamilyName() = KotlinBundle.message("suppress.warnings.family")
override fun getText() = KotlinBundle.message("suppress.warning.for", suppressKey, kind.kind, kind.name)
@@ -40,15 +48,43 @@ public class KotlinSuppressIntentionAction(
override fun invoke(project: Project, editor: Editor?, element: PsiElement) {
val id = "\"$suppressKey\""
if (suppressAt is KtModifierListOwner) {
suppressAtModifierListOwner(suppressAt, id)
when (suppressAt) {
is KtModifierListOwner ->
suppressAtModifierListOwner(suppressAt, id)
is KtAnnotatedExpression ->
suppressAtAnnotatedExpression(CaretBox(suppressAt, editor), id)
is KtExpression ->
suppressAtExpression(CaretBox(suppressAt, editor), id)
is KtFile ->
suppressAtFile(suppressAt, id)
}
else if (suppressAt is KtAnnotatedExpression) {
suppressAtAnnotatedExpression(CaretBox(suppressAt, editor), id)
}
private fun suppressAtFile(ktFile: KtFile, id: String) {
val psiFactory = KtPsiFactory(suppressAt)
val fileAnnotationList: KtFileAnnotationList? = ktFile.fileAnnotationList
if (fileAnnotationList == null) {
val newAnnotationList = psiFactory.createFileAnnotationListWithAnnotation(suppressAnnotationText(id, false))
val createAnnotationList = replaceFileAnnotationList(ktFile, newAnnotationList)
ktFile.addAfter(psiFactory.createWhiteSpace(kind), createAnnotationList)
return
}
else if (suppressAt is KtExpression) {
suppressAtExpression(CaretBox(suppressAt, editor), id)
val suppressAnnotation: KtAnnotationEntry? = findSuppressAnnotation(fileAnnotationList)
if (suppressAnnotation == null) {
val newSuppressAnnotation = psiFactory.createFileAnnotation(suppressAnnotationText(id, false))
fileAnnotationList.add(psiFactory.createWhiteSpace(kind))
fileAnnotationList.add(newSuppressAnnotation) as KtAnnotationEntry
return
}
addArgumentToSuppressAnnotation(suppressAnnotation, id)
}
private fun suppressAtModifierListOwner(suppressAt: KtModifierListOwner, id: String) {
@@ -125,11 +161,20 @@ public class KotlinSuppressIntentionAction(
}
}
private fun suppressAnnotationText(id: String) = "@Suppress($id)"
private fun suppressAnnotationText(id: String, withAt: Boolean = true) = "${if (withAt) "@" else ""}${KotlinBuiltIns.FQ_NAMES.suppress.shortName()}($id)"
private fun findSuppressAnnotation(annotated: KtAnnotated): KtAnnotationEntry? {
val context = annotated.analyze()
for (entry in annotated.getAnnotationEntries()) {
return findSuppressAnnotation(context, annotated.getAnnotationEntries())
}
private fun findSuppressAnnotation(annotationList: KtFileAnnotationList): KtAnnotationEntry? {
val context = annotationList.analyze()
return findSuppressAnnotation(context, annotationList.annotationEntries)
}
private fun findSuppressAnnotation(context: BindingContext, annotationEntries: List<KtAnnotationEntry>): KtAnnotationEntry? {
for (entry in annotationEntries) {
val annotationDescriptor = context.get(BindingContext.ANNOTATION, entry)
if (annotationDescriptor != null && KotlinBuiltIns.isSuppressAnnotation(annotationDescriptor)) {
return entry