113 lines
3.3 KiB
TypeScript
113 lines
3.3 KiB
TypeScript
import * as acorn from "npm:acorn";
|
|
import { assertEquals } from "https://deno.land/std@0.224.0/testing/asserts.ts";
|
|
|
|
/**
|
|
* Proof of Concept: Local Code Intelligence (Gen 2)
|
|
*
|
|
* Replaces the naive regex extraction in Gen 1 with actual AST parsing using
|
|
* acorn, proving that we can extract a true Semantic
|
|
* Code graph structure from code files.
|
|
*/
|
|
|
|
export interface ExportSymbol {
|
|
name: string;
|
|
type: "function" | "class" | "const";
|
|
signature: string;
|
|
}
|
|
|
|
export function extractExports(sourceCode: string): ExportSymbol[] {
|
|
// Strip TypeScript annotations using a regex just to let acorn parse it as JS
|
|
// In a real scenario we'd use a TS-capable parser like @typescript-eslint/typescript-estree or swc,
|
|
// but this proves the concept of AST walking vs regex scraping.
|
|
const jsCode = sourceCode
|
|
.replace(/:\s*Promise<[^>]+>/g, '')
|
|
.replace(/:\s*[a-zA-Z0-9_]+/g, '')
|
|
.replace(/<[^>]+>/g, '');
|
|
|
|
const ast = acorn.parse(jsCode, { ecmaVersion: 2022, sourceType: "module" }) as any;
|
|
const exports: ExportSymbol[] = [];
|
|
|
|
for (const node of ast.body) {
|
|
if (node.type === "ExportNamedDeclaration") {
|
|
if (node.declaration) {
|
|
if (node.declaration.type === "FunctionDeclaration") {
|
|
const name = node.declaration.id.name;
|
|
// Simple mock signature from JS AST
|
|
const params = node.declaration.params.map((p: any) => p.name).join(", ");
|
|
exports.push({
|
|
name,
|
|
type: "function",
|
|
signature: `(${params}) => any`,
|
|
});
|
|
} else if (node.declaration.type === "VariableDeclaration") {
|
|
for (const decl of node.declaration.declarations) {
|
|
exports.push({
|
|
name: decl.id.name,
|
|
type: "const",
|
|
signature: "const",
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return exports;
|
|
}
|
|
|
|
if (import.meta.main) {
|
|
console.log("Running Local Code Intelligence PoC (Gen 2) tests...");
|
|
|
|
const mockSourceCode = `
|
|
import { stuff } from "somewhere";
|
|
|
|
/**
|
|
* Calculates a complex value.
|
|
*/
|
|
export async function calculateValue(input: number, mode: string): Promise<number> {
|
|
return input * 2;
|
|
}
|
|
|
|
// An internal helper
|
|
function internalHelper() {
|
|
return true;
|
|
}
|
|
|
|
export const MAX_RETRIES = 5;
|
|
|
|
export function doSomethingElse(): void {
|
|
console.log(MAX_RETRIES);
|
|
}
|
|
`;
|
|
|
|
try {
|
|
const extracted = extractExports(mockSourceCode);
|
|
|
|
assertEquals(extracted.length, 3);
|
|
|
|
const calcFunc = extracted.find((e) => e.name === "calculateValue");
|
|
assertEquals(calcFunc?.type, "function");
|
|
assertEquals(
|
|
calcFunc?.signature,
|
|
"(input, mode) => any",
|
|
);
|
|
|
|
const maxRetries = extracted.find((e) => e.name === "MAX_RETRIES");
|
|
assertEquals(maxRetries?.type, "const");
|
|
|
|
const doSomething = extracted.find((e) => e.name === "doSomethingElse");
|
|
assertEquals(doSomething?.type, "function");
|
|
assertEquals(doSomething?.signature, "() => any");
|
|
|
|
console.log(
|
|
"✅ Local Code Intelligence PoC (Gen 2) successful: Extracted structured context from raw source using AST Parser.",
|
|
);
|
|
|
|
console.log("\n--- Agent Context Payload ---");
|
|
console.log(JSON.stringify(extracted, null, 2));
|
|
console.log("-----------------------------\n");
|
|
} catch (err) {
|
|
console.error("❌ Local Code Intelligence PoC (Gen 2) failed:", err);
|
|
}
|
|
}
|