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 | 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 28x 27x 27x 27x 16x 3x 13x 13x 12x 12x 10x 10x 9x | /**
* ArrayInitializerUtils - Shared utilities for analyzing array initializers.
* Issue #636: Used by both VariableCollector (headers) and CodeGenerator (.c files)
* to ensure consistent array size inference from initializers.
*/
import * as Parser from "../../../parser/grammar/CNextParser";
class ArrayInitializerUtils {
/**
* Find an ArrayInitializerContext from an expression.
* Traverses the parse tree: Expression → Ternary → Or → And → ... → Primary → ArrayInitializer
*
* @param expr The expression context to search
* @returns The array initializer context, or null if not found
*/
static findArrayInitializer(
expr: Parser.ExpressionContext,
): Parser.ArrayInitializerContext | null {
// Expression → TernaryExpression
const ternary = expr.ternaryExpression();
Iif (!ternary) return null;
// TernaryExpression → OrExpression (when not a ternary)
const orExpr = ternary.orExpression();
Iif (!orExpr || orExpr.length === 0) return null;
// OrExpression → AndExpression
const andExpr = orExpr[0].andExpression();
Iif (!andExpr || andExpr.length === 0) return null;
// AndExpression → EqualityExpression
const equality = andExpr[0].equalityExpression();
Iif (!equality || equality.length === 0) return null;
// EqualityExpression → RelationalExpression
const relational = equality[0].relationalExpression();
Iif (!relational || relational.length === 0) return null;
// RelationalExpression → BitwiseOrExpression
const bitwiseOr = relational[0].bitwiseOrExpression();
Iif (!bitwiseOr || bitwiseOr.length === 0) return null;
// BitwiseOrExpression → BitwiseXorExpression
const bitwiseXor = bitwiseOr[0].bitwiseXorExpression();
Iif (!bitwiseXor || bitwiseXor.length === 0) return null;
// BitwiseXorExpression → BitwiseAndExpression
const bitwiseAnd = bitwiseXor[0].bitwiseAndExpression();
Iif (!bitwiseAnd || bitwiseAnd.length === 0) return null;
// BitwiseAndExpression → ShiftExpression
const shift = bitwiseAnd[0].shiftExpression();
Iif (!shift || shift.length === 0) return null;
// ShiftExpression → AdditiveExpression
const additive = shift[0].additiveExpression();
Iif (!additive || additive.length === 0) return null;
// AdditiveExpression → MultiplicativeExpression
const multiplicative = additive[0].multiplicativeExpression();
Iif (!multiplicative || multiplicative.length === 0) return null;
// MultiplicativeExpression → UnaryExpression
const unaryArr = multiplicative[0].unaryExpression();
Iif (!unaryArr || unaryArr.length === 0) return null;
const unary = unaryArr[0];
// UnaryExpression → PostfixExpression
const postfix = unary.postfixExpression();
if (!postfix) return null;
// PostfixExpression → PrimaryExpression
const primary = postfix.primaryExpression();
Iif (!primary) return null;
// PrimaryExpression → ArrayInitializer
return primary.arrayInitializer();
}
/**
* Count the number of elements in an array initializer.
* Handles both list syntax [1, 2, 3] and fill-all syntax [0*].
*
* @param arrayInit The array initializer context
* @returns Object with count (for list) or isFillAll (for fill-all syntax)
*/
static countElements(arrayInit: Parser.ArrayInitializerContext): {
count: number;
isFillAll: boolean;
} {
// Check for fill-all syntax: [expr*]
// Fill-all has expression() directly on the arrayInitializer, not wrapped in elements
if (arrayInit.expression()) {
return { count: 0, isFillAll: true };
}
// List syntax: [elem1, elem2, ...]
const elements = arrayInit.arrayInitializerElement();
return { count: elements.length, isFillAll: false };
}
/**
* Get the inferred array size from an expression containing an array initializer.
* Returns the element count if the expression is a list-style array initializer,
* or undefined if no array initializer found or if it uses fill-all syntax.
*
* @param expr The expression context
* @returns The inferred size, or undefined
*/
static getInferredSize(expr: Parser.ExpressionContext): number | undefined {
const arrayInit = this.findArrayInitializer(expr);
if (!arrayInit) return undefined;
const { count, isFillAll } = this.countElements(arrayInit);
if (isFillAll) return undefined; // Fill-all requires explicit size
return count > 0 ? count : undefined;
}
}
export default ArrayInitializerUtils;
|