Skip to content

Commit

Permalink
Merge branch 'main' into psi-based-parser
Browse files Browse the repository at this point in the history
  • Loading branch information
kunli2 committed Oct 4, 2023
2 parents 09a09c6 + 3bf91df commit 1705bb7
Show file tree
Hide file tree
Showing 20 changed files with 830 additions and 236 deletions.
17 changes: 11 additions & 6 deletions src/main/java/org/openrewrite/kotlin/format/AutoFormatVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,19 @@ public J visit(@Nullable Tree tree, P p, Cursor cursor) {
.orElse(IntelliJ.tabsAndIndents()), stopAfter)
.visit(t, p, cursor.fork());

t = new TabsAndIndentsVisitor<>(Optional.ofNullable(((SourceFile) cu).getStyle(TabsAndIndentsStyle.class))
.orElse(IntelliJ.tabsAndIndents()), stopAfter)
.visit(t, p, cursor.fork());
t = new TabsAndIndentsVisitor<>(
Optional.ofNullable(((SourceFile) cu).getStyle(TabsAndIndentsStyle.class)).orElse(IntelliJ.tabsAndIndents()),
Optional.ofNullable(((SourceFile) cu).getStyle(WrappingAndBracesStyle.class)).orElse(IntelliJ.wrappingAndBraces()),
stopAfter
).visit(t, p, cursor.fork());

t = new NormalizeLineBreaksVisitor<>(Optional.ofNullable(((SourceFile) cu).getStyle(GeneralFormatStyle.class))
.orElse(new GeneralFormatStyle(false)), stopAfter)
.visit(t, p, cursor.fork());

t = new RemoveTrailingWhitespaceVisitor<>(stopAfter).visit(t, p, cursor.fork());

t = new ImportReorderingVisitor<>().visit(t, p, cursor.fork());
return t;
}

Expand Down Expand Up @@ -113,9 +116,11 @@ public J visit(@Nullable Tree tree, P p) {
.orElse(IntelliJ.tabsAndIndents()), stopAfter)
.visit(t, p);

t = (JavaSourceFile) new TabsAndIndentsVisitor<>(Optional.ofNullable(((SourceFile) cu).getStyle(TabsAndIndentsStyle.class))
.orElse(IntelliJ.tabsAndIndents()), stopAfter)
.visit(t, p);
t = (JavaSourceFile) new TabsAndIndentsVisitor<>(
Optional.ofNullable(((SourceFile) cu).getStyle(TabsAndIndentsStyle.class)).orElse(IntelliJ.tabsAndIndents()),
Optional.ofNullable(((SourceFile) cu).getStyle(WrappingAndBracesStyle.class)).orElse(IntelliJ.wrappingAndBraces()),
stopAfter
).visit(t, p);

assert t != null;
return t;
Expand Down
51 changes: 29 additions & 22 deletions src/main/java/org/openrewrite/kotlin/format/BlankLinesVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
import org.openrewrite.java.tree.*;
import org.openrewrite.kotlin.KotlinIsoVisitor;
import org.openrewrite.kotlin.marker.OmitBraces;
import org.openrewrite.kotlin.marker.SingleExpressionBlock;
import org.openrewrite.kotlin.style.BlankLinesStyle;
import org.openrewrite.kotlin.tree.K;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import static java.util.Objects.requireNonNull;

