norminette-mcp
Version:
MCP server for 42 School norminette coding standard checker
62 lines (61 loc) • 2.05 kB
JavaScript
import { CLexer } from "../../../lexer/lexer.js";
import { TokenType } from "../../../lexer/token.js";
export class NorminetteFormatter {
rules = [];
constructor() {
// Initialize with default rules (empty for now)
}
addRule(rule) {
this.rules.push(rule);
this.rules.sort((a, b) => a.priority - b.priority);
}
format(content, errors) {
// Step 1: Tokenize the input
const lexer = new CLexer(content);
let tokens = lexer.tokenize();
// Step 2: Apply formatting rules to tokens
for (const rule of this.rules) {
for (const error of errors) {
if (rule.errorCodes.includes(error.error_code) && rule.canFix(tokens, error)) {
tokens = rule.apply(tokens, error);
}
}
}
// Step 3: Reconstruct source code from tokens
return this.reconstructSource(tokens);
}
reconstructSource(tokens) {
let result = '';
for (const token of tokens) {
if (token.type === TokenType.EOF) {
break;
}
// For most tokens, just append their value
if (token.value !== undefined) {
result += token.value;
}
}
return result;
}
getAvailableRules() {
return this.rules.map(rule => rule.name);
}
getRulesByErrorCode(errorCode) {
return this.rules.filter(rule => rule.errorCodes.includes(errorCode));
}
// Utility method to find token at specific line/column
findTokenAtPosition(tokens, line, column) {
for (const token of tokens) {
if (token.lineno === line &&
token.column <= column &&
token.column + token.length > column) {
return token;
}
}
return null;
}
// Utility method to find tokens on a specific line
getTokensOnLine(tokens, line) {
return tokens.filter(token => token.lineno === line);
}
}