Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
2767738
Fix eight Scala parser round-trip bugs found by a corpus sweep
knutwannheden Aug 15, 2026
344a7eb
Keep trailing comments and semicolons out of Scala whitespace
knutwannheden Aug 15, 2026
135c0a3
Keep a bare `*` out of the Scala comment buffer
knutwannheden Aug 15, 2026
65c0140
Model chained package clauses instead of skipping them
knutwannheden Aug 15, 2026
5c1ac4a
Model self-type clauses and `derives` clauses
knutwannheden Aug 15, 2026
49edc00
Map a parenthesized template parent as a type
knutwannheden Aug 15, 2026
97bc82b
Recognize Scala 3 definition modifiers and a bare constructor modifier
knutwannheden Aug 15, 2026
88f301b
Keep a capture-set suffix on the type it follows
knutwannheden Aug 15, 2026
5b40510
Do not mistake a capture set's brace for a procedure-syntax body
knutwannheden Aug 15, 2026
83d035a
Keep a call-site `using` keyword with the argument list
knutwannheden Aug 15, 2026
5f6458b
Recognize `inline`, `transparent` and `opaque` on val and given defin…
knutwannheden Aug 15, 2026
d64489a
Claim `end` markers on extension blocks and try expressions
knutwannheden Aug 15, 2026
f521f46
Find a lambda's arrow after its parameter list, and keep backticks on…
knutwannheden Aug 15, 2026
dd5930a
Find a function type's arrow after its parameter list
knutwannheden Aug 15, 2026
9099dc5
Print a curried clause keyword ahead of its parameter annotations
knutwannheden Aug 15, 2026
5952b6a
Remove corpus-sweep scratch tests from the repository
knutwannheden Aug 16, 2026
4fce185
Size a wildcard kind parameter by its source, and print the pure func…
knutwannheden Aug 16, 2026
9e23fb2
Unwrap the capture-checking result wrapper
knutwannheden Aug 16, 2026
bafa88c
Keep `new` out of a curried constructor call's prefix
knutwannheden Aug 16, 2026
11f147a
Scan an object's modifiers from the cursor, not from its span
knutwannheden Aug 16, 2026
83a217e
Claim an `end` marker closing an object's indented body
knutwannheden Aug 16, 2026
a90d419
Keep a context bound written on a higher-kinded type parameter
knutwannheden Aug 16, 2026
2d55403
Keep an upper bound written on a higher-kinded type parameter
knutwannheden Aug 16, 2026
dd0ffee
Keep a trailing comma in an argument list
knutwannheden Aug 16, 2026
8609d62
Keep `inline` written on a method parameter
knutwannheden Aug 16, 2026
f0790dc
Remove corpus-sweep scratch tests from the repository
knutwannheden Aug 16, 2026
4b176bd
Visit a parenthesized or tuple annotated type in type position
knutwannheden Aug 16, 2026
ef6d709
Keep a trailing comma in import selectors
knutwannheden Aug 16, 2026
02e38a7
Print `final var` as written, and keep the space after an annotation'…
knutwannheden Aug 16, 2026
3958ace
Record an empty run before a method body's `=`, and visit extension p…
knutwannheden Aug 16, 2026
f22ac72
Find the `match` selector dot outside comments
knutwannheden Aug 16, 2026
3bdbc41
Skip comments when scanning for keywords in the parser
knutwannheden Aug 16, 2026
13cecc8
Consume curried parameter lists when the first list is empty
knutwannheden Aug 16, 2026
4d2b198
Print the body prefix of a curried method
knutwannheden Aug 16, 2026
7d5973d
Leave the space ahead of a capture-set type to its enclosing type
knutwannheden Aug 16, 2026
fee3304
Model the `then` after a parenthesized if condition
knutwannheden Aug 16, 2026
02a0bb7
Model the `case` of a pattern-filtering for generator
knutwannheden Aug 16, 2026
f40b3c9
Model the `do` after a parenthesized loop head
knutwannheden Aug 16, 2026
e7cc3a0
Keep the empty argument list of an anonymous class
knutwannheden Aug 16, 2026
e9ab506
Recognize a variable's access modifier in any position
knutwannheden Aug 16, 2026
0234ad6
Leave the comma of an import group to its continuation
knutwannheden Aug 16, 2026
a374928
Recognize `inline` on a using parameter
knutwannheden Aug 16, 2026
0c4e9c6
Model the `inline` of a Scala 3 `inline if`
knutwannheden Aug 16, 2026
06e4958
Recognize `inline` on a parameter across a line break
knutwannheden Aug 16, 2026
9bc65c4
Take an anonymous class's argument list from the token after the type
knutwannheden Aug 16, 2026
25e3887
Name the sentinel for an anonymous class with no body
knutwannheden Aug 16, 2026
15262ee
Take the space after the `package` keyword from the source
knutwannheden Aug 17, 2026
41ea6a4
Keep the handler of `try expr catch handler`
knutwannheden Aug 17, 2026
8af2405
Keep an `end` marker closing a braced object body
knutwannheden Aug 17, 2026
93c57fb
Bound the primary-constructor modifier scan to the class
knutwannheden Aug 17, 2026
17c3b60
Keep what sits between the parentheses of an empty argument list
knutwannheden Aug 17, 2026
21940eb
Parse a trailing-comma region with the Scala space parser
knutwannheden Aug 17, 2026
f91ce6e
Model `asInstanceOf` as the method invocation it is
knutwannheden Aug 17, 2026
d640068
Remove the unused type-ascription marker
knutwannheden Aug 17, 2026
83bd646
State the end-marker and parenthesized-type rules once
knutwannheden Aug 17, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,16 @@ public S.CompilationUnit visitCompilationUnit(ScalaParseResult parseResult) {
CompilationUnitResult result = converter.convertToCompilationUnit(parseResult, source, typeFactory);

J.Package packageDecl = result.getPackageDecl();
List<Statement> statements = result.getStatements();
List<JRightPadded<Statement>> statements = result.getStatements();


// Filter out any Unknown statements that contain the entire source with package
if (packageDecl != null) {
final String packageName = packageDecl.getPackageName();
statements = statements.stream()
.filter(stmt -> {
if (stmt instanceof J.Unknown) {
String text = ((J.Unknown) stmt).getSource().getText().trim();
.filter(rp -> {
if (rp.getElement() instanceof J.Unknown) {
String text = ((J.Unknown) rp.getElement()).getSource().getText().trim();
// Skip if this Unknown contains the same package declaration
boolean shouldFilter = text.startsWith("package " + packageName);
return !shouldFilter;
Expand Down Expand Up @@ -117,12 +117,14 @@ public S.CompilationUnit visitCompilationUnit(ScalaParseResult parseResult) {
unknownSource
);

statements.add(unknown);
statements.add(JRightPadded.build(unknown));
}

// Get remaining source for EOF
String remainingSource = converter.getRemainingSource(parseResult, source, result.getLastCursorPosition());
Space eof = remainingSource.isEmpty() ? EMPTY : Space.build(remainingSource, Collections.emptyList());
// Trailing source can hold comments, which belong in Space.comments rather than
// its whitespace
Space eof = remainingSource.isEmpty() ? EMPTY : ScalaSpace.format(remainingSource);

// Build S.CompilationUnit
return new S.CompilationUnit(
Expand All @@ -135,7 +137,7 @@ public S.CompilationUnit visitCompilationUnit(ScalaParseResult parseResult) {
charsetBomMarked, // boolean charsetBomMarked
null, // Checksum checksum
packageDecl == null ? null : JRightPadded.build(packageDecl),
JRightPadded.withElements(Collections.emptyList(), statements),
statements,
eof // Space eof
);
}
Expand Down
220 changes: 181 additions & 39 deletions rewrite-scala/src/main/java/org/openrewrite/scala/ScalaPrinter.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,14 @@ public J visitConstructorInvocation(S.ConstructorInvocation constructorInvocatio
return c;
}

public J visitLiteralType(S.LiteralType literalType, P p) {
S.LiteralType l = literalType;
l = l.withPrefix(visitSpace(l.getPrefix(), Space.Location.LANGUAGE_EXTENSION, p));
l = l.withMarkers(visitMarkers(l.getMarkers(), p));
l = l.withLiteral(visitAndCast(l.getLiteral(), p));
return l;
}

public J visitSingletonType(S.SingletonType singletonType, P p) {
S.SingletonType s = singletonType;
s = s.withPrefix(visitSpace(s.getPrefix(), Space.Location.LANGUAGE_EXTENSION, p));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,11 @@ public static Space format(String formatting, int beginIndex, int toIndex) {
} else if (last == '/' && blockDepth > 0) {
blockDepth++;
comment.append(c); // the '/' is already in the comment buffer
} else {
} else if (blockDepth > 0) {
comment.append(c);
} else {
// A bare `*` outside a comment, as in a `import a.*` wildcard
prefix.append(c);
}
break;
default:
Expand Down

This file was deleted.

This file was deleted.

45 changes: 45 additions & 0 deletions rewrite-scala/src/main/java/org/openrewrite/scala/tree/S.java
Original file line number Diff line number Diff line change
Expand Up @@ -1742,6 +1742,51 @@ public S.ConstructorInvocation withArguments(JContainer<Expression> arguments) {
}
}

/**
* A Scala literal type: the {@code true} of {@code def f(): true}, or {@code "a"}, {@code -1}.
* The literal itself is the type; there is no {@code .type} suffix as in {@link SingletonType}.
*/
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
final class LiteralType implements S, TypeTree, Expression {

@With @Getter @EqualsAndHashCode.Include
UUID id;

@With @Getter
Space prefix;

@With @Getter
Markers markers;

// Not `J.Literal` so that negated literals like `-1` are captured too
@With @Getter
Expression literal;

@With @Getter
@Nullable
JavaType type;

public LiteralType(UUID id, Space prefix, Markers markers, Expression literal,
@Nullable JavaType type) {
this.id = id;
this.prefix = prefix;
this.markers = markers;
this.literal = literal;
this.type = type;
}

@Override
public <P> J acceptScala(ScalaVisitor<P> v, P p) {
return v.visitLiteralType(this, p);
}

@Override
public CoordinateBuilder.Expression getCoordinates() {
return new CoordinateBuilder.Expression(this);
}
}

/**
* Represents a Scala singleton type: {@code foo.type}.
* The qualifier is any expression, typically an object/module reference.
Expand Down
Loading