diff --git a/.claudeignore b/.claudeignore new file mode 100644 index 0000000..c70c6df --- /dev/null +++ b/.claudeignore @@ -0,0 +1,9 @@ +# ============================================= +# .claudeignore – Optimierte Version für peakUp (Pro Plan) +# Ziel: Minimale automatische Datei-Reads + niedrige Burn-Rate +# ============================================= +target/ +*.class +*.iml +mvnw +mvnw.cmd \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..30cf57e --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml new file mode 100644 index 0000000..b24a990 --- /dev/null +++ b/.idea/checkstyle-idea.xml @@ -0,0 +1,15 @@ + + + + 13.5.0 + JavaOnly + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..6811ae8 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..234ae8b --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..3961015 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/sonarlint.xml b/.idea/sonarlint.xml new file mode 100644 index 0000000..574b89c --- /dev/null +++ b/.idea/sonarlint.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.mvn/jvm.config b/.mvn/jvm.config new file mode 100644 index 0000000..27dfc81 --- /dev/null +++ b/.mvn/jvm.config @@ -0,0 +1,11 @@ +--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED diff --git a/CLAUDE.md b/CLAUDE.md index 3e3d5d4..005deab 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -110,7 +110,7 @@ docker run -p 7474:7474 -p 7687:7687 \ ### General - Use Java 21 features: Records for DTOs/value objects, Sealed Classes for AST node types, Pattern Matching -- No `null` returns: use `Optional` or empty collections +- Non-null is the default (enforced by NullAway, packages annotated `@NullMarked`). Avoid `Optional` for fields, parameters, and most return types — use `@org.jspecify.annotations.Nullable` only where a value can genuinely be absent. Prefer empty collections over `Optional>`. - Immutable by default: prefer Records over mutable classes - Logging: `org.jboss.logging.Logger` (Quarkus standard) — no `System.out` diff --git a/README.md b/README.md index 569e818..1782d75 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,182 @@ -# agenticCode +# AgenticCode +> AI-agent-optimized code analysis platform — parse, store, enrich, and query source code as a graph. + +AgenticCode ingests source code (Natural/Software AG and Java), parses it into a unified AST, persists it in Neo4j, enriches it with semantic information (call graphs, DB accesses, data structures), and exposes everything through an agent-ready REST + MCP API. + +--- + +## Architecture + +```mermaid +flowchart TD + subgraph Sources["Source Files"] + N([Natural\nSoftware AG]) + J([Java]) + PY([Python\n_planned_]) + CB([COBOL\n_planned_]) + end + + subgraph Parsers["Parser Layer"] + NP["NaturalParser\ncustom implementation"] + JP["JavaParser\ncom.github.javaparser"] + PI["LanguageParser SPI\nshared interface + unified AST schema"] + end + + subgraph Store["AST Store"] + NEO[("Neo4j 5.x\nGraph Database\nModules · Functions · Variables\nData Structures · DB Tables")] + end + + subgraph Enrichment["Enrichment Layer"] + CG["CallGraphEnricher\nPERFORM / CALLNAT → CALLS edges"] + DB["DbAccessEnricher\nREAD / FIND / STORE → READS / WRITES edges"] + ID["IdentifierIndexEnricher\ncross-module variable index"] + DS["DataStructureEnricher\nDEFINE DATA → USES_TYPE edges"] + end + + subgraph API["Agentic API — Quarkus"] + REST["REST API\nJAX-RS · RESTEasy Reactive"] + MCP["MCP Endpoint\ntool-use optimized"] + end + + subgraph Agents["AI Agents"] + AG(["Claude / LLM Agent\ncall graph · DB access · identifier search\ncode generation · program analysis"]) + end + + N --> NP + J --> JP + PY --> PI + CB --> PI + NP --> PI + JP --> PI + PI --> NEO + NEO --> CG & DB & ID & DS + CG & DB & ID & DS --> REST + CG & DB & ID & DS --> MCP + REST --> AG + MCP --> AG +``` + +--- + +## Key API Tools (Agent-Facing) + +| Endpoint | Description | +|---|---| +| `POST /api/ingest` | Parse and ingest source files into the graph | +| `GET /api/modules/{name}/callers` | Who calls this module? | +| `GET /api/modules/{name}/callees` | What does this module call? | +| `GET /api/modules/{name}/db-accesses` | DB tables accessed and mode (READ/WRITE) | +| `GET /api/search/identifier?name=` | Find an identifier across all modules | +| `MCP tools/*` | All of the above as MCP tool-use endpoints | + +--- + +## Tech Stack + +| Component | Technology | +|---|---| +| Server | [Quarkus](https://quarkus.io) (latest stable) | +| Language | Java 21 — Records, Sealed Classes, Virtual Threads | +| Graph DB | Neo4j 5.x via `neo4j-java-driver` | +| REST | RESTEasy Reactive (JAX-RS) | +| Natural Parser | Custom implementation | +| Java Parser | [JavaParser](https://javaparser.org) | +| Tests | JUnit 5 + RestAssured + Testcontainers | +| Build | Maven (multi-module) | + +--- + +## Neo4j Graph Schema + +```mermaid +erDiagram + MODULE ||--o{ FUNCTION : CONTAINS + FUNCTION ||--o{ FUNCTION : CALLS + FUNCTION ||--o{ VARIABLE : READS + FUNCTION ||--o{ VARIABLE : WRITES + FUNCTION ||--o{ DB_TABLE : READS + FUNCTION ||--o{ DB_TABLE : WRITES + FUNCTION ||--o{ DATA_STRUCTURE : USES_TYPE + MODULE { + string id + string name + string language + string sourceFile + } + FUNCTION { + string id + string name + int startLine + int endLine + } + VARIABLE { + string id + string name + string dataType + } + DATA_STRUCTURE { + string id + string name + string scope + } + DB_TABLE { + string id + string name + string dbType + } +``` + +--- + +## Project Structure + +``` +agenticcode/ +├── api-server/ # Quarkus application (REST + MCP) +├── parser-core/ # Shared AST model + LanguageParser SPI +├── parser-natural/ # Custom Natural/Software AG parser +├── parser-java/ # Java parser (JavaParser-based) +├── neo4j-store/ # Neo4j persistence + Cypher queries +└── docs/ + ├── ast-schema.md + ├── natural-grammar.md + ├── api-endpoints.md + └── enrichment-pipelines.md +``` + +--- + +## Getting Started + +**Prerequisites:** Java 21+, Maven 3.9+, Docker + +```bash +# Clone and build +git clone https://github.com/your-org/agenticcode.git +cd agenticcode +mvn clean install + +# Start Neo4j +docker run -p 7474:7474 -p 7687:7687 \ + -e NEO4J_AUTH=neo4j/agenticcode \ + neo4j:5 + +# Run in dev mode (hot reload) +cd api-server && mvn quarkus:dev +``` + +The API is available at `http://localhost:8080/api` and the Neo4j browser at `http://localhost:7474`. + +--- + +## Supported Languages + +| Language | Status | Parser | +|---|---|---| +| Natural (Software AG) | 🚧 In development | Custom | +| Java | 🚧 In development | JavaParser | +| Python | 📋 Planned | — | +| COBOL | 📋 Planned | — | + +--- diff --git a/agenticcode-parent.iml b/agenticcode-parent.iml new file mode 100644 index 0000000..9e3449c --- /dev/null +++ b/agenticcode-parent.iml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/api-server/api-server.iml b/api-server/api-server.iml new file mode 100644 index 0000000..9e3449c --- /dev/null +++ b/api-server/api-server.iml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/api-server/pom.xml b/api-server/pom.xml new file mode 100644 index 0000000..4f57c36 --- /dev/null +++ b/api-server/pom.xml @@ -0,0 +1,106 @@ + + + 4.0.0 + + + com.agenticcode + agenticcode-parent + 1.0.0-SNAPSHOT + + + api-server + jar + + api-server + Quarkus application exposing the agentic source code API + + + + com.agenticcode + parser-core + + + com.agenticcode + parser-natural + + + com.agenticcode + parser-java + + + com.agenticcode + neo4j-store + + + + io.quarkus + quarkus-rest + + + io.quarkus + quarkus-rest-jackson + + + io.quarkus + quarkus-arc + + + io.quarkus + quarkus-smallrye-health + + + org.jspecify + jspecify + + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + org.testcontainers + testcontainers + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + ${quarkus.platform.group-id} + quarkus-maven-plugin + ${quarkus.platform.version} + true + + + + build + generate-code + generate-code-tests + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + com.agenticcode + package-info-maven-plugin + + + + diff --git a/api-server/src/main/java/com/agenticcode/apiserver/api/package-info.java b/api-server/src/main/java/com/agenticcode/apiserver/api/package-info.java new file mode 100644 index 0000000..daa2eaa --- /dev/null +++ b/api-server/src/main/java/com/agenticcode/apiserver/api/package-info.java @@ -0,0 +1,5 @@ +/** + * JAX-RS resources exposing the agentic source code API. + */ +@org.jspecify.annotations.NullMarked +package com.agenticcode.apiserver.api; diff --git a/api-server/src/main/java/com/agenticcode/apiserver/enrichment/package-info.java b/api-server/src/main/java/com/agenticcode/apiserver/enrichment/package-info.java new file mode 100644 index 0000000..0d64d6a --- /dev/null +++ b/api-server/src/main/java/com/agenticcode/apiserver/enrichment/package-info.java @@ -0,0 +1,5 @@ +/** + * Enrichment pipelines that run after AST ingest to add semantic information. + */ +@org.jspecify.annotations.NullMarked +package com.agenticcode.apiserver.enrichment; diff --git a/api-server/src/main/java/com/agenticcode/apiserver/mcp/package-info.java b/api-server/src/main/java/com/agenticcode/apiserver/mcp/package-info.java new file mode 100644 index 0000000..5db49f4 --- /dev/null +++ b/api-server/src/main/java/com/agenticcode/apiserver/mcp/package-info.java @@ -0,0 +1,5 @@ +/** + * MCP tool endpoints for AI agent integration. + */ +@org.jspecify.annotations.NullMarked +package com.agenticcode.apiserver.mcp; diff --git a/api-server/src/main/java/com/agenticcode/apiserver/service/package-info.java b/api-server/src/main/java/com/agenticcode/apiserver/service/package-info.java new file mode 100644 index 0000000..8236038 --- /dev/null +++ b/api-server/src/main/java/com/agenticcode/apiserver/service/package-info.java @@ -0,0 +1,5 @@ +/** + * Business logic services (ingest, call graph, enrichment orchestration). + */ +@org.jspecify.annotations.NullMarked +package com.agenticcode.apiserver.service; diff --git a/api-server/src/main/resources/application.properties b/api-server/src/main/resources/application.properties new file mode 100644 index 0000000..16789cc --- /dev/null +++ b/api-server/src/main/resources/application.properties @@ -0,0 +1,14 @@ +# Neo4j connection +quarkus.neo4j.uri=bolt://localhost:7687 +quarkus.neo4j.authentication.username=neo4j +quarkus.neo4j.authentication.password=agenticcode + +# Dev profile +%dev.quarkus.neo4j.uri=bolt://localhost:7687 +%dev.quarkus.neo4j.authentication.username=neo4j +%dev.quarkus.neo4j.authentication.password=agenticcode + +# Prod profile - override via environment variables +%prod.quarkus.neo4j.uri=${NEO4J_URI:bolt://neo4j:7687} +%prod.quarkus.neo4j.authentication.username=${NEO4J_USER:neo4j} +%prod.quarkus.neo4j.authentication.password=${NEO4J_PASSWORD} diff --git a/common/common.iml b/common/common.iml new file mode 100644 index 0000000..06aa59b --- /dev/null +++ b/common/common.iml @@ -0,0 +1,6 @@ + + + + + diff --git a/common/pom.xml b/common/pom.xml new file mode 100644 index 0000000..eda0819 --- /dev/null +++ b/common/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + + com.agenticcode + agenticcode-parent + 1.0.0-SNAPSHOT + + + common + jar + + common + Shared utility classes used across modules + + + + org.jspecify + jspecify + + + + org.junit.jupiter + junit-jupiter + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + com.agenticcode + package-info-maven-plugin + + + + diff --git a/common/src/main/java/com/agenticcode/common/util/package-info.java b/common/src/main/java/com/agenticcode/common/util/package-info.java new file mode 100644 index 0000000..911f6f3 --- /dev/null +++ b/common/src/main/java/com/agenticcode/common/util/package-info.java @@ -0,0 +1,2 @@ +@org.jspecify.annotations.NullMarked +package com.agenticcode.common.util; diff --git a/neo4j-store/pom.xml b/neo4j-store/pom.xml new file mode 100644 index 0000000..317daa1 --- /dev/null +++ b/neo4j-store/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + + + com.agenticcode + agenticcode-parent + 1.0.0-SNAPSHOT + + + neo4j-store + jar + + neo4j-store + Neo4j persistence and queries for the unified AST graph + + + + com.agenticcode + parser-core + + + + io.quarkiverse.neo4j + quarkus-neo4j + + + io.quarkus + quarkus-arc + + + org.jspecify + jspecify + + + + io.quarkus + quarkus-junit5 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + com.agenticcode + package-info-maven-plugin + + + + diff --git a/neo4j-store/src/main/java/com/agenticcode/neo4jstore/graph/package-info.java b/neo4j-store/src/main/java/com/agenticcode/neo4jstore/graph/package-info.java new file mode 100644 index 0000000..609b704 --- /dev/null +++ b/neo4j-store/src/main/java/com/agenticcode/neo4jstore/graph/package-info.java @@ -0,0 +1,5 @@ +/** + * Neo4j persistence and Cypher queries for the unified AST graph. + */ +@org.jspecify.annotations.NullMarked +package com.agenticcode.neo4jstore.graph; diff --git a/package-info-maven-plugin/package-info-maven-plugin.iml b/package-info-maven-plugin/package-info-maven-plugin.iml new file mode 100644 index 0000000..9e3449c --- /dev/null +++ b/package-info-maven-plugin/package-info-maven-plugin.iml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/package-info-maven-plugin/pom.xml b/package-info-maven-plugin/pom.xml new file mode 100644 index 0000000..072b3c5 --- /dev/null +++ b/package-info-maven-plugin/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + + com.agenticcode + agenticcode-parent + 1.0.0-SNAPSHOT + + + package-info-maven-plugin + maven-plugin + + package-info-maven-plugin + Generates @NullMarked package-info.java files for packages missing one + + + 3.9.9 + 3.13.1 + 3.13.1 + + + + + org.apache.maven + maven-plugin-api + ${maven-plugin-api.version} + + + org.apache.maven.plugin-tools + maven-plugin-annotations + ${maven-plugin-annotations.version} + provided + + + org.jspecify + jspecify + + + + org.junit.jupiter + junit-jupiter + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.maven.plugins + maven-plugin-plugin + ${maven-plugin-plugin.version} + + + + diff --git a/package-info-maven-plugin/src/main/java/com/agenticcode/packageinfo/PackageInfoGeneratorMojo.java b/package-info-maven-plugin/src/main/java/com/agenticcode/packageinfo/PackageInfoGeneratorMojo.java new file mode 100644 index 0000000..8e21050 --- /dev/null +++ b/package-info-maven-plugin/src/main/java/com/agenticcode/packageinfo/PackageInfoGeneratorMojo.java @@ -0,0 +1,89 @@ +package com.agenticcode.packageinfo; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; +import org.jspecify.annotations.Nullable; + +/** + * Generates package-info.java files annotated with {@code @NullMarked} + * for all packages that contain Java source files but no package-info.java yet. + */ +@Mojo(name = "generate-package-info", defaultPhase = LifecyclePhase.GENERATE_SOURCES, threadSafe = true) +public class PackageInfoGeneratorMojo extends AbstractMojo { + + private static final String ANNOTATION = "@org.jspecify.annotations.NullMarked"; + + @Parameter(defaultValue = "${project.build.sourceDirectory}", required = true) + private File sourceDirectory; + + @Override + public void execute() throws MojoExecutionException { + if (!sourceDirectory.exists()) { + getLog().info("Source directory does not exist, skipping: " + sourceDirectory); + return; + } + + final Path sourceRoot = sourceDirectory.toPath().toAbsolutePath().normalize(); + getLog().info("Generating package-info.java files in: " + sourceRoot); + + try (Stream stream = Files.walk(sourceRoot)) { + stream.filter(Files::isDirectory) + .forEach(directory -> processDirectory(sourceRoot, directory)); + } catch (IOException exception) { + throw new MojoExecutionException("Failed to walk source directory: " + sourceRoot, exception); + } + } + + private void processDirectory(Path sourceRoot, Path currentDir) { + try (Stream files = Files.list(currentDir)) { + boolean hasJavaFiles = files.anyMatch(path -> + path.toString().endsWith(".java") && !path.getFileName().toString().equals("package-info.java") + ); + + if (hasJavaFiles) { + String packageName = determinePackageName(sourceRoot, currentDir); + if (packageName != null) { + createPackageInfo(currentDir, packageName); + } + } + } catch (IOException exception) { + getLog().warn("Failed to process directory " + currentDir + ": " + exception.getMessage()); + } + } + + private @Nullable String determinePackageName(Path sourceRoot, Path currentDir) { + Path relativePath = sourceRoot.relativize(currentDir); + String packageName = StreamSupport.stream(relativePath.spliterator(), false) + .map(Path::toString) + .collect(Collectors.joining(".")); + return packageName.isEmpty() ? null : packageName; + } + + private void createPackageInfo(Path dir, String packageName) { + Path file = dir.resolve("package-info.java"); + + if (Files.exists(file)) { + return; + } + + String content = String.format("%s%npackage %s;%n", ANNOTATION, packageName); + try { + Files.writeString(file, content, StandardOpenOption.CREATE_NEW); + getLog().info("Created: " + file); + } catch (IOException exception) { + getLog().warn("Failed to create " + file + ": " + exception.getMessage()); + } + } +} diff --git a/parser-core/parser-core.iml b/parser-core/parser-core.iml new file mode 100644 index 0000000..9e3449c --- /dev/null +++ b/parser-core/parser-core.iml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/parser-core/pom.xml b/parser-core/pom.xml new file mode 100644 index 0000000..a38c258 --- /dev/null +++ b/parser-core/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + + + com.agenticcode + agenticcode-parent + 1.0.0-SNAPSHOT + + + parser-core + jar + + parser-core + Shared AST schema and language parser SPI + + + + com.fasterxml.jackson.core + jackson-databind + + + org.jspecify + jspecify + + + + org.junit.jupiter + junit-jupiter + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + com.agenticcode + package-info-maven-plugin + + + + diff --git a/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/AstEdge.java b/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/AstEdge.java new file mode 100644 index 0000000..1c5b3f5 --- /dev/null +++ b/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/AstEdge.java @@ -0,0 +1,14 @@ +package com.agenticcode.parsercore.ast.model; + +import java.util.UUID; + +/** + * A directed edge between two nodes in the unified AST graph. + */ +public record AstEdge( + UUID id, + EdgeType type, + UUID sourceId, + UUID targetId +) { +} diff --git a/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/AstNode.java b/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/AstNode.java new file mode 100644 index 0000000..c2a6aa9 --- /dev/null +++ b/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/AstNode.java @@ -0,0 +1,17 @@ +package com.agenticcode.parsercore.ast.model; + +import java.util.UUID; + +/** + * A node in the unified AST graph. + */ +public record AstNode( + UUID id, + NodeType type, + String name, + String sourceFile, + String language, + int startLine, + int endLine +) { +} diff --git a/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/EdgeType.java b/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/EdgeType.java new file mode 100644 index 0000000..d81c960 --- /dev/null +++ b/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/EdgeType.java @@ -0,0 +1,12 @@ +package com.agenticcode.parsercore.ast.model; + +/** + * Types of edges in the unified AST graph. + */ +public enum EdgeType { + CONTAINS, + CALLS, + READS, + WRITES, + USES_TYPE +} diff --git a/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/NodeType.java b/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/NodeType.java new file mode 100644 index 0000000..ccdac89 --- /dev/null +++ b/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/NodeType.java @@ -0,0 +1,12 @@ +package com.agenticcode.parsercore.ast.model; + +/** + * Types of nodes in the unified AST graph. + */ +public enum NodeType { + MODULE, + FUNCTION, + VARIABLE, + DATA_STRUCTURE, + DB_TABLE +} diff --git a/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/package-info.java b/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/package-info.java new file mode 100644 index 0000000..11e5ef0 --- /dev/null +++ b/parser-core/src/main/java/com/agenticcode/parsercore/ast/model/package-info.java @@ -0,0 +1,2 @@ +@org.jspecify.annotations.NullMarked +package com.agenticcode.parsercore.ast.model; diff --git a/parser-core/src/main/java/com/agenticcode/parsercore/ast/spi/LanguageParser.java b/parser-core/src/main/java/com/agenticcode/parsercore/ast/spi/LanguageParser.java new file mode 100644 index 0000000..ad4aeef --- /dev/null +++ b/parser-core/src/main/java/com/agenticcode/parsercore/ast/spi/LanguageParser.java @@ -0,0 +1,33 @@ +package com.agenticcode.parsercore.ast.spi; + +import com.agenticcode.parsercore.ast.model.AstEdge; +import com.agenticcode.parsercore.ast.model.AstNode; + +import java.util.List; + +/** + * SPI implemented by language-specific parsers (Natural, Java) to produce + * unified AST nodes and edges from a source file. + */ +public interface LanguageParser { + + /** + * @return the language identifier, e.g. "natural" or "java" + */ + String language(); + + /** + * Parses the given source file into unified AST nodes and edges. + * + * @param sourceFile path to the source file + * @param content full source content + * @return the parse result + */ + ParseResult parse(String sourceFile, String content); + + /** + * Result of parsing a single source file. + */ + record ParseResult(List nodes, List edges) { + } +} diff --git a/parser-core/src/main/java/com/agenticcode/parsercore/ast/spi/package-info.java b/parser-core/src/main/java/com/agenticcode/parsercore/ast/spi/package-info.java new file mode 100644 index 0000000..dc306ea --- /dev/null +++ b/parser-core/src/main/java/com/agenticcode/parsercore/ast/spi/package-info.java @@ -0,0 +1,2 @@ +@org.jspecify.annotations.NullMarked +package com.agenticcode.parsercore.ast.spi; diff --git a/parser-core/src/test/java/com/agenticcode/parsercore/ast/model/package-info.java b/parser-core/src/test/java/com/agenticcode/parsercore/ast/model/package-info.java new file mode 100644 index 0000000..763f727 --- /dev/null +++ b/parser-core/src/test/java/com/agenticcode/parsercore/ast/model/package-info.java @@ -0,0 +1,5 @@ +/** + * Unit tests for the unified AST model. + */ +@org.jspecify.annotations.NullMarked +package com.agenticcode.parsercore.ast.model; diff --git a/parser-java/parser-java.iml b/parser-java/parser-java.iml new file mode 100644 index 0000000..9e3449c --- /dev/null +++ b/parser-java/parser-java.iml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/parser-java/pom.xml b/parser-java/pom.xml new file mode 100644 index 0000000..821c675 --- /dev/null +++ b/parser-java/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + + com.agenticcode + agenticcode-parent + 1.0.0-SNAPSHOT + + + parser-java + jar + + parser-java + Java source parser based on JavaParser + + + + com.agenticcode + parser-core + + + + com.github.javaparser + javaparser-core + + + org.jspecify + jspecify + + + + org.junit.jupiter + junit-jupiter + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + com.agenticcode + package-info-maven-plugin + + + + diff --git a/parser-java/src/main/java/com/agenticcode/parserjava/package-info.java b/parser-java/src/main/java/com/agenticcode/parserjava/package-info.java new file mode 100644 index 0000000..cee726f --- /dev/null +++ b/parser-java/src/main/java/com/agenticcode/parserjava/package-info.java @@ -0,0 +1,5 @@ +/** + * Java source parser based on JavaParser. + */ +@org.jspecify.annotations.NullMarked +package com.agenticcode.parserjava; diff --git a/parser-natural/pom.xml b/parser-natural/pom.xml new file mode 100644 index 0000000..e95575a --- /dev/null +++ b/parser-natural/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + + + com.agenticcode + agenticcode-parent + 1.0.0-SNAPSHOT + + + parser-natural + jar + + parser-natural + Custom parser for Software AG Natural source code + + + + com.agenticcode + parser-core + + + org.jspecify + jspecify + + + + org.junit.jupiter + junit-jupiter + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + com.agenticcode + package-info-maven-plugin + + + + diff --git a/parser-natural/src/main/java/com/agenticcode/parsernatural/package-info.java b/parser-natural/src/main/java/com/agenticcode/parsernatural/package-info.java new file mode 100644 index 0000000..06ff516 --- /dev/null +++ b/parser-natural/src/main/java/com/agenticcode/parsernatural/package-info.java @@ -0,0 +1,5 @@ +/** + * Custom parser implementation for Software AG Natural source code. + */ +@org.jspecify.annotations.NullMarked +package com.agenticcode.parsernatural; diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..1b2322c --- /dev/null +++ b/pom.xml @@ -0,0 +1,160 @@ + + + 4.0.0 + + com.agenticcode + agenticcode-parent + 1.0.0-SNAPSHOT + pom + + AgenticCode + Parsing, storing, and agentically querying source code (Natural/Software AG and Java) + + + package-info-maven-plugin + common + parser-core + parser-natural + parser-java + neo4j-store + api-server + + + + 21 + UTF-8 + io.quarkus.platform + quarkus-bom + 3.17.7 + 5.0.3 + 3.26.2 + 5.11.3 + 3.13.0 + 3.5.3 + 2.36.0 + 0.13.1 + 1.0.0 + ${project.version} + + + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + + + com.agenticcode + common + ${project.version} + + + com.agenticcode + parser-core + ${project.version} + + + com.agenticcode + parser-natural + ${project.version} + + + com.agenticcode + parser-java + ${project.version} + + + com.agenticcode + neo4j-store + ${project.version} + + + + com.github.javaparser + javaparser-core + ${javaparser.version} + + + + io.quarkiverse.neo4j + quarkus-neo4j + ${quarkus-neo4j.version} + + + + org.junit.jupiter + junit-jupiter + ${junit.version} + test + + + + org.jspecify + jspecify + ${jspecify.version} + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${compiler-plugin.version} + + ${maven.compiler.release} + true + true + true + + -XDcompilePolicy=simple + --should-stop=ifError=FLOW + + -Xplugin:ErrorProne + + -Xpkginfo:always + + + + com.google.errorprone + error_prone_core + ${error-prone.version} + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + + + + + com.agenticcode + package-info-maven-plugin + ${package-info-maven-plugin.version} + + + + generate-package-info + + + + + + + +