Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UnnecessarySemicolonRule throws exceptions for Groovy 3 #506

Closed
dmurat opened this issue May 27, 2020 · 5 comments
Closed

UnnecessarySemicolonRule throws exceptions for Groovy 3 #506

dmurat opened this issue May 27, 2020 · 5 comments

Comments

@dmurat
Copy link
Contributor

dmurat commented May 27, 2020

I'm trying to run the latest CodeNarc from master on a Groovy 3 project (an exact groovy version is 3.0.4). However, UneccessarySemicoloRule throws IndexOutOfBoundException on line 69. After changing the checkLastLineForSemicolon method as shown below, everything started to work correctly.

private void checkLastLineForSemicolon(SourceCode sourceCode, List<Violation> violations, AnnotatedNode node) {
    int lineNumber = node.getLastLineNumber()
    if (lineNumber < 1) { // <--- check added
        return
    }

    String line = sourceCode.getLines().get(lineNumber - 1) + ' '   // to make it easier to extract the final chars
    int lastColumn = node.lastColumnNumber
    boolean lastCharIsSemicolon = line[lastColumn - 1] == ';'

    if (lastCharIsSemicolon) {
        violations << createViolation(lineNumber, line, MESSAGE)
    }
}

Tnx

@dmurat
Copy link
Contributor Author

dmurat commented May 28, 2020

I believe the root cause is in Groovy - https://issues.apache.org/jira/browse/GROOVY-9577
I'm not sure if it makes sense fixing it in CondeNarc. Probably not.

@chrismair
Copy link
Contributor

Can you please provide some sample code that causes the above exception, so I can add a test for that.

@dmurat
Copy link
Contributor Author

dmurat commented May 29, 2020

Sure, there is a test that triggered the problem for me:

@Test
void test_NoViolations_WithClassAnnotations() {
    final SOURCE = '''
        package foo
        
        import java.io.CharArrayReader
        import java.nio.file.AccessMode
        import java.io.Bits
        
        import java.lang.String

        class A {
            String firstName
            
            int a() {
                return 1
            }
        }
    '''

    assertNoViolations(SOURCE)
}

I added the test in UnnecessarySemicolonRuleTest and run it with following changes in build.gradle

def groovyTestVersion = '3.0.4'
...
dependencies {
  ...
  testRuntimeOnly("org.codehaus.groovy:groovy:$groovyTestVersion")
  testRuntimeOnly("org.codehaus.groovy:groovy-xml:$groovyTestVersion")
  testRuntimeOnly("org.codehaus.groovy:groovy-json:$groovyTestVersion")
  testRuntimeOnly("org.codehaus.groovy:groovy-ant:$groovyTestVersion")
  testRuntimeOnly("org.codehaus.groovy:groovy-templates:$groovyTestVersion")
}

Basically, whenever you add some package that Groovy does not include by default, the error can occur. If it passes, try adding more imports from "non-standard" packages.

@dmurat
Copy link
Contributor Author

dmurat commented May 29, 2020

I just noticed that the name of a test is wrong. Previously I suspected that rule failed because of additional annotations on a class. But it turns out that imports are the problem.

@chrismair
Copy link
Contributor

Thanks for providing the sample code and pointing out the fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants