Skip to content
This repository was archived by the owner on May 12, 2025. It is now read-only.

Commit 19e1206

Browse files
Deprecate IsNullable marker and use J.NullableType instead (#497)
* Deprecate IsNullable marker and use J.UnaryTypeTree instead * Update to use K.NullableTypeTree * polish * Use J.NullableType * clean up * Cleanup space locations and usages * Remove `K.NullableTypeTree` --------- Co-authored-by: Knut Wannheden <knut@moderne.io>
1 parent 22cae35 commit 19e1206

File tree

15 files changed

+112
-65
lines changed

15 files changed

+112
-65
lines changed

src/main/java/org/openrewrite/kotlin/KotlinVisitor.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public J visitDestructuringDeclaration(K.DestructuringDeclaration destructuringD
144144
d = (K.DestructuringDeclaration) temp;
145145
}
146146
d = d.withInitializer(visitAndCast(d.getInitializer(), p));
147-
d = d.getPadding().withDestructAssignments(visitContainer(d.getPadding().getDestructAssignments(), p));
147+
d = d.getPadding().withDestructAssignments(visitContainer(d.getPadding().getDestructAssignments(), KContainer.Location.DESTRUCT_ASSIGNMENTS, p));
148148
return d;
149149
}
150150

@@ -156,7 +156,7 @@ public J visitFunctionType(K.FunctionType functionType, P p) {
156156
f = f.withModifiers(ListUtils.map(f.getModifiers(), e -> visitAndCast(e, p)));
157157
f = f.withReceiver(visitRightPadded(f.getReceiver(), p));
158158
if (f.getPadding().getParameters() != null) {
159-
f = f.getPadding().withParameters(this.visitContainer(f.getPadding().getParameters(), KContainer.Location.FUNCTION_TYPE_PARAMETERS, p));
159+
f = f.getPadding().withParameters(visitContainer(f.getPadding().getParameters(), KContainer.Location.FUNCTION_TYPE_PARAMETERS, p));
160160
}
161161
f = f.withReturnType(visitRightPadded(f.getReturnType(), p));
162162
return f;
@@ -241,7 +241,7 @@ public J visitListLiteral(K.ListLiteral listLiteral, P p) {
241241
} else {
242242
l = (K.ListLiteral) temp;
243243
}
244-
l = l.getPadding().withElements(visitContainer(l.getPadding().getElements(), p));
244+
l = l.getPadding().withElements(visitContainer(l.getPadding().getElements(), KContainer.Location.LIST_LITERAL_ELEMENTS, p));
245245
l = l.withType(visitType(l.getType(), p));
246246
return l;
247247
}
@@ -349,7 +349,7 @@ public J visitWhenBranch(K.WhenBranch whenBranch, P p) {
349349
} else {
350350
w = (K.WhenBranch) temp;
351351
}
352-
w = w.getPadding().withExpressions(visitContainer(w.getPadding().getExpressions(), p));
352+
w = w.getPadding().withExpressions(visitContainer(w.getPadding().getExpressions(), KContainer.Location.WHEN_BRANCH_EXPRESSION, p));
353353
w = w.getPadding().withBody(visitRightPadded(w.getPadding().getBody(), JRightPadded.Location.CASE_BODY, p));
354354
return w;
355355
}
@@ -420,9 +420,6 @@ public <M extends Marker> M visitMarker(Marker marker, P p) {
420420
if (m instanceof AnnotationUseSite) {
421421
AnnotationUseSite acs = (AnnotationUseSite) marker;
422422
m = acs.withPrefix(visitSpace(acs.getPrefix(), KSpace.Location.ANNOTATION_CALL_SITE_PREFIX, p));
423-
} else if (marker instanceof IsNullable) {
424-
IsNullable isn = (IsNullable) marker;
425-
m = isn.withPrefix(visitSpace(isn.getPrefix(), KSpace.Location.IS_NULLABLE_PREFIX, p));
426423
} else if (marker instanceof TypeReferencePrefix) {
427424
TypeReferencePrefix tr = (TypeReferencePrefix) marker;
428425
m = tr.withPrefix(visitSpace(tr.getPrefix(), KSpace.Location.TYPE_REFERENCE_PREFIX, p));

src/main/java/org/openrewrite/kotlin/RenameTypeAlias.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public String getDescription() {
5555
public TreeVisitor<?, ExecutionContext> getVisitor() {
5656
return new KotlinIsoVisitor<ExecutionContext>() {
5757
@Override
58-
public J.Identifier visitIdentifier(J.Identifier i, ExecutionContext executionContext) {
58+
public J.Identifier visitIdentifier(J.Identifier i, ExecutionContext ctx) {
5959
if (!i.getSimpleName().equals(aliasName) || !TypeUtils.isOfClassType(i.getType(), fullyQualifiedAliasedType)) {
6060
return i;
6161
}

src/main/java/org/openrewrite/kotlin/cleanup/ReplaceCharToIntWithCode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
5252
return new KotlinVisitor<ExecutionContext>() {
5353
@Override
5454
public J visitMethodInvocation(J.MethodInvocation method,
55-
ExecutionContext executionContext) {
55+
ExecutionContext ctx) {
5656
if (CHAR_TO_INT_METHOD_MATCHER.matches(method) && method.getSelect() != null) {
5757
J.FieldAccess codeTemplate = getCharCodeTemplate();
5858
return codeTemplate.withTarget(method.getSelect()).withPrefix(method.getPrefix());
5959
}
60-
return super.visitMethodInvocation(method, executionContext);
60+
return super.visitMethodInvocation(method, ctx);
6161
}
6262
};
6363
}

src/main/java/org/openrewrite/kotlin/format/SpacesFromCompilationUnitStyle.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
public class SpacesFromCompilationUnitStyle extends KotlinIsoVisitor<ExecutionContext> {
2828
@Override
29-
public @Nullable J visit(@Nullable Tree tree, ExecutionContext executionContext) {
29+
public @Nullable J visit(@Nullable Tree tree, ExecutionContext ctx) {
3030
if (!(tree instanceof K.CompilationUnit)) {
3131
return (J) tree;
3232
}

src/main/java/org/openrewrite/kotlin/internal/KotlinPrinter.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,7 @@ public J visitDestructuringDeclaration(K.DestructuringDeclaration destructuringD
220220

221221
@Override
222222
public J visitFunctionType(K.FunctionType functionType, PrintOutputCapture<P> p) {
223-
boolean nullable = functionType.getMarkers().findFirst(IsNullable.class).isPresent();
224-
225223
beforeSyntax(functionType, KSpace.Location.FUNCTION_TYPE_PREFIX, p);
226-
if (nullable) {
227-
p.append("(");
228-
}
229224

230225
visit(functionType.getLeadingAnnotations(), p);
231226
for (J.Modifier modifier : functionType.getModifiers()) {
@@ -241,9 +236,6 @@ public J visitFunctionType(K.FunctionType functionType, PrintOutputCapture<P> p)
241236
p.append("->");
242237

243238
visitRightPadded(functionType.getReturnType(), p);
244-
if (nullable) {
245-
p.append(")");
246-
}
247239
afterSyntax(functionType, p);
248240
return functionType;
249241
}
@@ -1316,7 +1308,6 @@ protected void visitModifier(J.Modifier mod, PrintOutputCapture<P> p) {
13161308

13171309
@Override
13181310
protected void afterSyntax(J j, PrintOutputCapture<P> p) {
1319-
kotlinPrinter.trailingMarkers(j.getMarkers(), p);
13201311
super.afterSyntax(j, p);
13211312
}
13221313
}
@@ -1334,15 +1325,6 @@ private static String getClassKind(J.ClassDeclaration classDecl) {
13341325
return kind;
13351326
}
13361327

1337-
private void trailingMarkers(Markers markers, PrintOutputCapture<P> p) {
1338-
for (Marker marker : markers.getMarkers()) {
1339-
if (marker instanceof IsNullable) {
1340-
KotlinPrinter.this.visitSpace(((IsNullable) marker).getPrefix(), KSpace.Location.TYPE_REFERENCE_PREFIX, p);
1341-
p.append("?");
1342-
}
1343-
}
1344-
}
1345-
13461328
@Override
13471329
public Space visitSpace(Space space, KSpace.Location loc, PrintOutputCapture<P> p) {
13481330
return delegate.visitSpace(space, Space.Location.LANGUAGE_EXTENSION, p);
@@ -1424,7 +1406,6 @@ private void beforeSyntax(Space prefix, Markers markers, @Nullable Space.Locatio
14241406
}
14251407

14261408
private void afterSyntax(J j, PrintOutputCapture<P> p) {
1427-
trailingMarkers(j.getMarkers(), p);
14281409
afterSyntax(j.getMarkers(), p);
14291410
}
14301411

src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ public J visitBinaryWithTypeRHSExpression(KtBinaryExpressionWithTypeRHS expressi
221221
TypeTree clazz = (TypeTree) (requireNonNull(expression.getRight()).accept(this, data));
222222
Markers markers = Markers.EMPTY;
223223
if (type == KtTokens.AS_SAFE) {
224-
markers = markers.addIfAbsent(new IsNullSafe(randomId(), Space.EMPTY));
224+
markers = markers.addIfAbsent(new IsNullSafe(randomId()));
225225
}
226226

227227
return new J.TypeCast(
@@ -308,7 +308,13 @@ public J visitCallableReferenceExpression(KtCallableReferenceExpression expressi
308308
Expression receiverExp = convertToExpression(expression.getReceiverExpression().accept(this, data));
309309
if (expression.getHasQuestionMarks()) {
310310
PsiElement questionMark = PsiTreeUtil.findSiblingForward(expression.getFirstChild(), KtTokens.QUEST, null);
311-
receiverExp = receiverExp.withMarkers(receiverExp.getMarkers().addIfAbsent(new IsNullable(randomId(), prefix(questionMark))));
311+
312+
receiverExp = new J.NullableType(randomId(),
313+
receiverExp.getPrefix(),
314+
Markers.EMPTY,
315+
Collections.emptyList(),
316+
padRight(receiverExp.withPrefix(Space.EMPTY), prefix(questionMark))
317+
);
312318
}
313319
receiver = padRight(receiverExp, prefix(expression.findColonColon()));
314320
}
@@ -809,7 +815,18 @@ public J visitNamedDeclaration(KtNamedDeclaration declaration, ExecutionContext
809815

810816
@Override
811817
public J visitNullableType(KtNullableType nullableType, ExecutionContext data) {
812-
TypeTree typeTree = (TypeTree) requireNonNull(nullableType.getInnerType()).accept(this, data);
818+
KtTypeElement innerType = nullableType.getInnerType();
819+
if (innerType == null) {
820+
throw new UnsupportedOperationException("This should never happen");
821+
}
822+
823+
TypeTree typeTree = (TypeTree) requireNonNull(innerType).accept(this, data);
824+
Set<PsiElement> consumedSpaces = new HashSet<>();
825+
if (innerType.getNextSibling() != null &&
826+
isSpace(innerType.getNextSibling().getNode()) &&
827+
!(innerType instanceof KtNullableType)) {
828+
consumedSpaces.add(innerType.getNextSibling());
829+
}
813830

814831
if (typeTree instanceof K.FunctionType && nullableType.getModifierList() != null) {
815832
List<J.Annotation> leadingAnnotations = new ArrayList<>();
@@ -824,10 +841,43 @@ public J visitNullableType(KtNullableType nullableType, ExecutionContext data) {
824841
typeTree = ((K.FunctionType) typeTree).withModifiers(modifiers).withLeadingAnnotations(leadingAnnotations);
825842
}
826843

827-
return typeTree.withPrefix(merge(deepPrefix(nullableType), typeTree.getPrefix()))
828-
.withMarkers(typeTree.getMarkers().addIfAbsent(new IsNullable(randomId(),
829-
prefix((PsiElement) nullableType.getQuestionMarkNode())
830-
)));
844+
// Handle parentheses or potential nested parentheses
845+
Stack<Pair<Integer, Integer>> parenPairs = new Stack<>();
846+
List<PsiElement> allChildren = getAllChildren(nullableType);
847+
848+
TypeTree j = typeTree;
849+
int l = 0;
850+
int r = allChildren.size() - 1;
851+
while (l < r) {
852+
l = findFirstLPAR(allChildren, l);
853+
r = findLastRPAR(allChildren, r);
854+
if (l * r < 0) {
855+
throw new UnsupportedOperationException("Unpaired parentheses!");
856+
}
857+
if (l < 0 || r < 0) {
858+
break;
859+
}
860+
parenPairs.add(new Pair<>(l++, r--));
861+
}
862+
863+
while (!parenPairs.empty()) {
864+
Pair<Integer, Integer> parenPair = parenPairs.pop();
865+
PsiElement lPAR = allChildren.get(parenPair.getFirst());
866+
PsiElement rPAR = allChildren.get(parenPair.getSecond());
867+
j = new J.ParenthesizedTypeTree(randomId(),
868+
Space.EMPTY,
869+
Markers.EMPTY,
870+
emptyList(),
871+
new J.Parentheses<>(randomId(), prefix(lPAR), Markers.EMPTY, padRight(j, prefix(rPAR, consumedSpaces)))
872+
);
873+
}
874+
875+
return new J.NullableType(randomId(),
876+
merge(deepPrefix(nullableType), j.getPrefix()),
877+
Markers.EMPTY,
878+
Collections.emptyList(),
879+
padRight(j, prefix(findFirstChild(nullableType, c -> c.getNode().getElementType() == KtTokens.QUEST)))
880+
);
831881
}
832882

833883
@Override
@@ -1094,7 +1144,7 @@ public J visitReturnExpression(KtReturnExpression expression, ExecutionContext d
10941144
@Override
10951145
public J visitSafeQualifiedExpression(KtSafeQualifiedExpression expression, ExecutionContext data) {
10961146
J j = visitQualifiedExpression(expression, data);
1097-
return j.withMarkers(j.getMarkers().addIfAbsent(new IsNullSafe(randomId(), Space.EMPTY)));
1147+
return j.withMarkers(j.getMarkers().addIfAbsent(new IsNullSafe(randomId())));
10981148
}
10991149

11001150
@Override
@@ -2709,7 +2759,7 @@ public J visitObjectDeclaration(KtObjectDeclaration declaration, ExecutionContex
27092759
}
27102760

27112761
if (declaration.getObjectKeyword() != null) {
2712-
markers = markers.add(new KObject(randomId(), Space.EMPTY));
2762+
markers = markers.add(new KObject(randomId()));
27132763
}
27142764

27152765
J.Identifier name;

src/main/java/org/openrewrite/kotlin/marker/Extension.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
public class Extension implements Marker {
2727
UUID id;
2828

29-
3029
public Extension(UUID id) {
3130
this.id = id;
3231
}

src/main/java/org/openrewrite/kotlin/marker/IsNullSafe.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
*/
1616
package org.openrewrite.kotlin.marker;
1717

18+
import com.fasterxml.jackson.annotation.JsonCreator;
19+
import com.fasterxml.jackson.annotation.JsonProperty;
1820
import lombok.Value;
1921
import lombok.With;
22+
import org.openrewrite.internal.lang.Nullable;
2023
import org.openrewrite.java.tree.Space;
2124
import org.openrewrite.marker.Marker;
2225

@@ -27,11 +30,14 @@
2730
public class IsNullSafe implements Marker {
2831
UUID id;
2932

30-
@Deprecated
31-
Space prefix;
33+
public IsNullSafe(UUID id) {
34+
this.id = id;
35+
}
3236

33-
public IsNullSafe(UUID id, Space prefix) {
37+
// to be dereleased
38+
@Deprecated
39+
@JsonCreator
40+
IsNullSafe(UUID id, @Deprecated @Nullable @JsonProperty("prefix") Space prefix) {
3441
this.id = id;
35-
this.prefix = Space.EMPTY;
3642
}
3743
}

src/main/java/org/openrewrite/kotlin/marker/IsNullable.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import java.util.UUID;
2424

25+
@Deprecated
2526
@Value
2627
@With
2728
public class IsNullable implements Marker {

src/main/java/org/openrewrite/kotlin/marker/KObject.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
*/
1616
package org.openrewrite.kotlin.marker;
1717

18+
import com.fasterxml.jackson.annotation.JsonCreator;
19+
import com.fasterxml.jackson.annotation.JsonProperty;
1820
import lombok.Value;
1921
import lombok.With;
22+
import org.openrewrite.internal.lang.Nullable;
2023
import org.openrewrite.java.tree.Space;
2124
import org.openrewrite.marker.Marker;
2225

@@ -26,11 +29,15 @@
2629
@With
2730
public class KObject implements Marker {
2831
UUID id;
29-
@Deprecated
30-
Space prefix;
3132

32-
public KObject(UUID id, Space prefix) {
33+
public KObject(UUID id) {
34+
this.id = id;
35+
}
36+
37+
// to be dereleased
38+
@Deprecated
39+
@JsonCreator
40+
KObject(UUID id, @Deprecated @Nullable @JsonProperty("prefix") Space prefix) {
3341
this.id = id;
34-
this.prefix = prefix;
3542
}
3643
}

0 commit comments

Comments
 (0)