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 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | 26x 19x 19x 14x 5x 4x 173x 170x 170x 49x 47x 47x 47x 8x 10x 59x 4x 219x 169x 662x 438x 430x 428x | /**
* SymbolLookupHelper
*
* Helper class for symbol table lookup operations.
* Extracts common lookup patterns for improved testability.
*/
import ESymbolKind from "../../../../utils/types/ESymbolKind.js";
import ESourceLanguage from "../../../../utils/types/ESourceLanguage.js";
/**
* Symbol interface for lookups
*/
interface ISymbol {
kind: ESymbolKind;
sourceLanguage: ESourceLanguage;
}
/**
* Symbol table interface
*/
interface ISymbolTable {
getOverloads(name: string): ISymbol[];
getStructFields?(name: string): unknown;
}
class SymbolLookupHelper {
/**
* Check if a symbol exists with the given kind and language.
*/
static hasSymbolWithKindAndLanguage(
symbolTable: ISymbolTable | null | undefined,
name: string,
kind: ESymbolKind,
languages: ESourceLanguage[],
): boolean {
if (!symbolTable) return false;
const symbols = symbolTable.getOverloads(name);
return symbols.some(
(sym) => sym.kind === kind && languages.includes(sym.sourceLanguage),
);
}
/**
* Check if a type is a C++ enum class (scoped enum).
* Issue #304: These require explicit casts to integer types in C++.
*/
static isCppEnumClass(
symbolTable: ISymbolTable | null | undefined,
typeName: string,
): boolean {
return SymbolLookupHelper.hasSymbolWithKindAndLanguage(
symbolTable,
typeName,
ESymbolKind.Enum,
[ESourceLanguage.Cpp],
);
}
/**
* Check if a function is an external C or C++ function.
* External functions use pass-by-value semantics.
*/
static isExternalCFunction(
symbolTable: ISymbolTable | null | undefined,
name: string,
): boolean {
return SymbolLookupHelper.hasSymbolWithKindAndLanguage(
symbolTable,
name,
ESymbolKind.Function,
[ESourceLanguage.C, ESourceLanguage.Cpp],
);
}
/**
* Check if a name refers to a namespace/scope.
*/
static isNamespace(
symbolTable: ISymbolTable | null | undefined,
name: string,
): boolean {
if (!symbolTable) return false;
const symbols = symbolTable.getOverloads(name);
return symbols.some((sym) => sym.kind === ESymbolKind.Namespace);
}
/**
* Check if a type name is from a C++ header.
* Issue #304: Used to determine whether to use {} or {0} for initialization.
* C++ types with constructors may fail with {0} but work with {}.
*/
static isCppType(
symbolTable: ISymbolTable | null | undefined,
typeName: string,
): boolean {
if (!symbolTable) return false;
const symbols = symbolTable.getOverloads(typeName);
const cppTypeKinds = new Set([
ESymbolKind.Struct,
ESymbolKind.Class,
ESymbolKind.Type,
]);
return symbols.some(
(sym) =>
sym.sourceLanguage === ESourceLanguage.Cpp &&
cppTypeKinds.has(sym.kind),
);
}
/**
* Check if a function is a C-Next function (uses pass-by-reference semantics).
* Returns true if the function is found in symbol table as C-Next.
*/
static isCNextFunction(
symbolTable: ISymbolTable | null | undefined,
name: string,
): boolean {
return SymbolLookupHelper.hasSymbolWithKindAndLanguage(
symbolTable,
name,
ESymbolKind.Function,
[ESourceLanguage.CNext],
);
}
/**
* Check if a function is a C-Next function (combined local + symbol table lookup).
* Checks local knownFunctions set first, then falls back to symbol table.
*/
static isCNextFunctionCombined(
knownFunctions: ReadonlySet<string> | undefined,
symbolTable: ISymbolTable | null | undefined,
name: string,
): boolean {
if (knownFunctions?.has(name)) return true;
return SymbolLookupHelper.isCNextFunction(symbolTable, name);
}
/**
* Check if a name is a known scope (combined local + symbol table lookup).
* Checks local knownScopes set first, then falls back to symbol table.
*/
static isKnownScope(
knownScopes: ReadonlySet<string> | undefined,
symbolTable: ISymbolTable | null | undefined,
name: string,
): boolean {
if (knownScopes?.has(name)) return true;
return SymbolLookupHelper.isNamespace(symbolTable, name);
}
/**
* Check if a type is a known struct (combined local + symbol table lookup).
* Checks local knownStructs and knownBitmaps, then falls back to symbol table.
* Issue #551: Bitmaps are struct-like (use pass-by-reference with -> access).
*/
static isKnownStruct(
knownStructs: ReadonlySet<string> | undefined,
knownBitmaps: ReadonlySet<string> | undefined,
symbolTable: ISymbolTable | null | undefined,
typeName: string,
): boolean {
if (knownStructs?.has(typeName)) return true;
if (knownBitmaps?.has(typeName)) return true;
if (symbolTable?.getStructFields?.(typeName)) return true;
return false;
}
}
export default SymbolLookupHelper;
|