reportIssue on SyntaxTrivia fails with UnsupportedOperationException

Hi there,

I’m playing around with writing a custom rule plugin. I’m implementing a rule checking Java comments to match a certain pattern. Reporting an issue, however, fails with an UnsupportedOperationException:

@Override
public List<Kind> nodesToVisit() {
	return Collections.singletonList(Kind.TRIVIA);
}
@Override
public void visitTrivia(SyntaxTrivia syntaxTrivia) {
	checkForPattern(syntaxTrivia);
}
private void checkForPattern(SyntaxTrivia syntaxTrivia) {
if (JAVA_COMMENT_PATTERN.matcher(syntaxTrivia.comment()).find()) {
    final boolean isPatternBroken = isPatternBroken(syntaxTrivia, JAVA_VALID_COMMENT_PATTERN);
    if (isPatternBroken) {
        reportIssue(syntaxTrivia, FAIL_MESSAGE);
   }
}
}

I get the exception and message below. Is it not allowed to put a syntaxTrivia into the reportIssue method of a IssuableSubscriptionVisitor? What to put else? syntaxTrivia.parent() is null and this results in an NPE.

Cheers,
Hauke

ERROR Unable to run check class org.sonar.samples.java.checks.MyFirstCustomCheck - MyFirstCustomRule on file 'src/test/files/MyFirstCustomCheck.java', To help improve the SonarSource Java Analyzer, please report this problem to SonarSource: see https://community.sonarsource.com/
java.lang.UnsupportedOperationException
	at org.sonar.java.model.InternalSyntaxTrivia.children(InternalSyntaxTrivia.java:61)
	at org.sonar.java.model.JavaTree.getChildren(JavaTree.java:137)
	at org.sonar.java.model.JavaTree.firstToken(JavaTree.java:76)
	at org.sonar.java.AnalyzerMessage.getNonEmptyTree(AnalyzerMessage.java:195)
	at org.sonar.java.AnalyzerMessage.textSpanFor(AnalyzerMessage.java:125)
	at org.sonar.java.model.DefaultJavaFileScannerContext.createAnalyzerMessage(DefaultJavaFileScannerContext.java:218)
	at org.sonar.java.model.VisitorsBridgeForTests$TestJavaFileScannerContext.reportIssue(VisitorsBridgeForTests.java:101)
	at org.sonar.java.model.DefaultJavaFileScannerContext.reportIssue(DefaultJavaFileScannerContext.java:129)
	at org.sonar.plugins.java.api.IssuableSubscriptionVisitor.reportIssue(IssuableSubscriptionVisitor.java:62)
	at org.sonar.samples.java.checks.MyFirstCustomCheck.checkForPattern(MyFirstCustomCheck.java:38)
	at org.sonar.samples.java.checks.MyFirstCustomCheck.visitTrivia(MyFirstCustomCheck.java:29)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.lambda$visit$7(VisitorsBridge.java:269)
	at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.lambda$forEach$9(VisitorsBridge.java:280)
	at org.sonar.java.model.VisitorsBridge.runScanner(VisitorsBridge.java:144)
	at org.sonar.java.model.VisitorsBridge.access$100(VisitorsBridge.java:60)
	at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.forEach(VisitorsBridge.java:280)
	at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:269)
	at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visitChildren(VisitorsBridge.java:251)
	at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:271)
	at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visitChildren(VisitorsBridge.java:251)
	at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:271)
	at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.run(VisitorsBridge.java:242)
	at org.sonar.java.model.VisitorsBridge.visitFile(VisitorsBridge.java:126)
	at org.sonar.java.ast.JavaAstScanner.simpleScan(JavaAstScanner.java:123)
	at org.sonar.java.ast.JavaAstScanner.scan(JavaAstScanner.java:77)
	at org.sonar.java.checks.verifier.InternalCheckVerifier.verifyAll(InternalCheckVerifier.java:219)
	at org.sonar.java.checks.verifier.InternalCheckVerifier.verifyIssues(InternalCheckVerifier.java:167)
	at org.sonar.samples.java.checks.MyFirstCustomCheckTest.test(MyFirstCustomCheckTest.java:13)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:84)
	at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)


Hello @SuperOok

The simple way to do this is to use addIssue(syntaxTrivia.startLine(), message), at least that’s what is done in the “track use of TODO” rule.

Hope that helps,
Quentin

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.