mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-11 22:53:04 +00:00
fix(schema): persist Spring constructor-to-bean injection edges (#3239)
Co-authored-by: Jayson Albert <momeijw@gamil.com> Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
This commit is contained in:
parent
3236e2fbcd
commit
e7141ab0c1
7 changed files with 72 additions and 1 deletions
|
|
@ -518,7 +518,7 @@ const ATTACHMENT_TARGET_LABELS: readonly NodeTableName[] = [
|
|||
];
|
||||
|
||||
/**
|
||||
* The 66 pairs NEITHER rule above generates — everything left after the two
|
||||
* The pairs NEITHER rule above generates — everything left after the two
|
||||
* cross products are subtracted. Carried by CONTAINMENT, inheritance, imports
|
||||
* and DI: a container label crossed with a contained label. No predicate
|
||||
* describes that surface (any container can hold any definition).
|
||||
|
|
@ -531,6 +531,8 @@ const ATTACHMENT_TARGET_LABELS: readonly NodeTableName[] = [
|
|||
* templates), the two `Route|Process` / `Tool|Process` entry points whose
|
||||
* emitter names both labels as literals, and `BasicBlock|BasicBlock`, the PDG
|
||||
* substrate.
|
||||
* Spring dynamic lookup in a constructor also emits INJECTS to a synthetic
|
||||
* @Bean CodeElement (#3238), so Constructor|CodeElement belongs here.
|
||||
*
|
||||
* NOTHING A RULE ALREADY COVERS BELONGS HERE. `generatedRelationPairs` skips
|
||||
* any pair present in this block, so a redundant line does not merely duplicate
|
||||
|
|
@ -624,6 +626,7 @@ export const STRUCTURAL_PAIR_DDL = ` FROM File TO Folder,
|
|||
FROM \`Constructor\` TO \`Impl\`,
|
||||
FROM \`Constructor\` TO \`Namespace\`,
|
||||
FROM \`Constructor\` TO \`Typedef\`,
|
||||
FROM \`Constructor\` TO CodeElement,
|
||||
FROM Route TO Process,
|
||||
FROM Tool TO Process,
|
||||
FROM Destination TO \`Property\`,
|
||||
|
|
|
|||
12
gitnexus/test/fixtures/lang-resolution/spring-constructor-bean-lookup/src/example/AppConfig.java
vendored
Normal file
12
gitnexus/test/fixtures/lang-resolution/spring-constructor-bean-lookup/src/example/AppConfig.java
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package example;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class AppConfig {
|
||||
@Bean
|
||||
public Handler handler() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package example;
|
||||
|
||||
public interface Handler {}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package example;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SpringContextUtil {
|
||||
public static <T> Map<String, T> getBeans(Class<T> type) {
|
||||
return Map.of();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package example;
|
||||
|
||||
public class Worker {
|
||||
public Worker() {
|
||||
SpringContextUtil.getBeans(Handler.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/** Regression for #3238: a constructor's dynamic @Bean lookup must survive COPY. */
|
||||
import { expect, it } from 'vitest';
|
||||
import path from 'path';
|
||||
import { FIXTURES, runPipelineFromRepo } from './resolvers/helpers.js';
|
||||
import { createTempDir } from '../helpers/test-db.js';
|
||||
import * as adapter from '../../src/core/lbug/lbug-adapter.js';
|
||||
|
||||
it('persists the constructor-to-factory-bean INJECTS edge from the real pipeline', async () => {
|
||||
const fixture = path.join(FIXTURES, 'spring-constructor-bean-lookup');
|
||||
const result = await runPipelineFromRepo(fixture, () => {}, { workerPoolSize: 1 });
|
||||
const temp = await createTempDir();
|
||||
try {
|
||||
await adapter.initLbug(path.join(temp.dbPath, 'lbug'));
|
||||
await adapter.loadGraphToLbug(result.graph, fixture, temp.dbPath);
|
||||
const rows = await adapter.executeQuery(
|
||||
"MATCH (c:`Constructor`)-[r:CodeRelation]->(b:CodeElement) WHERE r.type = 'INJECTS' " +
|
||||
'RETURN c.filePath AS sourceFile, b.filePath AS targetFile, b.name AS beanName',
|
||||
);
|
||||
expect(rows).toEqual([
|
||||
{
|
||||
sourceFile: 'src/example/Worker.java',
|
||||
targetFile: 'src/example/AppConfig.java',
|
||||
beanName: 'handler',
|
||||
},
|
||||
]);
|
||||
} finally {
|
||||
await adapter.closeLbug();
|
||||
await temp.cleanup();
|
||||
}
|
||||
}, 120_000);
|
||||
|
|
@ -71,6 +71,13 @@ type CorpusEntry = {
|
|||
* exists to catch.
|
||||
*/
|
||||
const NON_BRIDGE_CORPUS = [
|
||||
{
|
||||
// Dynamic Spring lookup inside a constructor targets a synthetic @Bean
|
||||
// CodeElement, not the bean's declared return-type Class/Interface (#3238).
|
||||
fixture: 'spring-constructor-bean-lookup',
|
||||
emitter: 'spring constructor INJECTS',
|
||||
sentinels: ['Constructor|CodeElement'],
|
||||
},
|
||||
{
|
||||
// `cobol-processor.ts`: CONTAINS/CALLS/ACCESSES over Module / Namespace /
|
||||
// Record / Property / CodeElement.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue