depgraph-core 1.5.1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,144 +0,0 @@
1
- # Stage 2 — Parser
2
-
3
- > **File**: `src/stages/parser.ts`
4
- > **Exports**: `parseFile(filePath: string): ParsedFile | null`, `parseFiles(filePaths: string[]): ParsedFile[]`
5
-
6
- ---
7
-
8
- ## What It Does
9
-
10
- The parser takes each file path from the collector and:
11
-
12
- 1. Reads the raw source code from disk.
13
- 2. Looks up the correct **language parser** from the registry based on the file extension.
14
- 3. Strips single-line `//` comments from the code before analysis.
15
- 4. Calls the language parser to extract **entities**, **imports**, and **exports**.
16
- 5. Returns a structured `ParsedFile` object.
17
-
18
- ---
19
-
20
- ## The `parseFile` Function — Step by Step
21
-
22
- ### Step 1: Read the file
23
-
24
- ```ts
25
- const code = fs.readFileSync(filePath, 'utf-8');
26
- ```
27
-
28
- If the file can't be read, it logs a warning and returns `null`.
29
-
30
- ### Step 2: Resolve the language parser
31
-
32
- ```ts
33
- const ext = path.extname(filePath).toLowerCase();
34
- const parser = getLanguageParser(ext);
35
- if (!parser) return null;
36
- ```
37
-
38
- `getLanguageParser` queries the language registry (see [language-registry.md](./language-registry.md)). If no parser is registered for the extension, the file is silently skipped.
39
-
40
- ### Step 3: Strip single-line comments
41
-
42
- ```ts
43
- const cleanCode = code
44
- .split('\n')
45
- .map(line => {
46
- const commentIndex = line.indexOf('//');
47
- if (commentIndex === -1) return line;
48
- // make sure // is not inside a string
49
- const before = line.slice(0, commentIndex);
50
- const inString = (before.match(/"/g) || []).length % 2 !== 0
51
- || (before.match(/'/g) || []).length % 2 !== 0;
52
- return inString ? line : line.slice(0, commentIndex);
53
- })
54
- .join('\n');
55
- ```
56
-
57
- This is done before passing code to any parser to prevent `//` inside comments from confusing regex patterns. The string-detection guard prevents false positives on lines like:
58
-
59
- ```ts
60
- const url = "https://example.com"; // this would break without the guard
61
- ```
62
-
63
- > **Limitation**: The guard only checks for unbalanced `"` or `'` quotes on the *same line*. Multi-line strings or template literals are not fully handled.
64
-
65
- ### Step 4: Extract data via the language parser
66
-
67
- ```ts
68
- const lines = code.split('\n').length; // count from original code
69
- const entities = parser.extractEntities(cleanCode, filePath);
70
- const imports = parser.extractImports(cleanCode);
71
- const exports = parser.extractExports(cleanCode);
72
- ```
73
-
74
- Note that line counting uses the **original** code (before stripping) to get accurate line numbers. Extraction uses the **clean** code.
75
-
76
- ### Step 5: Return the result
77
-
78
- ```ts
79
- return { filePath, lang: parser.lang, lines, entities, imports, exports };
80
- ```
81
-
82
- ---
83
-
84
- ## The `parseFiles` Function
85
-
86
- A simple iterator over `parseFile`. Files that return `null` are silently dropped:
87
-
88
- ```ts
89
- for (const filePath of filePaths) {
90
- const parsed = parseFile(filePath);
91
- if (parsed) results.push(parsed);
92
- }
93
- ```
94
-
95
- ---
96
-
97
- ## Output Shape — `ParsedFile`
98
-
99
- ```ts
100
- interface ParsedFile {
101
- filePath: string; // e.g. "/project/src/auth.ts"
102
- lang: string; // e.g. "js" — from the parser's lang field
103
- lines: number; // total line count
104
- entities: RawEntity[];
105
- imports: RawImport[];
106
- exports: string[];
107
- }
108
- ```
109
-
110
- See [data-types.md](./data-types.md) for the full definitions of `RawEntity` and `RawImport`.
111
-
112
- ---
113
-
114
- ## What "entities" means
115
-
116
- An entity is any named code construct the parser can recognise:
117
-
118
- - Functions, async functions, arrow functions
119
- - Classes, interfaces, types (TypeScript)
120
- - React components and hooks
121
- - Express/Fastify API route declarations
122
- - Python classes and `def` functions
123
-
124
- Every entity has a `name`, `type`, `line`, and `complexity` rating.
125
-
126
- ---
127
-
128
- ## Complexity Estimation
129
-
130
- Each language parser estimates complexity by counting branching keywords in the entity's body:
131
-
132
- | Branch count | Rating |
133
- |---|---|
134
- | 0–3 | `"low"` |
135
- | 4–8 | `"medium"` |
136
- | 9+ | `"high"` |
137
-
138
- Thresholds are set in `COMPLEXITY_THRESHOLDS` in [`src/constants.ts`](../src/constants.ts).
139
-
140
- ---
141
-
142
- ## Adding Support for a New Language
143
-
144
- You don't touch the parser stage at all. Instead, register a new language parser — see [language-registry.md](./language-registry.md).