( fileContent: string, filePath: string, config: RepomixConfigMerged, )
| 41 | // whole pack. The success path is fully wrapped so a partially-built result is |
| 42 | // never returned on error. |
| 43 | export const parseFile = async ( |
| 44 | fileContent: string, |
| 45 | filePath: string, |
| 46 | config: RepomixConfigMerged, |
| 47 | ): Promise<string | undefined> => { |
| 48 | // Split the file content into individual lines |
| 49 | const lines = fileContent.split('\n'); |
| 50 | |
| 51 | try { |
| 52 | const languageParser = await getLanguageParserSingleton(); |
| 53 | |
| 54 | const lang: SupportedLang | undefined = languageParser.guessTheLang(filePath); |
| 55 | if (lang === undefined) { |
| 56 | // Language not supported: fall back to uncompressed content quietly. |
| 57 | return undefined; |
| 58 | } |
| 59 | |
| 60 | const query = await languageParser.getQueryForLang(lang); |
| 61 | const parser = await languageParser.getParserForLang(lang); |
| 62 | const processedChunks = new Set<string>(); |
| 63 | const capturedChunks: CapturedChunk[] = []; |
| 64 | |
| 65 | // Parse the file content into an Abstract Syntax Tree (AST) |
| 66 | const tree = parser.parse(fileContent); |
| 67 | if (!tree) { |
| 68 | logger.debug(`Failed to parse file: ${filePath}`); |
| 69 | return undefined; |
| 70 | } |
| 71 | |
| 72 | // Get the appropriate parse strategy for the language |
| 73 | const parseStrategy = await languageParser.getStrategyForLang(lang); |
| 74 | |
| 75 | // Create parse context |
| 76 | const context: ParseContext = { |
| 77 | fileContent, |
| 78 | lines, |
| 79 | tree, |
| 80 | query, |
| 81 | config, |
| 82 | }; |
| 83 | |
| 84 | // Apply the query to the AST and get the captures |
| 85 | const captures = query.captures(tree.rootNode); |
| 86 | |
| 87 | // Sort captures by their start position |
| 88 | captures.sort((a, b) => a.node.startPosition.row - b.node.startPosition.row); |
| 89 | |
| 90 | for (const capture of captures) { |
| 91 | const capturedChunkContent = parseStrategy.parseCapture(capture, lines, processedChunks, context); |
| 92 | if (capturedChunkContent !== null) { |
| 93 | capturedChunks.push({ |
| 94 | content: capturedChunkContent.trim(), |
| 95 | startRow: capture.node.startPosition.row, |
| 96 | endRow: capture.node.endPosition.row, |
| 97 | }); |
| 98 | } |
| 99 | } |
| 100 |
no test coverage detected