I'm in the process of migrating from PSI to UAST and yesterday I've seen that there is the following function, that I assume will also work better within the IDE (just like the Timber method comparison check).
context.evaluator.getAllAnnotations
Unfortunately when I use it on this test case:
fun testOverrideComesFirstOnParameters() {
@Language("java") val source = """
package foo;
public class MyTest {
public void myTest(@Test @Override int something) { }
}""".trimMargin()
assertThat(lintProject(java(source))).startsWith("""src/foo/MyTest.java:4: Warning: Annotations are in wrong order. Should be @Override @Test [WrongAnnotationOrder]
| public void myTest(@Test @Override int something) { }
| ~~~~~~~~~
|0 errors, 1 warnings""".trimMargin())
}
It fails with:
java.lang.RuntimeException: java.lang.AssertionError: org.jetbrains.uast.java.JavaUParameter@10ed5906:class org.jetbrains.uast.java.JavaUParameter not found among parameters: [PsiParameter:something]. parameterList' parent: PsiMethod:myTest; parameter.isValid()=true; parameterList.isValid()= true; parameterList stub: null; parameter stub: ---; suspect: PsiParameter:something (index=0); class com.intellij.psi.impl.source.PsiParameterImpl suspect stub: null; parameter.equals(suspect) = false; parameter.getNode() == suspect.getNode(): true; .
at com.android.tools.lint.checks.infrastructure.LintDetectorTest$TestLintClient.log(LintDetectorTest.java:990)
at com.android.tools.lint.client.api.LintDriver$LintClientWrapper.log(LintDriver.kt:2173)
at com.android.tools.lint.client.api.LintDriver$Companion.handleDetectorError(LintDriver.kt:2772)
at com.android.tools.lint.client.api.LintDriver.analyze(LintDriver.kt:394)
at com.android.tools.lint.checks.infrastructure.LintDetectorTest$TestLintClient.analyze(LintDetectorTest.java:1225)
at com.android.tools.lint.checks.infrastructure.LintDetectorTest.checkLint(LintDetectorTest.java:292)
at com.android.tools.lint.checks.infrastructure.LintDetectorTest.checkLint(LintDetectorTest.java:265)
at com.android.tools.lint.checks.infrastructure.LintDetectorTest.lintProject(LintDetectorTest.java:422)
at com.vanniktech.lintrules.android.AnnotationOrderDetectorTest.testOverrideComesFirstOnParameters(AnnotationOrderDetectorTest.kt:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at junit.framework.TestCase.runTest(TestCase.java:176)
at junit.framework.TestCase.runBare(TestCase.java:141)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:252)
at junit.framework.TestSuite.run(TestSuite.java:247)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:114)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:57)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:66)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy1.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:108)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:146)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:128)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.AssertionError: org.jetbrains.uast.java.JavaUParameter@10ed5906:class org.jetbrains.uast.java.JavaUParameter not found among parameters: [PsiParameter:something]. parameterList' parent: PsiMethod:myTest; parameter.isValid()=true; parameterList.isValid()= true; parameterList stub: null; parameter stub: ---; suspect: PsiParameter:something (index=0); class com.intellij.psi.impl.source.PsiParameterImpl suspect stub: null; parameter.equals(suspect) = false; parameter.getNode() == suspect.getNode(): true; .
at com.intellij.openapi.diagnostic.DefaultLogger.error(DefaultLogger.java:77)
at com.intellij.openapi.diagnostic.Logger.error(Logger.java:132)
at com.intellij.psi.impl.PsiImplUtil.getParameterIndex(PsiImplUtil.java:162)
at com.intellij.psi.impl.source.PsiParameterListImpl.getParameterIndex(PsiParameterListImpl.java:51)
at com.intellij.codeInsight.AnnotationUtil.getAllAnnotations(AnnotationUtil.java:455)
at com.android.tools.lint.helpers.DefaultJavaEvaluator.getAllAnnotations(DefaultJavaEvaluator.kt:96)
at com.vanniktech.lintrules.android.AnnotationOrderDetector$AnnotationOrderVisitor.processAnnotations(AnnotationOrderDetector.kt:159)
at com.vanniktech.lintrules.android.AnnotationOrderDetector$AnnotationOrderVisitor.visitVariable(AnnotationOrderDetector.kt:149)
at com.android.tools.lint.client.api.UElementVisitor$DispatchPsiVisitor.visitVariable(UElementVisitor.java:1084)
at org.jetbrains.uast.visitor.UastVisitor$DefaultImpls.visitParameter(UastVisitor.kt:29)
at org.jetbrains.uast.visitor.AbstractUastVisitor.visitParameter(UastVisitor.kt:129)
at com.android.tools.lint.client.api.UElementVisitor$DispatchPsiVisitor.visitParameter(UElementVisitor.java:909)
at org.jetbrains.uast.UParameter$DefaultImpls.accept(UVariable.kt:72)
at org.jetbrains.uast.java.JavaUParameter.accept(JavaUVariable.kt:58)
at org.jetbrains.uast.internal.ImplementationUtilsKt.acceptList(implementationUtils.kt:23)
at org.jetbrains.uast.UMethod$DefaultImpls.accept(UMethod.kt:52)
at org.jetbrains.uast.java.JavaUMethod.accept(JavaUMethod.kt:25)
at org.jetbrains.uast.internal.ImplementationUtilsKt.acceptList(implementationUtils.kt:23)
at org.jetbrains.uast.UClass$DefaultImpls.accept(UClass.kt:63)
at org.jetbrains.uast.java.AbstractJavaUClass.accept(JavaUClass.kt:26)
at org.jetbrains.uast.internal.ImplementationUtilsKt.acceptList(implementationUtils.kt:23)
at org.jetbrains.uast.UFile$DefaultImpls.accept(UFile.kt:87)
at org.jetbrains.uast.java.JavaUFile.accept(JavaUFile.kt:27)
at com.android.tools.lint.client.api.UElementVisitor.lambda$visitFile$7(UElementVisitor.java:299)
at com.android.tools.lint.client.api.LintClient.runReadAction(LintClient.kt:1482)
at com.android.tools.lint.client.api.LintDriver$LintClientWrapper.runReadAction(LintDriver.kt:2111)
at com.android.tools.lint.client.api.UElementVisitor.visitFile(UElementVisitor.java:296)
at com.android.tools.lint.client.api.LintDriver$visitJavaFiles$1.run(LintDriver.kt:1533)
at com.android.tools.lint.client.api.LintClient.runReadAction(LintClient.kt:1482)
at com.android.tools.lint.client.api.LintDriver$LintClientWrapper.runReadAction(LintDriver.kt:2111)
at com.android.tools.lint.client.api.LintDriver.visitJavaFiles(LintDriver.kt:1533)
at com.android.tools.lint.client.api.LintDriver.visitJavaFiles(LintDriver.kt:1494)
at com.android.tools.lint.client.api.LintDriver.checkJava(LintDriver.kt:1472)
at com.android.tools.lint.client.api.LintDriver.runFileDetectors(LintDriver.kt:1025)
at com.android.tools.lint.client.api.LintDriver.checkProject(LintDriver.kt:882)
at com.android.tools.lint.client.api.LintDriver.analyze(LintDriver.kt:385)
... 47 more
Caused by: java.lang.Throwable
... 82 more
I also tested 26.1.0-alpha03 and there it's failing too. My calling code looks like this:
class AnnotationOrderVisitor(private val context: JavaContext) : UElementHandler() {
override fun visitVariable(variable: UVariable) {
processAnnotations(variable, variable)
}
override fun visitMethod(method: UMethod) {
processAnnotations(method, method)
}
private fun processAnnotations(element: UElement, modifierListOwner: PsiModifierListOwner) {
val annotations = context.evaluator.getAllAnnotations(modifierListOwner, true).mapNotNull { it.qualifiedName?.split(".")?.lastOrNull() }
...
}
Any help is appreciated.