mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-09 03:17:54 +00:00
fix(objective-c): complete provider follow-ups
This commit is contained in:
parent
27c0e5d9ee
commit
6054ed5304
13 changed files with 113 additions and 8 deletions
|
|
@ -186,6 +186,10 @@ const getNodeTypeIcon = (label: NodeLabel) => {
|
|||
return FileCode;
|
||||
case 'Class':
|
||||
return Box;
|
||||
case 'Protocol':
|
||||
return Hash;
|
||||
case 'Category':
|
||||
return Box;
|
||||
case 'Function':
|
||||
return Braces;
|
||||
case 'Method':
|
||||
|
|
|
|||
|
|
@ -135,6 +135,8 @@ export const FILTERABLE_LABELS: NodeLabel[] = [
|
|||
'Folder',
|
||||
'File',
|
||||
'Class',
|
||||
'Protocol',
|
||||
'Category',
|
||||
'Interface',
|
||||
'Enum',
|
||||
'Type',
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ describe('FILTERABLE_LABELS', () => {
|
|||
expect(FILTERABLE_LABELS).toContain('Type');
|
||||
expect(FILTERABLE_LABELS).toContain('Decorator');
|
||||
expect(FILTERABLE_LABELS).toContain('Variable');
|
||||
expect(FILTERABLE_LABELS).toContain('Protocol');
|
||||
expect(FILTERABLE_LABELS).toContain('Category');
|
||||
});
|
||||
|
||||
it('every filterable label has a defined color in NODE_COLORS', () => {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ const LEGEND_LABELS: NodeLabel[] = [
|
|||
'Folder',
|
||||
'File',
|
||||
'Class',
|
||||
'Protocol',
|
||||
'Category',
|
||||
'Interface',
|
||||
'Enum',
|
||||
'Type',
|
||||
|
|
@ -20,6 +22,8 @@ const ICON_MAP: Record<string, string> = {
|
|||
Folder: 'Folder',
|
||||
File: 'FileCode',
|
||||
Class: 'Box',
|
||||
Protocol: 'Hash',
|
||||
Category: 'Box',
|
||||
Function: 'Braces',
|
||||
Method: 'Braces',
|
||||
Interface: 'Hash',
|
||||
|
|
@ -62,6 +66,8 @@ describe('color legend', () => {
|
|||
expect(LEGEND_LABELS).toContain('Type');
|
||||
expect(LEGEND_LABELS).toContain('Decorator');
|
||||
expect(LEGEND_LABELS).toContain('Variable');
|
||||
expect(LEGEND_LABELS).toContain('Protocol');
|
||||
expect(LEGEND_LABELS).toContain('Category');
|
||||
});
|
||||
|
||||
it('every legend label has a color defined', () => {
|
||||
|
|
@ -76,6 +82,8 @@ describe('color legend', () => {
|
|||
'Folder',
|
||||
'File',
|
||||
'Class',
|
||||
'Protocol',
|
||||
'Category',
|
||||
'Interface',
|
||||
'Enum',
|
||||
'Type',
|
||||
|
|
|
|||
|
|
@ -163,7 +163,10 @@ const FIELD_LIKE_MEMBER_TYPES = new Set([
|
|||
'enum_assignment',
|
||||
]);
|
||||
|
||||
const DECLARATION_MEMBER_WRAPPER_TYPES = new Set(['qualified_protocol_interface_declaration']);
|
||||
const DECLARATION_MEMBER_WRAPPER_TYPES = new Set([
|
||||
'qualified_protocol_interface_declaration',
|
||||
'instance_variables',
|
||||
]);
|
||||
|
||||
const declarationChunk = async (
|
||||
content: string,
|
||||
|
|
|
|||
|
|
@ -112,8 +112,6 @@ export const isShortLabel = (label: string): boolean =>
|
|||
*/
|
||||
export const STRUCTURAL_LABELS: ReadonlySet<string> = new Set([
|
||||
LABEL_CLASS,
|
||||
LABEL_PROTOCOL,
|
||||
LABEL_CATEGORY,
|
||||
LABEL_STRUCT,
|
||||
LABEL_INTERFACE,
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
interface ScanState {
|
||||
inBlockComment: boolean;
|
||||
inLineCommentContinuation: boolean;
|
||||
inPreprocessorDirective: boolean;
|
||||
quote: '"' | "'" | undefined;
|
||||
braceDepth: number;
|
||||
|
|
@ -66,6 +67,10 @@ function startsPreprocessorDirective(line: string): boolean {
|
|||
}
|
||||
|
||||
function scanLine(line: string, state: ScanState): void {
|
||||
if (state.inLineCommentContinuation) {
|
||||
state.inLineCommentContinuation = hasEscapedLineEnding(line);
|
||||
return;
|
||||
}
|
||||
if (state.inPreprocessorDirective) {
|
||||
state.inPreprocessorDirective = hasEscapedLineEnding(line);
|
||||
return;
|
||||
|
|
@ -96,7 +101,10 @@ function scanLine(line: string, state: ScanState): void {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (code === 0x2f && next === 0x2f) return;
|
||||
if (code === 0x2f && next === 0x2f) {
|
||||
state.inLineCommentContinuation = hasEscapedLineEnding(line);
|
||||
return;
|
||||
}
|
||||
if (code === 0x2f && next === 0x2a) {
|
||||
state.inBlockComment = true;
|
||||
index++;
|
||||
|
|
@ -123,6 +131,7 @@ function scanLine(line: string, state: ScanState): void {
|
|||
export function preprocessObjectiveCMacroMarkers(source: string, _filePath?: string): string {
|
||||
const state: ScanState = {
|
||||
inBlockComment: false,
|
||||
inLineCommentContinuation: false,
|
||||
inPreprocessorDirective: false,
|
||||
quote: undefined,
|
||||
braceDepth: 0,
|
||||
|
|
@ -134,6 +143,7 @@ export function preprocessObjectiveCMacroMarkers(source: string, _filePath?: str
|
|||
const line = segments[index];
|
||||
if (
|
||||
!state.inBlockComment &&
|
||||
!state.inLineCommentContinuation &&
|
||||
!state.inPreprocessorDirective &&
|
||||
state.quote === undefined &&
|
||||
state.braceDepth === 0 &&
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* └── symbols (SymbolTable) ← owns fileIndex + callableByName,
|
||||
* calls dispatch() in add()
|
||||
*
|
||||
* ## Behavior groups (5 hooks, 13 table entries)
|
||||
* ## Behavior groups (4 hooks, 12 table entries)
|
||||
*
|
||||
* | Group | NodeLabel values | Hook | Skip callable? |
|
||||
* |---------------|---------------------------------------------------|--------------|----------------|
|
||||
|
|
|
|||
|
|
@ -55,5 +55,4 @@ export const SCOPE_RESOLVERS: ReadonlyMap<SupportedLanguages, ScopeResolver> = n
|
|||
[SupportedLanguages.Vue, vueScopeResolver],
|
||||
[SupportedLanguages.Zig, zigScopeResolver],
|
||||
[SupportedLanguages.ObjectiveC, objectiveCScopeResolver],
|
||||
[SupportedLanguages.Zig, zigScopeResolver],
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -412,6 +412,53 @@ describe('chunkNode', () => {
|
|||
expect(createParserForLanguage).toHaveBeenCalledWith('objective-c', 'ProtocolSections.m');
|
||||
});
|
||||
|
||||
it('expands Objective-C instance variables before chunking a class declaration', async () => {
|
||||
const content = [
|
||||
'@interface Worker {',
|
||||
' id _first;',
|
||||
' id _second;',
|
||||
'}',
|
||||
'- (void)run;',
|
||||
'@end',
|
||||
].join('\n');
|
||||
const firstIvar = 'id _first;';
|
||||
const secondIvar = 'id _second;';
|
||||
const method = '- (void)run;';
|
||||
const firstIvarStart = content.indexOf(firstIvar);
|
||||
const secondIvarStart = content.indexOf(secondIvar);
|
||||
const methodStart = content.indexOf(method);
|
||||
const instanceVariables = makeFakeNode(
|
||||
'instance_variables',
|
||||
content.indexOf('{'),
|
||||
content.indexOf('}') + 1,
|
||||
[
|
||||
makeFakeNode('field_definition', firstIvarStart, firstIvarStart + firstIvar.length),
|
||||
makeFakeNode('field_definition', secondIvarStart, secondIvarStart + secondIvar.length),
|
||||
],
|
||||
);
|
||||
const declaration = makeFakeNode('class_interface', 0, content.length, [
|
||||
makeFakeNode('identifier', content.indexOf('Worker'), content.indexOf('Worker') + 'Worker'.length),
|
||||
instanceVariables,
|
||||
makeFakeNode('method_declaration', methodStart, methodStart + method.length),
|
||||
]);
|
||||
createParserForLanguage.mockResolvedValue({
|
||||
parse: vi.fn().mockReturnValue({
|
||||
rootNode: makeFakeNode('program', 0, content.length, [declaration]),
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await chunkNode('Class', content, 'Worker.m', 1, 6, 48, 0);
|
||||
const combined = result.map((chunk) => chunk.text).join('\n');
|
||||
|
||||
expect(result.length).toBeGreaterThan(1);
|
||||
expect(combined).toContain(firstIvar);
|
||||
expect(combined).toContain(secondIvar);
|
||||
expect(combined).toContain(method);
|
||||
expect(result.some((chunk) => chunk.text.includes(firstIvar) && chunk.text.includes(secondIvar))).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it('keeps Objective-C protocol inheritance in the declaration prefix', async () => {
|
||||
const content = ['@protocol Worker <Runnable, Observable>', '- (void)run;', '@end'].join('\n');
|
||||
const protocolNameStart = content.indexOf('Worker');
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
LABEL_CATEGORY,
|
||||
LABEL_PROTOCOL,
|
||||
LABELS_WITH_EXPORTED,
|
||||
STRUCTURAL_LABELS,
|
||||
} from '../../src/core/embeddings/types.js';
|
||||
import { STALE_HASH_SENTINEL } from '../../src/core/lbug/schema.js';
|
||||
|
||||
|
|
@ -24,6 +25,13 @@ describe('embedding schema column contracts', () => {
|
|||
expect(LABELS_WITH_EXPORTED.has(LABEL_PROTOCOL)).toBe(false);
|
||||
expect(LABELS_WITH_EXPORTED.has(LABEL_CATEGORY)).toBe(false);
|
||||
});
|
||||
|
||||
it('keeps Objective-C protocol/category declaration chunking without unsupported structural extraction', () => {
|
||||
expect(STRUCTURAL_LABELS.has(LABEL_PROTOCOL)).toBe(false);
|
||||
expect(STRUCTURAL_LABELS.has(LABEL_CATEGORY)).toBe(false);
|
||||
expect(EMBEDDABLE_LABELS).toContain(LABEL_PROTOCOL);
|
||||
expect(EMBEDDABLE_LABELS).toContain(LABEL_CATEGORY);
|
||||
});
|
||||
});
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -140,8 +140,17 @@ describe('BasicBlock taint/PDG substrate label (issue #2080)', () => {
|
|||
// reference-equality assertions on the hook functions themselves.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('class-like behavior group — all 6 labels route to types.registerClass', () => {
|
||||
const CLASS_LIKE_LABELS = ['Class', 'Struct', 'Interface', 'Enum', 'Record', 'Trait'] as const;
|
||||
describe('class-like behavior group — all 8 labels route to types.registerClass', () => {
|
||||
const CLASS_LIKE_LABELS = [
|
||||
'Class',
|
||||
'Protocol',
|
||||
'Category',
|
||||
'Struct',
|
||||
'Interface',
|
||||
'Enum',
|
||||
'Record',
|
||||
'Trait',
|
||||
] as const;
|
||||
|
||||
for (const label of CLASS_LIKE_LABELS) {
|
||||
it(`${label} writes to types.registerClass`, () => {
|
||||
|
|
|
|||
|
|
@ -48,4 +48,19 @@ describe('preprocessObjectiveCMacroMarkers', () => {
|
|||
|
||||
expect(preprocessObjectiveCMacroMarkers(source, 'Example.m')).toBe(source);
|
||||
});
|
||||
|
||||
it('does not rewrite markers inside a continued line comment', () => {
|
||||
const source = [
|
||||
'// The following token remains part of this comment \\',
|
||||
'RCT_EXTERN_C_END',
|
||||
'RCT_EXTERN_C_BEGIN',
|
||||
'',
|
||||
].join('\n');
|
||||
|
||||
const normalized = preprocessObjectiveCMacroMarkers(source, 'CommentedMarker.h');
|
||||
|
||||
expect(normalized).toHaveLength(source.length);
|
||||
expect(normalized).toContain('RCT_EXTERN_C_END');
|
||||
expect(normalized.split('\n')[2]).toBe(' '.repeat('RCT_EXTERN_C_BEGIN'.length));
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue