* feat(extraction): add Terraform and OpenTofu language support Index .tf, .tfvars, and .tofu files via the tree-sitter-terraform dialect of HCL (vendored from @tree-sitter-grammars/tree-sitter-hcl, Apache-2.0). Symbols extracted: - resource / data → class (qualified "type.name" / "data.type.name") - module → module (qualified "module.name") - variable → variable (qualified "var.name") - output → variable (qualified "output.name") - provider → namespace - locals → constant per attribute (qualified "local.key") References resolved cross-file: - var.X, local.X, module.M[.out], data.T.N[.attr], <type>.<name>[.attr] - built-ins skipped: each.*, count.*, self.*, path.*, terraform.workspace The Terraform framework resolver disambiguates same-named candidates across modules by preferring the one in the same directory as the reference site, then by closest common-ancestor path, falling back to the generic name matcher only when neither applies. Validated on two Terraform monorepos (277 and 470 .tf files): indexing runs in 1.3s and 2.4s respectively, query latency stays under 200ms, and cross-module references resolve to the correct module 100% of the time on inspected samples. 18 new extraction tests; full suite 1146/1148 green (2 pre-existing flaky skips, 0 regressions). * feat(terraform): bridge the module boundary and enforce directory scoping Builds on #706. The module declaration was a dead end: module.M.out resolved to the declaration and stopped, module inputs never reached the child module's variables, and impact could not cross the boundary — on real multi-module repos that breaks the core blast-radius question ("what breaks upstream if I change this module's variable/output"). - module blocks now wire across the boundary through :-scoped refs only the Terraform resolver understands: module.M:var.<input> → the child's variable node, module.M:output.<o> → the child's output node (emitted alongside the module.M declaration ref), and module.M:file → the local source directory's entry file (imports). Registry/git sources emit no file ref and resolve nothing — an out-of-repo module stays a visible boundary instead of a guess. - .tfvars top-level assignments reference the variable they set, walking up to the nearest ancestor directory (envs/prod.tfvars → root vars). - Resolution now enforces Terraform's real scoping: same-directory only (no cross-module fallback by common path prefix, no single-candidate anywhere-in-tree binding), and terraform refs never fall through to the generic name matcher — var.X can never legally bind outside its module directory, so the fallback could only add wrong edges. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(terraform): README language table + changelog entry + agent-eval corpus Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Javier Rodríguez Fernández <jfernandez@freepik.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
69 lines
2.2 KiB
TypeScript
69 lines
2.2 KiB
TypeScript
/**
|
|
* Per-language extraction configurations.
|
|
*
|
|
* Each file exports a LanguageExtractor config object.
|
|
* This barrel builds the EXTRACTORS map consumed by TreeSitterExtractor.
|
|
*/
|
|
|
|
import { Language } from '../../types';
|
|
import type { LanguageExtractor } from '../tree-sitter-types';
|
|
|
|
import { typescriptExtractor } from './typescript';
|
|
import { javascriptExtractor } from './javascript';
|
|
import { pythonExtractor } from './python';
|
|
import { goExtractor } from './go';
|
|
import { rustExtractor } from './rust';
|
|
import { javaExtractor } from './java';
|
|
import { cExtractor, cppExtractor } from './c-cpp';
|
|
import { csharpExtractor } from './csharp';
|
|
import { phpExtractor } from './php';
|
|
import { rubyExtractor } from './ruby';
|
|
import { swiftExtractor } from './swift';
|
|
import { kotlinExtractor } from './kotlin';
|
|
import { dartExtractor } from './dart';
|
|
import { pascalExtractor } from './pascal';
|
|
import { scalaExtractor } from './scala';
|
|
import { luaExtractor } from './lua';
|
|
import { rExtractor } from './r';
|
|
import { luauExtractor } from './luau';
|
|
import { objcExtractor } from './objc';
|
|
import { cfscriptExtractor } from './cfscript';
|
|
import { cfqueryExtractor } from './cfquery';
|
|
import { cobolExtractor } from './cobol';
|
|
import { vbnetExtractor } from './vbnet';
|
|
import { erlangExtractor } from './erlang';
|
|
import { solidityExtractor } from './solidity';
|
|
import { terraformExtractor } from './terraform';
|
|
|
|
export const EXTRACTORS: Partial<Record<Language, LanguageExtractor>> = {
|
|
typescript: typescriptExtractor,
|
|
tsx: typescriptExtractor,
|
|
javascript: javascriptExtractor,
|
|
jsx: javascriptExtractor,
|
|
python: pythonExtractor,
|
|
go: goExtractor,
|
|
rust: rustExtractor,
|
|
java: javaExtractor,
|
|
c: cExtractor,
|
|
cpp: cppExtractor,
|
|
csharp: csharpExtractor,
|
|
php: phpExtractor,
|
|
ruby: rubyExtractor,
|
|
swift: swiftExtractor,
|
|
kotlin: kotlinExtractor,
|
|
dart: dartExtractor,
|
|
pascal: pascalExtractor,
|
|
scala: scalaExtractor,
|
|
lua: luaExtractor,
|
|
r: rExtractor,
|
|
luau: luauExtractor,
|
|
objc: objcExtractor,
|
|
cfscript: cfscriptExtractor,
|
|
cfquery: cfqueryExtractor,
|
|
cobol: cobolExtractor,
|
|
vbnet: vbnetExtractor,
|
|
erlang: erlangExtractor,
|
|
solidity: solidityExtractor,
|
|
terraform: terraformExtractor,
|
|
};
|