import { getNodeText, getChildByField } from '../tree-sitter-helpers'; import type { LanguageExtractor } from '../tree-sitter-types'; export const javascriptExtractor: LanguageExtractor = { functionTypes: ['function_declaration', 'arrow_function', 'function_expression'], classTypes: ['class_declaration'], methodTypes: ['method_definition', 'field_definition'], interfaceTypes: [], structTypes: [], enumTypes: [], typeAliasTypes: [], importTypes: ['import_statement'], callTypes: ['call_expression'], variableTypes: ['lexical_declaration', 'variable_declaration'], nameField: 'name', bodyField: 'body', paramsField: 'parameters', getSignature: (node, source) => { const params = getChildByField(node, 'parameters'); return params ? getNodeText(params, source) : undefined; }, isExported: (node, _source) => { let current = node.parent; while (current) { if (current.type === 'export_statement') return true; current = current.parent; } return false; }, isAsync: (node) => { for (let i = 0; i < node.childCount; i++) { const child = node.child(i); if (child?.type === 'async') return true; } return false; }, isConst: (node) => { if (node.type === 'lexical_declaration') { for (let i = 0; i < node.childCount; i++) { const child = node.child(i); if (child?.type === 'const') return true; } } return false; }, extractImport: (node, source) => { const sourceField = node.childForFieldName('source'); if (sourceField) { const moduleName = source.substring(sourceField.startIndex, sourceField.endIndex).replace(/['"]/g, ''); if (moduleName) { return { moduleName, signature: source.substring(node.startIndex, node.endIndex).trim() }; } } return null; }, };