Skip to content

Commit 4355e8c

Browse files
authored
Fix lineSpan (#193)
Fix lineSpan function to not throw NPE.
1 parent 484db76 commit 4355e8c

File tree

4 files changed

+38
-8
lines changed

4 files changed

+38
-8
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
type: fix
2+
fix:
3+
description: Fix bug in 0.3.24 that could sometimes cause a NPE when encountering
4+
a newline right after a string concatenation expression.
5+
links:
6+
- https://github.com/palantir/palantir-java-format/pull/193

palantir-java-format/src/main/java/com/palantir/javaformat/java/JavaInputAstVisitor.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import com.google.common.base.Verify;
5050
import com.google.common.collect.HashMultiset;
5151
import com.google.common.collect.ImmutableList;
52+
import com.google.common.collect.ImmutableRangeMap;
5253
import com.google.common.collect.ImmutableSet;
5354
import com.google.common.collect.ImmutableSortedSet;
5455
import com.google.common.collect.Iterables;
@@ -84,7 +85,6 @@
8485
import java.util.Map;
8586
import java.util.Optional;
8687
import java.util.Set;
87-
import java.util.function.IntFunction;
8888
import java.util.regex.Pattern;
8989
import java.util.stream.Stream;
9090
import javax.annotation.Nullable;
@@ -3304,13 +3304,24 @@ private Integer actualColumn(ExpressionTree expression) {
33043304

33053305
/** How many lines does this node take up in the input. Returns at least 1. */
33063306
int lineSpan(Tree node) {
3307-
IntFunction<Integer> lineNumberAt = tokenPosition -> {
3308-
Input.Token token = builder.getInput().getPositionTokenMap().get(tokenPosition);
3309-
return builder.getInput().getLineNumber(token.getTok().getPosition());
3310-
};
3311-
return lineNumberAt.apply(getEndPosition(node, getCurrentPath()))
3312-
- lineNumberAt.apply(getStartPosition(node))
3313-
+ 1;
3307+
ImmutableRangeMap<Integer, ? extends Input.Token> positionTokenMap =
3308+
builder.getInput().getPositionTokenMap();
3309+
3310+
int startPosition = getStartPosition(node);
3311+
int endPosition = getEndPosition(node, getCurrentPath());
3312+
// The last token will not be in the range map if it's whitespace, because of JavaOutput.endTok's filtering.
3313+
// Thus, we go back until we find a "real" last token.
3314+
// If all tokens down from endPosition are null, then we are guaranteed stop at startPosition.
3315+
while (endPosition > startPosition && positionTokenMap.get(endPosition) == null) {
3316+
endPosition--;
3317+
}
3318+
Input.Token startToken = positionTokenMap.get(startPosition);
3319+
Input.Token endToken = positionTokenMap.get(endPosition);
3320+
return lineNumberAt(endToken) - lineNumberAt(startToken) + 1;
3321+
}
3322+
3323+
private int lineNumberAt(Input.Token token) {
3324+
return builder.getInput().getLineNumber(token.getTok().getPosition());
33143325
}
33153326

33163327
/** Returns true if {@code atLeastM} of the expressions in the given column are the same kind. */

palantir-java-format/src/test/resources/com/palantir/javaformat/java/testdata/palantir-10.input

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,12 @@ class Palantir10 {
1616
+ "bar" + THING + "baz");
1717
foo("foo"
1818
+ "bar" + THING + "baz");
19+
20+
// This causes an NPE if we're not careful when getting the last token of the binary expression
21+
if (!partialDataSourceType.equals(dataSourceType)) {
22+
throw new ClientException("You may not use a " + partialDataSourceType
23+
+ " partial in a " + dataSourceType + " query. Caused by partial \"" + partialName + "\""
24+
);
25+
}
1926
}
2027
}

palantir-java-format/src/test/resources/com/palantir/javaformat/java/testdata/palantir-10.output

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,11 @@ class Palantir10 {
1313
// Test that we still reflow short string concatenations (spanning exactly 2 lines)
1414
foo("foo" + "bar" + THING + "baz");
1515
foo("foo" + "bar" + THING + "baz");
16+
17+
// This causes an NPE if we're not careful when getting the last token of the binary expression
18+
if (!partialDataSourceType.equals(dataSourceType)) {
19+
throw new ClientException("You may not use a " + partialDataSourceType + " partial in a " + dataSourceType
20+
+ " query. Caused by partial \"" + partialName + "\"");
21+
}
1622
}
1723
}

0 commit comments

Comments
 (0)