lsp-intelligence 0.2.0 → 0.2.1
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.
- package/README.md +41 -13
- package/dist/analysis/pattern/collectSearchFiles.d.ts +2 -1
- package/dist/analysis/pattern/collectSearchFiles.js +6 -6
- package/dist/analysis/pattern/collectSearchFiles.js.map +1 -1
- package/dist/analysis/pattern/runPatternSearch.d.ts +1 -1
- package/dist/analysis/pattern/runPatternSearch.js +4 -2
- package/dist/analysis/pattern/runPatternSearch.js.map +1 -1
- package/dist/analysis/ts/extractUsages.js +19 -0
- package/dist/analysis/ts/extractUsages.js.map +1 -1
- package/dist/analysis/ts/parseSourceFile.d.ts +2 -1
- package/dist/analysis/ts/parseSourceFile.js +5 -9
- package/dist/analysis/ts/parseSourceFile.js.map +1 -1
- package/dist/analysis/ts/reactState.d.ts +9 -0
- package/dist/analysis/ts/reactState.js +57 -0
- package/dist/analysis/ts/reactState.js.map +1 -0
- package/dist/analysis/ts/structuralPredicates.js +31 -2
- package/dist/analysis/ts/structuralPredicates.js.map +1 -1
- package/dist/ast/parseFile.d.ts +4 -3
- package/dist/ast/parseFile.js +22 -5
- package/dist/ast/parseFile.js.map +1 -1
- package/dist/engine/LspEngine.js +23 -1
- package/dist/engine/LspEngine.js.map +1 -1
- package/dist/git/getBaseFileContent.d.ts +1 -0
- package/dist/git/getBaseFileContent.js +10 -3
- package/dist/git/getBaseFileContent.js.map +1 -1
- package/dist/git/getChangedFiles.d.ts +2 -1
- package/dist/git/getChangedFiles.js +11 -5
- package/dist/git/getChangedFiles.js.map +1 -1
- package/dist/git/getChangedHunks.d.ts +1 -0
- package/dist/git/getChangedHunks.js +15 -10
- package/dist/git/getChangedHunks.js.map +1 -1
- package/dist/git/getGitRoot.d.ts +15 -0
- package/dist/git/getGitRoot.js +33 -0
- package/dist/git/getGitRoot.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/resolve/searchScope.d.ts +8 -2
- package/dist/resolve/searchScope.js +26 -14
- package/dist/resolve/searchScope.js.map +1 -1
- package/dist/search/adapters/config.d.ts +5 -0
- package/dist/search/adapters/config.js +56 -0
- package/dist/search/adapters/config.js.map +1 -0
- package/dist/search/adapters/http.d.ts +6 -0
- package/dist/search/adapters/http.js +58 -0
- package/dist/search/adapters/http.js.map +1 -0
- package/dist/search/adapters/react.d.ts +12 -0
- package/dist/search/adapters/react.js +92 -0
- package/dist/search/adapters/react.js.map +1 -0
- package/dist/search/adapters/registry.d.ts +6 -0
- package/dist/search/adapters/registry.js +20 -0
- package/dist/search/adapters/registry.js.map +1 -0
- package/dist/search/adapters/types.d.ts +5 -0
- package/dist/search/adapters/types.js +2 -0
- package/dist/search/adapters/types.js.map +1 -0
- package/dist/search/debug/trace.d.ts +6 -0
- package/dist/search/debug/trace.js +25 -0
- package/dist/search/debug/trace.js.map +1 -0
- package/dist/search/expand/graphExpansion.d.ts +16 -0
- package/dist/search/expand/graphExpansion.js +168 -0
- package/dist/search/expand/graphExpansion.js.map +1 -0
- package/dist/search/fileKinds.d.ts +13 -0
- package/dist/search/fileKinds.js +74 -0
- package/dist/search/fileKinds.js.map +1 -0
- package/dist/search/index/configIndex.d.ts +6 -0
- package/dist/search/index/configIndex.js +196 -0
- package/dist/search/index/configIndex.js.map +1 -0
- package/dist/search/index/docIndex.d.ts +7 -0
- package/dist/search/index/docIndex.js +116 -0
- package/dist/search/index/docIndex.js.map +1 -0
- package/dist/search/index/workspaceIndex.d.ts +6 -0
- package/dist/search/index/workspaceIndex.js +50 -14
- package/dist/search/index/workspaceIndex.js.map +1 -1
- package/dist/search/query/compileEffectiveSearchSpec.d.ts +24 -0
- package/dist/search/query/compileEffectiveSearchSpec.js +67 -0
- package/dist/search/query/compileEffectiveSearchSpec.js.map +1 -0
- package/dist/search/query/parseQuery.d.ts +1 -0
- package/dist/search/query/parseQuery.js +40 -0
- package/dist/search/query/parseQuery.js.map +1 -1
- package/dist/search/query/phraseRules.d.ts +10 -0
- package/dist/search/query/phraseRules.js +58 -0
- package/dist/search/query/phraseRules.js.map +1 -0
- package/dist/search/query/planQuery.d.ts +4 -3
- package/dist/search/query/planQuery.js +39 -6
- package/dist/search/query/planQuery.js.map +1 -1
- package/dist/search/ranking/assessConfidence.js +6 -0
- package/dist/search/ranking/assessConfidence.js.map +1 -1
- package/dist/search/ranking/candidateIdentity.d.ts +21 -0
- package/dist/search/ranking/candidateIdentity.js +29 -0
- package/dist/search/ranking/candidateIdentity.js.map +1 -0
- package/dist/search/ranking/coalesceCandidates.d.ts +9 -0
- package/dist/search/ranking/coalesceCandidates.js +48 -0
- package/dist/search/ranking/coalesceCandidates.js.map +1 -0
- package/dist/search/ranking/fieldedTextRanker.d.ts +26 -0
- package/dist/search/ranking/fieldedTextRanker.js +79 -0
- package/dist/search/ranking/fieldedTextRanker.js.map +1 -0
- package/dist/search/ranking/mergeCandidates.d.ts +3 -0
- package/dist/search/ranking/mergeCandidates.js +39 -0
- package/dist/search/ranking/mergeCandidates.js.map +1 -1
- package/dist/search/ranking/rankCandidates.d.ts +1 -1
- package/dist/search/ranking/rankCandidates.js +51 -3
- package/dist/search/ranking/rankCandidates.js.map +1 -1
- package/dist/search/retrievers/behaviorRetriever.d.ts +3 -3
- package/dist/search/retrievers/behaviorRetriever.js +64 -69
- package/dist/search/retrievers/behaviorRetriever.js.map +1 -1
- package/dist/search/retrievers/configRetriever.d.ts +7 -0
- package/dist/search/retrievers/configRetriever.js +46 -0
- package/dist/search/retrievers/configRetriever.js.map +1 -0
- package/dist/search/retrievers/docRetriever.d.ts +7 -0
- package/dist/search/retrievers/docRetriever.js +46 -0
- package/dist/search/retrievers/docRetriever.js.map +1 -0
- package/dist/search/retrievers/identifierRetriever.d.ts +3 -3
- package/dist/search/retrievers/identifierRetriever.js +7 -6
- package/dist/search/retrievers/identifierRetriever.js.map +1 -1
- package/dist/search/retrievers/structuralRetriever.d.ts +4 -6
- package/dist/search/retrievers/structuralRetriever.js +47 -84
- package/dist/search/retrievers/structuralRetriever.js.map +1 -1
- package/dist/search/retrievers/textPatternRetriever.d.ts +7 -0
- package/dist/search/retrievers/textPatternRetriever.js +90 -0
- package/dist/search/retrievers/textPatternRetriever.js.map +1 -0
- package/dist/search/structural/locators/callLocator.d.ts +6 -0
- package/dist/search/structural/locators/callLocator.js +57 -0
- package/dist/search/structural/locators/callLocator.js.map +1 -0
- package/dist/search/structural/locators/declarationLocator.d.ts +6 -0
- package/dist/search/structural/locators/declarationLocator.js +57 -0
- package/dist/search/structural/locators/declarationLocator.js.map +1 -0
- package/dist/search/structural/locators/statementLocator.d.ts +6 -0
- package/dist/search/structural/locators/statementLocator.js +65 -0
- package/dist/search/structural/locators/statementLocator.js.map +1 -0
- package/dist/search/structural/locators/types.d.ts +12 -0
- package/dist/search/structural/locators/types.js +2 -0
- package/dist/search/structural/locators/types.js.map +1 -0
- package/dist/search/structural/selectLocators.d.ts +7 -0
- package/dist/search/structural/selectLocators.js +21 -0
- package/dist/search/structural/selectLocators.js.map +1 -0
- package/dist/search/types.d.ts +77 -7
- package/dist/search/types.js.map +1 -1
- package/dist/tools/composites/apiGuard.js +6 -28
- package/dist/tools/composites/apiGuard.js.map +1 -1
- package/dist/tools/composites/findCode.js +92 -15
- package/dist/tools/composites/findCode.js.map +1 -1
- package/dist/tools/composites/findPattern.js +1 -1
- package/dist/tools/composites/findPattern.js.map +1 -1
- package/dist/tools/live/clearIndex.d.ts +1 -0
- package/dist/tools/live/clearIndex.js +19 -0
- package/dist/tools/live/clearIndex.js.map +1 -0
- package/dist/tools/primitives/callHierarchy.js +1 -1
- package/dist/tools/primitives/callHierarchy.js.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# lsp-intelligence
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Local code intelligence for real engineering workflows.
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**Find** implementations, API usage, structural patterns, configs, and routes. **Explain** why something broke. **Guard** the API contract before merging.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
29 MCP tools across 5 layers. Supports **TypeScript and JavaScript** (TS, TSX, JS, JSX, MJS, CJS). Local-only — no paid API, no external calls.
|
|
8
8
|
|
|
9
9
|
## Why this exists
|
|
10
10
|
|
|
@@ -150,7 +150,7 @@ Combine LSP, AST, and Git substrates into high-level operations.
|
|
|
150
150
|
|------|-------------|
|
|
151
151
|
| `api_guard` | Detect public API contract changes — export diffs, structural classification, consumer impact, semver summary. |
|
|
152
152
|
| `root_cause_trace` | Trace the root cause of a TypeScript error — find the originating declaration change, not just the symptom. |
|
|
153
|
-
| `find_code` | Unified code search: behavior discovery, identifier/API usage
|
|
153
|
+
| `find_code` | Unified code search: behavior discovery, identifier/API usage, structural queries, config/route lookup, and implementation-root discovery. Routes automatically. |
|
|
154
154
|
| `find_pattern` | AST structural search — find code by pattern (e.g. `useEffect($$$)`, `try { $$$ } catch ($E) { $$$ }`). |
|
|
155
155
|
| `inspect_symbol` | Hover + definition + references in one call. Full context about any symbol. |
|
|
156
156
|
| `batch_query` | Look up multiple symbols at once. Saves round-trips when exploring. |
|
|
@@ -178,6 +178,18 @@ Post-edit verification.
|
|
|
178
178
|
| `find_unused_exports` | Find exported symbols with zero cross-package importers. |
|
|
179
179
|
| `auto_import` | Resolve the correct import path for a symbol name. |
|
|
180
180
|
|
|
181
|
+
## find_code query classes
|
|
182
|
+
|
|
183
|
+
`find_code` supports five query classes, routed automatically:
|
|
184
|
+
|
|
185
|
+
| Class | Example query | What happens |
|
|
186
|
+
|-------|--------------|-------------|
|
|
187
|
+
| **Identifier / API usage** | `useEffect`, `Promise.all` | Usage index → exact call/import sites with enclosing context |
|
|
188
|
+
| **Structural** | `useEffect that returns cleanup conditionally` | Identifier + structural predicates → AST evaluation on located nodes |
|
|
189
|
+
| **Behavior / entrypoint** | `where do we validate permissions` | Fielded BM25 over declarations + JSDoc/comments + family hints |
|
|
190
|
+
| **Config / route / flag** | `where is the feature flag configured` | Config index → JSON/YAML/package.json + env usage in code |
|
|
191
|
+
| **Implementation root** | `where is this actually implemented` | Graph expansion → wrapper detection → root promotion |
|
|
192
|
+
|
|
181
193
|
## Architecture
|
|
182
194
|
|
|
183
195
|
```
|
|
@@ -189,7 +201,7 @@ Post-edit verification.
|
|
|
189
201
|
│ gather_context, outline │
|
|
190
202
|
├─────────────────────────────────────────────────────────┤
|
|
191
203
|
│ Layer 2: Intelligence Tools [read-only] │
|
|
192
|
-
│
|
|
204
|
+
│ find_code, find_pattern, root_cause_trace, api_guard, │
|
|
193
205
|
│ impact_trace, semantic_diff, inspect_symbol, │
|
|
194
206
|
│ batch_query, find_test_files, explain_error │
|
|
195
207
|
├─────────────────────────────────────────────────────────┤
|
|
@@ -197,9 +209,13 @@ Post-edit verification.
|
|
|
197
209
|
│ find_references, hover, definition, call_hierarchy, │
|
|
198
210
|
│ rename, diagnostics, symbols, imports, exports │
|
|
199
211
|
├─────────────────────────────────────────────────────────┤
|
|
200
|
-
│ Layer 0:
|
|
201
|
-
│ TypeScript Server
|
|
202
|
-
│
|
|
212
|
+
│ Layer 0: Analysis Substrates [infrastructure] │
|
|
213
|
+
│ LSP Engine (TypeScript Server, symbol resolver) │
|
|
214
|
+
│ TypeScript AST (declarations, usages, predicates) │
|
|
215
|
+
│ Local text/regex search (recipe-compiled patterns) │
|
|
216
|
+
│ Config/doc indexes (JSON, YAML, env, JSDoc, comments) │
|
|
217
|
+
│ Graph expansion (wrapper detection, root promotion) │
|
|
218
|
+
│ Git integration (semantic diff, base comparison) │
|
|
203
219
|
└─────────────────────────────────────────────────────────┘
|
|
204
220
|
```
|
|
205
221
|
|
|
@@ -225,7 +241,7 @@ Requires **Node.js 20+**.
|
|
|
225
241
|
|
|
226
242
|
### Option 1: Claude Code plugin (recommended)
|
|
227
243
|
|
|
228
|
-
Installs the MCP server, hooks, and skills (`/impact`, `/context`, `/
|
|
244
|
+
Installs the MCP server, hooks, and skills (`/find`, `/why`, `/api-check`, `/verify`, `/check`, `/impact`, `/context`, `/diff`) as a single package.
|
|
229
245
|
|
|
230
246
|
```bash
|
|
231
247
|
claude plugin add perilevy/lsp-intelligence
|
|
@@ -244,7 +260,7 @@ Add to your `.mcp.json`:
|
|
|
244
260
|
"mcpServers": {
|
|
245
261
|
"lsp": {
|
|
246
262
|
"command": "npx",
|
|
247
|
-
"args": ["
|
|
263
|
+
"args": ["-y", "lsp-intelligence"],
|
|
248
264
|
"env": {
|
|
249
265
|
"LSP_WORKSPACE_ROOT": "${CLAUDE_PROJECT_DIR}"
|
|
250
266
|
}
|
|
@@ -285,18 +301,30 @@ Then in `.mcp.json`:
|
|
|
285
301
|
git clone https://github.com/perilevy/lsp-intelligence.git
|
|
286
302
|
cd lsp-intelligence
|
|
287
303
|
yarn install
|
|
288
|
-
yarn build #
|
|
304
|
+
yarn build # clean build (rm -rf dist && tsc)
|
|
289
305
|
yarn test # vitest
|
|
290
306
|
yarn typecheck # TypeScript strict mode — no emit
|
|
307
|
+
yarn bench # search quality benchmarks
|
|
291
308
|
```
|
|
292
309
|
|
|
293
310
|
### Testing
|
|
294
311
|
|
|
295
|
-
Tests verify cross-package reference resolution, symbol-name lookup, type alias tracing, impact trace traversal, context building, and output formatting — all against
|
|
312
|
+
Tests verify cross-package reference resolution, symbol-name lookup, type alias tracing, impact trace traversal, search quality, context building, and output formatting — all against self-contained fixture repos at `test-fixtures/`. No external dependencies needed.
|
|
313
|
+
|
|
314
|
+
### Benchmarks
|
|
315
|
+
|
|
316
|
+
`benchmarks/` contains reproducible quality cases for `find_code`, `root_cause_trace`, and `api_guard`. Every serious real-world failure should become a benchmark case.
|
|
317
|
+
|
|
318
|
+
## What this is not
|
|
319
|
+
|
|
320
|
+
- **Not a universal semantic search engine.** Strong on code structure, API usage, configs, and known patterns. Does not understand arbitrary business logic.
|
|
321
|
+
- **Not a replacement for full-text search.** Use grep for literal string matching. `find_code` uses text patterns internally but optimizes for code-aware ranking.
|
|
322
|
+
- **Not an AI model.** All intelligence is local: AST analysis, LSP queries, fielded text ranking, adapter recipes. No paid API calls, no external services.
|
|
323
|
+
- **Does not index secret-bearing `.env` files.** Env variable usage in code (`process.env.X`, `import.meta.env.X`) is indexed and searchable. Non-secret template/example files (`.env.example`, `.env.template`) are indexed. Real `.env` files are excluded by default.
|
|
296
324
|
|
|
297
325
|
## Dependencies
|
|
298
326
|
|
|
299
|
-
All dependencies are installed automatically. Under the hood: [`typescript-language-server`](https://github.com/typescript-language-server/typescript-language-server) for LSP, [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk) for MCP,
|
|
327
|
+
All dependencies are installed automatically. Under the hood: [`typescript-language-server`](https://github.com/typescript-language-server/typescript-language-server) for LSP, [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk) for MCP, [`@ast-grep/napi`](https://github.com/ast-grep/ast-grep) for structural patterns. Uses your project's own TypeScript version.
|
|
300
328
|
|
|
301
329
|
## License
|
|
302
330
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SearchScope } from '../../search/types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Collect files matching a
|
|
3
|
+
* Collect files matching a set of extensions within a search scope.
|
|
4
|
+
* Skips dot-prefixed dirs, build output, minified/bundled files, and oversized files.
|
|
4
5
|
*/
|
|
5
6
|
export declare function collectSearchFiles(scope: SearchScope, extensions: string[], maxFiles: number): string[];
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
-
import {
|
|
4
|
-
const TEST_PATTERN = /\.(spec|test|stories)\.(ts|tsx|js|jsx)$/;
|
|
3
|
+
import { isTestFile, shouldSkipDir, shouldSkipFile } from '../../search/fileKinds.js';
|
|
5
4
|
/**
|
|
6
|
-
* Collect files matching a
|
|
5
|
+
* Collect files matching a set of extensions within a search scope.
|
|
6
|
+
* Skips dot-prefixed dirs, build output, minified/bundled files, and oversized files.
|
|
7
7
|
*/
|
|
8
8
|
export function collectSearchFiles(scope, extensions, maxFiles) {
|
|
9
9
|
const files = [];
|
|
@@ -19,15 +19,15 @@ function walkDir(dir, files, extensions, includeTests, maxFiles, depth) {
|
|
|
19
19
|
return;
|
|
20
20
|
try {
|
|
21
21
|
for (const entry of fs.readdirSync(dir)) {
|
|
22
|
-
if (
|
|
22
|
+
if (shouldSkipDir(entry))
|
|
23
23
|
continue;
|
|
24
24
|
const full = path.join(dir, entry);
|
|
25
25
|
const stat = fs.statSync(full);
|
|
26
26
|
if (stat.isDirectory()) {
|
|
27
27
|
walkDir(full, files, extensions, includeTests, maxFiles, depth + 1);
|
|
28
28
|
}
|
|
29
|
-
else if (extensions.some((e) => entry.endsWith(e)) && !
|
|
30
|
-
if (!includeTests &&
|
|
29
|
+
else if (extensions.some((e) => entry.endsWith(e)) && !shouldSkipFile(full, stat.size)) {
|
|
30
|
+
if (!includeTests && isTestFile(full))
|
|
31
31
|
continue;
|
|
32
32
|
files.push(full);
|
|
33
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collectSearchFiles.js","sourceRoot":"","sources":["../../../src/analysis/pattern/collectSearchFiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"collectSearchFiles.js","sourceRoot":"","sources":["../../../src/analysis/pattern/collectSearchFiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEtF;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAkB,EAClB,UAAoB,EACpB,QAAgB;IAEhB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QAClE,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;YAAE,MAAM;IACtC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,OAAO,CACd,GAAW,EACX,KAAe,EACf,UAAoB,EACpB,YAAqB,EACrB,QAAgB,EAChB,KAAa;IAEb,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO;IAClD,IAAI,CAAC;QACH,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACxC,IAAI,aAAa,CAAC,KAAK,CAAC;gBAAE,SAAS;YACnC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACnC,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YACtE,CAAC;iBAAM,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzF,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC,IAAI,CAAC;oBAAE,SAAS;gBAChD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACZ,CAAC"}
|
|
@@ -5,7 +5,7 @@ import type { SearchScope, PatternMatch } from '../../search/types.js';
|
|
|
5
5
|
*/
|
|
6
6
|
export declare function runPatternSearch(input: {
|
|
7
7
|
pattern: string;
|
|
8
|
-
language: 'typescript' | 'tsx' | 'javascript';
|
|
8
|
+
language: 'typescript' | 'tsx' | 'javascript' | 'jsx';
|
|
9
9
|
scope: SearchScope;
|
|
10
10
|
maxResults: number;
|
|
11
11
|
contextLines: number;
|
|
@@ -6,11 +6,13 @@ const LANG_MAP = {
|
|
|
6
6
|
typescript: Lang.TypeScript,
|
|
7
7
|
tsx: Lang.Tsx,
|
|
8
8
|
javascript: Lang.JavaScript,
|
|
9
|
+
jsx: Lang.Tsx, // ast-grep uses Tsx parser for JSX
|
|
9
10
|
};
|
|
10
11
|
const EXT_MAP = {
|
|
11
|
-
typescript: ['.ts'],
|
|
12
|
+
typescript: ['.ts', '.mjs', '.cjs'],
|
|
12
13
|
tsx: ['.tsx', '.ts'],
|
|
13
|
-
javascript: ['.js'],
|
|
14
|
+
javascript: ['.js', '.mjs', '.cjs'],
|
|
15
|
+
jsx: ['.jsx', '.js'],
|
|
14
16
|
};
|
|
15
17
|
/**
|
|
16
18
|
* Run an ast-grep pattern search across files in scope.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runPatternSearch.js","sourceRoot":"","sources":["../../../src/analysis/pattern/runPatternSearch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,MAAM,QAAQ,GAAyB;IACrC,UAAU,EAAE,IAAI,CAAC,UAAU;IAC3B,GAAG,EAAE,IAAI,CAAC,GAAG;IACb,UAAU,EAAE,IAAI,CAAC,UAAU;
|
|
1
|
+
{"version":3,"file":"runPatternSearch.js","sourceRoot":"","sources":["../../../src/analysis/pattern/runPatternSearch.ts"],"names":[],"mappings":"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"}
|
|
@@ -83,6 +83,25 @@ export function extractUsages(sf) {
|
|
|
83
83
|
entries.push(makeUsage(tagName.text, tagName.text, 'jsx-tag', node, sf, filePath, pathToks, enclosingSymbol, enclosingKind));
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
+
// Env usage: process.env.X, import.meta.env.X
|
|
87
|
+
// Only match the exact env access (3 parts for process.env.X, 4 for import.meta.env.X)
|
|
88
|
+
// Skip if parent is also a PropertyAccessExpression (e.g. process.env.X.includes → skip, let process.env.X match)
|
|
89
|
+
if (ts.isPropertyAccessExpression(node) && !ts.isPropertyAccessExpression(node.parent)) {
|
|
90
|
+
const text = getPropertyAccessText(node);
|
|
91
|
+
const parts = text.split('.');
|
|
92
|
+
if (parts[0] === 'process' && parts[1] === 'env' && parts.length === 3) {
|
|
93
|
+
const envKey = parts[2];
|
|
94
|
+
const entry = makeUsage(`process.env.${envKey}`, envKey.toLowerCase(), 'env-usage', node, sf, filePath, pathToks, enclosingSymbol, enclosingKind);
|
|
95
|
+
entry.metadata = { envKey };
|
|
96
|
+
entries.push(entry);
|
|
97
|
+
}
|
|
98
|
+
else if (parts[0] === 'import' && parts[1] === 'meta' && parts[2] === 'env' && parts.length === 4) {
|
|
99
|
+
const envKey = parts[3];
|
|
100
|
+
const entry = makeUsage(`import.meta.env.${envKey}`, envKey.toLowerCase(), 'env-usage', node, sf, filePath, pathToks, enclosingSymbol, enclosingKind);
|
|
101
|
+
entry.metadata = { envKey };
|
|
102
|
+
entries.push(entry);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
86
105
|
ts.forEachChild(node, visit);
|
|
87
106
|
// Restore enclosing context on unwind
|
|
88
107
|
enclosingSymbol = prevSymbol;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractUsages.js","sourceRoot":"","sources":["../../../src/analysis/ts/extractUsages.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extractUsages.js","sourceRoot":"","sources":["../../../src/analysis/ts/extractUsages.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
/**
|
|
3
|
-
* Parse a TypeScript/
|
|
3
|
+
* Parse a TypeScript/JavaScript file into a ts.SourceFile using the TypeScript compiler API.
|
|
4
|
+
* Supports: .ts, .tsx, .js, .jsx, .mjs, .cjs
|
|
4
5
|
* Returns null if the file doesn't exist or can't be parsed.
|
|
5
6
|
*/
|
|
6
7
|
export declare function parseSourceFile(filePath: string): ts.SourceFile | null;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
import * as fs from 'fs';
|
|
3
|
+
import { scriptKindForFile } from '../../search/fileKinds.js';
|
|
3
4
|
/**
|
|
4
|
-
* Parse a TypeScript/
|
|
5
|
+
* Parse a TypeScript/JavaScript file into a ts.SourceFile using the TypeScript compiler API.
|
|
6
|
+
* Supports: .ts, .tsx, .js, .jsx, .mjs, .cjs
|
|
5
7
|
* Returns null if the file doesn't exist or can't be parsed.
|
|
6
8
|
*/
|
|
7
9
|
export function parseSourceFile(filePath) {
|
|
8
10
|
try {
|
|
9
11
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
10
|
-
|
|
11
|
-
: filePath.endsWith('.jsx') ? ts.ScriptKind.JSX
|
|
12
|
-
: ts.ScriptKind.TS;
|
|
13
|
-
return ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, scriptKind);
|
|
12
|
+
return ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, scriptKindForFile(filePath));
|
|
14
13
|
}
|
|
15
14
|
catch {
|
|
16
15
|
return null;
|
|
@@ -20,9 +19,6 @@ export function parseSourceFile(filePath) {
|
|
|
20
19
|
* Parse source content directly (for base-version comparison).
|
|
21
20
|
*/
|
|
22
21
|
export function parseSourceContent(content, fileName) {
|
|
23
|
-
|
|
24
|
-
: fileName.endsWith('.jsx') ? ts.ScriptKind.JSX
|
|
25
|
-
: ts.ScriptKind.TS;
|
|
26
|
-
return ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, true, scriptKind);
|
|
22
|
+
return ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, true, scriptKindForFile(fileName));
|
|
27
23
|
}
|
|
28
24
|
//# sourceMappingURL=parseSourceFile.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseSourceFile.js","sourceRoot":"","sources":["../../../src/analysis/ts/parseSourceFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"parseSourceFile.js","sourceRoot":"","sources":["../../../src/analysis/ts/parseSourceFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3G,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,QAAgB;IAClE,OAAO,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC3G,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Detect if a node contains a functional state updater pattern.
|
|
4
|
+
* Matches: setState(prev => ...), setCount(current => current + 1), etc.
|
|
5
|
+
*
|
|
6
|
+
* Only matches when the updater parameter is actually used in the body.
|
|
7
|
+
* Does NOT match: setState(() => 1) — that's a constant updater.
|
|
8
|
+
*/
|
|
9
|
+
export declare function hasFunctionalStateUpdater(node: ts.Node): boolean;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Detect if a node contains a functional state updater pattern.
|
|
4
|
+
* Matches: setState(prev => ...), setCount(current => current + 1), etc.
|
|
5
|
+
*
|
|
6
|
+
* Only matches when the updater parameter is actually used in the body.
|
|
7
|
+
* Does NOT match: setState(() => 1) — that's a constant updater.
|
|
8
|
+
*/
|
|
9
|
+
export function hasFunctionalStateUpdater(node) {
|
|
10
|
+
let found = false;
|
|
11
|
+
function walk(n) {
|
|
12
|
+
if (found)
|
|
13
|
+
return;
|
|
14
|
+
// Look for calls like setFoo(param => ...)
|
|
15
|
+
if (ts.isCallExpression(n) && ts.isIdentifier(n.expression)) {
|
|
16
|
+
const callee = n.expression.text;
|
|
17
|
+
// Must start with "set" and have PascalCase after (setState, setCount, setItems)
|
|
18
|
+
if (/^set[A-Z]/.test(callee) && n.arguments.length >= 1) {
|
|
19
|
+
const arg = n.arguments[0];
|
|
20
|
+
if (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) {
|
|
21
|
+
// Must have exactly one parameter
|
|
22
|
+
if (arg.parameters.length === 1) {
|
|
23
|
+
const paramName = arg.parameters[0].name;
|
|
24
|
+
if (ts.isIdentifier(paramName)) {
|
|
25
|
+
// Check if the parameter is actually used in the body
|
|
26
|
+
if (isIdentifierUsedInBody(paramName.text, arg.body)) {
|
|
27
|
+
found = true;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
ts.forEachChild(n, walk);
|
|
36
|
+
}
|
|
37
|
+
walk(node);
|
|
38
|
+
return found;
|
|
39
|
+
}
|
|
40
|
+
function isIdentifierUsedInBody(name, body) {
|
|
41
|
+
let used = false;
|
|
42
|
+
function walk(n) {
|
|
43
|
+
if (used)
|
|
44
|
+
return;
|
|
45
|
+
if (ts.isIdentifier(n) && n.text === name) {
|
|
46
|
+
// Make sure it's not the parameter declaration itself
|
|
47
|
+
if (!ts.isParameter(n.parent)) {
|
|
48
|
+
used = true;
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
ts.forEachChild(n, walk);
|
|
53
|
+
}
|
|
54
|
+
walk(body);
|
|
55
|
+
return used;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=reactState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactState.js","sourceRoot":"","sources":["../../../src/analysis/ts/reactState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B;;;;;;GAMG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAa;IACrD,IAAI,KAAK,GAAG,KAAK,CAAC;IAElB,SAAS,IAAI,CAAC,CAAU;QACtB,IAAI,KAAK;YAAE,OAAO;QAElB,2CAA2C;QAC3C,IAAI,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5D,MAAM,MAAM,GAAG,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;YACjC,iFAAiF;YACjF,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBACxD,MAAM,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC3B,IAAI,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC5D,kCAAkC;oBAClC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBAChC,MAAM,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;wBACzC,IAAI,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;4BAC/B,sDAAsD;4BACtD,IAAI,sBAAsB,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gCACrD,KAAK,GAAG,IAAI,CAAC;gCACb,OAAO;4BACT,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,CAAC;IACX,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAY,EAAE,IAAa;IACzD,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,SAAS,IAAI,CAAC,CAAU;QACtB,IAAI,IAAI;YAAE,OAAO;QACjB,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC1C,sDAAsD;YACtD,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC9B,IAAI,GAAG,IAAI,CAAC;gBACZ,OAAO;YACT,CAAC;QACH,CAAC;QACD,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,CAAC;IACX,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
+
import { hasFunctionalStateUpdater } from './reactState.js';
|
|
2
3
|
/**
|
|
3
4
|
* Evaluate structural predicates on a TS AST node.
|
|
4
5
|
* Returns which predicates matched and evidence strings.
|
|
@@ -37,6 +38,8 @@ function evaluatePredicate(sf, node, pred) {
|
|
|
37
38
|
return isInsideHookCall(node) ? 'inside a React hook call' : null;
|
|
38
39
|
case 'hook-callback':
|
|
39
40
|
return isHookCallback(node) ? 'is a callback argument to a hook' : null;
|
|
41
|
+
case 'functional-state-updater':
|
|
42
|
+
return hasFunctionalStateUpdater(node) ? 'contains functional state updater (e.g. setState(prev => ...))' : null;
|
|
40
43
|
default:
|
|
41
44
|
return null;
|
|
42
45
|
}
|
|
@@ -83,6 +86,8 @@ function isCallbackLike(node) {
|
|
|
83
86
|
return getFirstCallbackArg(node) !== null;
|
|
84
87
|
}
|
|
85
88
|
function containsTryCatch(node) {
|
|
89
|
+
if (ts.isTryStatement(node))
|
|
90
|
+
return true;
|
|
86
91
|
let found = false;
|
|
87
92
|
function walk(n) {
|
|
88
93
|
if (found)
|
|
@@ -97,6 +102,10 @@ function containsTryCatch(node) {
|
|
|
97
102
|
return found;
|
|
98
103
|
}
|
|
99
104
|
function hasSwitchWithoutDefault(node) {
|
|
105
|
+
// Check node itself first (statementLocator passes the SwitchStatement directly)
|
|
106
|
+
if (ts.isSwitchStatement(node)) {
|
|
107
|
+
return !node.caseBlock.clauses.some((c) => ts.isDefaultClause(c));
|
|
108
|
+
}
|
|
100
109
|
let found = false;
|
|
101
110
|
function walk(n) {
|
|
102
111
|
if (found)
|
|
@@ -114,19 +123,39 @@ function hasSwitchWithoutDefault(node) {
|
|
|
114
123
|
return found;
|
|
115
124
|
}
|
|
116
125
|
function hasAwaitInLoop(node) {
|
|
126
|
+
const isLoop = (n) => ts.isForStatement(n) || ts.isForOfStatement(n) || ts.isForInStatement(n) || ts.isWhileStatement(n) || ts.isDoStatement(n);
|
|
127
|
+
// If node itself is a loop, check its body for await
|
|
128
|
+
if (isLoop(node)) {
|
|
129
|
+
let found = false;
|
|
130
|
+
function walkBody(n) {
|
|
131
|
+
if (found)
|
|
132
|
+
return;
|
|
133
|
+
if (ts.isAwaitExpression(n)) {
|
|
134
|
+
found = true;
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (ts.isFunctionDeclaration(n) || ts.isArrowFunction(n) || ts.isFunctionExpression(n))
|
|
138
|
+
return;
|
|
139
|
+
ts.forEachChild(n, walkBody);
|
|
140
|
+
}
|
|
141
|
+
ts.forEachChild(node, walkBody);
|
|
142
|
+
return found;
|
|
143
|
+
}
|
|
144
|
+
// Otherwise search descendants for loop-with-await
|
|
117
145
|
let insideLoop = false;
|
|
118
146
|
let found = false;
|
|
119
147
|
function walk(n) {
|
|
120
148
|
if (found)
|
|
121
149
|
return;
|
|
122
150
|
const wasInsideLoop = insideLoop;
|
|
123
|
-
if (
|
|
151
|
+
if (isLoop(n))
|
|
124
152
|
insideLoop = true;
|
|
125
|
-
}
|
|
126
153
|
if (insideLoop && ts.isAwaitExpression(n)) {
|
|
127
154
|
found = true;
|
|
128
155
|
return;
|
|
129
156
|
}
|
|
157
|
+
if (ts.isFunctionDeclaration(n) || ts.isArrowFunction(n) || ts.isFunctionExpression(n))
|
|
158
|
+
return;
|
|
130
159
|
ts.forEachChild(n, walk);
|
|
131
160
|
insideLoop = wasInsideLoop;
|
|
132
161
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structuralPredicates.js","sourceRoot":"","sources":["../../../src/analysis/ts/structuralPredicates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"structuralPredicates.js","sourceRoot":"","sources":["../../../src/analysis/ts/structuralPredicates.ts"],"names":[],"mappings":"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"}
|
package/dist/ast/parseFile.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { type SgNode } from '@ast-grep/napi';
|
|
2
2
|
/**
|
|
3
|
-
* Parse a
|
|
4
|
-
*
|
|
3
|
+
* Parse a source file into an ast-grep root node.
|
|
4
|
+
* Supports TS, TSX, JS, JSX, MJS, CJS.
|
|
5
5
|
*/
|
|
6
6
|
export declare function parseFile(filePath: string): SgNode | null;
|
|
7
7
|
/**
|
|
8
8
|
* Parse source content directly.
|
|
9
|
+
* Pass the file path or extension to determine the correct language.
|
|
9
10
|
*/
|
|
10
|
-
export declare function parseSource(content: string,
|
|
11
|
+
export declare function parseSource(content: string, filePathOrTsx?: string | boolean): SgNode | null;
|
package/dist/ast/parseFile.js
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import { parse, Lang } from '@ast-grep/napi';
|
|
3
|
+
const LANG_MAP = {
|
|
4
|
+
'.ts': Lang.TypeScript,
|
|
5
|
+
'.tsx': Lang.Tsx,
|
|
6
|
+
'.js': Lang.JavaScript,
|
|
7
|
+
'.jsx': Lang.Tsx, // ast-grep uses Tsx for JSX
|
|
8
|
+
'.mjs': Lang.JavaScript,
|
|
9
|
+
'.cjs': Lang.JavaScript,
|
|
10
|
+
};
|
|
3
11
|
/**
|
|
4
|
-
* Parse a
|
|
5
|
-
*
|
|
12
|
+
* Parse a source file into an ast-grep root node.
|
|
13
|
+
* Supports TS, TSX, JS, JSX, MJS, CJS.
|
|
6
14
|
*/
|
|
7
15
|
export function parseFile(filePath) {
|
|
8
16
|
try {
|
|
9
17
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
10
|
-
const
|
|
18
|
+
const ext = filePath.match(/\.[^.]+$/)?.[0] ?? '.ts';
|
|
19
|
+
const lang = LANG_MAP[ext] ?? Lang.TypeScript;
|
|
11
20
|
return parse(lang, content).root();
|
|
12
21
|
}
|
|
13
22
|
catch {
|
|
@@ -16,10 +25,18 @@ export function parseFile(filePath) {
|
|
|
16
25
|
}
|
|
17
26
|
/**
|
|
18
27
|
* Parse source content directly.
|
|
28
|
+
* Pass the file path or extension to determine the correct language.
|
|
19
29
|
*/
|
|
20
|
-
export function parseSource(content,
|
|
30
|
+
export function parseSource(content, filePathOrTsx = false) {
|
|
21
31
|
try {
|
|
22
|
-
|
|
32
|
+
let lang;
|
|
33
|
+
if (typeof filePathOrTsx === 'string') {
|
|
34
|
+
const ext = filePathOrTsx.match(/\.[^.]+$/)?.[0] ?? '.ts';
|
|
35
|
+
lang = LANG_MAP[ext] ?? Lang.TypeScript;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
lang = filePathOrTsx ? Lang.Tsx : Lang.TypeScript;
|
|
39
|
+
}
|
|
23
40
|
return parse(lang, content).root();
|
|
24
41
|
}
|
|
25
42
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseFile.js","sourceRoot":"","sources":["../../src/ast/parseFile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAe,MAAM,gBAAgB,CAAC;AAE1D;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,
|
|
1
|
+
{"version":3,"file":"parseFile.js","sourceRoot":"","sources":["../../src/ast/parseFile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAe,MAAM,gBAAgB,CAAC;AAE1D,MAAM,QAAQ,GAAyB;IACrC,KAAK,EAAE,IAAI,CAAC,UAAU;IACtB,MAAM,EAAE,IAAI,CAAC,GAAG;IAChB,KAAK,EAAE,IAAI,CAAC,UAAU;IACtB,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,4BAA4B;IAC9C,MAAM,EAAE,IAAI,CAAC,UAAU;IACvB,MAAM,EAAE,IAAI,CAAC,UAAU;CACxB,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;QACrD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC;QAC9C,OAAO,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,gBAAkC,KAAK;IAClF,IAAI,CAAC;QACH,IAAI,IAAU,CAAC;QACf,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;YAC1D,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QACpD,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/dist/engine/LspEngine.js
CHANGED
|
@@ -331,9 +331,31 @@ export class LspEngine {
|
|
|
331
331
|
this.connection.sendNotification('exit');
|
|
332
332
|
}
|
|
333
333
|
catch { }
|
|
334
|
+
}
|
|
335
|
+
// Wait for the process to exit gracefully after receiving 'exit' notification.
|
|
336
|
+
// If it doesn't exit within 3s, force-kill.
|
|
337
|
+
if (this.process) {
|
|
338
|
+
await new Promise((resolve) => {
|
|
339
|
+
const timeout = setTimeout(() => {
|
|
340
|
+
this.process?.kill();
|
|
341
|
+
resolve();
|
|
342
|
+
}, 3000);
|
|
343
|
+
this.process.on('exit', () => {
|
|
344
|
+
clearTimeout(timeout);
|
|
345
|
+
resolve();
|
|
346
|
+
});
|
|
347
|
+
// If process already exited, resolve immediately
|
|
348
|
+
if (this.process.exitCode !== null) {
|
|
349
|
+
clearTimeout(timeout);
|
|
350
|
+
resolve();
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
// Dispose connection after process is gone — no more writes possible
|
|
355
|
+
if (this.connection) {
|
|
334
356
|
this.connection.dispose();
|
|
357
|
+
this.connection = null;
|
|
335
358
|
}
|
|
336
|
-
this.process?.kill();
|
|
337
359
|
}
|
|
338
360
|
}
|
|
339
361
|
//# sourceMappingURL=LspEngine.js.map
|