Allow annotations within angle brackets to be placed on same line (#654)

diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationRule.kt
index 84f1cec..476c648 100644
--- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationRule.kt
+++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationRule.kt
@@ -2,9 +2,11 @@
 
 import com.pinterest.ktlint.core.Rule
 import com.pinterest.ktlint.core.ast.ElementType.MODIFIER_LIST
+import com.pinterest.ktlint.core.ast.ElementType.TYPE_ARGUMENT_LIST
 import com.pinterest.ktlint.core.ast.ElementType.VALUE_ARGUMENT_LIST
 import com.pinterest.ktlint.core.ast.ElementType.VALUE_PARAMETER_LIST
 import com.pinterest.ktlint.core.ast.children
+import com.pinterest.ktlint.core.ast.isPartOf
 import com.pinterest.ktlint.core.ast.upsertWhitespaceBeforeMe
 import org.jetbrains.kotlin.com.intellij.lang.ASTNode
 import org.jetbrains.kotlin.com.intellij.psi.PsiComment
@@ -74,8 +76,9 @@
             annotations.any { it.valueArgumentList != null } &&
                 !whiteSpaces.all { it.textContains('\n') } &&
                 doesNotEndWithAComment(whiteSpaces) &&
-                node.treeParent.elementType != VALUE_PARAMETER_LIST &&
-                node.treeParent.elementType != VALUE_ARGUMENT_LIST
+                node.treeParent.elementType != VALUE_PARAMETER_LIST && // fun fn(@Ann("blah") a: String)
+                node.treeParent.elementType != VALUE_ARGUMENT_LIST && // fn(@Ann("blah") "42")
+                !node.isPartOf(TYPE_ARGUMENT_LIST) // val property: Map<@Ann("blah") String, Int>
 
         if (multipleAnnotationsOnSameLineAsAnnotatedConstruct) {
             emit(
diff --git a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationRuleTest.kt b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationRuleTest.kt
index 8a54fe2..6d38228 100644
--- a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationRuleTest.kt
+++ b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/AnnotationRuleTest.kt
@@ -549,4 +549,40 @@
             """.trimIndent()
         assertThat(AnnotationRule().format(code)).isEqualTo(code)
     }
+
+    @Test
+    fun `lint annotations on type arguments may be placed on same line`() {
+        val code =
+            """
+            val aProperty: Map<@Ann("test") Int, @JvmSuppressWildcards(true) (String) -> Int?>
+            val bProperty: Map<
+                @Ann String,
+                @Ann("test") Int, 
+                @JvmSuppressWildcards(true) (String) -> Int?
+                >
+                
+            fun doSomething() {
+                funWithGenericsCall<@JvmSuppressWildcards(true) Int>()
+            }
+            """.trimIndent()
+        assertThat(AnnotationRule().lint(code)).isEmpty()
+    }
+
+    @Test
+    fun `format annotations on type arguments may be placed on same line`() {
+        val code =
+            """
+            val aProperty: Map<@Ann("test") Int, @JvmSuppressWildcards(true) (String) -> Int?>
+            val bProperty: Map<
+                @Ann String,
+                @Ann("test") Int, 
+                @JvmSuppressWildcards(true) (String) -> Int?
+                >
+                
+            fun doSomething() {
+                funWithGenericsCall<@JvmSuppressWildcards(true) Int>()
+            }
+            """.trimIndent()
+        assertThat(AnnotationRule().format(code)).isEqualTo(code)
+    }
 }