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 | 8x 160x 160x 24x 24x 24x 24x 38x 38x 38x 38x 38x 8x 159x 160x 160x 160x 160x 8x 8x | /**
* Struct Field Analyzer
* Validates that struct field names don't conflict with C-Next reserved property names
*
* Fields cannot use reserved names like 'length' which conflict with C-Next's
* built-in .length property for primitives and arrays.
*/
import { ParseTreeWalker } from "antlr4ng";
import { CNextListener } from "../parser/grammar/CNextListener";
import * as Parser from "../parser/grammar/CNextParser";
import IStructFieldError from "./types/IStructFieldError";
import SymbolUtils from "../symbols/SymbolUtils";
/**
* Pure function to create the error message
*
* @param fieldName - The field name
* @param structName - The containing struct name
* @returns The formatted error message
*/
function formatStructFieldError(fieldName: string, structName: string): string {
return (
`Struct field '${fieldName}' in '${structName}' uses a reserved C-Next property name. ` +
`The '.${fieldName}' property is built-in and will shadow this field.`
);
}
/**
* Listener that walks the parse tree to find struct field naming violations
*/
class StructFieldListener extends CNextListener {
private readonly analyzer: StructFieldAnalyzer;
constructor(analyzer: StructFieldAnalyzer) {
super();
this.analyzer = analyzer;
}
override enterStructDeclaration = (
ctx: Parser.StructDeclarationContext,
): void => {
const structName = ctx.IDENTIFIER().getText();
const members = ctx.structMember();
for (const member of members) {
const fieldIdentifier = member.IDENTIFIER();
const fieldName = fieldIdentifier.getText();
const line = fieldIdentifier.symbol.line;
const column = fieldIdentifier.symbol.column;
if (SymbolUtils.isReservedFieldName(fieldName)) {
this.analyzer.addError(structName, fieldName, line, column);
}
}
};
}
/**
* Analyzer for struct field naming violations
*/
class StructFieldAnalyzer {
private errors: IStructFieldError[] = [];
/**
* Analyze the parse tree for struct field naming violations
*
* @param tree - The parsed program AST
* @returns Array of errors (empty if all pass)
*/
public analyze(tree: Parser.ProgramContext): IStructFieldError[] {
this.errors = [];
const listener = new StructFieldListener(this);
ParseTreeWalker.DEFAULT.walk(listener, tree);
return this.errors;
}
/**
* Add a struct field naming error
*/
public addError(
structName: string,
fieldName: string,
line: number,
column: number,
): void {
const reservedNames = SymbolUtils.getReservedFieldNames().join(", ");
this.errors.push({
code: "E0355",
structName,
fieldName,
line,
column,
message: formatStructFieldError(fieldName, structName),
helpText: `Reserved field names: ${reservedNames}. Consider using 'len', 'size', or 'count' instead.`,
});
}
}
export default StructFieldAnalyzer;
|