Feat/webflux entrypoints test linkage config#462
Open
jaissebastian wants to merge 6 commits into
Open
Conversation
…l extraction Fix three gaps identified in Spring Boot / WebFlux usage: 1. Decorators were extracted in parser.py but never written to the node extra dict, so flows.py always received None and skipped Spring mapping annotations. Store deco_list under the decorators key for all languages. 2. @KafkaListener and @WorkflowMethod were stored in parser extra but absent from _FRAMEWORK_DECORATOR_PATTERNS in flows.py. Add both plus RestController. 3. WebFlux functional routing: @bean methods returning RouterFunction<ServerResponse> are now detected as entry points via return_type inspection in flows.py. Add RouterFunction and HandlerFunction decorator patterns as a fallback. 4. tests_for in query.py performed only direct TESTED_BY lookups. Switch to get_transitive_tests(depth=3) which already existed in graph.py, surfacing tests that cover the target indirectly through call chains. 5. Add @value("${property.key}") and @ConfigurationProperties(prefix=...) extraction in parser.py, emitting DEPENDS_ON_CONFIG edges with resolution=value_annotation or resolution=configuration_properties. Tests: 6 new assertions across test_flows.py and test_multilang.py; full suite remains at same failure count (6 pre-existing unrelated test_main failures). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…g file indexing Four parser gaps addressed based on Spring Boot / WebFlux usage observations: 1. Java method_reference nodes (handler::method) were absent from _CALL_TYPES and _get_call_name(). Add method_reference to _CALL_TYPES["java"] and handle it in both _get_call_name() and _extract_calls() so a CALLS edge is emitted with the receiver stored in extra, enabling Spring DI resolver rewriting. 2. object_creation_expression (new Foo()) was visited but _get_call_name() returned None because its first child is the `new` keyword, not an identifier. Add a Java-specific branch that reads the type_identifier child directly, making switch-based factory methods (return new ConcreteType()) visible. 3. HTTP path literals from @GetMapping/@PostMapping etc. are now first-class graph content. Add _HTTP_MAPPING_ANNOTATIONS constant, _get_http_annotation_path() extraction, and _emit_http_endpoint_nodes_and_edges() producing Endpoint nodes with HANDLES edges. Endpoints are searchable via semantic_search_nodes. 4. YAML and .properties config files are now indexed. Add .yml, .yaml, .properties to EXTENSION_TO_LANGUAGE and implement _parse_yaml_config() and _parse_properties_config() — regex-based, no extra dependency. Nested YAML keys are flattened to dotted paths (spring.datasource.url). These ConfigProperty nodes cross-link with existing DEPENDS_ON_CONFIG edges from @value annotations. Tests: 16 new assertions across TestJavaMethodReferenceAndConstructorCalls, TestJavaHttpEndpointExtraction, TestYamlConfigParsing, TestPropertiesConfigParsing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…fig key normalization - @bean method parameters now emit INJECTS edges so the Spring DI resolver can map field receivers to their declared types for method references - WebFlux route().GET/POST/PUT/DELETE/PATCH calls now emit Endpoint nodes and HANDLES edges; fix _get_call_name to return method name for chained Java method invocations (was returning None, skipping the call block) - YAML and @value config keys normalized to camelCase (kebab-case and snake_case variants all map to the same node name so edges resolve) - Add fixture examples and tests covering all three improvements Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add GraphStore.get_edges_by_config_key() to find DEPENDS_ON_CONFIG edges by the config: prefix key (bridges the gap between edge targets stored as 'config:key' and node qualified names stored as 'file.yml::key') - Add query_graph pattern 'consumers_of': returns all classes/methods that read a given config property, working even when no ConfigProperty node exists yet (e.g. only @value annotations parsed, no YAML file indexed) - Fix traverse_graph BFS to resolve config edges in both directions: - Starting from ConfigProperty: augments in_edges with get_edges_by_config_key - Following out_edges: resolves 'config:key' targets to real ConfigProperty nodes - Add 'consumers_of' to query_graph_tool docstring in main.py - Add integration tests covering all three code paths Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
HANDLES edges store targets as 'http:METHOD:path' while Endpoint nodes
are stored with qualified names like 'file.java::Class.METHOD path'.
BFS had no way to bridge this, so traverse_graph from an Endpoint node
returned only that one node.
- Add GraphStore.get_edges_by_endpoint_key(key) to find HANDLES edges
by their 'http:METHOD:path' target key
- Fix traverse_graph BFS in both directions:
- Starting from an Endpoint: augments in_edges via get_edges_by_endpoint_key
so the handler method is found at depth 1
- Following out_edges: resolves 'http:*' targets to actual Endpoint nodes
- Add integration tests covering the new traversal behaviour
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pattern The variable 't' was first inferred as dict (from get_transitive_tests) and then reused as GraphNode in the naming-convention fallback loop, causing mypy to flag incompatible type assignments and missing attributes. Rename the second loop variable to 'candidate' to give each binding a distinct, unambiguous type. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds comprehensive Spring Boot and Spring WebFlux support to the code graph, addressing the core gap where
callers_ofreturned 0 for field-injected Spring service calls.Spring DI Resolution (two-pass)
spring_resolver.py): Pass 1 collects all field/type declarations across Java files; Pass 2 rewrites CALLS edges using the type map — resolves@Autowired,@RequiredArgsConstructor(Lombok), and explicit constructor injection@Beanparameter injection:@Beanfactory method parameters now emitINJECTSedges so method-reference receivers (handler::method) resolve to their declared typeEXTRACTEDwith confidence 0.95 (constructor), 0.70 (autowired), 0.60 (constant reference)HTTP Endpoint Indexing
@GetMapping,@PostMapping,@PutMapping,@DeleteMapping,@PatchMapping,@RequestMappingon@RestControllermethods emitEndpointnodes (http:GET:/path) andHANDLESedgesroute().GET("/path", handler::method)chains now emit the same Endpoint nodes — fixed_get_call_nameto return the method name for chained Java method invocations (was returningNone, silently skipping the entire call block)Config File Indexing
.propertiesparsing:.yml,.yaml,.propertiesfiles are now parsed intoConfigPropertynodesgateway-url) and camelCase (gatewayUrl) and@Value("${payment.gatewayUrl}")all normalize to the same key so edges resolve@Valueand@ConfigurationPropertiesemitDEPENDS_ON_CONFIGedgesGraph Traversal Fixes (BFS edge bridging)
query_graph consumers_of: new pattern — "which classes/methods read this config property?" Works even without aConfigPropertynode (only@Valueannotations parsed)traverse_graphconfig-aware BFS:ConfigPropertynodes now have BFS neighbours;config:keyedge targets resolve to actual nodestraverse_graphEndpoint-aware BFS:traverse_graph("POST /bulk-calculation")now walksHANDLESedges to the handler method (depth 1) rather than returning only the Endpoint node. Same bridge pattern as config:get_edges_by_endpoint_key("http:POST:/path")maps the virtual key to real node QNsget_edges_by_config_key/get_edges_by_endpoint_key: newGraphStoremethods that bridge virtual edge targets to graph nodesJava Parser Improvements
method_reference(handler::process) added to_CALL_TYPES— emits CALLS edges with receiver stored for DI resolutionobject_creation_expression(new Foo()) now correctly extracts the type name fromtype_identifierchild (was returningNone)route().GET(...)now returns"GET"instead ofNoneExecution Flow Detection (
flows.py)@RestController,@KafkaListener,@WorkflowMethod,@ActivityMethod,@ScheduledRouterFunctionreturn type detected as entry pointextradict so flow detection can read themToken Efficiency (from merged branches)
detail_levelparameter on all major toolsquery_graphTest plan
uv run pytest tests/ --tb=short -q— 1269 tests pass (6 pre-existingtest_main.py::TestApplyToolFilterfailures unrelated to this PR)uv tool run ruff check code_review_graph/— cleancallers_of(ServiceA.fieldInjectedMethod)returns callers withresolution="spring_di_*"traverse_graph("POST /my-endpoint", depth=3)reaches the handler methodquery_graph("consumers_of", "some.config.key")returns the Java class that reads ittests/fixtures/SampleJava.java,tests/fixtures/SpringDI.java,tests/fixtures/application.yml,tests/fixtures/app.properties