swift.ts 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import type { Node as SyntaxNode } from 'web-tree-sitter';
  2. import { getNodeText, getChildByField } from '../tree-sitter-helpers';
  3. import type { LanguageExtractor } from '../tree-sitter-types';
  4. export const swiftExtractor: LanguageExtractor = {
  5. functionTypes: ['function_declaration'],
  6. classTypes: ['class_declaration'],
  7. methodTypes: ['function_declaration'], // Methods are functions inside classes
  8. interfaceTypes: ['protocol_declaration'],
  9. structTypes: ['struct_declaration'],
  10. enumTypes: ['enum_declaration'],
  11. typeAliasTypes: ['typealias_declaration'],
  12. importTypes: ['import_declaration'],
  13. callTypes: ['call_expression'],
  14. variableTypes: ['property_declaration', 'constant_declaration'],
  15. nameField: 'name',
  16. bodyField: 'body',
  17. paramsField: 'parameter',
  18. returnField: 'return_type',
  19. getSignature: (node, source) => {
  20. // Swift function signature: func name(params) -> ReturnType
  21. const params = getChildByField(node, 'parameter');
  22. const returnType = getChildByField(node, 'return_type');
  23. if (!params) return undefined;
  24. let sig = getNodeText(params, source);
  25. if (returnType) {
  26. sig += ' -> ' + getNodeText(returnType, source);
  27. }
  28. return sig;
  29. },
  30. getVisibility: (node) => {
  31. // Check for visibility modifiers in Swift
  32. for (let i = 0; i < node.childCount; i++) {
  33. const child = node.child(i);
  34. if (child?.type === 'modifiers') {
  35. const text = child.text;
  36. if (text.includes('public')) return 'public';
  37. if (text.includes('private')) return 'private';
  38. if (text.includes('internal')) return 'internal';
  39. if (text.includes('fileprivate')) return 'private';
  40. }
  41. }
  42. return 'internal'; // Swift defaults to internal
  43. },
  44. isStatic: (node) => {
  45. for (let i = 0; i < node.childCount; i++) {
  46. const child = node.child(i);
  47. if (child?.type === 'modifiers') {
  48. if (child.text.includes('static') || child.text.includes('class')) {
  49. return true;
  50. }
  51. }
  52. }
  53. return false;
  54. },
  55. classifyClassNode: (node) => {
  56. // Swift uses class_declaration for classes, structs, and enums
  57. for (let i = 0; i < node.childCount; i++) {
  58. const child = node.child(i);
  59. if (child?.type === 'struct') return 'struct';
  60. if (child?.type === 'enum') return 'enum';
  61. }
  62. return 'class';
  63. },
  64. isAsync: (node) => {
  65. for (let i = 0; i < node.childCount; i++) {
  66. const child = node.child(i);
  67. if (child?.type === 'modifiers' && child.text.includes('async')) {
  68. return true;
  69. }
  70. }
  71. return false;
  72. },
  73. extractImport: (node, source) => {
  74. const importText = source.substring(node.startIndex, node.endIndex).trim();
  75. const identifier = node.namedChildren.find((c: SyntaxNode) => c.type === 'identifier');
  76. if (identifier) {
  77. return { moduleName: source.substring(identifier.startIndex, identifier.endIndex), signature: importText };
  78. }
  79. return null;
  80. },
  81. };