diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..886c3e56 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,245 @@ +# AGENTS.md + +## Project Overview + +Function-Graph-Overview generates control-flow graphs (CFGs) from source code. It runs as a VSCode extension and a web demo. It uses **tree-sitter** WASM parsers to produce ASTs, then walks them with language-specific statement handlers to build CFGs. + +## Commands + +- **Install**: `bun install` +- **Test**: `bun vitest run` +- **Lint & format**: `bun lint` +- **Dev server (web demo)**: `bun demo` +- **Generate parsers**: `bun generate-parsers` +- **Build**: `bun run build` (check package.json for exact scripts) + +## Platform Notes + +This project uses **bun** as its JavaScript runtime, package manager, and script runner — not npm or node. Use `bun` in place of `npm run`, `npx`, and `node` for all commands (e.g., `bun install`, `bun vitest run`, `bun run build`). + +On Windows, bun runs commands via PowerShell. Unix utilities like `tail`, `head`, `grep` are not available — use PowerShell equivalents or omit them. Pipe bun command output directly without filters (e.g., `bun vitest run 2>&1` not `bun vitest run 2>&1 | tail -30`). + +## Supported Languages + +C, C++, Go, Java, Python, TypeScript, TSX. + +Each language has a `cfg-.ts` file in `src/control-flow/`. + +## Architecture: How CFGs Are Built + +### Core Types (src/control-flow/cfg-defs.ts) + +- **`BasicBlock`** — The fundamental unit of CFG construction. Has `entry` (node ID), `exit` (node ID or null), plus optional `breaks`, `continues`, `gotos`, `labels`, `functionExits`. +- **`CFG`** — Final result: `{ graph, entry, offsetToNode }`. +- **`CFGGraph`** — A `MultiDirectedGraph` from graphology. +- **`GraphNode`** — Has `type: NodeType`, `code`, `lines`, `markers`, `cluster`, `targets`, `startOffset`. +- **`NodeType`** — One of: `START`, `END`, `STATEMENT`, `CONDITION`, `RETURN`, `BREAK`, `CONTINUE`, `MERGE`, `LOOP_HEAD`, `FOR_EXIT`, `SWITCH_CONDITION`, `CASE_CONDITION`, `SWITCH_MERGE`, `THROW`, `YIELD`, `GOTO`, `LABEL`, `EMPTY`, etc. +- **`EdgeType`** — `regular`, `consequence`, `alternative`, `exception`. +- **`BlockHandler`** — Collects breaks/continues/gotos/functionExits from child blocks and provides `forEachBreak`, `forEachContinue`, `forEachFunctionExit`, `processGotos` methods. +- **`BuilderOptions`** — `{ flatSwitch?, markerPattern?, callProcessor? }`. + +### GenericCFGBuilder (src/control-flow/generic-cfg-builder.ts) + +The shared engine all languages use. Constructed with `StatementHandlers` + `BuilderOptions`. + +- **`StatementHandlers`** — `{ named: { [nodeType: string]: StatementHandler }, default: StatementHandler }`. Maps tree-sitter AST node type names to handler functions. +- **`StatementHandler`** — `(syntax: SyntaxNode, ctx: Context) => BasicBlock`. Converts one AST node into a CFG fragment. +- **`Context`** — `{ builder, options, matcher, dispatch, state, link, extra?, callProcessor? }`. Passed to every handler. + - `builder` (Builder) — Adds nodes/edges to the graph. + - `matcher` (BlockMatcher) — Runs tree-sitter queries on AST nodes to extract sub-nodes. + - `dispatch.single(syntax)` / `dispatch.many(statements, parent)` — Recursively process child AST nodes. + - `state` (BlockHandler) — Tracks breaks/continues/gotos for the current scope. + - `link.syntaxToNode()` / `link.offsetToSyntax()` — Maps source offsets to CFG nodes. + +**`buildCFG(functionNode)`** flow: +1. Creates a `START` node. +2. Gets `functionNode.childForFieldName("body")`. +3. Calls `dispatchMany` on the body's named children. +4. Resolves gotos, creates implicit `RETURN` node, links edges. + +**`dispatchMany(statements)`** — Filters out non-marker comments, calls `dispatchSingle` per statement, chains blocks (exit→entry edges). + +**`dispatchSingle(syntax)`** — Looks up `handlers.named[syntax.type]` or falls back to `handlers.default`. + +### LanguageDefinition (src/control-flow/cfg.ts) + +Each language exports a `LanguageDefinition`: +```typescript +{ + wasmPath: string; // import of parsers/tree-sitter-.wasm?url + createCFGBuilder: (options: BuilderOptions) => CFGBuilder; + functionNodeTypes: string[]; // AST types representing functions + extractFunctionName: (node: SyntaxNode) => string | undefined; +} +``` + +Registered in `languageDefinitions: Record` in `src/control-flow/cfg.ts`. + +### Common Patterns (src/control-flow/common-patterns.ts) + +Reusable handler factories for common control-flow constructs: + +- **`cStyleIfProcessor(query)`** — C/C++/TS-style if/else-if/else chains. +- **`cStyleForStatementProcessor(query)`** — C-style `for(init;cond;update)` loops. +- **`cStyleWhileProcessor()`** — `while(cond) body` loops. +- **`cStyleDoWhileProcessor()`** — `do body while(cond)` loops. +- **`forEachLoopProcessor(definition)`** — Range/for-each loops (Go `for range`, Python `for in`, TS `for of`). +- **`labeledBreakProcessor(query)` / `labeledContinueProcessor(query)`** — Break/continue with optional labels. +- **`processReturnStatement`**, **`processBreakStatement`**, **`processContinueStatement`** — Simple flow-exit handlers. +- **`processGotoStatement`**, **`processLabeledStatement`** — Goto/label support. +- **`processStatementSequence`** — Dispatches all named children of a block node. +- **`processComment`** — Handles marker comments for testing. +- **`processThrowStatement`** — Throw/raise with `functionExits`. + +Each factory takes a **tree-sitter query string** that captures the relevant sub-parts of the AST node (e.g., `@cond`, `@body`, `@then`, `@else`). + +### BlockMatcher (src/control-flow/block-matcher.ts) + +Wraps tree-sitter queries. Usage pattern: +```typescript +const match = ctx.matcher.match(syntax, queryString); +const bodySyntax = match.requireSyntax("body"); +const bodyBlock = match.getBlock(bodySyntax); // recursively dispatches +``` +- `match.getSyntax(name)` — Optional capture. +- `match.requireSyntax(name)` — Required capture (throws if missing). +- `match.getSyntaxMany(name)` — Multiple captures. +- `match.getBlock(syntax)` — Dispatches the syntax node and returns its BasicBlock. + +### Switch Utilities (src/control-flow/switch-utils.ts) + +Shared logic for switch/select/match statements: `collectCases`, `buildSwitch`. + +### Per-Language Call Handlers (src/control-flow/per-language-call-handlers.ts) + +Special handling for specific function calls (e.g., `panic` in Go → TERMINATE, `sys.exit` in Python → TERMINATE). + +## Adding a New Language — Complete Checklist + +Also see: `docs/AddNewLanguage.md` + +### 1. Install the tree-sitter parser +```shell +bun add --dev tree-sitter- +``` + +### 2. Register the parser in scripts/generate-parsers.ts +Add `"tree-sitter-"` to the `parsersToBuild` array (line ~27). + +### 3. Generate the WASM parser +```shell +bun generate-parsers +``` +This copies/builds the `.wasm` file into `./parsers/`. + +### 4. Create src/control-flow/cfg-.ts +Export a `LanguageDefinition` object with: +- `wasmPath` — `import treeSitter from "../../parsers/tree-sitter-.wasm?url";` +- `createCFGBuilder(options)` — Returns `new GenericCFGBuilder(statementHandlers, options)` +- `functionNodeTypes` — Array of AST node types representing functions (check tree-sitter playground) +- `extractFunctionName(node)` — Uses `extractCapturedTextsByCaptureName` from `query-utils.ts` + +Define `statementHandlers: StatementHandlers` mapping AST node types to handlers. Reuse common patterns from `common-patterns.ts` where possible. Write custom handlers for language-specific constructs. + +Starter template: +```typescript +import type { Node as SyntaxNode } from "web-tree-sitter"; +import treeSitter from "../../parsers/tree-sitter-.wasm?url"; +import type { BasicBlock, BuilderOptions, CFGBuilder } from "./cfg-defs"; +import { type Context, GenericCFGBuilder, type StatementHandlers } from "./generic-cfg-builder.ts"; + +export const LanguageDefinition = { + wasmPath: treeSitter, + createCFGBuilder, + functionNodeTypes: ["function_definition"], // adjust per language + extractFunctionName: extractFunctionName, +}; + +const statementHandlers: StatementHandlers = { + named: { + // Map AST node type names to handler functions + }, + default: defaultProcessStatement, +}; + +function createCFGBuilder(options: BuilderOptions): CFGBuilder { + return new GenericCFGBuilder(statementHandlers, options); +} + +function defaultProcessStatement(syntax: SyntaxNode, ctx: Context): BasicBlock { + const newNode = ctx.builder.addNode("STATEMENT", syntax.text, syntax.startIndex); + ctx.link.syntaxToNode(syntax, newNode); + return { entry: newNode, exit: newNode }; +} +``` + +### 5. Register in src/control-flow/cfg.ts (ADD-LANGUAGES-HERE) +- Add to `supportedLanguages` array +- Import your language definition +- Add to `languageDefinitions` record + +### 6. Register in src/file-parsing/file-parsing.ts (ADD-LANGUAGES-HERE) +Add `{ ext: "", language: "" }` entries to `fileTypes`. + +### 7. Register in src/vscode/extension.ts (ADD-LANGUAGES-HERE) +Add VSCode `languageId` → Language mapping to `languageMapping`. + +### 8. Register in src/components/Demo.svelte (ADD-LANGUAGES-HERE, 3 spots) +- `defaultCodeSamples` — Add a default code snippet +- `languages` array — Add entry with `language`, `text`, and `codeMirror` factory +- `languageAliases` — Add lowercase alias + +### 9. Register in src/demo/src/App.svelte (ADD-LANGUAGES-HERE) +- Import a demo file: `import demoCode from "./assets/demo.?raw";` +- Add to `code` object +- Create `src/demo/src/assets/demo.` with example code + +### 10. Add test infrastructure +- Create `src/test/collect-.ts` — Parses test files and yields `TestFunction` objects. Use `initializeParser("")` from `src/parser-loader/bun.ts`. Pattern: parse the file, find function nodes preceded by comments, extract requirements from comment JSON. +- Register in `src/test/commentTestCollector.ts` (ADD-LANGUAGES-HERE) — Add to the `languages` array with `{ ext, getTestFuncs }`. +- Create test samples in `src/test/commentTestSamples/sample.` — Functions preceded by comment blocks containing JSON-like requirements (`nodes`, `exits`, `reaches`, `render`). + +### 11. Optionally add per-language call handlers +In `src/control-flow/per-language-call-handlers.ts`, add entries for functions that terminate the process (e.g., `panic`, `sys.exit`). + +## Comment-Test Format + +Tests are defined as source code files where each function is preceded by a comment containing requirements: + +**Go/C/C++ style** (block comments): +```go +/* +nodes: 3, +exits: 1, +reaches: [["A", "B"]], +render: true +*/ +func example() { ... } +``` + +**Python style** (line comments): +```python +# nodes: 3, +# exits: 1 +def example(): + ... +``` + +Requirements fields (all optional): +- `nodes` — Expected number of CFG nodes (simplified, if-chain switch) +- `flatNodes` — Expected nodes with flat switch rendering +- `exits` — Expected number of exit nodes +- `reaches` — `[["source_marker", "target_marker"]]` pairs for reachability assertions +- `flatReaches` — Same as reaches but for flat switch mode +- `unreach` — `[["source_marker", "target_marker"]]` pairs for unreachability assertions +- `render` — `true` to require rendering to succeed + +Markers are placed with comments containing `CFG: ` in the source code. + +## Key Design Patterns + +1. **Tree-sitter queries** are the primary mechanism for extracting AST structure. Use the [tree-sitter playground](https://tree-sitter.github.io/tree-sitter/playground) to understand the AST and write queries. +2. **BasicBlock chaining** — Each handler returns a `BasicBlock` with entry/exit. The framework chains them. Returning `exit: null` means the block diverts control flow (return, break, continue, throw). +3. **BlockHandler accumulation** — Call `ctx.state.update(block)` to accumulate breaks/continues/gotos, then resolve them at loop/switch boundaries with `forEachBreak`, `forEachContinue`, etc. +4. **Clusters** — Used for try/except/finally rendering. Created via `builder.withCluster(type, callback)`. +5. **Offset mapping** — `link.syntaxToNode` and `link.offsetToSyntax` maintain mappings between source positions and CFG nodes for navigation. diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b615f82..079e076f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,17 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how ## [Unreleased] +## [0.0.17] - 2026-02-21 + ### Added - Function name extraction with support for multiple programming languages. - Unit tests for function name extraction, covering various structures and languages. - Frontend logic in `render/src/App.svelte` to extract and display metadata based on render type. - Display of both CFG and function metadata in the GitHub render view, and CFG metadata in the Graph render view. +- Visual Studio extension (at https://github.com/tmr232/vs-function-graph-overview/) +- Initial Java support +- Initial C# support ## [0.0.16] - 2025-05-07 diff --git a/bun.lock b/bun.lock index 246347fe..8c43c1e4 100644 --- a/bun.lock +++ b/bun.lock @@ -1,9 +1,11 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "function-graph-overview", "dependencies": { + "@codemirror/lang-java": "^6.0.2", "@hpcc-js/wasm-graphviz": "^1.7.0", "@svgdotjs/svg.js": "^3.2.4", "@ts-graphviz/ast": "^2.0.7", @@ -31,6 +33,7 @@ "@codemirror/theme-one-dark": "^6.1.2", "@eslint/js": "^9.12.0", "@panzoom/panzoom": "^4.5.1", + "@replit/codemirror-lang-csharp": "^6.2.0", "@rollup/plugin-wasm": "^6.2.2", "@sveltejs/vite-plugin-svelte": "^5.0.3", "@types/bun": "latest", @@ -50,9 +53,11 @@ "svelte-awesome-color-picker": "^4.0.0", "svelte-codemirror-editor": "^1.4.1", "tree-sitter-c": "^0.23.5", + "tree-sitter-c-sharp": "^0.23.1", "tree-sitter-cli": "^0.25.3", "tree-sitter-cpp": "^0.23.4", "tree-sitter-go": "^0.23.1", + "tree-sitter-java": "^0.23.5", "tree-sitter-python": "^0.23.6", "tree-sitter-typescript": "^0.23.2", "typedoc": "^0.28.1", @@ -130,6 +135,8 @@ "@codemirror/lang-go": ["@codemirror/lang-go@6.0.1", "", { "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/language": "^6.6.0", "@codemirror/state": "^6.0.0", "@lezer/common": "^1.0.0", "@lezer/go": "^1.0.0" } }, "sha512-7fNvbyNylvqCphW9HD6WFnRpcDjr+KXX/FgqXy5H5ZS0eC5edDljukm/yNgYkwTsgp2busdod50AOTIy6Jikfg=="], + "@codemirror/lang-java": ["@codemirror/lang-java@6.0.2", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@lezer/java": "^1.0.0" } }, "sha512-m5Nt1mQ/cznJY7tMfQTJchmrjdjQ71IDs+55d1GAa8DGaB8JXWsVCkVT284C3RTASaY43YknrK2X3hPO/J3MOQ=="], + "@codemirror/lang-javascript": ["@codemirror/lang-javascript@6.2.3", "", { "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/language": "^6.6.0", "@codemirror/lint": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0", "@lezer/javascript": "^1.0.0" } }, "sha512-8PR3vIWg7pSu7ur8A07pGiYHgy3hHj+mRYRCSG8q+mPIrl0F02rgpGv+DsQTHRTc30rydOsf5PZ7yjKFg2Ackw=="], "@codemirror/lang-python": ["@codemirror/lang-python@6.1.6", "", { "dependencies": { "@codemirror/autocomplete": "^6.3.2", "@codemirror/language": "^6.8.0", "@codemirror/state": "^6.0.0", "@lezer/common": "^1.2.1", "@lezer/python": "^1.1.4" } }, "sha512-ai+01WfZhWqM92UqjnvorkxosZ2aq2u28kHvr+N3gu012XqY2CThD67JPMHnGceRfXPDBmn1HnyqowdpF57bNg=="], @@ -248,6 +255,8 @@ "@lezer/highlight": ["@lezer/highlight@1.2.1", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA=="], + "@lezer/java": ["@lezer/java@1.1.3", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0" } }, "sha512-yHquUfujwg6Yu4Fd1GNHCvidIvJwi/1Xu2DaKl/pfWIA2c1oXkVvawH3NyXhCaFx4OdlYBVX5wvz2f7Aoa/4Xw=="], + "@lezer/javascript": ["@lezer/javascript@1.4.21", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.1.3", "@lezer/lr": "^1.3.0" } }, "sha512-lL+1fcuxWYPURMM/oFZLEDm0XuLN128QPV+VuGtKpeaOGdcl9F2LYC3nh1S9LkPqx9M0mndZFdXCipNAZpzIkQ=="], "@lezer/lr": ["@lezer/lr@1.4.2", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA=="], @@ -282,6 +291,8 @@ "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], + "@replit/codemirror-lang-csharp": ["@replit/codemirror-lang-csharp@6.2.0", "", { "peerDependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.0.0", "@lezer/common": "^1.0.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0" } }, "sha512-6utbaWkoymhoAXj051mkRp+VIJlpwUgCX9Toevz3YatiZsz512fw3OVCedXQx+WcR0wb6zVHjChnuxqfCLtFVQ=="], + "@rollup/plugin-wasm": ["@rollup/plugin-wasm@6.2.2", "", { "dependencies": { "@rollup/pluginutils": "^5.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-gpC4R1G9Ni92ZIRTexqbhX7U+9estZrbhP+9SRb0DW9xpB9g7j34r+J2hqrcW/lRI7dJaU84MxZM0Rt82tqYPQ=="], "@rollup/pluginutils": ["@rollup/pluginutils@5.1.2", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^2.3.1" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw=="], @@ -1046,12 +1057,16 @@ "tree-sitter-c": ["tree-sitter-c@0.23.5", "", { "dependencies": { "node-addon-api": "^8.3.0", "node-gyp-build": "^4.8.4" }, "peerDependencies": { "tree-sitter": "^0.22.1" }, "optionalPeers": ["tree-sitter"] }, "sha512-riDWhqVIt8J14R7G0YMKlUy8E7eYR0Vp6DSGL90nX5CTAXkORCyp4WaOgNtfo8dEsHyZF5e/4E9Z9kWj+qLnTQ=="], + "tree-sitter-c-sharp": ["tree-sitter-c-sharp@0.23.1", "", { "dependencies": { "node-addon-api": "^8.2.2", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" }, "optionalPeers": ["tree-sitter"] }, "sha512-9zZ4FlcTRWWfRf6f4PgGhG8saPls6qOOt75tDfX7un9vQZJmARjPrAC6yBNCX2T/VKcCjIDbgq0evFaB3iGhQw=="], + "tree-sitter-cli": ["tree-sitter-cli@0.25.3", "", { "bin": { "tree-sitter": "cli.js" } }, "sha512-Bk6ZUXG+cKnwZpfR/te4NDrKld90p6350eqWlbLwSpV9/8vmL/x8LCw+3k7quY9oMDaYoMXHMvokXJbkM5A7bA=="], "tree-sitter-cpp": ["tree-sitter-cpp@0.23.4", "", { "dependencies": { "node-addon-api": "^8.2.1", "node-gyp-build": "^4.8.2", "tree-sitter-c": "^0.23.1" }, "peerDependencies": { "tree-sitter": "^0.21.1" }, "optionalPeers": ["tree-sitter"] }, "sha512-qR5qUDyhZ5jJ6V8/umiBxokRbe89bCGmcq/dk94wI4kN86qfdV8k0GHIUEKaqWgcu42wKal5E97LKpLeVW8sKw=="], "tree-sitter-go": ["tree-sitter-go@0.23.1", "", { "dependencies": { "node-addon-api": "^8.1.0", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.0" } }, "sha512-WfDdd/OVwzShWkhBoh2f3nE2VBhffOGpOrTHEI7z80Yjh3TcdPp3OCryYOStYwaDdSK4+f5ZUO9dMtpXsYRRoA=="], + "tree-sitter-java": ["tree-sitter-java@0.23.5", "", { "dependencies": { "node-addon-api": "^8.2.2", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" }, "optionalPeers": ["tree-sitter"] }, "sha512-Yju7oQ0Xx7GcUT01mUglPP+bYfvqjNCGdxqigTnew9nLGoII42PNVP3bHrYeMxswiCRM0yubWmN5qk+zsg0zMA=="], + "tree-sitter-javascript": ["tree-sitter-javascript@0.23.1", "", { "dependencies": { "node-addon-api": "^8.2.2", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" }, "optionalPeers": ["tree-sitter"] }, "sha512-/bnhbrTD9frUYHQTiYnPcxyHORIw157ERBa6dqzaKxvR/x3PC4Yzd+D1pZIMS6zNg2v3a8BZ0oK7jHqsQo9fWA=="], "tree-sitter-python": ["tree-sitter-python@0.23.6", "", { "dependencies": { "node-addon-api": "^8.3.0", "node-gyp-build": "^4.8.4" }, "peerDependencies": { "tree-sitter": "^0.22.1" }, "optionalPeers": ["tree-sitter"] }, "sha512-yIM9z0oxKIxT7bAtPOhgoVl6gTXlmlIhue7liFT4oBPF/lha7Ha4dQBS82Av6hMMRZoVnFJI8M6mL+SwWoLD3A=="], diff --git a/package.json b/package.json index 8e241b6b..0af8f188 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "module": "index.ts", "type": "module", "dependencies": { + "@codemirror/lang-java": "^6.0.2", "@hpcc-js/wasm-graphviz": "^1.7.0", "@svgdotjs/svg.js": "^3.2.4", "@ts-graphviz/ast": "^2.0.7", @@ -18,8 +19,8 @@ "lru-cache": "^11.0.2", "object-hash": "^3.0.0", "svgdom": "^0.1.21", - "web-tree-sitter": "^0.25.3", - "ts-graphviz": "^2.1.6" + "ts-graphviz": "^2.1.6", + "web-tree-sitter": "^0.25.3" }, "devDependencies": { "@biomejs/biome": "1.9.4", @@ -30,6 +31,7 @@ "@codemirror/theme-one-dark": "^6.1.2", "@eslint/js": "^9.12.0", "@panzoom/panzoom": "^4.5.1", + "@replit/codemirror-lang-csharp": "^6.2.0", "@rollup/plugin-wasm": "^6.2.2", "@sveltejs/vite-plugin-svelte": "^5.0.3", "@types/bun": "latest", @@ -49,9 +51,11 @@ "svelte-awesome-color-picker": "^4.0.0", "svelte-codemirror-editor": "^1.4.1", "tree-sitter-c": "^0.23.5", + "tree-sitter-c-sharp": "^0.23.1", "tree-sitter-cli": "^0.25.3", "tree-sitter-cpp": "^0.23.4", "tree-sitter-go": "^0.23.1", + "tree-sitter-java": "^0.23.5", "tree-sitter-python": "^0.23.6", "tree-sitter-typescript": "^0.23.2", "typedoc": "^0.28.1", @@ -90,7 +94,7 @@ "//": "START EXTENSION ATTRIBUTES", "publisher": "tamir-bahar", "name": "function-graph-overview", - "version": "0.0.16", + "version": "0.0.17", "description": "Function Graph Overview", "displayName": "Function Graph Overview", "icon": "./media/icon.png", diff --git a/parsers/tree-sitter-c_sharp.wasm b/parsers/tree-sitter-c_sharp.wasm new file mode 100644 index 00000000..ec79f5f2 Binary files /dev/null and b/parsers/tree-sitter-c_sharp.wasm differ diff --git a/parsers/tree-sitter-java.wasm b/parsers/tree-sitter-java.wasm new file mode 100644 index 00000000..68a0c1f3 Binary files /dev/null and b/parsers/tree-sitter-java.wasm differ diff --git a/scripts/generate-parsers.ts b/scripts/generate-parsers.ts index b374295b..262eb2e6 100644 --- a/scripts/generate-parsers.ts +++ b/scripts/generate-parsers.ts @@ -31,6 +31,8 @@ const parsersToBuild: (Location | string)[] = [ "tree-sitter-cpp", "tree-sitter-typescript", { package: "tree-sitter-typescript", name: "tree-sitter-tsx" }, + "tree-sitter-java", + { package: "tree-sitter-c-sharp", name: "tree-sitter-c_sharp" }, ]; function locatePrebuiltWasm(location: Location): string { diff --git a/src/components/Demo.svelte b/src/components/Demo.svelte index 126503a4..13492471 100644 --- a/src/components/Demo.svelte +++ b/src/components/Demo.svelte @@ -1,10 +1,12 @@