From 31678188c402f8ff4a0cd173f1c53f7d82fa1033 Mon Sep 17 00:00:00 2001 From: nickreid Date: Fri, 29 Mar 2024 19:08:52 -0700 Subject: [PATCH] Stop using floats to represent line widths, which must be integers. Float was used so that forced breaks could be modeled with POSITIVE_INFINISTY, but an arbitrary large int works just as well. PiperOrigin-RevId: 620395732 --- .../java/com/google/googlejavaformat/Doc.java | 63 +++++++++++-------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Doc.java b/core/src/main/java/com/google/googlejavaformat/Doc.java index cab688558..01a75846e 100644 --- a/core/src/main/java/com/google/googlejavaformat/Doc.java +++ b/core/src/main/java/com/google/googlejavaformat/Doc.java @@ -63,6 +63,16 @@ public enum FillMode { FORCED } + /** + * The maximum supported line width. + * + *

This can be used as a sentinel/threshold for {@code Doc}s that break unconditionally. + * + *

The value was selected to be obviously too large for any practical line, but small enough to + * prevent accidental overflow. + */ + public static final int MAX_LINE_WIDTH = 1000; + /** State for writing. */ public static final class State { final int lastIndent; @@ -103,8 +113,7 @@ public String toString() { private static final Range EMPTY_RANGE = Range.closedOpen(-1, -1); private static final DiscreteDomain INTEGERS = DiscreteDomain.integers(); - // Memoized width; Float.POSITIVE_INFINITY if contains forced breaks. - private final Supplier width = Suppliers.memoize(this::computeWidth); + private final Supplier width = Suppliers.memoize(this::computeWidth); // Memoized flat; not defined (and never computed) if contains forced breaks. private final Supplier flat = Suppliers.memoize(this::computeFlat); @@ -113,16 +122,16 @@ public String toString() { private final Supplier> range = Suppliers.memoize(this::computeRange); /** - * Return the width of a {@code Doc}, or {@code Float.POSITIVE_INFINITY} if it must be broken. + * Return the width of a {@code Doc}. * * @return the width */ - final float getWidth() { + final int getWidth() { return width.get(); } /** - * Return a {@code Doc}'s flat-string value; not defined (and never called) if the (@code Doc} + * Return a {@code Doc}'s flat-string value; not defined (and never called) if the {@code Doc} * contains forced breaks. * * @return the flat-string value @@ -143,9 +152,9 @@ final Range range() { /** * Compute the {@code Doc}'s width. * - * @return the width, or {@code Float.POSITIVE_INFINITY} if it must be broken + * @return the width */ - abstract float computeWidth(); + abstract int computeWidth(); /** * Compute the {@code Doc}'s flat value. Not defined (and never called) if contains forced breaks. @@ -202,12 +211,8 @@ void add(Doc doc) { } @Override - float computeWidth() { - float thisWidth = 0.0F; - for (Doc doc : docs) { - thisWidth += doc.getWidth(); - } - return thisWidth; + int computeWidth() { + return getWidth(docs); } @Override @@ -246,10 +251,10 @@ Range computeRange() { @Override public State computeBreaks(CommentsHelper commentsHelper, int maxWidth, State state) { - float thisWidth = getWidth(); + int thisWidth = getWidth(); if (state.column + thisWidth <= maxWidth) { oneLine = true; - return state.withColumn(state.column + (int) thisWidth); + return state.withColumn(state.column + thisWidth); } State broken = computeBroken( @@ -295,8 +300,8 @@ private static State computeBreakAndSplit( State state, Optional optBreakDoc, List split) { - float breakWidth = optBreakDoc.isPresent() ? optBreakDoc.get().getWidth() : 0.0F; - float splitWidth = getWidth(split); + int breakWidth = optBreakDoc.isPresent() ? optBreakDoc.get().getWidth() : 0; + int splitWidth = getWidth(split); boolean shouldBreak = (optBreakDoc.isPresent() && optBreakDoc.get().fillMode == FillMode.UNIFIED) || state.mustBreak @@ -348,12 +353,16 @@ private void writeFilled(Output output) { * Get the width of a sequence of {@link Doc}s. * * @param docs the {@link Doc}s - * @return the width, or {@code Float.POSITIVE_INFINITY} if any {@link Doc} must be broken + * @return the width */ - static float getWidth(List docs) { - float width = 0.0F; + static int getWidth(List docs) { + int width = 0; for (Doc doc : docs) { width += doc.getWidth(); + + if (width >= MAX_LINE_WIDTH) { + return MAX_LINE_WIDTH; // Paranoid overflow protection + } } return width; } @@ -455,7 +464,7 @@ public void add(DocBuilder builder) { } @Override - float computeWidth() { + int computeWidth() { return token.getTok().length(); } @@ -512,8 +521,8 @@ public void add(DocBuilder builder) { } @Override - float computeWidth() { - return 1.0F; + int computeWidth() { + return 1; } @Override @@ -615,8 +624,8 @@ public void add(DocBuilder builder) { } @Override - float computeWidth() { - return isForced() ? Float.POSITIVE_INFINITY : (float) flat.length(); + int computeWidth() { + return isForced() ? MAX_LINE_WIDTH : flat.length(); } @Override @@ -705,7 +714,7 @@ public void add(DocBuilder builder) { } @Override - float computeWidth() { + int computeWidth() { int idx = Newlines.firstBreak(tok.getOriginalText()); // only count the first line of multi-line block comments if (tok.isComment()) { @@ -718,7 +727,7 @@ float computeWidth() { return reformatParameterComment(tok).map(String::length).orElse(tok.length()); } } - return idx != -1 ? Float.POSITIVE_INFINITY : (float) tok.length(); + return idx != -1 ? MAX_LINE_WIDTH : tok.length(); } @Override