Skip to content

Commit b58f5c6

Browse files
committed
Measure the whole type of a cast before inlining a chain onto it
In sun.rmi.transport.tcp.TCPTransport the cast (PrivilegedAction<String>) came out cut between "<" and "String", with the lambda it applies to on a third line, while the call around it stayed on one line (#60): static final Log tcpLog = Log.getLog( "sun.rmi.transport.tcp", "tcp", LogStream.parseLevel(AccessController.doPrivileged((PrivilegedAction< String>) () -> System.getProperty("sun.rmi.transport.tcp.logLevel")))); The arguments of getLog are inlined when a prefix of the last one fits, and CountWidthUntilBreakVisitor measures that prefix up to the first break inside the last level. visitTypeCast declares its level ACCEPT_INLINE_CHAIN, which means that first break is the one before the operand. The first break was the one visitParameterizedType emits after "<", so the prefix ended at "(PrivilegedAction<", fit, and the type had to take the break because "String>)" did not fit behind it. A wildcard bound, an intersection type and an annotated type offer breaks of their own in the same place and split the same way. The cast's level now has PartialInlineability.IF_FIRST_LEVEL_FITS, what visitDotWithPrefix uses for the same purpose: the visitor counts the whole first inner level, which is the rest of the type up to the break before the operand, when it fits. A chain is inlined onto a cast only if the type fits behind it. Here it does not, the chain is not inlined, and the arguments break one per line, as they do when the type is not parameterized. The type stays breakable for a cast that does not fit on a line at all, so the golden C keeps its output. The golden holds the statement above, the same cast one call shallower, which fit and does not change, and a method reference, two type arguments, a wildcard bound, a qualified name, an intersection type and an annotated type in the cast. Of the 15,747 files of the JDK 21 sources, that one statement in TCPTransport is the only one that formats differently, and its new output is stable.
1 parent 8a39a6a commit b58f5c6

3 files changed

Lines changed: 92 additions & 4 deletions

File tree

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -678,10 +678,18 @@ public Void visitBreak(BreakTree node, Void unused) {
678678
@Override
679679
public Void visitTypeCast(TypeCastTree node, Void unused) {
680680
sync(node);
681-
builder.open(
682-
plusFour,
683-
BreakBehaviours.preferBreakingLastInnerLevel(true),
684-
LastLevelBreakability.ACCEPT_INLINE_CHAIN);
681+
// An inline chain that ends at this level must have room for the whole type before the break in front of the
682+
// operand. Without IF_FIRST_LEVEL_FITS the chain measured the type up to its first break, the one after the
683+
// "<" of a parameterized type, and once inlined the type itself had to take that break: "(PrivilegedAction<"
684+
// at the end of one line and "String>)" on the next. The type stays breakable for the rare cast that does not
685+
// fit on a line at all.
686+
builder.open(OpenOp.builder()
687+
.debugName("typeCast")
688+
.plusIndent(plusFour)
689+
.breakBehaviour(BreakBehaviours.preferBreakingLastInnerLevel(true))
690+
.breakabilityIfLastLevel(LastLevelBreakability.ACCEPT_INLINE_CHAIN)
691+
.partialInlineability(PartialInlineability.IF_FIRST_LEVEL_FITS)
692+
.build());
685693
token("(");
686694
scan(node.getType(), null);
687695
token(")");
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class TCPTransport {
2+
@SuppressWarnings("removal")
3+
static final Log tcpLog = Log.getLog("sun.rmi.transport.tcp", "tcp",
4+
LogStream.parseLevel(AccessController.doPrivileged(
5+
(PrivilegedAction<String>) () -> System.getProperty("sun.rmi.transport.tcp.logLevel"))));
6+
7+
static final Level level = LogStream.parseLevel(AccessController.doPrivileged(
8+
(PrivilegedAction<String>) () -> System.getProperty("sun.rmi.transport.tcp.logLevel.and.some.more")));
9+
10+
static final Log methodReference = Log.getLog("sun.rmi.transport.tcp", "tcp",
11+
LogStream.parseLevel(AccessController.doPrivileged(
12+
(PrivilegedAction<String>) SomeVeryLongClassNameToFillTheLine::getTheTcpLogLevelProperty)));
13+
14+
static final Log twoTypeArguments = Log.getLog("sun.rmi.transport.tcp", "tcp",
15+
LogStream.parseLevel(AccessController.doPrivileged(
16+
(Function<String, Integer>) s -> System.getProperty("sun.rmi.transport.tcp.logLevel.x"))));
17+
18+
static final Log nested = Log.getLog("sun.rmi.transport.tcp", "tcp",
19+
LogStream.parseLevel(AccessController.doPrivileged(
20+
(Map<String, ? extends List<Integer>>) () -> System.getProperty("sun.rmi.transport.tcp.lv"))));
21+
22+
static final Log qualified = Log.getLog("sun.rmi.transport.tcp", "tcp",
23+
LogStream.parseLevel(AccessController.doPrivileged(
24+
(java.util.function.Function<String, Integer>) s -> System.getProperty("sun.rmi.logLevel"))));
25+
26+
static final Log intersection = Log.getLog("sun.rmi.transport.tcp", "tcp",
27+
LogStream.parseLevel(AccessController.doPrivileged(
28+
(Runnable & java.io.Serializable) () -> System.getProperty("sun.rmi.transport.tcp.logLevelxx"))));
29+
30+
static final Log annotated = Log.getLog("sun.rmi.transport.tcp", "tcp",
31+
LogStream.parseLevel(AccessController.doPrivileged(
32+
(Function<@Nullable String, Integer[]>) s -> System.getProperty("sun.rmi.transport.tcp.lvl"))));
33+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
class TCPTransport {
2+
@SuppressWarnings("removal")
3+
static final Log tcpLog = Log.getLog(
4+
"sun.rmi.transport.tcp",
5+
"tcp",
6+
LogStream.parseLevel(AccessController.doPrivileged(
7+
(PrivilegedAction<String>) () -> System.getProperty("sun.rmi.transport.tcp.logLevel"))));
8+
9+
static final Level level = LogStream.parseLevel(AccessController.doPrivileged(
10+
(PrivilegedAction<String>) () -> System.getProperty("sun.rmi.transport.tcp.logLevel.and.some.more")));
11+
12+
static final Log methodReference = Log.getLog(
13+
"sun.rmi.transport.tcp",
14+
"tcp",
15+
LogStream.parseLevel(AccessController.doPrivileged(
16+
(PrivilegedAction<String>) SomeVeryLongClassNameToFillTheLine::getTheTcpLogLevelProperty)));
17+
18+
static final Log twoTypeArguments = Log.getLog(
19+
"sun.rmi.transport.tcp",
20+
"tcp",
21+
LogStream.parseLevel(AccessController.doPrivileged(
22+
(Function<String, Integer>) s -> System.getProperty("sun.rmi.transport.tcp.logLevel.x"))));
23+
24+
static final Log nested = Log.getLog(
25+
"sun.rmi.transport.tcp",
26+
"tcp",
27+
LogStream.parseLevel(AccessController.doPrivileged(
28+
(Map<String, ? extends List<Integer>>) () -> System.getProperty("sun.rmi.transport.tcp.lv"))));
29+
30+
static final Log qualified = Log.getLog(
31+
"sun.rmi.transport.tcp",
32+
"tcp",
33+
LogStream.parseLevel(AccessController.doPrivileged(
34+
(java.util.function.Function<String, Integer>) s -> System.getProperty("sun.rmi.logLevel"))));
35+
36+
static final Log intersection = Log.getLog(
37+
"sun.rmi.transport.tcp",
38+
"tcp",
39+
LogStream.parseLevel(AccessController.doPrivileged(
40+
(Runnable & java.io.Serializable) () -> System.getProperty("sun.rmi.transport.tcp.logLevelxx"))));
41+
42+
static final Log annotated = Log.getLog(
43+
"sun.rmi.transport.tcp",
44+
"tcp",
45+
LogStream.parseLevel(AccessController.doPrivileged(
46+
(Function<@Nullable String, Integer[]>) s -> System.getProperty("sun.rmi.transport.tcp.lvl"))));
47+
}

0 commit comments

Comments
 (0)