Skip to content

grounds 0.0.9

Choose a tag to compare

@github-actions github-actions released this 15 Oct 06:18
· 22 commits to master since this release
ee7a75b

Type inference you can trust, more breaks caught across files, and Spring libraries. Still experimental. Binaries for macOS (Apple Silicon, Intel) and Linux (x86_64, arm64, statically linked: any distribution, Alpine and NixOS included).

target=aarch64-apple-darwin   # x86_64-apple-darwin, x86_64-unknown-linux-musl, aarch64-unknown-linux-musl
curl -fsSL https://github.com/mihaidaniel34/grounds/releases/download/v0.0.9/grounds-0.0.9-$target.tar.gz | tar -xz
sudo mv grounds-0.0.9-$target/grounds /usr/local/bin/

Each archive has a .sha256. The macOS binaries are not notarized: after a browser download, xattr -d com.apple.quarantine grounds.

Overload resolution and inference, checked against javac
Rules trust the types grounds is certain of, so a confidently wrong type is worse than an unknown one. Three differential fuzzers now compare grounds with javac on every pull request and nightly, and the inference was rebuilt until they agreed:

  • explicit type arguments, inferred bounds and F-bounds, wildcard capture, unchecked conversion (which erases the result), and ambiguous null calls;
  • lambda inputs resolved before the body, explicitly typed lambdas, method references treated as inexact, and target types bounding results from above;
  • generic calls and diamonds used as arguments that adapt to their parameter (collect(Collectors.groupingBy(...)), Map<Number, String> m = s.collect(toMap(...)));
  • a single remaining candidate is trusted only when no other overload can apply in any phase. An argument of unknown type that might be raw makes only the result's erasure certain.

In numbers:

  • the first fuzz run found 95 confidently wrong call types; now there are none, over 16,000 generated calls;
  • calls javac rejects but grounds typed with certainty fell from 2,187 to a handful;
  • an argument of unknown type (no jar for it) no longer hides what the other arguments prove: new String(Objects.requireNonNullElse(x, new byte[0])) is still String(byte[]).

CI mode: more breaks across files
grounds changed --base now also reports, in unchanged files:

  • uses of a deleted or renamed class (imported, by its simple name, or fully qualified);
  • calls and method references to a method made private (including implicit calls inherited from a superclass);
  • static imports of a member that no longer exists;
  • a changed return type assigned to an incompatible variable (incompatible-assignment, new);
  • a new bean that makes an injection ambiguous.

Each one stays silent wherever another class could legally take the name: another import, a wildcard package grounds cannot see, an inherited member, or a class defined in two modules.

Spring libraries
A project is an application only if it has a @SpringBootApplication / @SpringBootConfiguration class, or a @ComponentScan class with main. Otherwise it's a library: injections in its main code are left to the consuming application, so there are no bean-not-found reports for beans a consumer provides, and no bean-name clashes. A bean that injects its own type to wrap another implementation (a decorator) is no longer reported as ambiguous; grounds skips self-references the way Spring does (#15).

grounds classpath
Multi-module Maven projects that were never installed (most fresh clones) now get a classpath: grounds retries through the lifecycle up to test-compile, with compilation and checkers skipped, and installs nothing into ~/.m2.

Fixes

  • Without a JDK, grounds warns once and stays silent, instead of reporting toString() and getClass() as missing (225 false errors on camunda).
  • unresolved-method: an array passed alone in a varargs position counts as one element (of(byte[]) for of(byte[]...)).
  • DI: Jakarta Data repositories are beans; wiring that involves a class defined in several source files is left unknown; ObjectProvider / Provider with several beans or none is not a startup failure.
  • Unused-private-method, redundant-cast and infinite-recursion false positives that came from overload picks fixed by the new inference.

Testing

  • The corpus now runs in two setups: 26 projects without jars, and 20 with their exact build classpath. It also checks CI mode under scripted edits: 208 safe edits got no reports.
  • Before release, Astra reviewed all product code since 0.0.8 in five rounds. That found 13 false positives and 3 missed breaks, all fixed with regression tests.