[groovy] IDEA-207415: Fix incorrect inference of visibility from annotation
authorKonstantin Nisht <konstantin.nisht@jetbrains.com>
Mon, 10 Aug 2020 00:53:45 +0000 (03:53 +0300)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Mon, 10 Aug 2020 13:54:00 +0000 (13:54 +0000)
GitOrigin-RevId: 7184217a76edb8b2341a3e11a50c2253aca0d3e5

plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ast/GrVisibilityUtils.kt
plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TupleConstructorTest.groovy

index 444d3beef336991f01f874225f467c764b04a465..4cfad9ae41a5348494d996eba4c55568ed0b99aa 100644 (file)
@@ -35,12 +35,16 @@ fun getVisibility(annotation: PsiAnnotation, sourceElement: PsiElement, defaultV
   val targetAnnotation = visAnnotations.firstOrNull { inferStringAttribute(it, "id") == visAnnotationId }
   if (targetAnnotation == null) return defaultVisibility
 
-  val visibility: GroovyVisibility = when {
-    sourceElement is PsiMethod && sourceElement.isConstructor -> inferGroovyVisibility(targetAnnotation, "constructor")
-    sourceElement is PsiMethod -> inferGroovyVisibility(targetAnnotation, "method")
-    sourceElement is PsiClass -> inferGroovyVisibility(targetAnnotation, "type")
-    else -> null
-  } ?: inferGroovyVisibility(targetAnnotation, "value") ?: return defaultVisibility
+  val visibility: GroovyVisibility =
+    when {
+      sourceElement is PsiMethod && sourceElement.isConstructor -> inferGroovyVisibility(targetAnnotation, "constructor")
+      sourceElement is PsiMethod -> inferGroovyVisibility(targetAnnotation, "method")
+      sourceElement is PsiClass -> inferGroovyVisibility(targetAnnotation, "type")
+      else -> null
+    }?.takeUnless { it == GroovyVisibility.UNDEFINED }
+     ?: inferGroovyVisibility(targetAnnotation, "value")
+     ?.takeUnless { it == GroovyVisibility.UNDEFINED }
+     ?: return defaultVisibility
 
   return when (visibility) {
     GroovyVisibility.UNDEFINED -> defaultVisibility
@@ -53,10 +57,11 @@ fun getVisibility(annotation: PsiAnnotation, sourceElement: PsiElement, defaultV
 
 private fun inferGroovyVisibility(annotation: PsiAnnotation, attributeName: String) : GroovyVisibility? {
   val targetValue = annotation.findAttributeValue(attributeName)
-  return if (targetValue is PsiReference) {
+  return if (targetValue is PsiQualifiedReference) {
     try {
-      GroovyVisibility.valueOf(targetValue.canonicalText)
-    } catch (e : IllegalArgumentException) {
+      targetValue.referenceName?.run(GroovyVisibility::valueOf) ?: return null
+    }
+    catch (e: IllegalArgumentException) {
       null
     }
   } else {
index 247f168e40850e62cdbf9547211049df0f36ae5f..41199283e649b4eb4117859451220e46e294e2cc 100644 (file)
@@ -311,6 +311,28 @@ class X {
         def x = new <error>Cde</error>("mem", 1, true)
     }
 
+}"""
+  }
+
+  @Test
+  void 'test visibility options with value'() {
+    fixture.addFileToProject 'other.groovy', """
+@groovy.transform.CompileStatic
+@groovy.transform.TupleConstructor(defaults = false)
+@groovy.transform.VisibilityOptions(Visibility.PRIVATE)
+class Cde {
+    String actionType
+    long referrerCode
+    boolean referrerUrl
+}"""
+    highlightingTest """
+class X {
+
+    @groovy.transform.CompileStatic
+    static void main(String[] args) {
+        def x = new <error>Cde</error>("mem", 1, true)
+    }
+
 }"""
   }
 }