Skip to content

Commit 3fd7156

Browse files
committed
Fix Scala parser gaps surfaced by prethink integration testing
ScalaTreeVisitor: mirror the else branch's expression-wrapping fallback that the then branch already had, so `if (x) a else b` with expression operands parses (closes asymmetry that threw UnsupportedOperationException). Add `case j: J => new S.StatementExpression(Tree.randomId(), j)` fallbacks at ~25 visitUnknown sites where the parser previously crashed on any J that wasn't exactly an Expression/Statement — covering visitWhileDo body/cond, visitForDo body/iterable, visitReturn, visitThrow, visitMatchImpl selector, visitAssign lhs/rhs, visitInfixOp / visitBinaryOperation / visitInfixMethodCall operands, visitPrefixOp / visitPostfixOp operand, visitParentheses inner, visitTyped, visitTypeApply asInstanceOf/isInstanceOf, visitAppliedTypeTree args, method call target, ArrayAccess array/index, NewArray / NewArrayWithType elements, NewClassWithArgs constructor args, annotation args, tuple elements. Try body/finalizer now also accept Statement, matching the existing ParsedTry behavior. ScalaParser.sourcePathFromSourceText: was hard-coded to "file.scala" so every source in a multi-file test collided on the same path and clobbered each other on print round-trip. Extract package + class name via a shared derivedRelativePath helper (reusing logic from parse()) so each source gets a distinct path. 7 new regression tests covering if-else-as-expression (literal/ident operands), return/throw/assign with if-rhs, binary/tuple/paren with if-operand, while-with-unit-body, and multi-file distinct paths. Full rewrite-scala suite passes.
1 parent 59d98eb commit 3fd7156

4 files changed

Lines changed: 248 additions & 48 deletions

File tree

rewrite-scala/src/main/java/org/openrewrite/scala/ScalaParser.java

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import java.nio.file.Path;
3333
import java.nio.file.Paths;
3434
import java.util.*;
35-
import java.util.function.Function;
3635
import java.util.regex.Matcher;
3736
import java.util.regex.Pattern;
3837
import java.util.stream.Collectors;
@@ -46,26 +45,25 @@ public class ScalaParser implements Parser {
4645
private final boolean logCompilationWarningsAndErrors;
4746
private final JavaTypeCache typeCache;
4847

49-
@Override
50-
public Stream<SourceFile> parse(@Language("scala") String... sources) {
51-
Pattern packagePattern = Pattern.compile("\\bpackage\\s+([.\\w]+)");
52-
Pattern classPattern = Pattern.compile("(class|object|trait|case\\s+class)\\s*(<[^>]*>)?\\s+(\\w+)");
48+
private static final Pattern PACKAGE_PATTERN = Pattern.compile("\\bpackage\\s+([.\\w]+)");
49+
private static final Pattern CLASS_PATTERN = Pattern.compile("(class|object|trait|case\\s+class)\\s*(<[^>]*>)?\\s+(\\w+)");
50+
51+
private static String derivedRelativePath(String sourceCode) {
52+
Matcher packageMatcher = PACKAGE_PATTERN.matcher(sourceCode);
53+
String pkg = packageMatcher.find() ? packageMatcher.group(1).replace('.', '/') + "/" : "";
5354

54-
Function<String, String> simpleName = sourceStr -> {
55-
Matcher classMatcher = classPattern.matcher(sourceStr);
56-
return classMatcher.find() ? classMatcher.group(3) : null;
57-
};
55+
Matcher classMatcher = CLASS_PATTERN.matcher(sourceCode);
56+
String simpleName = classMatcher.find() ? classMatcher.group(3) : Long.toString(System.nanoTime());
57+
58+
return pkg + simpleName + ".scala";
59+
}
5860

61+
@Override
62+
public Stream<SourceFile> parse(@Language("scala") String... sources) {
5963
return parseInputs(
6064
Arrays.stream(sources)
6165
.map(sourceFile -> {
62-
Matcher packageMatcher = packagePattern.matcher(sourceFile);
63-
String pkg = packageMatcher.find() ? packageMatcher.group(1).replace('.', '/') + "/" : "";
64-
65-
String className = Optional.ofNullable(simpleName.apply(sourceFile))
66-
.orElse(Long.toString(System.nanoTime())) + ".scala";
67-
68-
Path path = Paths.get(pkg + className);
66+
Path path = Paths.get(derivedRelativePath(sourceFile));
6967
return Input.fromString(path, sourceFile);
7068
})
7169
.collect(Collectors.toList()),
@@ -154,7 +152,7 @@ public ScalaParser reset() {
154152

155153
@Override
156154
public Path sourcePathFromSourceText(Path prefix, String sourceCode) {
157-
return prefix.resolve("file.scala");
155+
return prefix.resolve(derivedRelativePath(sourceCode));
158156
}
159157

160158
public static ScalaParser.Builder builder() {

0 commit comments

Comments
 (0)