(filePath: string, source?: string, overrides?: Record<string, Language>)
| 475 | * `EXTENSION_MAP`. Omitting it is byte-identical to the zero-config behavior. |
| 476 | */ |
| 477 | export function detectLanguage(filePath: string, source?: string, overrides?: Record<string, Language>): Language { |
| 478 | // Play `conf/routes` has no grammar — route through the no-symbol path; the |
| 479 | // Play framework resolver extracts route nodes from it. |
| 480 | if (isPlayRoutesFile(filePath)) return 'yaml'; |
| 481 | const ext = filePath.substring(filePath.lastIndexOf('.')).toLowerCase(); |
| 482 | // Shopify OS 2.0 JSON templates / section groups → the Liquid extractor (it |
| 483 | // links each section `"type"` to its `sections/<type>.liquid`). |
| 484 | if (isShopifyLiquidJson(filePath)) return 'liquid'; |
| 485 | // OTP `.app`/`.app.src` resource files — Erlang terms the grammar parses as |
| 486 | // top-level expressions (last-dot ext `.src` is too generic for the map). |
| 487 | if (isErlangAppFile(filePath)) return 'erlang'; |
| 488 | const lang = (overrides && overrides[ext]) || EXTENSION_MAP[ext] || 'unknown'; |
| 489 | |
| 490 | // .h files could be C, C++, or Objective-C — check source content |
| 491 | if (lang === 'c' && ext === '.h' && source) { |
| 492 | if (looksLikeCpp(source)) return 'cpp'; |
| 493 | if (looksLikeObjc(source)) return 'objc'; |
| 494 | } |
| 495 | |
| 496 | return lang; |
| 497 | } |
| 498 | |
| 499 | /** |
| 500 | * Heuristic: does a .h file contain C++ constructs? |
no test coverage detected