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 | 1141x 1141x 1141x 1141x 237x 237x 591x 219x 331x 331x 331x 255x 255x 331x | /**
* Factory functions and type guards for IScopeSymbol.
*
* Provides utilities for creating and inspecting C-Next scopes.
*/
import type IScopeSymbol from "../transpiler/types/symbols/IScopeSymbol";
import type TVisibility from "../transpiler/types/TVisibility";
import ESourceLanguage from "./types/ESourceLanguage";
class ScopeUtils {
// ============================================================================
// Factory Functions
// ============================================================================
/**
* Create the global scope with self-reference parent.
*
* Global scope has:
* - name: "" (empty string)
* - parent: points to itself (self-reference)
* - scope: points to itself (self-reference)
*/
static createGlobalScope(): IScopeSymbol {
// Create a mutable object first to establish self-references
const global: IScopeSymbol = {
kind: "scope",
name: "",
parent: null as unknown as IScopeSymbol, // Temporary, will be set below
scope: null as unknown as IScopeSymbol, // Temporary, will be set below
members: [],
functions: [],
variables: [],
memberVisibility: new Map(),
sourceFile: "",
sourceLine: 0,
sourceLanguage: ESourceLanguage.CNext,
isExported: true,
};
// Set self-references for global scope
(global as unknown as { parent: IScopeSymbol }).parent = global;
(global as unknown as { scope: IScopeSymbol }).scope = global;
return global;
}
/**
* Create a named scope with the given parent.
*
* Named scopes can be nested (e.g., Outer.Inner).
*/
static createScope(name: string, parent: IScopeSymbol): IScopeSymbol {
const scope: IScopeSymbol = {
kind: "scope",
name,
parent,
scope: parent, // Scope's containing scope is its parent
members: [],
functions: [],
variables: [],
memberVisibility: new Map(),
sourceFile: "",
sourceLine: 0,
sourceLanguage: ESourceLanguage.CNext,
isExported: true,
};
return scope;
}
// ============================================================================
// Type Guards
// ============================================================================
/**
* Check if a scope is the global scope.
*
* Global scope is identified by:
* - Empty name ("")
* - Self-referential parent (parent === scope)
*/
static isGlobalScope(scope: IScopeSymbol): boolean {
return scope.name === "" && scope.parent === scope;
}
// ============================================================================
// Visibility Utilities
// ============================================================================
/**
* ADR-016: Get the default visibility for a scope member based on its type.
*
* Member-type-aware defaults reduce boilerplate:
* - Functions: public by default (API surface)
* - Variables/types: private by default (internal state)
*
* @param isFunction - Whether the member is a function declaration
* @returns The default visibility for this member type
*/
static getDefaultVisibility(isFunction: boolean): TVisibility {
return isFunction ? "public" : "private";
}
// ============================================================================
// Path Utilities
// ============================================================================
/**
* Get the scope path from outermost to innermost (excluding global scope).
*
* For scope "Outer.Inner", returns ["Outer", "Inner"].
* For global scope, returns [].
*/
static getScopePath(scope: IScopeSymbol): string[] {
const path: string[] = [];
let current = scope;
while (!ScopeUtils.isGlobalScope(current)) {
path.unshift(current.name);
current = current.parent;
}
return path;
}
}
export default ScopeUtils;
|