@@ -8,13 +8,20 @@ import com.pinterest.ktlint.core.ast.ElementType.VALUE_ARGUMENT
8
8
import com.pinterest.ktlint.core.ast.ElementType.VALUE_PARAMETER
9
9
import com.pinterest.ktlint.core.ast.children
10
10
import com.pinterest.ktlint.core.ast.isPartOf
11
+ import com.pinterest.ktlint.core.ast.isPartOfComment
12
+ import com.pinterest.ktlint.core.ast.isWhiteSpace
13
+ import com.pinterest.ktlint.core.ast.lineNumber
14
+ import com.pinterest.ktlint.core.ast.nextSibling
15
+ import com.pinterest.ktlint.core.ast.prevSibling
11
16
import com.pinterest.ktlint.core.ast.upsertWhitespaceBeforeMe
12
17
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
13
18
import org.jetbrains.kotlin.com.intellij.psi.PsiComment
14
19
import org.jetbrains.kotlin.com.intellij.psi.PsiWhiteSpace
15
20
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement
21
+ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl
16
22
import org.jetbrains.kotlin.psi.KtAnnotationEntry
17
23
import org.jetbrains.kotlin.psi.psiUtil.endOffset
24
+ import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments
18
25
import org.jetbrains.kotlin.psi.psiUtil.nextLeaf
19
26
20
27
/* *
@@ -30,6 +37,7 @@ class AnnotationRule : Rule("annotation") {
30
37
" Multiple annotations should not be placed on the same line as the annotated construct"
31
38
const val annotationsWithParametersAreNotOnSeparateLinesErrorMessage =
32
39
" Annotations with parameters should all be placed on separate lines prior to the annotated construct"
40
+ const val fileAnnotationsShouldBeSeparated = " File annotations should be separated from packages with a blank line"
33
41
}
34
42
35
43
override fun visit (
@@ -62,7 +70,8 @@ class AnnotationRule : Rule("annotation") {
62
70
.take(annotations.size)
63
71
.toList()
64
72
65
- val noWhiteSpaceAfterAnnotation = whiteSpaces.isEmpty() || whiteSpaces.last().nextSibling is KtAnnotationEntry
73
+ val noWhiteSpaceAfterAnnotation = node.elementType != FILE_ANNOTATION_LIST &&
74
+ (whiteSpaces.isEmpty() || whiteSpaces.last().nextSibling is KtAnnotationEntry )
66
75
if (noWhiteSpaceAfterAnnotation) {
67
76
emit(
68
77
annotations.last().endOffset - 1 ,
@@ -106,6 +115,29 @@ class AnnotationRule : Rule("annotation") {
106
115
}
107
116
}
108
117
}
118
+
119
+ if (node.elementType == FILE_ANNOTATION_LIST ) {
120
+ val lineNumber = node.lineNumber()
121
+ val next = node.nextSibling {
122
+ ! it.isWhiteSpace() && it.textLength > 0 && ! (it.isPartOfComment() && it.lineNumber() == lineNumber)
123
+ }
124
+ val nextLineNumber = next?.lineNumber()
125
+ if (lineNumber != null && nextLineNumber != null ) {
126
+ val diff = nextLineNumber - lineNumber
127
+ if (diff < 2 ) {
128
+ emit(0 , fileAnnotationsShouldBeSeparated, true )
129
+ if (autoCorrect) {
130
+ if (diff == 0 ) {
131
+ node.psi.getNextSiblingIgnoringWhitespaceAndComments(withItself = false )?.node
132
+ ?.prevSibling { it.isWhiteSpace() }
133
+ ?.let { (it as ? LeafPsiElement )?.delete() }
134
+ next.treeParent.addChild(PsiWhiteSpaceImpl (" \n " ), next)
135
+ }
136
+ next.treeParent.addChild(PsiWhiteSpaceImpl (" \n " ), next)
137
+ }
138
+ }
139
+ }
140
+ }
109
141
}
110
142
111
143
private fun getNewlineWithIndent (modifierListRoot : ASTNode ): String {
0 commit comments