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

GroovyParsingException when parsing Gradle build file #5072

Open
BrendanHart opened this issue Feb 20, 2025 · 13 comments
Open

GroovyParsingException when parsing Gradle build file #5072

BrendanHart opened this issue Feb 20, 2025 · 13 comments
Labels
bug Something isn't working parser-groovy

Comments

@BrendanHart
Copy link

What version of OpenRewrite are you using?

I am using

  • OpenRewrite v8.45.0
  • Gradle plugin v7.1.4
  • rewrite-groovy v8.45.0
  • rewrite-gradle v8.45.0
  • Gradle 6.9

How are you running OpenRewrite?

I am using the Gradle plugin, with an init script.

What is the smallest, simplest way to reproduce the problem?

I have simplified my original build.gradle to something which produces a similar exception. I have been unable to reproduce this in a unit test since they use Groovy 3, which doesn't seem to produce the exception. I have tried to create a unit test with Groovy 2 dependencies, but it seemed the GroovyParserVisitor then sees a ClassNotFoundException for LamdaExpression, so I'm unsure how to configure a test to compile the Groovy code with Groovy 2 yet have Groovy 3 classes available. The only way I have been able to reproduce is by actually running gradle --init-script init.gradle rewriteDryRun.

init.gradle

initscript {
    repositories {
        maven { url "https://plugins.gradle.org/m2" }
    }
    dependencies { classpath("org.openrewrite:plugin:latest.release") }
}
rootProject {
    plugins.apply(org.openrewrite.gradle.RewritePlugin)
    dependencies {
        rewrite("org.openrewrite:rewrite-java")
    }
    rewrite {
        activeRecipe("org.openrewrite.groovy.format.AutoFormat")
        setExportDatatables(true)
    }
    afterEvaluate {
        if (repositories.isEmpty()) {
            repositories {
                mavenCentral()
            }
        }
    }
}

build.gradle

def x = (1 / 1 ) * 100
System.out.println("test")

What did you expect to see?

No fail to parse errors.

What did you see instead?

Failed to parse error.

What is the full stack trace of any errors you encountered?

