consys
Version:
consys is a flexible tool to evaluate models using generic and readable constraints.
93 lines (92 loc) • 3.67 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Util_1 = require("./Util");
const Lexer_1 = __importDefault(require("./dsl/Lexer"));
const Parser_1 = __importDefault(require("./dsl/Parser"));
const Emitter_1 = __importDefault(require("./dsl/Emitter"));
const FunctionGenerator_1 = __importDefault(require("./ignoreCoverage/FunctionGenerator"));
const TextProcessor_1 = __importDefault(require("./dsl/TextProcessor"));
/**
* Represents a single constraint, with specified model and state data types.
*/
class Constraint {
/**
* Create a new constraint from constraint data.
*
* @param resource constraint data
*/
constructor(resource) {
this.resource = resource;
const tokens = new Lexer_1.default(resource.constraint).scan();
this.ast = new Parser_1.default(resource.constraint, tokens).parse();
const js = new Emitter_1.default(this.ast).emit();
this.assertionFunction = FunctionGenerator_1.default.generateFromString(js);
}
/**
* Returns a map of the number of occurrences for each key of the model.
*/
getModelVarOccurrences() {
return this.ast.statistics.counts.model;
}
/**
* Returns a map of the number of occurrences for each key of the state.
*/
getStateVarOccurrences() {
return this.ast.statistics.counts.state;
}
/**
* Evaluate this constraint with a given model and state, along with custom functions.
*
* @param data data to evaluate, along with functions
* @param rescan determine if the text processor should rescan if something has changed
*/
evaluate(data, rescan) {
if (!this.textProcessor) {
this.textProcessor = new TextProcessor_1.default(!!this.resource.message ? this.resource.message : '', data.functions);
}
try {
const consistent = this.isConsistent(data);
return {
consistent: consistent,
message: consistent || !this.resource.message
? ''
: this.textProcessor.process(data.model, data.state, data.functions, rescan),
resource: this.resource,
};
}
catch (error) {
const errorVariable = error.message;
const variable = errorVariable.substring(1);
const isModel = errorVariable.startsWith('$');
const type = isModel ? 'model' : 'state';
const provided = isModel ? data.model : data.state;
const position = this.resource.constraint.indexOf(variable);
Util_1.Log.reportError('Evaluation', this.resource.constraint, `Attribute '${variable}' not found in ${type}: ${JSON.stringify(provided)}`, position);
return {
consistent: false,
message: !this.resource.message
? ''
: this.textProcessor.process(data.model, data.state, data.functions, rescan),
resource: this.resource,
};
}
}
/**
* Checks if this constraint is consistent with given model, state and functions.
*
* @param data data to evaluate, along with functions
*/
isConsistent(data) {
return this.assertionFunction.apply(data, null);
}
/**
* Returns the original resource that was used to generate this constraint.
*/
getResource() {
return this.resource;
}
}
exports.default = Constraint;