* Parse and extract from the source code
()
| 452 | * Parse and extract from the source code |
| 453 | */ |
| 454 | extract(): ExtractionResult { |
| 455 | const startTime = Date.now(); |
| 456 | |
| 457 | if (!isLanguageSupported(this.language)) { |
| 458 | return { |
| 459 | nodes: [], |
| 460 | edges: [], |
| 461 | unresolvedReferences: [], |
| 462 | errors: [ |
| 463 | { |
| 464 | message: `Unsupported language: ${this.language}`, |
| 465 | filePath: this.filePath, |
| 466 | severity: 'error', |
| 467 | code: 'unsupported_language', |
| 468 | }, |
| 469 | ], |
| 470 | durationMs: Date.now() - startTime, |
| 471 | }; |
| 472 | } |
| 473 | |
| 474 | const parser = getParser(this.language); |
| 475 | if (!parser) { |
| 476 | return { |
| 477 | nodes: [], |
| 478 | edges: [], |
| 479 | unresolvedReferences: [], |
| 480 | errors: [ |
| 481 | { |
| 482 | message: `Failed to get parser for language: ${this.language}`, |
| 483 | filePath: this.filePath, |
| 484 | severity: 'error', |
| 485 | code: 'parser_error', |
| 486 | }, |
| 487 | ], |
| 488 | durationMs: Date.now() - startTime, |
| 489 | }; |
| 490 | } |
| 491 | |
| 492 | try { |
| 493 | // Optional pre-parse source transform (offset-preserving) to work around |
| 494 | // grammar gaps — e.g. C# blanks conditional-compilation directive lines |
| 495 | // the grammar mis-parses inside enum bodies (#237). We reassign |
| 496 | // this.source so downstream getNodeText reads the same bytes the parser |
| 497 | // saw (identical outside the blanked directive lines). Skipped when the |
| 498 | // kernel route point already applied it (sourceIsPreParsed). |
| 499 | if (this.extractor?.preParse && !this.sourceIsPreParsed) { |
| 500 | this.source = this.extractor.preParse(this.source, this.filePath); |
| 501 | } |
| 502 | this.tree = parser.parse(this.source) ?? null; |
| 503 | if (!this.tree) { |
| 504 | throw new Error('Parser returned null tree'); |
| 505 | } |
| 506 | |
| 507 | // Create file node representing the source file |
| 508 | const fileNode: Node = { |
| 509 | id: `file:${this.filePath}`, |
| 510 | kind: 'file', |
| 511 | name: path.basename(this.filePath), |
no test coverage detected