Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions gitnexus/src/core/ingestion/export-detection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,6 @@ const CSHARP_DECL_TYPES = new Set([
'struct_declaration',
'enum_declaration',
'record_declaration',
// tree-sitter-c-sharp absorbs 'record struct' and 'record class' into
// record_declaration — these two node types are listed defensively but
// never emitted by the grammar in practice (verified against ^0.23.1).
'record_struct_declaration',
'record_class_declaration',
'delegate_declaration',
'property_declaration',
'field_declaration',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,7 @@ export const dartConfig: FieldExtractionConfig = {
// declaration > type_identifier (first named child usually)
for (let i = 0; i < node.namedChildCount; i++) {
const child = node.namedChild(i);
if (
child &&
(child.type === 'type_identifier' ||
child.type === 'generic_type' ||
child.type === 'function_type')
) {
if (child && (child.type === 'type_identifier' || child.type === 'function_type')) {
return extractSimpleTypeName(child) ?? child.text?.trim();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ export const phpConfig: FieldExtractionConfig = {
child.type === 'named_type' ||
child.type === 'optional_type' ||
child.type === 'primitive_type' ||
child.type === 'intersection_type' ||
child.type === 'nullable_type'
child.type === 'intersection_type'
) {
return extractSimpleTypeName(child) ?? child.text?.trim();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const SWIFT_VIS = new Set<FieldVisibility>([
*/
export const swiftConfig: FieldExtractionConfig = {
language: SupportedLanguages.Swift,
typeDeclarationNodes: ['class_declaration', 'struct_declaration', 'protocol_declaration'],
typeDeclarationNodes: ['class_declaration', 'protocol_declaration'],
fieldNodeTypes: ['property_declaration'],
bodyNodeTypes: ['class_body', 'protocol_body'],
defaultVisibility: 'internal',
Expand Down
32 changes: 0 additions & 32 deletions gitnexus/src/core/ingestion/field-extractors/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,6 @@ export class TypeScriptFieldExtractor extends BaseFieldExtractor {
}
}

// Check for modifier node (tree-sitter typescript may group these)
const modifiers = node.childForFieldName('modifiers');
if (modifiers) {
for (let i = 0; i < modifiers.childCount; i++) {
const modifier = modifiers.child(i);
const modText = modifier?.text.trim() as FieldVisibility | undefined;
if (modText && TypeScriptFieldExtractor.VISIBILITY_MODIFIERS.has(modText)) {
return modText;
}
}
}

// TypeScript class members are public by default
return 'public';
}
Expand All @@ -113,16 +101,6 @@ export class TypeScriptFieldExtractor extends BaseFieldExtractor {
}
}

const modifiers = node.childForFieldName('modifiers');
if (modifiers) {
for (let i = 0; i < modifiers.childCount; i++) {
const modifier = modifiers.child(i);
if (modifier && modifier.text === 'static') {
return true;
}
}
}

return false;
}

Expand All @@ -137,16 +115,6 @@ export class TypeScriptFieldExtractor extends BaseFieldExtractor {
}
}

const modifiers = node.childForFieldName('modifiers');
if (modifiers) {
for (let i = 0; i < modifiers.childCount; i++) {
const modifier = modifiers.child(i);
if (modifier && modifier.text === 'readonly') {
return true;
}
}
}

return false;
}

Expand Down
12 changes: 2 additions & 10 deletions gitnexus/src/core/ingestion/languages/cpp/arity-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export function computeCppDeclarationArity(node: SyntaxNode): CppArityInfo {
if (
child.type === 'parameter_declaration' ||
child.type === 'optional_parameter_declaration' ||
child.type === 'variadic_parameter' ||
child.type === 'variadic_parameter_declaration'
) {
params.push(child);
Expand All @@ -60,11 +59,7 @@ export function computeCppDeclarationArity(node: SyntaxNode): CppArityInfo {
// token in tree-sitter-cpp, detected via `hasEllipsis` above.
// C++ parameter packs: `template<typename... Ts> void foo(Ts... args)` —
// detected as `variadic_parameter_declaration`.
const isVariadic =
hasEllipsis ||
params.some(
(p) => p.type === 'variadic_parameter' || p.type === 'variadic_parameter_declaration',
);
const isVariadic = hasEllipsis || params.some((p) => p.type === 'variadic_parameter_declaration');
const optionalCount = params.filter((p) => p.type === 'optional_parameter_declaration').length;
const requiredCount = params.filter(
(p) =>
Expand All @@ -77,10 +72,7 @@ export function computeCppDeclarationArity(node: SyntaxNode): CppArityInfo {
const types: string[] = [];
const typeClasses: ParameterTypeClass[] = [];
for (const p of params) {
if (p.type === 'variadic_parameter') {
types.push('...');
typeClasses.push(unknownTypeClass('...'));
} else if (p.type === 'variadic_parameter_declaration') {
if (p.type === 'variadic_parameter_declaration') {
// Parameter pack: treated as variadic
types.push('...');
typeClasses.push(unknownTypeClass('...'));
Expand Down
2 changes: 1 addition & 1 deletion gitnexus/src/core/ingestion/languages/cpp/captures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1360,7 +1360,7 @@ function lookupAdlIdentifierType(identNode: SyntaxNode): CppAdlArgInfo | null {
inner = next;
continue;
}
if (inner.type === 'reference_declarator' || inner.type === 'rvalue_reference_declarator') {
if (inner.type === 'reference_declarator') {
// reference_declarator has a single child (the inner declarator).
let next: SyntaxNode | null = null;
for (let j = 0; j < inner.namedChildCount; j++) {
Expand Down
4 changes: 3 additions & 1 deletion gitnexus/src/core/ingestion/languages/csharp/captures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,9 @@ function terminalTypeNameNode(node: SyntaxNode): SyntaxNode | null {
case 'qualified_name':
return node.lastNamedChild;
case 'generic_name':
return node.childForFieldName('name') ?? node.firstNamedChild;
// generic_name has no `name` field (verified by real parse, #1920); the
// base identifier is the first named child.
return node.firstNamedChild;
default:
return null;
}
Expand Down
7 changes: 6 additions & 1 deletion gitnexus/src/core/ingestion/languages/java/captures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,15 @@ export function emitJavaScopeCaptures(
findNodeAtRange(tree.rootNode, anchor.range, 'object_creation_expression');
if (callNode !== null) {
const argList = callNode.childForFieldName('arguments');
// Exclude interleaved comments — tree-sitter-java emits `block_comment` /
// `line_comment` as named children of argument_list, which would inflate
// arity (and arity feeds call-processor symbol-ID generation). #1920
const args =
argList === null
? []
: argList.namedChildren.filter((c) => c !== null && c.type !== 'comment');
: argList.namedChildren.filter(
(c) => c !== null && c.type !== 'block_comment' && c.type !== 'line_comment',
);
grouped['@reference.arity'] = syntheticCapture(
'@reference.arity',
callNode,
Expand Down
35 changes: 2 additions & 33 deletions gitnexus/src/core/ingestion/languages/php/import-decomposer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,23 +116,7 @@ function parseUseClause(clause: SyntaxNode, qualifier: PhpImportKind): PhpImport
const source = qualName.text.trim();
if (source === '') return null;

// Strategy 1: explicit alias_clause wrapper (older grammar versions).
const aliasClause = findNamedChild(clause, 'alias_clause');
if (aliasClause !== null) {
// alias_clause: "as" name
const aliasName = findNamedChild(aliasClause, 'name') ?? aliasClause.firstNamedChild;
const alias = aliasName?.text.trim() ?? '';
if (alias === '') return null;
return {
kind: 'alias',
source,
name: alias,
alias,
atNode: clause,
};
}

// Strategy 2: bare sibling `name` node after the qualified_name.
// Strategy: bare sibling `name` node after the qualified_name.
// tree-sitter-php (≥ 0.22) emits `use Foo\Bar as Baz` as:
// namespace_use_clause
// qualified_name "Foo\Bar"
Expand Down Expand Up @@ -231,22 +215,7 @@ function parseInnerClause(

const source = prefix !== '' ? `${prefix}\\${innerPath}` : innerPath;

// Strategy 1: explicit alias_clause wrapper (older grammar versions).
const aliasClause = findNamedChild(clause, 'alias_clause');
if (aliasClause !== null) {
const aliasName = findNamedChild(aliasClause, 'name') ?? aliasClause.firstNamedChild;
const alias = aliasName?.text.trim() ?? '';
if (alias === '') return null;
return {
kind: 'alias',
source,
name: alias,
alias,
atNode: clause,
};
}

// Strategy 2: bare sibling `name` node after the qualified_name (tree-sitter-php ≥ 0.22).
// Strategy: bare sibling `name` node after the qualified_name (tree-sitter-php ≥ 0.22).
if (clause.namedChildCount >= 2) {
const lastChild = clause.namedChild(clause.namedChildCount - 1);
if (lastChild !== null && lastChild !== qualName && lastChild.type === 'name') {
Expand Down
13 changes: 8 additions & 5 deletions gitnexus/src/core/ingestion/languages/php/receiver-binding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ const TYPE_DECL_NODE_TYPES = new Set([
'interface_declaration',
'trait_declaration',
'enum_declaration',
// tree-sitter-php node for `new class {...}` (real node is `anonymous_class`,
// not `anonymous_class_declaration`). Included so the enclosing-type walk
// stops AT the anon class and the guard below skips it (otherwise a method in
// an anon class nested in a named class would mis-bind $this to the outer class).
'anonymous_class',
]);

const FUNCTION_NODE_TYPES = new Set([
Expand Down Expand Up @@ -98,18 +103,16 @@ export function synthesizePhpReceiverBinding(fnNode: SyntaxNode): CaptureMatch[]
if (enclosingType === null) return [];

// Anonymous class — skip (no stable name).
if (enclosingType.type === 'anonymous_class_declaration') return [];
if (enclosingType.type === 'anonymous_class') return [];

const enclosingName = typeName(enclosingType);
if (enclosingName === null) return [];

// Anchor the synthesized captures to the method body (compound_statement)
// so they land inside the function scope, not at the class scope.
// For interface/abstract methods that have no body, skip.
const bodyNode =
fnNode.childForFieldName('body') ??
// arrow_function: body is the expression after `=>`
fnNode.childForFieldName('return_value');
// tree-sitter-php arrow_function also exposes its expression via the `body` field.
const bodyNode = fnNode.childForFieldName('body');
if (bodyNode === null) return [];

const out: CaptureMatch[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function synthesizeDependsReferences(fnNode: SyntaxNode): readonly Captur
continue;
}

const defaultValue = param.childForFieldName('value') ?? param.childForFieldName('default');
const defaultValue = param.childForFieldName('value');
if (defaultValue === null) continue;

const callNode = defaultValue.type === 'call' ? defaultValue : null;
Expand Down
4 changes: 2 additions & 2 deletions gitnexus/src/core/ingestion/languages/ruby/captures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export function emitRubyScopeCaptures(
if (argList !== null) {
for (let ai = 0; ai < argList.namedChildCount; ai++) {
const arg = argList.namedChild(ai);
if (arg !== null && (arg.type === 'simple_symbol' || arg.type === 'symbol')) {
if (arg !== null && arg.type === 'simple_symbol') {
const propName = arg.text.replace(/^:/, '');
out.push({
'@import.statement': grouped['@reference.call.free']!,
Expand Down Expand Up @@ -327,7 +327,7 @@ export function emitRubyScopeCaptures(
if (argList !== null) {
for (let ai = 0; ai < argList.namedChildCount; ai++) {
const arg = argList.namedChild(ai);
if (arg !== null && (arg.type === 'simple_symbol' || arg.type === 'symbol')) {
if (arg !== null && arg.type === 'simple_symbol') {
const propName = arg.text.replace(/^:/, '');
out.push({
'@type-binding.return': syntheticCapture('@type-binding.return', attrNode, text),
Expand Down
4 changes: 2 additions & 2 deletions gitnexus/src/core/ingestion/languages/rust/range-binding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,9 @@ function processStructDestructuring(
for (const fieldNode of patternNode.namedChildren) {
let fieldName: string | undefined;
if (fieldNode.type === 'field_pattern') {
// shorthand `{ a }` and full `{ b: c }` are both field_pattern; the
// `name` field is shorthand_field_identifier or field_identifier.
fieldName = fieldNode.childForFieldName('name')?.text;
} else if (fieldNode.type === 'shorthand_field_pattern') {
fieldName = fieldNode.firstNamedChild?.text;
}
if (fieldName === undefined) continue;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ const TYPE_DECL_NODE_TYPES = new Set([
'class_declaration',
'abstract_class_declaration',
'class',
'class_expression',
'interface_declaration',
]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import type { SyntaxNode } from '../../utils/ast-helpers.js';
/** Type node types that represent a return type in function/getter/setter signatures. */
const TYPE_NODE_TYPES = new Set([
'type_identifier',
'generic_type',
'function_type',
'nullable_type',
'void_type',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ function extractPhpReturnType(node: SyntaxNode): string | undefined {
'named_type',
'union_type',
'optional_type',
'nullable_type',
'intersection_type',
]);

Expand Down
2 changes: 0 additions & 2 deletions gitnexus/src/core/ingestion/type-env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ type PatternOverrides = Map<string, Map<string, PatternOverride[]>>;
* Includes both multi-arm pattern-match branches AND if-statement bodies for null-check narrowing. */
const NARROWING_BRANCH_TYPES = new Set([
'when_entry', // Kotlin when
'switch_block_label', // Java switch (enhanced)
'if_statement', // TS/JS, Java, C/C++
'if_expression', // Kotlin (if is an expression)
'statement_block', // TS/JS: { ... } body of if
Expand Down Expand Up @@ -977,7 +976,6 @@ export const buildTypeEnv = (
(child.type === 'user_type' ||
child.type === 'type_identifier' ||
child.type === 'generic_type' ||
child.type === 'parameterized_type' ||
child.type === 'nullable_type')
) {
fallbackType = child;
Expand Down
20 changes: 8 additions & 12 deletions gitnexus/src/core/ingestion/type-extractors/c-cpp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,14 @@ const extractInitializer: InitializerExtractor = (
const templateFunc =
func.type === 'template_function'
? func
: func.type === 'qualified_identifier' || func.type === 'scoped_identifier'
: func.type === 'qualified_identifier'
? (func.namedChildren.find((c: SyntaxNode) => c.type === 'template_function') ?? null)
: null;
if (templateFunc) {
const nameNode = templateFunc.firstNamedChild;
if (nameNode) {
const funcName =
nameNode.type === 'qualified_identifier' || nameNode.type === 'scoped_identifier'
nameNode.type === 'qualified_identifier'
? (nameNode.lastNamedChild?.text ?? '')
: nameNode.text;
if (SMART_PTR_FACTORIES.has(funcName)) {
Expand Down Expand Up @@ -214,7 +214,7 @@ const scanConstructorBinding: ConstructorBindingScanner = (node) => {
if (!value || value.type !== 'call_expression') return undefined;
const func = value.childForFieldName('function');
if (!func) return undefined;
if (func.type === 'qualified_identifier' || func.type === 'scoped_identifier') {
if (func.type === 'qualified_identifier') {
const last = func.lastNamedChild;
if (!last) return undefined;
const nameNode = declarator.childForFieldName('declarator');
Expand Down Expand Up @@ -331,17 +331,13 @@ const extractCppElementTypeFromTypeNode = (
const args = extractCppTemplateTypeArgs(typeNode);
if (args.length >= 1) return pos === 'first' ? args[0] : args[args.length - 1];
}
// reference/pointer types: unwrap and recurse (vector<User>& → vector<User>)
if (
typeNode.type === 'reference_type' ||
typeNode.type === 'pointer_type' ||
typeNode.type === 'type_descriptor'
) {
// type_descriptor wrapper: unwrap and recurse (vector<User>& → vector<User>)
if (typeNode.type === 'type_descriptor') {
const inner = typeNode.lastNamedChild;
if (inner) return extractCppElementTypeFromTypeNode(inner, pos, depth + 1);
}
// qualified/scoped types: std::vector<User> → unwrap to template_type child
if (typeNode.type === 'qualified_identifier' || typeNode.type === 'scoped_type_identifier') {
// qualified types: std::vector<User> → unwrap to template_type child
if (typeNode.type === 'qualified_identifier') {
const inner = typeNode.lastNamedChild;
if (inner) return extractCppElementTypeFromTypeNode(inner, pos, depth + 1);
}
Expand Down Expand Up @@ -527,7 +523,7 @@ const detectCppConstructorType: ConstructorTypeDetector = (node, classNames) =>
const nameNode = func.firstNamedChild;
if (!nameNode) return undefined;
let funcName: string;
if (nameNode.type === 'qualified_identifier' || nameNode.type === 'scoped_identifier') {
if (nameNode.type === 'qualified_identifier') {
funcName = nameNode.lastNamedChild?.text ?? '';
} else {
funcName = nameNode.text;
Expand Down
Loading
Loading