Expand All @@ -50,7 +52,7 @@ public class BlankLinesVisitor<P> extends KotlinIsoVisitor<P> {
private static final int minimumBlankLines_AroundFieldInInterface = 0;
private static final int minimumBlankLines_AroundField = 0;
private static final int minimumBlankLines_AroundMethodInInterface = 1;
private static final int minimumBlankLines_AroundMethod = 1;
private static final int minimumBlankLines_AfterDeclarationWithBody = 1;
private static final int minimumBlankLines_BeforeMethodBody = 0;
private static final int minimumBlankLines_AroundInitializer = 1;

Expand Down Expand Up @@ -123,7 +125,7 @@ public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, P
}
} else if (statements.get(i - 1).getElement() instanceof J.Block) {
s = minimumLines(s, minimumBlankLines_AroundInitializer);
} else if (s.getElement() instanceof J.ClassDeclaration) {
} else if (s.getElement() instanceof J.ClassDeclaration || s.getElement() instanceof K.ClassDeclaration) {
// Apply `style.getMinimum().getAroundClass()` to inner classes.
s = minimumLines(s, minimumBlankLines_AroundClass);
}
Expand Down Expand Up @@ -231,18 +233,15 @@ public Statement visitStatement(Statement statement, P p) {
declMax = Math.max(declMax, minimumBlankLines_AroundField);
j = minimumLines(j, minimumBlankLines_AroundField);
}
} else if (j instanceof J.MethodDeclaration) {
} else if (j instanceof J.MethodDeclaration || j instanceof K.MethodDeclaration) {
if (classDecl.getKind() == J.ClassDeclaration.Kind.Type.Interface) {
declMax = Math.max(declMax, minimumBlankLines_AroundMethodInInterface);
j = minimumLines(j, minimumBlankLines_AroundMethodInInterface);
} else {
declMax = Math.max(declMax, minimumBlankLines_AroundMethod);
j = minimumLines(j, minimumBlankLines_AroundMethod);
}
} else if (j instanceof J.Block) {
declMax = Math.max(declMax, minimumBlankLines_AroundInitializer);
j = minimumLines(j, minimumBlankLines_AroundInitializer);
} else if (j instanceof J.ClassDeclaration) {
} else if (j instanceof J.ClassDeclaration || j instanceof K.ClassDeclaration) {
declMax = Math.max(declMax, minimumBlankLines_AroundClass);
j = minimumLines(j, minimumBlankLines_AroundClass);
}
Expand All @@ -263,8 +262,8 @@ public Statement visitStatement(Statement statement, P p) {
declMax = Math.max(declMax, minimumBlankLines_AroundField);
j = minimumLines(j, minimumBlankLines_AroundField);
} else if (j instanceof J.MethodDeclaration || j instanceof K.MethodDeclaration) {
declMax = Math.max(declMax, minimumBlankLines_AroundMethod);
j = minimumLines(j, minimumBlankLines_AroundMethod);
declMax = Math.max(declMax, minimumBlankLines_AfterDeclarationWithBody);
j = minimumLines(j, minimumBlankLines_AfterDeclarationWithBody);
} else if (j instanceof J.Block) {
declMax = Math.max(declMax, minimumBlankLines_AroundInitializer);
j = minimumLines(j, minimumBlankLines_AroundInitializer);
Expand All @@ -284,33 +283,41 @@ public J.Block visitBlock(J.Block block, P p) {
J.Block b = super.visitBlock(block, p);
b = b.withEnd(keepMaximumLines(b.getEnd(), style.getKeepMaximum().getBeforeEndOfBlock()));

List<Statement> blockStatements = b.getStatements();
blockStatements = ListUtils.map(blockStatements, (index, statement) -> {
if (index == 0) {
return statement;
}

if (statement instanceof J.MethodDeclaration) {
J.MethodDeclaration m = (J.MethodDeclaration) statement;
AtomicBoolean previousWithBody = new AtomicBoolean();
List<JRightPadded<Statement>> blockStatements = b.getPadding().getStatements();
blockStatements = ListUtils.map(blockStatements, (index, padded) -> {
Statement statement = padded.getElement();
if (statement instanceof J.MethodDeclaration || statement instanceof K.MethodDeclaration) {
J.MethodDeclaration m = statement instanceof J.MethodDeclaration ? (J.MethodDeclaration) statement :
((K.MethodDeclaration) statement).getMethodDeclaration();
if (previousWithBody.get()) {
m = minimumLines(m, minimumBlankLines_AfterDeclarationWithBody);
}
if (m.getBody() != null && !m.getBody().getMarkers().findFirst(SingleExpressionBlock.class).isPresent()) {
previousWithBody.set(true);
} else {
previousWithBody.set(false);
}
if (!m.getPrefix().getComments().isEmpty()) {
return minimumLines(m, style.getMinimum().getBeforeDeclarationWithCommentOrAnnotation());
m = minimumLines(m, style.getMinimum().getBeforeDeclarationWithCommentOrAnnotation());
}

if (!m.getLeadingAnnotations().isEmpty()) {
return minimumLines(m, style.getMinimum().getBeforeDeclarationWithCommentOrAnnotation());
m = minimumLines(m, style.getMinimum().getBeforeDeclarationWithCommentOrAnnotation());
}
statement = statement instanceof J.MethodDeclaration ? m : ((K.MethodDeclaration) statement).withMethodDeclaration(m);
} else if (statement instanceof J.VariableDeclarations) {
J.VariableDeclarations v = (J.VariableDeclarations) statement;

if (!v.getLeadingAnnotations().isEmpty()) {
return minimumLines(v, style.getMinimum().getBeforeDeclarationWithCommentOrAnnotation());
statement = minimumLines(v, style.getMinimum().getBeforeDeclarationWithCommentOrAnnotation());
}
}

return statement;
return padded.withElement(statement);
});

b = b.withStatements(blockStatements);
b = b.getPadding().withStatements(blockStatements);
return b;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite.kotlin.format;

import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JRightPadded;
import org.openrewrite.kotlin.KotlinIsoVisitor;
import org.openrewrite.kotlin.style.ImportLayoutStyle;
import org.openrewrite.kotlin.style.IntelliJ;
import org.openrewrite.kotlin.tree.K;

import java.util.HashSet;
import java.util.List;
import java.util.Optional;

public class ImportReorderingVisitor<P> extends KotlinIsoVisitor<P> {

@Override
public K.CompilationUnit visitCompilationUnit(K.CompilationUnit cu, P p) {
List<JRightPadded<J.Import>> importList = cu.getPadding().getImports();

ImportLayoutStyle layoutStyle = Optional.ofNullable(cu.getStyle(ImportLayoutStyle.class))
.orElse(IntelliJ.importLayout());

List<JRightPadded<J.Import>> ordered = layoutStyle.orderImports(importList, new HashSet<>());

if (referentialIdentical(importList, ordered)) {
return cu;
} else {
return cu.getPadding().withImports(ordered);
}
}

private <T> boolean referentialIdentical(List<T> l1, List<T> l2) {
if (l1.size() != l2.size()) {
return false;
}

for (int i = 0; i < l1.size(); i++) {
if (l1.get(i) != l2.get(i)) {
return false;
}
}

return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, P
if (!hasFinalModifierOnly && !c.getModifiers().isEmpty()) {
if (!first && Space.firstPrefix(c.getModifiers()).getWhitespace().isEmpty()) {
c = c.withModifiers(Space.formatFirstPrefix(c.getModifiers(),
c.getModifiers().iterator().next().getPrefix().withWhitespace(" ")));
updateSpace(c.getModifiers().iterator().next().getPrefix(), true)));
}
if (c.getModifiers().size() > 1) {
c = c.withModifiers(ListUtils.map(c.getModifiers(), (index, modifier) -> {
if (index > 0 &&
modifier.getPrefix().getWhitespace().isEmpty() &&
modifier.getType() != J.Modifier.Type.Final) {
return modifier.withPrefix(modifier.getPrefix().withWhitespace(" "));
return spaceBefore(modifier, true);
}
return modifier;
}));
Expand All @@ -88,21 +88,21 @@ public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, P

if (!first && !c.getName().getMarkers().findFirst(Implicit.class).isPresent() &&
c.getName().getPrefix().getWhitespace().isEmpty()) {
c = c.withName(c.getName().withPrefix(c.getName().getPrefix().withWhitespace(" ")));
c = c.withName(spaceBefore(c.getName(), true));
}

J.ClassDeclaration.Padding padding = c.getPadding();
JContainer<J.TypeParameter> typeParameters = padding.getTypeParameters();
if (typeParameters != null && !typeParameters.getElements().isEmpty()) {
if (!first && !typeParameters.getBefore().getWhitespace().isEmpty()) {
c = padding.withTypeParameters(typeParameters.withBefore(typeParameters.getBefore().withWhitespace(" ")));
c = padding.withTypeParameters(typeParameters.withBefore(updateSpace(typeParameters.getBefore(), true)));
}
}

if (c.getPadding().getExtends() != null) {
Space before = c.getPadding().getExtends().getBefore();
if (before.getWhitespace().isEmpty()) {
c = c.getPadding().withExtends(c.getPadding().getExtends().withBefore(before.withWhitespace(" ")));
c = c.getPadding().withExtends(c.getPadding().getExtends().withBefore(updateSpace(before, true)));
}
}

Expand Down Expand Up @@ -161,15 +161,15 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, P

if (!first && !firstFinal && Space.firstPrefix(m.getModifiers()).getWhitespace().isEmpty()) {
m = m.withModifiers(Space.formatFirstPrefix(m.getModifiers(),
m.getModifiers().iterator().next().getPrefix().withWhitespace(" ")));
updateSpace(m.getModifiers().iterator().next().getPrefix(), true)));
}

if (m.getModifiers().size() > 1) {
m = m.withModifiers(ListUtils.map(m.getModifiers(), (index, modifier) -> {
if (index > startPosition &&
modifier.getType() != J.Modifier.Type.Final &&
modifier.getPrefix().getWhitespace().isEmpty()) {
return modifier.withPrefix(modifier.getPrefix().withWhitespace(" "));
return spaceBefore(modifier, true);
}
return modifier;
}));
Expand All @@ -181,9 +181,7 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, P
if (typeParameters != null && !typeParameters.getTypeParameters().isEmpty()) {
if (!first && typeParameters.getPrefix().getWhitespace().isEmpty()) {
m = m.getAnnotations().withTypeParameters(
typeParameters.withPrefix(
typeParameters.getPrefix().withWhitespace(" ")
)
spaceBefore(typeParameters, true)
);
}
first = false;
Expand All @@ -198,7 +196,7 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, P
if (returnTypeExpression instanceof J.AnnotatedType) {
J.AnnotatedType annotatedType = (J.AnnotatedType) returnTypeExpression;
List<J.Annotation> annotations = ListUtils.mapFirst(annotatedType.getAnnotations(), annotation ->
annotation.withPrefix(annotation.getPrefix().withWhitespace(" "))
spaceBefore(annotation, true)
);
m = m.withReturnTypeExpression(annotatedType.withAnnotations(annotations));
}
Expand All @@ -214,7 +212,7 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, P
if (m.getPadding().getThrows() != null) {
Space before = m.getPadding().getThrows().getBefore();
if (before.getWhitespace().isEmpty()) {
m = m.getPadding().withThrows(m.getPadding().getThrows().withBefore(before.withWhitespace(" ")));
m = m.getPadding().withThrows(m.getPadding().getThrows().withBefore(updateSpace(before, true)));
}
}

Expand Down Expand Up @@ -247,7 +245,7 @@ public J.Return visitReturn(J.Return return_, P p) {
J.Return r = super.visitReturn(return_, p);
if (r.getExpression() != null && r.getExpression().getPrefix().getWhitespace().isEmpty() &&
!return_.getMarkers().findFirst(ImplicitReturn.class).isPresent()) {
r = r.withExpression(r.getExpression().withPrefix(r.getExpression().getPrefix().withWhitespace(" ")));
r = r.withExpression(spaceBefore(r.getExpression(), true));
}
return r;
}
Expand Down Expand Up @@ -298,7 +296,7 @@ public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations m
ListUtils.map(v.getModifiers(), (index, modifier) -> {
if (index != 0 || needFirstSpace) {
if (modifier.getPrefix().getWhitespace().isEmpty()) {
modifier = modifier.withPrefix(modifier.getPrefix().withWhitespace(" "));
modifier = spaceBefore(modifier, true);
}
}
return modifier;
Expand All @@ -310,7 +308,7 @@ public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations m
if (!v.getVariables().isEmpty() && !(firstEnclosing instanceof J.Lambda)) {
boolean extension = v.getMarkers().findFirst(Extension.class).isPresent();
if (v.getVariables().get(0).getPrefix().getWhitespace().isEmpty() && !v.getModifiers().isEmpty() && !extension) {
v = v.withVariables(ListUtils.mapFirst(v.getVariables(), v0 -> v0.withName(v0.getName().withPrefix(v0.getName().getPrefix().withWhitespace(" ")))));
v = v.withVariables(ListUtils.mapFirst(v.getVariables(), v0 -> v0.withName(spaceBefore(v0.getName(), true))));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,10 @@ public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, P
}
}
}
// Defaulted to `true` in IntelliJ's Kotlin formatting.
boolean beforeTypeParameterLeftAngleBracket = true;
if (c.getPadding().getTypeParameters() != null) {
c = c.getPadding().withTypeParameters(
spaceBefore(c.getPadding().getTypeParameters(),
beforeTypeParameterLeftAngleBracket, true)
false, true)
);
}
if (c.getPadding().getTypeParameters() != null) {
Expand Down
Loading

0 comments on commit 1705bb7

Please sign in to comment.