Error during rewrite dry run
org.openrewrite.groovy.GroovyParsingException: Failed to parse build.gradle, cursor position likely inaccurate.
	at org.openrewrite.groovy.GroovyParserVisitor.visit(GroovyParserVisitor.java:203)
	at org.openrewrite.groovy.GroovyParser.lambda$parseInputs$3(GroovyParser.java:147)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
	at java.util.Collections$2.tryAdvance(Collections.java:4717)
	at java.util.Collections$2.forEachRemaining(Collections.java:4725)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
	at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:270)
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
	at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
	at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
	at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:743)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
	at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:743)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
	at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
	at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
	at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:743)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
	at org.openrewrite.gradle.isolated.DefaultProjectParser.listResults(DefaultProjectParser.java:1387)
	at org.openrewrite.gradle.isolated.DefaultProjectParser.dryRun(DefaultProjectParser.java:334)
	at org.openrewrite.gradle.DelegatingProjectParser.lambda$dryRun$3(DelegatingProjectParser.java:123)
	at org.openrewrite.gradle.DelegatingProjectParser.unwrapInvocationException(DelegatingProjectParser.java:164)
	at org.openrewrite.gradle.DelegatingProjectParser.dryRun(DelegatingProjectParser.java:122)
	at org.openrewrite.gradle.RewriteDryRunTask.run(RewriteDryRunTask.java:52)
	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.reflect.JavaMethod.invoke(JavaMethod.java:104)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:58)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$2.run(ExecuteActionsTaskExecuter.java:494)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:479)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:462)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$400(ExecuteActionsTaskExecuter.java:105)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.executeWithPreviousOutputFiles(ExecuteActionsTaskExecuter.java:273)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:251)
	at org.gradle.internal.execution.steps.ExecuteStep.lambda$executeOperation$1(ExecuteStep.java:66)
	at java.util.Optional.orElseGet(Optional.java:267)
	at org.gradle.internal.execution.steps.ExecuteStep.executeOperation(ExecuteStep.java:66)
	at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:34)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:47)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:44)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:44)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:34)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:72)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:42)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:53)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:39)
	at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:44)
	at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:77)
	at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:58)
	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:54)
	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:32)
	at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:57)
	at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:38)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:63)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:30)
	at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:176)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:76)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:47)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:43)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:32)
	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:39)
	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:25)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:102)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:95)
	at java.util.Optional.map(Optional.java:215)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:55)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:39)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:83)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:44)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:96)
	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:52)
	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:83)
	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:54)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:74)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:88)
	at java.util.Optional.orElseGet(Optional.java:267)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:88)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:34)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
	at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:46)
	at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:34)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:43)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution$3.withWorkspace(ExecuteActionsTaskExecuter.java:286)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:43)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:33)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:40)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:30)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:54)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:40)
	at org.gradle.internal.execution.impl.DefaultExecutionEngine.rebuild(DefaultExecutionEngine.java:46)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$0(ExecuteActionsTaskExecuter.java:182)
	at java.util.Optional.map(Optional.java:215)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:182)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:173)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:411)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:398)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:391)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:377)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: 50
	at java.lang.String.substring(String.java:1963)
	at org.openrewrite.groovy.GroovyParserVisitor.whitespace(GroovyParserVisitor.java:2336)
	at org.openrewrite.groovy.GroovyParserVisitor.access$000(GroovyParserVisitor.java:80)
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: 50

	at org.openrewrite.groovy.GroovyParserVisitor$RewriteGroovyVisitor.insideParentheses(GroovyParserVisitor.java:681)
	at org.openrewrite.groovy.GroovyParserVisitor$RewriteGroovyVisitor.visitConstantExpression(GroovyParserVisitor.java:1233)
	at org.codehaus.groovy.ast.expr.ConstantExpression.visit(ConstantExpression.java:81)
	at org.openrewrite.groovy.GroovyParserVisitor$RewriteGroovyVisitor.visit(GroovyParserVisitor.java:640)
	at org.openrewrite.groovy.GroovyParserVisitor$RewriteGroovyVisitor.lambda$visitBinaryExpression$1(GroovyParserVisitor.java:961)
	at org.openrewrite.groovy.GroovyParserVisitor$RewriteGroovyVisitor.insideParentheses(GroovyParserVisitor.java:674)
	at org.openrewrite.groovy.GroovyParserVisitor$RewriteGroovyVisitor.visitBinaryExpression(GroovyParserVisitor.java:840)
	at org.codehaus.groovy.ast.expr.BinaryExpression.visit(BinaryExpression.java:49)
	at org.openrewrite.groovy.GroovyParserVisitor$RewriteGroovyVisitor.visit(GroovyParserVisitor.java:640)
	at org.openrewrite.groovy.GroovyParserVisitor$RewriteGroovyVisitor.visitDeclarationExpression(GroovyParserVisitor.java:1400)
	at org.codehaus.groovy.ast.expr.DeclarationExpression.visit(DeclarationExpression.java:89)
	at org.codehaus.groovy.ast.CodeVisitorSupport.visitExpressionStatement(CodeVisitorSupport.java:120)
	at org.openrewrite.groovy.GroovyParserVisitor$RewriteGroovyVisitor.lambda$visitExpressionStatement$8(GroovyParserVisitor.java:1468)
	at org.openrewrite.groovy.GroovyParserVisitor$RewriteGroovyVisitor.labeled(GroovyParserVisitor.java:696)
	at org.openrewrite.groovy.GroovyParserVisitor$RewriteGroovyVisitor.visitExpressionStatement(GroovyParserVisitor.java:1467)
	at org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:40)
	at org.openrewrite.groovy.GroovyParserVisitor.convertTopLevelStatement(GroovyParserVisitor.java:2195)
	at org.openrewrite.groovy.GroovyParserVisitor.visit(GroovyParserVisitor.java:195)
	... 176 more

Are you interested in contributing a fix to OpenRewrite?

@BrendanHart BrendanHart added the bug Something isn't working label Feb 20, 2025
@timtebeek
Copy link
Contributor

Any improvement with the latest releases? There were fixes specifically for the Groovy parser:
https://github.com/openrewrite/rewrite/releases

@BrendanHart
Copy link
Author

