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 | 1173x 1173x 10x 1173x 151x 151x 8x 151x 151x 1x 150x 150x 1x 149x 149x 139x 149x 2x 147x 147x 1x 146x 146x 1x 145x 145x 2x 143x 143x 1x 142x 142x 1x 142x | /**
* Run all semantic analyzers on a parsed C-Next program
*
* Extracted from transpiler.ts for reuse in the unified pipeline.
* All 8 analyzers run in sequence, each returning errors that block compilation.
*/
import { CommonTokenStream } from "antlr4ng";
import { ProgramContext } from "../parser/grammar/CNextParser";
import ParameterNamingAnalyzer from "./ParameterNamingAnalyzer";
import StructFieldAnalyzer from "./StructFieldAnalyzer";
import InitializationAnalyzer from "./InitializationAnalyzer";
import FunctionCallAnalyzer from "./FunctionCallAnalyzer";
import NullCheckAnalyzer from "./NullCheckAnalyzer";
import DivisionByZeroAnalyzer from "./DivisionByZeroAnalyzer";
import FloatModuloAnalyzer from "./FloatModuloAnalyzer";
import CommentExtractor from "./CommentExtractor";
import ITranspileError from "../../../lib/types/ITranspileError";
import SymbolTable from "../symbols/SymbolTable";
/**
* Options for running analyzers
*/
interface IAnalyzerOptions {
/**
* External struct field information from C/C++ headers
* Maps struct name -> Set of field names
*/
externalStructFields?: Map<string, Set<string>>;
/**
* Symbol table containing external function definitions from C/C++ headers
* Used by FunctionCallAnalyzer to recognize external functions
*/
symbolTable?: SymbolTable;
}
/**
* Generic analyzer error with common fields
*/
interface IAnalyzerError {
line: number;
column: number;
message: string;
code?: string;
rule?: string;
}
/**
* Convert analyzer errors to ITranspileError format and add to accumulator.
* Returns true if any errors were added (for early return logic).
*/
function collectErrors(
analyzerErrors: IAnalyzerError[],
target: ITranspileError[],
formatMessage?: (err: IAnalyzerError) => string,
): boolean {
const formatter = formatMessage ?? ((e) => e.message);
for (const err of analyzerErrors) {
target.push({
line: err.line,
column: err.column,
message: formatter(err),
severity: "error",
});
}
return analyzerErrors.length > 0;
}
/**
* Run all semantic analyzers on a parsed program
*
* @param tree - The parsed program AST
* @param tokenStream - Token stream for comment validation
* @param options - Optional configuration including external struct info
* @returns Array of errors (empty if all pass)
*/
function runAnalyzers(
tree: ProgramContext,
tokenStream: CommonTokenStream,
options?: IAnalyzerOptions,
): ITranspileError[] {
const errors: ITranspileError[] = [];
const formatWithCode = (e: IAnalyzerError) =>
`error[${e.code}]: ${e.message}`;
// 1. Parameter naming validation (Issue #227: reserved naming patterns)
const paramNamingAnalyzer = new ParameterNamingAnalyzer();
if (collectErrors(paramNamingAnalyzer.analyze(tree), errors)) {
return errors;
}
// 2. Struct field validation (reserved field names like 'length')
const structFieldAnalyzer = new StructFieldAnalyzer();
if (
collectErrors(structFieldAnalyzer.analyze(tree), errors, formatWithCode)
) {
return errors;
}
// 3. Initialization analysis (Rust-style use-before-init detection)
const initAnalyzer = new InitializationAnalyzer();
if (options?.externalStructFields) {
initAnalyzer.registerExternalStructFields(options.externalStructFields);
}
// Issue #503: Pass symbol table so C++ classes with default constructors are recognized
if (
collectErrors(
initAnalyzer.analyze(tree, options?.symbolTable),
errors,
formatWithCode,
)
) {
return errors;
}
// 4. Call analysis (ADR-030: define-before-use)
const funcAnalyzer = new FunctionCallAnalyzer();
if (
collectErrors(
funcAnalyzer.analyze(tree, options?.symbolTable),
errors,
formatWithCode,
)
) {
return errors;
}
// 5. NULL check analysis (ADR-047: C library interop)
const nullAnalyzer = new NullCheckAnalyzer();
if (collectErrors(nullAnalyzer.analyze(tree), errors, formatWithCode)) {
return errors;
}
// 6. Division by zero analysis (ADR-051: compile-time detection)
const divZeroAnalyzer = new DivisionByZeroAnalyzer();
if (collectErrors(divZeroAnalyzer.analyze(tree), errors, formatWithCode)) {
return errors;
}
// 7. Float modulo analysis (catch % with f32/f64 early)
const floatModAnalyzer = new FloatModuloAnalyzer();
if (collectErrors(floatModAnalyzer.analyze(tree), errors, formatWithCode)) {
return errors;
}
// 8. Comment validation (MISRA C:2012 Rules 3.1, 3.2) - ADR-043
const commentExtractor = new CommentExtractor(tokenStream);
collectErrors(
commentExtractor.validate(),
errors,
(e) => `error[MISRA-${e.rule}]: ${e.message}`,
);
return errors;
}
export default runAnalyzers;
|