The doc-sniffing dog

fix regex problem

knotbin.com 76701749 e8a72f0d

verified
Changed files
+51 -16
tests
fixtures
prefix_bug
+19 -15
core.ts
···
return null;
}
+
function escapeRegExp(str: string): string {
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
+
}
+
async function findSymbolInFile(
filePath: string,
symbolName: string,
···
// Also check for non-exported declarations (class, function, interface, type, enum, const)
// that might be exported later with export { ... }
const patterns = [
-
new RegExp(`^(?:async\\s+)?function\\s+${symbolName}\\b`),
-
new RegExp(`^class\\s+${symbolName}\\b`),
-
new RegExp(`^interface\\s+${symbolName}\\b`),
-
new RegExp(`^type\\s+${symbolName}\\b`),
-
new RegExp(`^enum\\s+${symbolName}\\b`),
-
new RegExp(`^(?:const|let|var)\\s+${symbolName}\\b`),
+
new RegExp(`^(?:async\\s+)?function\\s+${escapeRegExp(symbolName)}\\b`),
+
new RegExp(`^class\\s+${escapeRegExp(symbolName)}\\b`),
+
new RegExp(`^interface\\s+${escapeRegExp(symbolName)}\\b`),
+
new RegExp(`^type\\s+${escapeRegExp(symbolName)}\\b`),
+
new RegExp(`^enum\\s+${escapeRegExp(symbolName)}\\b`),
+
new RegExp(`^(?:const|let|var)\\s+${escapeRegExp(symbolName)}\\b`),
];
for (const pattern of patterns) {
···
// Check for non-exported declarations that match symbols in sourceExports
for (const exp of sourceExports) {
const patterns = [
-
`class ${exp.originalName}`,
-
`function ${exp.originalName}`,
-
`const ${exp.originalName}`,
-
`let ${exp.originalName}`,
-
`var ${exp.originalName}`,
-
`interface ${exp.originalName}`,
-
`type ${exp.originalName}`,
-
`enum ${exp.originalName}`,
+
new RegExp(`^class\\s+${escapeRegExp(exp.originalName)}\\b`),
+
new RegExp(`^(?:async\\s+)?function\\s+${escapeRegExp(exp.originalName)}\\b`),
+
new RegExp(`^const\\s+${escapeRegExp(exp.originalName)}\\b`),
+
new RegExp(`^let\\s+${escapeRegExp(exp.originalName)}\\b`),
+
new RegExp(`^var\\s+${escapeRegExp(exp.originalName)}\\b`),
+
new RegExp(`^interface\\s+${escapeRegExp(exp.originalName)}\\b`),
+
new RegExp(`^type\\s+${escapeRegExp(exp.originalName)}\\b`),
+
new RegExp(`^enum\\s+${escapeRegExp(exp.originalName)}\\b`),
];
for (const pattern of patterns) {
-
if (trimmed.startsWith(pattern)) {
+
if (pattern.test(trimmed)) {
let fullDeclaration = trimmed;
const declarationStartLine = i;
+1 -1
deno.json
···
{
"name": "@knotbin/doggo",
-
"version": "0.1.1",
+
"version": "0.1.2",
"exports": "./mod.ts",
"imports": {
"@std/assert": "jsr:@std/assert@^1.0.15",
+22
tests/core_test.ts
···
assertEquals(byType["interface"]?.total, 1);
assertEquals(byType["const"]?.total, 1);
});
+
+
Deno.test("analyzeDirectory - correctly matches symbols with prefix names", async () => {
+
const fixturesPath = join(
+
Deno.cwd(),
+
"tests",
+
"fixtures",
+
"prefix_bug",
+
"types.ts",
+
);
+
+
const result = await analyzeDirectory(fixturesPath);
+
+
assertEquals(result.symbols.length, 2);
+
+
const serverSymbol = result.symbols.find((s) => s.name === "Server");
+
assertEquals(serverSymbol?.type, "type");
+
assertEquals(serverSymbol?.line, 6);
+
+
const serverRateLimitSymbol = result.symbols.find((s) => s.name === "ServerRateLimitDescription");
+
assertEquals(serverRateLimitSymbol?.type, "type");
+
assertEquals(serverRateLimitSymbol?.line, 1);
+
});
+9
tests/fixtures/prefix_bug/types.ts
···
+
export type ServerRateLimitDescription = {
+
name: string;
+
duration: number;
+
};
+
+
export type Server = {
+
host: string;
+
port: number;
+
};