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 | 671x 3x 668x 668x 109x 96x 13x 12x 656x 132x 1x 131x 118x 13x 13x 13x 67x 1x 66x 61x 5x 5x 2x 3x | /**
* C++ Namespace Detection Utilities
*
* Provides shared logic for detecting C++ namespaced types and converting
* between underscore format (used in C headers) and :: format (used in C++).
*
* Issue #522: Consolidated from duplicate implementations in:
* - CodeGenerator.ts (isCppScopeSymbol)
* - generateStructHeader.ts (isCppNamespace, convertToCppNamespaceIfNeeded)
*/
import SymbolTable from "../transpiler/logic/symbols/SymbolTable";
import ESourceLanguage from "./types/ESourceLanguage";
import ESymbolKind from "./types/ESymbolKind";
/**
* Static utility methods for C++ namespace operations
*/
class CppNamespaceUtils {
/**
* Check if a symbol name refers to a C++ scope-like symbol that requires :: syntax.
* This includes C++ namespaces, classes, and enum classes (scoped enums).
*
* @param name - The symbol name to check (e.g., "SeaDash" or "Lib")
* @param symbolTable - Optional symbol table for lookups
* @returns true if the symbol is a C++ namespace, class, or enum
*/
static isCppNamespace(
name: string,
symbolTable: SymbolTable | undefined,
): boolean {
if (!symbolTable) {
return false;
}
const symbols = symbolTable.getOverloads(name);
for (const sym of symbols) {
// Only consider C++ symbols
if (sym.sourceLanguage !== ESourceLanguage.Cpp) {
continue;
}
// C++ namespaces, classes, and enums (enum class) need :: syntax
if (
sym.kind === ESymbolKind.Namespace ||
sym.kind === ESymbolKind.Class ||
sym.kind === ESymbolKind.Enum
) {
return true;
}
}
return false;
}
/**
* Check if a type name (potentially with underscores) is a C++ namespaced type.
* This checks if the first part of an underscore-separated name is a C++ namespace.
*
* @param typeName - The type name to check (e.g., "SeaDash_Parse_ParseResult")
* @param symbolTable - Optional symbol table for lookups
* @returns true if this is a C++ namespaced type in underscore format
*/
static isCppNamespaceType(
typeName: string,
symbolTable: SymbolTable | undefined,
): boolean {
// Types already in :: format are clearly C++ namespaced
if (typeName.includes("::")) {
return true;
}
// Check underscore-separated names
if (!typeName.includes("_")) {
return false;
}
const parts = typeName.split("_");
Eif (parts.length > 1) {
return CppNamespaceUtils.isCppNamespace(parts[0], symbolTable);
}
return false;
}
/**
* Convert underscore-separated type names to C++ namespace syntax
* if the first part is a known C++ namespace.
*
* @param typeName - The type name to convert (e.g., "SeaDash_Parse_ParseResult")
* @param symbolTable - Optional symbol table for lookups
* @returns The converted type name (e.g., "SeaDash::Parse::ParseResult") or original if not C++ namespaced
*/
static convertToCppNamespace(
typeName: string,
symbolTable: SymbolTable | undefined,
): string {
// Already in :: format
if (typeName.includes("::")) {
return typeName;
}
// Only process types that contain underscores
if (!typeName.includes("_")) {
return typeName;
}
// Check if this looks like a qualified type
const parts = typeName.split("_");
if (
parts.length > 1 &&
CppNamespaceUtils.isCppNamespace(parts[0], symbolTable)
) {
// It's a C++ namespaced type - convert _ to ::
return parts.join("::");
}
return typeName;
}
}
export default CppNamespaceUtils;
|