All files / PARSE/3-Declare/cpp/collectors FunctionCollector.ts

85.71% Statements 18/21
75% Branches 15/20
100% Functions 5/5
100% Lines 17/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157                                            27x                                             13x 13x   13x 13x     13x 13x       13x 13x       13x                                                             11x 11x   11x 11x       11x                                                                     3x       3x                                
/**
 * FunctionCollector - Extracts function definitions and declarations from C++ parse trees.
 *
 * Produces ICppFunctionSymbol instances with parameters.
 */
 
/* eslint-disable @typescript-eslint/no-explicit-any */
 
import ESourceLanguage from "../../../../utils/types/ESourceLanguage";
import ICppFunctionSymbol from "../../../../types/symbols/cpp/ICppFunctionSymbol";
import ICppParameterInfo from "../../../../types/symbols/cpp/ICppParameterInfo";
import DeclaratorUtils from "../utils/DeclaratorUtils";
import IExtractedParameter from "../../shared/IExtractedParameter";
import type ISourceSpan from "../../../../types/ISourceSpan";
 
class FunctionCollector {
  /**
   * Map extracted parameters to ICppParameterInfo array.
   */
  private static _mapParameters(
    extracted: IExtractedParameter[],
  ): ICppParameterInfo[] {
    return extracted.map((p) => ({
      name: p.name,
      type: p.type,
      isConst: p.isConst,
      isArray: p.isArray,
    }));
  }
 
  /**
   * Collect a function definition and return an ICppFunctionSymbol.
   *
   * @param funcDef The function definition context
   * @param sourceFile Source file path
   * @param span Source span of the declaration
   * @param currentNamespace Optional current namespace
   * @returns The function symbol or null if no name
   */
  static collectDefinition(
    funcDef: any,
    sourceFile: string,
    span: ISourceSpan,
    currentNamespace?: string,
  ): ICppFunctionSymbol | null {
    const declarator = funcDef.declarator?.();
    Iif (!declarator) return null;
 
    const name = DeclaratorUtils.extractDeclaratorName(declarator);
    Iif (!name) return null;
 
    // Get return type
    const declSpecSeq = funcDef.declSpecifierSeq?.();
    const returnType = declSpecSeq
      ? DeclaratorUtils.extractTypeFromDeclSpecSeq(declSpecSeq)
      : "void";
 
    const fullName = currentNamespace ? `${currentNamespace}::${name}` : name;
    const params = FunctionCollector._mapParameters(
      DeclaratorUtils.extractFunctionParameters(declarator),
    );
 
    return {
      kind: "function",
      name: fullName,
      type: returnType,
      sourceFile,
      span,
      sourceLanguage: ESourceLanguage.Cpp,
      visibility: "public",
      parent: currentNamespace,
      parameters: params.length > 0 ? params : undefined,
      isDeclaration: false,
    };
  }
 
  /**
   * Collect a function declaration (prototype) and return an ICppFunctionSymbol.
   *
   * @param declarator The function declarator context
   * @param baseType The return type string
   * @param sourceFile Source file path
   * @param span Source span of the declaration
   * @param currentNamespace Optional current namespace
   * @returns The function symbol or null if no name
   */
  static collectDeclaration(
    declarator: any,
    baseType: string,
    sourceFile: string,
    span: ISourceSpan,
    currentNamespace?: string,
  ): ICppFunctionSymbol | null {
    const name = DeclaratorUtils.extractDeclaratorName(declarator);
    Iif (!name) return null;
 
    const fullName = currentNamespace ? `${currentNamespace}::${name}` : name;
    const params = FunctionCollector._mapParameters(
      DeclaratorUtils.extractFunctionParameters(declarator),
    );
 
    return {
      kind: "function",
      name: fullName,
      type: baseType,
      sourceFile,
      span,
      sourceLanguage: ESourceLanguage.Cpp,
      visibility: "public",
      parent: currentNamespace,
      parameters: params.length > 0 ? params : undefined,
      isDeclaration: true,
    };
  }
 
  /**
   * Collect a member function (method) and return an ICppFunctionSymbol.
   *
   * @param className The class this method belongs to
   * @param funcName The method name
   * @param declarator The function declarator context
   * @param returnType The return type string
   * @param sourceFile Source file path
   * @param span Source span of the declaration
   * @param isDeclaration Whether this is a declaration (vs inline definition)
   * @returns The function symbol
   */
  static collectMemberFunction(
    className: string,
    funcName: string,
    declarator: any,
    returnType: string,
    sourceFile: string,
    span: ISourceSpan,
    isDeclaration: boolean,
  ): ICppFunctionSymbol {
    const params = FunctionCollector._mapParameters(
      DeclaratorUtils.extractFunctionParameters(declarator),
    );
 
    return {
      kind: "function",
      name: `${className}::${funcName}`,
      type: returnType,
      sourceFile,
      span,
      sourceLanguage: ESourceLanguage.Cpp,
      visibility: "public",
      parent: className,
      parameters: params.length > 0 ? params : undefined,
      isDeclaration: isDeclaration || undefined,
    };
  }
}
 
export default FunctionCollector;