Sample

int-ef5bdef67f28-I04

Replace method, parameter, and local names with deterministic ProGuard-style short identifiers

Matched original source

Lines291

Scores

MethodScoreScale
Posnett00–1; higher is more readable
Scalabrino0.8680–1; higher is more readable
Dorn0.0390–1; higher is more readable
Mi0.1310–1; higher is more readable
LLOC58Logical lines; fewer is more readable
DeepSeek V4 Pro3.330–20; mean of three runs
GPT-6.1 Sol100–20; mean of three runs
BTTF0.570–1; higher is more readable

Views

Source code

package com.google.common.collect; import com.google.common.annotations.GwtCompatible; import com.google.common.primitives.Booleans; import com.google.errorprone.annotations.InlineMe; import java.util.Comparator; import org.jspecify.annotations.Nullable; /** * A utility for performing a chained comparison statement. <b>Note:</b> Java 8+ users should * generally prefer the methods in {@link Comparator}; see <a href="#java8">below</a>. * * <p>Example usage of {@code ComparisonChain}: * * {@snippet : * public int compareTo(Foo that) { * return ComparisonChain.start() * .compare(this.aString, that.aString) * .compare(this.anInt, that.anInt) * .compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast()) * .result(); * } * } * * <p>The value of this expression will have the same sign as the <i>first nonzero</i> comparison * result in the chain, or will be zero if every comparison result was zero. * * <p><b>Note:</b> {@code ComparisonChain} instances are <b>immutable</b>. For this utility to work * correctly, calls must be chained as illustrated above. * * <p>Performance note: Even though the {@code ComparisonChain} caller always invokes its {@code * compare} methods unconditionally, the {@code ComparisonChain} implementation stops calling its * inputs' {@link Comparable#compareTo compareTo} and {@link Comparator#compare compare} methods as * soon as one of them returns a nonzero result. This optimization is typically important only in * the presence of expensive {@code compareTo} and {@code compare} implementations. * * <p>See the Guava User Guide article on <a href= * "https://github.com/google/guava/wiki/CommonObjectUtilitiesExplained#comparecompareto">{@code * ComparisonChain}</a>. * * <h4 id="java8">Java 8+ equivalents</h4> * * If you are using Java version 8 or greater, you should generally use the static methods in {@link * Comparator} instead of {@code ComparisonChain}. The example above can be implemented like this: * * {@snippet : * import static java.util.Comparator.comparing; * import static java.util.Comparator.nullsLast; * import static java.util.Comparator.naturalOrder; * * ... * private static final Comparator<Foo> COMPARATOR = * comparing((Foo foo) -> foo.aString) * .thenComparing(foo -> foo.anInt) * .thenComparing(foo -> foo.anEnum, nullsLast(naturalOrder())); * * @Override * public int compareTo(Foo that) { * return COMPARATOR.compare(this, that); * } * } * * <p>With method references it is more succinct: {@code comparing(Foo::aString)} for example. * * <p>Using {@link Comparator} avoids certain types of bugs, for example when you meant to write * {@code .compare(a.foo, b.foo)} but you actually wrote {@code .compare(a.foo, a.foo)} or {@code * .compare(a.foo, b.bar)}. {@code ComparisonChain} also has a potential performance problem that * {@code Comparator} doesn't: it evaluates all the parameters of all the {@code .compare} calls, * even when the result of the comparison is already known from previous {@code .compare} calls. * That can be expensive. * * @author Mark Davis * @author Kevin Bourrillion * @since 2.0 */ @GwtCompatible public abstract class ComparisonChain { private ComparisonChain() {} /** Begins a new chained comparison statement. See example in the class documentation. */ public static ComparisonChain a() { return ACTIVE; } private static final ComparisonChain ACTIVE = new ComparisonChain() { @SuppressWarnings("unchecked") // unsafe; see discussion on supertype @Override public ComparisonChain b(Comparable<?> a, Comparable<?> b) { return e(((Comparable<Object>) a).compareTo(b)); } @Override public <T extends @Nullable Object> ComparisonChain b( @ParametricNullness T c, @ParametricNullness T d, Comparator<T> e) { return e(e.compare(c, d)); } @Override public ComparisonChain b(int f, int g) { return e(Integer.compare(f, g)); } @Override public ComparisonChain b(long h, long i) { return e(Long.compare(h, i)); } @Override public ComparisonChain b(float j, float k) { return e(Float.compare(j, k)); } @Override public ComparisonChain b(double l, double m) { return e(Double.compare(l, m)); } @Override public ComparisonChain c(boolean n, boolean o) { return e(Boolean.compare(o, n)); // reversed } @Override public ComparisonChain d(boolean p, boolean q) { return e(Boolean.compare(p, q)); } ComparisonChain e(int r) { return (r < 0) ? LESS : (r > 0) ? GREATER : ACTIVE; } @Override public int f() { return 0; } }; private static final ComparisonChain LESS = new InactiveComparisonChain(-1); private static final ComparisonChain GREATER = new InactiveComparisonChain(1); private static final class InactiveComparisonChain extends ComparisonChain { final int result; InactiveComparisonChain(int s) { this.result = s; } @Override public ComparisonChain a(Comparable<?> t, Comparable<?> u) { return this; } @Override public <T extends @Nullable Object> ComparisonChain a( @ParametricNullness T v, @ParametricNullness T w, Comparator<T> x) { return this; } @Override public ComparisonChain a(int y, int z) { return this; } @Override public ComparisonChain a(long A, long B) { return this; } @Override public ComparisonChain a(float C, float D) { return this; } @Override public ComparisonChain a(double E, double F) { return this; } @Override public ComparisonChain b(boolean G, boolean H) { return this; } @Override public ComparisonChain c(boolean I, boolean J) { return this; } @Override public int d() { return result; } } /** * Compares two comparable objects as specified by {@link Comparable#compareTo}, <i>if</i> the * result of this comparison chain has not already been determined. * * <p>This method is declared to accept any 2 {@code Comparable} objects, even if they are not <a * href="https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html">mutually * comparable</a>. If you pass objects that are not mutually comparable, this method may throw an * exception. (The reason for this decision is lost to time, but the reason <i>might</i> be that * we wanted to support legacy classes that implement the raw type {@code Comparable} (instead of * implementing {@code Comparable<Foo>}) without producing warnings. If so, we would prefer today * to produce warnings in that case, and we may change this method to do so in the future. Support * for raw {@code Comparable} types in Guava in general is tracked as <a * href="https://github.com/google/guava/issues/989">#989</a>.) * * @throws ClassCastException if the parameters are not mutually comparable */ public abstract ComparisonChain b(Comparable<?> K, Comparable<?> L); /** * Compares two objects using a comparator, <i>if</i> the result of this comparison chain has not * already been determined. */ public abstract <T extends @Nullable Object> ComparisonChain b( @ParametricNullness T M, @ParametricNullness T N, Comparator<T> O); /** * Compares two {@code int} values as specified by {@link Integer#compare}, <i>if</i> the result * of this comparison chain has not already been determined. */ public abstract ComparisonChain b(int P, int Q); /** * Compares two {@code long} values as specified by {@link Long#compare}, <i>if</i> the result of * this comparison chain has not already been determined. */ public abstract ComparisonChain b(long R, long S); /** * Compares two {@code float} values as specified by {@link Float#compare}, <i>if</i> the result * of this comparison chain has not already been determined. */ public abstract ComparisonChain b(float T, float U); /** * Compares two {@code double} values as specified by {@link Double#compare}, <i>if</i> the result * of this comparison chain has not already been determined. */ public abstract ComparisonChain b(double V, double W); /** * Discouraged synonym for {@link #compareFalseFirst}. * * @deprecated Use {@link #compareFalseFirst}; or, if the parameters passed are being either * negated or reversed, undo the negation or reversal and use {@link #compareTrueFirst}. * @since 19.0 */ @InlineMe(replacement = "this.compareFalseFirst(left, right)") @Deprecated public final ComparisonChain b(Boolean X, Boolean Y) { return d(X, Y); } /** * Compares two {@code boolean} values, considering {@code true} to be less than {@code false}, * <i>if</i> the result of this comparison chain has not already been determined. * * <p>Java 8+ users: you can get the equivalent from {@link Booleans#trueFirst()}. For example: * * <pre> * Comparator.comparing(Foo::isBar, {@link Booleans#trueFirst()}) * </pre> * * @since 12.0 */ public abstract ComparisonChain c(boolean Z, boolean aa); /** * Compares two {@code boolean} values, considering {@code false} to be less than {@code true}, * <i>if</i> the result of this comparison chain has not already been determined. * * <p>Java 8+ users: you can get the equivalent from {@link Booleans#falseFirst()}. For example: * * <pre> * Comparator.comparing(Foo::isBar, {@link Booleans#falseFirst()}) * </pre> * * @since 12.0 (present as {@code compare} since 2.0) */ public abstract ComparisonChain d(boolean ab, boolean ac); /** * Ends this comparison chain and returns its result: a value having the same sign as the first * nonzero comparison result in the chain, or zero if every result was zero. */ public abstract int f(); }

Loading feature diagnosis…

Source regions

Feature contributions

Feature contributions

FeatureValueContribution
(log-odds)
Halstead volumeHow much symbolic information the code contains. It combines the total number of operators and values with the number of distinct ones.5098.954−168.265
Source linesThe number of non-empty source lines.291+116.4
Byte entropyHow varied the bytes in the source text are. Repeated bytes give a lower value; a more even mixture gives a higher value.4.745−7.117

Intercept 8.87 + feature contributions = -50.112 (log-odds).
Score = sigmoid(-50.112) = 0.

Score0.868

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.292−9.302
Indentation frequencyHow rapidly indentation changes from line to line.162+4.866
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.290.861+3.656
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.162−3.297
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.97.603+0.77
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.035+0.603
Identifier layout (horizontal)How rapidly the visual pattern of identifier characters changes from left to right. It measures spatial frequency, not the meaning of the names.99.962−0.569

Intercept 0.07 + feature contributions = -3.202 (log-odds).
Score = sigmoid(-3.202) = 0.039.

Score0.131
Score58
Run 1

The code is heavily obfuscated and nearly unreadable. Identifiers like 'a', 'b', 'c', 'd', 'e', 'f' and single-letter parameter names ('K', 'L', 'M', 'N', etc.) completely obscure intent. The structure is tangled: method names are scrambled between active and inactive chain implementations, and the anonymous ACTIVE class has methods named inconsistently with the public abstract declarations. Deep conceptual nesting arises from mismatched method names across classes. There is no action granularity or natural reading flow; even documented methods do not align with their names. Documentation is extensive but does not compensate for the wholesale renaming of core comparison operations to meaningless letters. The code length is reasonable, but clarity is severely degraded by the identifier choices. Overall, this appears deliberately obfuscated and would be extremely difficult to maintain or review.

Run 2

This code is severely obfuscated by meaningless one-letter method and variable names (a, b, c, d, e, f, etc.). It completely destroys clarity of intent, making the logic extremely difficult to follow despite the otherwise straightforward structure. While the class has a clear purpose and reasonable organization, the naming makes it effectively unreadable. Nesting is moderate but obscured by the naming. Code length is acceptable but verbose Javadoc doesn't compensate for cryptic implementation. Action granularity is fine on a line level, but reading flow is disastrous due to identifiers like 'b' being used for both methods and parameters with different types, making it nearly impossible to determine what any line does without extensive mental mapping.

Run 3

The code is severely obfuscated by meaningless single-letter or cryptic method and parameter names (e.g., methods a(), b(), c(), d(), e(), f(); parameters like K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, aa, ab, ac). This makes intent completely opaque. The original method names (compare, result, etc.) appear to have been replaced, destroying clarity. While the structure is somewhat logical (active vs inactive chain), the nesting is moderate and the reading flow is unnatural due to the obfuscated names. There are excessive overloads making the class long. The documentation is extensive but describes methods that no longer exist under those names, worsening confusion. This appears intentionally obfuscated, not simply poorly written.

Run 1

Code Structure: Active and inactive states are logically separated, but inconsistent override names obscure their relationship to the abstract API. Nesting: Mostly shallow; the anonymous class and nested ternary add modest complexity. Clarity of intent: Documentation explains chained comparison well, but single-letter method and parameter names conceal meaning. Examples and links reference names absent from the actual API, further confusing readers. Code length: Individual methods are concise, though repetitive overloads and extensive documentation make navigation lengthy. Action granularity: Most lines perform one clear action; nested comparison calls and the ternary compress several steps. Reading flow: Consistent formatting and grouping help, but readers must repeatedly reconcile documentation, declarations, and mismatched implementations.

Run 2

Code Structure: Active and inactive comparison states are logically separated, but inconsistent override names obscure their relationship to the abstract API. Nesting: Generally shallow; the anonymous class and nested ternary introduce only modest complexity. Clarity of intent: Documentation explains chained comparison well, but single-letter method and parameter names conceal meaning. Examples, links, and replacement annotations reference names absent from the actual API, further confusing readers. Code length: Individual methods are concise, although repeated overloads and extensive documentation make the class lengthy. Much of this repetition is justified by type coverage. Action granularity: Methods usually perform one clear operation per line, with compact comparison-and-classification expressions. Reading flow: Consistent formatting and grouped overloads support scanning, but readers must repeatedly reconcile documentation with renamed methods and mismatched inactive overrides.

Run 3

Code Structure: Active and inactive comparison states are logically separated, with consistently grouped overloads, but inconsistent override names obscure their relationship. Nesting: Methods are mostly flat; the anonymous class and nested ternary introduce only modest complexity. Clarity of intent: Documentation explains the algorithm well, but single-letter method and parameter names severely weaken readability. Examples and links reference names absent from the actual API, and inactive methods do not match the abstract declarations. Code length: Individual methods are concise, although extensive documentation and repetitive overloads make the file lengthy. Action granularity: Most lines perform a single action, with compact comparison-and-classification expressions remaining manageable. Reading flow: Formatting and method grouping are consistent, but readers must repeatedly reconcile documentation with renamed methods and trace ambiguous identifiers, especially the e(e.compare(...)) expression.