Skip to content

Commit

Permalink
Support nest parentheses of type
Browse files Browse the repository at this point in the history
  • Loading branch information
kunli2 committed Nov 9, 2023
1 parent 6175c8a commit 21be273
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,13 @@ public J visitMethodDeclaration(K.MethodDeclaration methodDeclaration, PrintOutp
return delegate.visitMethodDeclaration0(methodDeclaration.getMethodDeclaration(), methodDeclaration.getTypeConstraints(), p);
}

@Override
public J visitParenthesizedTypeTree(J.ParenthesizedTypeTree parTree, PrintOutputCapture<P> p) {
visitSpace(parTree.getPrefix(), Space.Location.PARENTHESES_PREFIX, p);
visitParentheses(parTree.getParenthesizedType(), p);
return parTree;
}

@Override
public J visitProperty(K.Property property, PrintOutputCapture<P> p) {
beforeSyntax(property, KSpace.Location.PROPERTY_PREFIX, p);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.openrewrite.kotlin.internal;

import kotlin.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.KtNodeTypes;
import org.jetbrains.kotlin.com.intellij.lang.ASTNode;
Expand Down Expand Up @@ -778,7 +779,8 @@ public J visitNamedDeclaration(KtNamedDeclaration declaration, ExecutionContext
@Override
public J visitNullableType(KtNullableType nullableType, ExecutionContext data) {
J j = requireNonNull(nullableType.getInnerType()).accept(this, data);
return j.withMarkers(j.getMarkers().addIfAbsent(new IsNullable(randomId(),
return j.withPrefix(deepPrefix(nullableType))
.withMarkers(j.getMarkers().addIfAbsent(new IsNullable(randomId(),
prefix((PsiElement) nullableType.getQuestionMarkNode())
)));
}
Expand Down Expand Up @@ -3020,7 +3022,7 @@ public J visitTypeReference(KtTypeReference typeReference, ExecutionContext data
}

J j = requireNonNull(typeReference.getTypeElement()).accept(this, data);
j = j.withPrefix(merge(j.getPrefix(), prefix(typeReference, consumedSpaces)));
// j = j.withPrefix(merge(j.getPrefix(), prefix(typeReference, consumedSpaces)));

consumedSpaces.add(findFirstPrefixSpace(typeReference.getTypeElement()));

Expand All @@ -3042,7 +3044,39 @@ public J visitTypeReference(KtTypeReference typeReference, ExecutionContext data
} else if (j instanceof J.Identifier) {
j = ((J.Identifier) j).withAnnotations(leadingAnnotations);
}
return j;

// Handle potential redundant nested parentheses
Stack<Pair<Integer, Integer>> parenPairs = new Stack<>();
List<PsiElement> allChildren = getAllChildren(typeReference);

int l = 0;
int r = allChildren.size() - 1;
while (l < r) {
l = findFirstLPAR(allChildren, l);
r = findLastRPAR(allChildren, r);
if (l * r < 0) {
throw new UnsupportedOperationException("Unpaired parentheses!");
}
if (l < 0 || r < 0) {
break;
}
parenPairs.add(new Pair<>(l++, r--));
}

while (!parenPairs.empty()) {
Pair<Integer, Integer> parenPair = parenPairs.pop();
PsiElement lPAR = allChildren.get(parenPair.getFirst());
PsiElement rPAR = allChildren.get(parenPair.getSecond());
TypeTree typeTree = (TypeTree) j;
j = new J.ParenthesizedTypeTree(randomId(),
Space.EMPTY,
Markers.EMPTY,
emptyList(),
new J.Parentheses<>(randomId(), prefix(lPAR), Markers.EMPTY, padRight(typeTree, prefix(rPAR)))
);
}

return j.withPrefix(merge(prefix(typeReference, consumedSpaces), j.getPrefix()));
}

@Override
Expand Down Expand Up @@ -3420,6 +3454,17 @@ private Space prefix(@Nullable PsiElement element, @Nullable Set<PsiElement> con
return space(first);
}

private static List<PsiElement> getAllChildren(PsiElement psiElement) {
List<PsiElement> allChildren = new ArrayList<>();

Iterator<PsiElement> iterator = PsiUtilsKt.getAllChildren(psiElement).iterator();
while (iterator.hasNext()) {
PsiElement it = iterator.next();
allChildren.add(it);
}
return allChildren;
}

@Nullable
private PsiElement findFirstPrefixSpace(@Nullable PsiElement element) {
if (element == null) {
Expand Down Expand Up @@ -3552,6 +3597,33 @@ private static boolean isSpace(ASTNode node) {
isCRLF(node);
}

private static boolean isLPAR(PsiElement element) {
return element instanceof LeafPsiElement && ((LeafPsiElement) element).getElementType() == KtTokens.LPAR;
}
private static boolean isRPAR(PsiElement element) {
return element instanceof LeafPsiElement && ((LeafPsiElement) element).getElementType() == KtTokens.RPAR;
}

private static int findFirstLPAR(List<PsiElement> elements, int start) {
int ret = -1;
for (int i = start; i < elements.size(); i++) {
if (isLPAR(elements.get(i))) {
return i;
}
}
return ret;
}

private static int findLastRPAR(List<PsiElement> elements, int end) {
int ret = -1;
for (int i = end; i >= 0; i--) {
if (isRPAR(elements.get(i))) {
return i;
}
}
return ret;
}

private static boolean isCRLF(ASTNode node) {
return node instanceof PsiErrorElementImpl && node.getText().equals("\r");
}
Expand All @@ -3568,7 +3640,6 @@ private String nodeRangeText(@Nullable ASTNode first, @Nullable ASTNode last) {
return builder.toString();
}


private List<J.Annotation> mapAnnotations(List<KtAnnotationEntry> ktAnnotationEntries, ExecutionContext data) {
return ktAnnotationEntries.stream()
.map(annotation -> (J.Annotation) annotation.accept(this, data))
Expand Down
6 changes: 2 additions & 4 deletions src/test/java/org/openrewrite/kotlin/tree/CastTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ fun method ( a : Any ) {
);
}

@ExpectedToFail
@Test
@Issue("https://github.com/openrewrite/rewrite-kotlin/issues/276")
void parenthesized() {
Expand All @@ -51,14 +50,13 @@ void parenthesized() {
);
}

@ExpectedToFail
@Test
@Issue("https://github.com/openrewrite/rewrite-kotlin/issues/276")
void parenthesize2() {
void nestedParenthesize() {
rewriteRun(
kotlin(
"""
val b = "s" as ( ( /*c1*/ (String?) /*c2*/ ) )
val b = "s" as ( ( /*c0*/ ( /*c1*/ String? /*c2*/ ) /*c3*/ ) )
"""
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ void parenthesizedNullableType() {
);
}

@SuppressWarnings("UNUSED_PARAMETER")
@ExpectedToFail
@Test
@Issue("https://github.com/openrewrite/rewrite-kotlin/issues/292")
void functionTypeParentheses() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

class ParenthesesTest implements RewriteTest {

@ExpectedToFail
@Test
void variableTypeInParentheses() {
rewriteRun(
Expand Down

0 comments on commit 21be273

Please sign in to comment.