Files
codegraph/__tests__/fixtures/kernel-parity/Torture.java
T
Colby MchenryandClaude Opus 5.5 51be28d15b fix(extraction): a function in an initializer is referenced once, by what the initializer declares (#2743)
PRs #693 and #1802 walk a declaration's initializer under the symbol it declares,
so `const routes = { home }` references `home` from `routes`. The
dispatcher's declaration-wide function-as-value scan then took the same
values again for the enclosing file (or class). Flush-time dedup keys on
the source, so both stayed: a second reference to the same function from
the same spot.

Each initializer walk now records what it walked, and the scan skips it.
PR #2738 added that mechanism for component wrappers, and C#, Scala and Dart
already had their own. The newly covered paths:
- TS/JS module-level constants and variables, owned object literals
  included (#2300), and TS/JS class properties;
- Python assignments, Go var/const specs, Rust const/static items;
- Java fields, and Kotlin properties (walkInitializer takes the property's
  id, so their walk is unchanged).
Mirrored in the kernel: tsjs, python, go, rustlang, java and kotlin.

References no initializer walk takes are unchanged: a module-level call
argument `register(fn)`, C-family tables, Rust's `static CB: fn() = handler`
(the declaration's own value, which the scan still reads).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 11:41:45 +00:00

134 lines
3.2 KiB
Java

/**
* Java torture fixture — exercises every Java extraction path the kernel
* ports: package namespace, imports, javadoc, annotations, inheritance,
* fields/constants, enums, anonymous classes, method references, static
* member reads, fluent chains, Lombok synthesis, value refs + shadowing.
*/
package com.example.torture;
import java.util.List;
import java.util.Map;
import static java.util.Objects.requireNonNull;
import com.example.other.OtherClass;
import lombok.Data;
/** Javadoc for the service. */
@Service
@Component("torture")
public class TortureService extends BaseService implements Runnable, AutoCloseable {
/** A shared constant table (value-ref target). */
public static final Map<String, Integer> RETRY_LIMITS = Map.of("a", 1);
private static final String API_BASE = "https://example.test";
protected int count = 0;
private final List<String> names;
int packagePrivate, secondDeclarator;
/** Field initializers — walked scoped to the field (#693). */
private final Runnable fieldLambda = () -> helper(RETRY_LIMITS);
private final Runnable fieldAnonClass = new Runnable() {
@Override
public void run() {
helper(RETRY_LIMITS);
}
};
private final Runnable fieldMethodRef = TortureService::compute;
private static final List<Runnable> FIELD_TABLE = List.of(TortureService::compute);
/** Ctor javadoc. */
public TortureService(List<String> names) {
this.names = requireNonNull(names);
register(this::onEvent);
queue(TortureService::compute);
queue(OtherClass::handle);
Runnable r = () -> helper(RETRY_LIMITS);
executor.submit(new Runnable() {
@Override
public void run() {
helper(RETRY_LIMITS);
}
});
}
@Override
@Deprecated
public void run() {
Config cfg = ConfigLoader.getInstance().load();
this.registry.lookup("x");
helper(Direction.UP);
String base = API_BASE;
int max = Limits.MAX_VALUE;
new StringBuilder(16).append(base);
}
private static Config helper(Object arg) {
return new Config();
}
private void onEvent() {}
private static void compute() {}
public void shadowed() {
String API_BASE = "local"; // shadows the class constant
log(API_BASE);
}
enum Direction {
UP,
DOWN;
Direction opposite() {
return this == UP ? DOWN : UP;
}
}
enum Step {
NEXT(1) {
@Override
int apply(int at) {
return clamp(at + size);
}
},
BACK(-1) {
@Override
int apply(int at) { return at + size; }
};
final int size;
Step(int size) { this.size = size; }
abstract int apply(int at);
static int clamp(int at) { return Math.max(0, at); }
}
interface Listener {
void onChange(TortureService svc);
}
}
@Data
class LombokBean {
private String name;
private boolean isActive;
private final int id;
private static int counter;
private String toString; // taken: no synthetic toString field collision
public String getName() { return name; } // explicit getter — never overridden
}
@lombok.Getter
@lombok.extern.slf4j.Slf4j
@Builder
class LombokBuilderBean {
private List<String> items;
}
interface Shape extends Comparable<Shape>, Cloneable {
double area();
}
@interface Marker {
String value() default "";
}