Thanks for the suggestion, but just tried 8.46.1 and unfortunately still seeing the same error (8.47.0 doesn't seem available in maven central yet).

@greg-at-moderne
Copy link
Contributor

I've just tried reproducing by creating these two files in an empty directory and running ~/git/openrewrite/rewrite/gradlew --init-script init.gradle rewriteDryRun and it worked.

Also adding the two lines:

def x = (1 / 1 ) * 100
System.out.println("test")

in a unit test for GroovyParser also passes.

So I think there might be a bit more of a nuance to pinpoint the actual issue here.

@BrendanHart
Copy link
Author

Hi @greg-at-moderne, thanks for trying, did you use Gradle 6.9 also?

@greg-at-moderne
Copy link
Contributor

Ah. No. I didn't. I've used 8.12. Maybe that's the thing.

@greg-at-moderne
Copy link
Contributor

greg-at-moderne commented Feb 21, 2025

When I try
gradle-6.9/bin/gradle --init-script init.gradle rewriteDryRun
using JDK 11 I get a successful build (with JDK 17 it wouldn't work):

➜  g1 sdk use java 11.0.25-amzn

Using java version 11.0.25-amzn in this shell.
➜  g1 gradle-6.9/bin/gradle --init-script init.gradle rewriteDryRun
Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details

> Configure project :
test

> Task :rewriteDryRun
Validating active recipes
Scanning sources in project :
Using active styles []
There were problems parsing some source files, run with --info to see full stack traces
There were problems parsing build.gradle
All sources parsed, running active recipes: org.openrewrite.groovy.format.AutoFormat
These recipes would make changes to init.gradle:
    org.openrewrite.groovy.format.AutoFormat
Report available:
    /private/tmp/g1/build/reports/rewrite/rewrite.patch
Estimate time saved: 5m
Run 'gradle rewriteRun' to apply the recipes.

BUILD SUCCESSFUL in 10s
1 actionable task: 1 executed

@BrendanHart
Copy link
Author

BrendanHart commented Feb 21, 2025

Hi @greg-at-moderne,

In your logs I see "there were problems parsing build.gradle", I think if you run your build with --info it will show the stack trace I seen

@greg-at-moderne
Copy link
Contributor

And you are right indeed!
I get a slightly different exception:

Caused by: java.lang.StringIndexOutOfBoundsException: begin 51, end 51, length 50
        at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3319)
        at java.base/java.lang.String.substring(String.java:1874)
        at org.openrewrite.groovy.GroovyParserVisitor.whitespace(GroovyParserVisitor.java:2288)
        at org.openrewrite.groovy.GroovyParserVisitor.access$000(GroovyParserVisitor.java:81)
        at org.openrewrite.groovy.GroovyParserVisitor$RewriteGroovyVisitor.insideParentheses(GroovyParserVisitor.java:660)

But it looks too similar to yours for it to be an accident.

Thanks!

@BrendanHart
Copy link
Author

Just some extra info - I just tried with Java 11, and then the stack trace looks like yours, I was previously using Java 8.

@shanman190
Copy link
Contributor

shanman190 commented Feb 26, 2025

So it's probably the parentheses. Gradle 6.x I believe uses Groovy 2.5 while Gradle 7.x uses Groovy 3.x. One of the features that comes with Groovy 3.x is better recording of parentheses depth which rewrite-groovy takes advantage of when it's available, but has to fallback to trying to guess the parentheses depth on these older versions.

@BrendanHart
Copy link
Author

When I was previously debugging this, I did notice that when using Gradle 8, the parentheses level of the * node was 0, whereas in Gradle 6 it was 1. I think the parentColumn and childColumn differed in determineParenthesisLevel. Not sure if this is helpful but it aligns with what you have suggested @shanman190 .

@jevanlingen
Copy link
Contributor

jevanlingen commented Mar 5, 2025

I can confirm it's probably the parentheses stuff. I I disable both the retrieval of the flag and the fallback:

private @Nullable Integer getInsideParenthesesLevel(ASTNode node) {
  Object rawIpl = null; //node.getNodeMetaData("_INSIDE_PARENTHESES_LEVEL");
  ..
  } else if (node instanceof BinaryExpression) {
    BinaryExpression expr = (BinaryExpression) node;
    // return determineParenthesisLevel(expr.getLeftExpression().getLineNumber(), expr.getLineNumber(), expr.getLeftExpression().getColumnNumber(), expr.getColumnNumber());
  }
  return null;
}

And I use following unit test:

@Test
void doTest() {
  rewriteRun(
    groovy(
      """
      def x = (1 / 1 ) * 100
      """
    )
  );
}

I'll get the error:

Expected :"def x = (1 / 1 ) * 100"
Actual   :"def x = 1/ 1 * 100 100"

N.B. There is still a debate going on if (and how) we are going to create Groovy 2 unit tests.

@shanman190
Copy link
Contributor

So one way for Groovy 2.x tests could be to utilize the jvm-teat-suite plugin to have unique test suites. Depends a little on how much test duplication want to avoid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working parser-groovy
Projects
Status: No status
Development

No branches or pull requests

5 participants