diff --git a/src/core/treeSitter/queries/querySwift.ts b/src/core/treeSitter/queries/querySwift.ts index 6454062e..589c4825 100644 --- a/src/core/treeSitter/queries/querySwift.ts +++ b/src/core/treeSitter/queries/querySwift.ts @@ -12,13 +12,7 @@ export const querySwift = ` (function_declaration name: (simple_identifier) @name ) @definition.method - ; Note: Subscript currently captures parameter name (e.g., "key") rather than - ; the subscript itself. This may cause non-unique identifiers when multiple - ; subscripts use the same parameter name. Consider capturing the type signature - ; or the entire subscript declaration in future improvements. - (subscript_declaration - (parameter (simple_identifier) @name) - ) @definition.method + (subscript_declaration) @name.definition.method (init_declaration "init" @name) @definition.method (deinit_declaration "deinit" @name) @definition.method ] @@ -29,10 +23,7 @@ export const querySwift = ` (protocol_function_declaration name: (simple_identifier) @name ) @definition.method - ; Note: Same subscript parameter naming consideration as in class_body above - (subscript_declaration - (parameter (simple_identifier) @name) - ) @definition.method + (subscript_declaration) @name.definition.method (init_declaration "init" @name) @definition.method ] ) diff --git a/tests/core/treeSitter/parseFile.csharp.test.ts b/tests/core/treeSitter/parseFile.csharp.test.ts index 43d8cfae..febfcabd 100644 --- a/tests/core/treeSitter/parseFile.csharp.test.ts +++ b/tests/core/treeSitter/parseFile.csharp.test.ts @@ -256,4 +256,76 @@ describe('parseFile for C#', () => { expect(result).toContain(expectContent); } }); + + test('should parse mixed inheritance with base class and interfaces', async () => { + const fileContent = ` + // Base class + public class Animal { + public virtual void Speak() { + Console.WriteLine("Animal speaks"); + } + } + + // Interface for movement + public interface IMovable { + void Move(); + } + + // Interface for sound + public interface IAudible { + void Hear(); + } + + // Mixed inheritance: base class + multiple interfaces + public class Dog : Animal, IMovable, IAudible { + // Override Speak from Animal + public override void Speak() { + Console.WriteLine("Dog barks"); + } + + // Implementation of IMovable + public void Move() { + Console.WriteLine("Dog runs"); + } + + // Implementation of IAudible + public void Hear() { + Console.WriteLine("Dog listens"); + } + } + `; + const filePath = 'inheritance.cs'; + const config = {}; + const result = await parseFile(fileContent, filePath, createMockConfig(config)); + expect(typeof result).toBe('string'); + + const expectContents = [ + // Base class + 'Base class', + 'class Animal', + 'virtual void Speak()', + + // Interfaces + 'Interface for movement', + 'interface IMovable', + 'void Move()', + 'Interface for sound', + 'interface IAudible', + 'void Hear()', + + // Mixed inheritance class + 'Mixed inheritance: base class + multiple interfaces', + 'class Dog', + 'Animal', + 'IMovable', + 'IAudible', + 'void Move()', + 'void Hear()', + 'override void Speak()', + ]; + + for (const expectContent of expectContents) { + expect(result).toContain(expectContent); + } + }); }); diff --git a/tests/core/treeSitter/parseFile.swift.test.ts b/tests/core/treeSitter/parseFile.swift.test.ts index 89a113fd..29b11e75 100644 --- a/tests/core/treeSitter/parseFile.swift.test.ts +++ b/tests/core/treeSitter/parseFile.swift.test.ts @@ -319,4 +319,69 @@ describe('parseFile for Swift', () => { expect(result).toContain(expectContent); } }); + + test('should handle multiple subscripts with different parameter names', async () => { + const fileContent = ` + /// A storage protocol with multiple subscript accessors + protocol Storage { + /// Access by string key + subscript(key: String) -> Value? { get set } + + /// Access by integer index + subscript(index: Int) -> Value? { get set } + + /// Access by range + subscript(range: Range) -> [Value] { get } + } + + /// A dictionary-like class with multiple subscripts + class Dictionary { + /// Access by string key + subscript(key: String) -> Int? { + get { return nil } + set { } + } + + /// Access by integer index + subscript(index: Int) -> String? { + get { return nil } + set { } + } + + /// Access by key and default value + subscript(key: String, default defaultValue: Int) -> Int { + get { return defaultValue } + set { } + } + } + `; + const filePath = 'storage.swift'; + const config = {}; + const result = await parseFile(fileContent, filePath, createMockConfig(config)); + expect(typeof result).toBe('string'); + + const expectContents = [ + // Protocol + 'A storage protocol with multiple subscript accessors', + 'protocol Storage', + 'Access by string key', + 'subscript(key: String) -> Value?', + 'Access by integer index', + 'subscript(index: Int) -> Value?', + 'Access by range', + 'subscript(range: Range) -> [Value]', + + // Class + 'A dictionary-like class with multiple subscripts', + 'class Dictionary', + 'Access by string key', + 'Access by integer index', + 'Access by key and default value', + 'subscript(key: String, default defaultValue: Int) -> Int', + ]; + + for (const expectContent of expectContents) { + expect(result).toContain(expectContent); + } + }); });