Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions rewrite-groovy/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,20 @@ testing {
}

register<JvmTestSuite>("groovy2Test") {
configurations.getByName("groovy2TestRuntimeClasspath") {
resolutionStrategy {
force("org.codehaus.groovy:groovy:2.5.22")
}
}

dependencies {
implementation(project())
implementation(project(":rewrite-test"))
implementation("org.assertj:assertj-core:latest.release")
}

// Replace Groovy 4.x (org.apache.groovy) with Groovy 2.x (org.codehaus.groovy)
configurations.named("groovy2TestRuntimeClasspath") {
exclude(group = "org.apache.groovy")
}
configurations.named("groovy2TestRuntimeOnly") {
dependencies.add(project.dependencies.create("org.codehaus.groovy:groovy:2.5.22"))
}

targets {
all {
testTask.configure {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@
import org.junit.jupiter.api.Test;
import org.openrewrite.test.RewriteTest;

import static org.assertj.core.api.Assertions.assertThat;
import static org.openrewrite.groovy.Assertions.groovy;

class GroovyParserTest implements RewriteTest {

@Test
void groovyRuntimeIsVersion2() throws Exception {
Class<?> groovySystem = Class.forName("groovy.lang.GroovySystem");
String version = (String) groovySystem.getMethod("getVersion").invoke(null);
assertThat(version).startsWith("2.");
}

@Test
void shouldNotTreatDivisionAsDelimiter() {
rewriteRun(
Expand Down Expand Up @@ -90,4 +98,17 @@ void shouldBeAbleToParseParenthesisedIntegerConstantExpressions() {
);
}

@Test
void shouldBeAbleToParseClassDeclaration() {
rewriteRun(
groovy(
"""
class Foo {
String bar
}
"""
)
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ public class GroovyParserVisitor {
@Nullable
private static Boolean olderThanGroovy3;

@Nullable
private static Boolean groovy4OrLater;

@SuppressWarnings("unused")
public GroovyParserVisitor(Path sourcePath, @Nullable FileAttributes fileAttributes, EncodingDetectingInputStream source, JavaTypeCache typeCache, ExecutionContext ctx) {
this.sourcePath = sourcePath;
Expand All @@ -124,15 +127,25 @@ public GroovyParserVisitor(Path sourcePath, @Nullable FileAttributes fileAttribu
this.typeMapping = new GroovyTypeMapping(typeCache);
}

private static int groovyMajorVersion() {
String groovyVersionText = GroovySystem.getVersion();
return Integer.parseInt(groovyVersionText.substring(0, groovyVersionText.indexOf('.')));
}

private static boolean isOlderThanGroovy3() {
if (olderThanGroovy3 == null) {
String groovyVersionText = GroovySystem.getVersion();
int majorVersion = Integer.parseInt(groovyVersionText.substring(0, groovyVersionText.indexOf('.')));
olderThanGroovy3 = majorVersion < 3;
olderThanGroovy3 = groovyMajorVersion() < 3;
}
return olderThanGroovy3;
}

private static boolean isGroovy4OrLater() {
if (groovy4OrLater == null) {
groovy4OrLater = groovyMajorVersion() >= 4;
}
return groovy4OrLater;
}

public G.CompilationUnit visit(SourceUnit unit, ModuleNode ast) throws GroovyParsingException {
NavigableMap<LineColumn, ASTNode> sortedByPosition = new TreeMap<>();
for (org.codehaus.groovy.ast.stmt.Statement s : ast.getStatementBlock().getStatements()) {
Expand Down Expand Up @@ -254,7 +267,7 @@ public void visitClass(ClassNode clazz) {
} else if (clazz.isEnum()) {
kindType = J.ClassDeclaration.Kind.Type.Enum;
skip("enum");
} else if (clazz.isRecord()) {
} else if (isGroovy4OrLater() && clazz.isRecord()) {
kindType = J.ClassDeclaration.Kind.Type.Record;
skip("record");
} else {
Expand Down Expand Up @@ -328,7 +341,7 @@ public void visitClass(ClassNode clazz) {
}

JContainer<TypeTree> permitting = null;
if (clazz.isSealed() && clazz.getPermittedSubclasses() != null && !clazz.getPermittedSubclasses().isEmpty()) {
if (isGroovy4OrLater() && clazz.isSealed() && clazz.getPermittedSubclasses() != null && !clazz.getPermittedSubclasses().isEmpty()) {
Space permitsPrefix = sourceBefore("permits");
List<ClassNode> permitted = clazz.getPermittedSubclasses();
List<JRightPadded<TypeTree>> permitTypes = new ArrayList<>(permitted.size());
Expand Down Expand Up @@ -393,7 +406,7 @@ class A {
*/
Set<InnerClassNode> fieldInitializers = new HashSet<>();
Set<String> recordComponentNames = new HashSet<>();
if (clazz.getRecordComponents() != null) {
if (isGroovy4OrLater() && clazz.getRecordComponents() != null) {
for (RecordComponentNode rc : clazz.getRecordComponents()) {
recordComponentNames.add(rc.getName());
}
Expand Down