chevrotain
Version:
Chevrotain is a high performance fault tolerant javascript parsing DSL for building recursive decent parsers
116 lines • 6.26 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateRedundantMethods = exports.validateMissingCstMethods = exports.validateVisitor = exports.CstVisitorDefinitionError = exports.createBaseVisitorConstructorWithDefaults = exports.createBaseSemanticVisitorConstructor = exports.defaultVisit = void 0;
var utils_1 = require("../../utils/utils");
var lang_extensions_1 = require("../../lang/lang_extensions");
function defaultVisit(ctx, param) {
var childrenNames = utils_1.keys(ctx);
var childrenNamesLength = childrenNames.length;
for (var i = 0; i < childrenNamesLength; i++) {
var currChildName = childrenNames[i];
var currChildArray = ctx[currChildName];
var currChildArrayLength = currChildArray.length;
for (var j = 0; j < currChildArrayLength; j++) {
var currChild = currChildArray[j];
// distinction between Tokens Children and CstNode children
if (currChild.tokenTypeIdx === undefined) {
this[currChild.name](currChild.children, param);
}
}
}
// defaultVisit does not support generic out param
return undefined;
}
exports.defaultVisit = defaultVisit;
function createBaseSemanticVisitorConstructor(grammarName, ruleNames) {
var derivedConstructor = function () { };
// can be overwritten according to:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/
// name?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fname
lang_extensions_1.defineNameProp(derivedConstructor, grammarName + "BaseSemantics");
var semanticProto = {
visit: function (cstNode, param) {
// enables writing more concise visitor methods when CstNode has only a single child
if (utils_1.isArray(cstNode)) {
// A CST Node's children dictionary can never have empty arrays as values
// If a key is defined there will be at least one element in the corresponding value array.
cstNode = cstNode[0];
}
// enables passing optional CstNodes concisely.
if (utils_1.isUndefined(cstNode)) {
return undefined;
}
return this[cstNode.name](cstNode.children, param);
},
validateVisitor: function () {
var semanticDefinitionErrors = validateVisitor(this, ruleNames);
if (!utils_1.isEmpty(semanticDefinitionErrors)) {
var errorMessages = utils_1.map(semanticDefinitionErrors, function (currDefError) { return currDefError.msg; });
throw Error("Errors Detected in CST Visitor <" + lang_extensions_1.functionName(this.constructor) + ">:\n\t" + ("" + errorMessages.join("\n\n").replace(/\n/g, "\n\t")));
}
}
};
derivedConstructor.prototype = semanticProto;
derivedConstructor.prototype.constructor = derivedConstructor;
derivedConstructor._RULE_NAMES = ruleNames;
return derivedConstructor;
}
exports.createBaseSemanticVisitorConstructor = createBaseSemanticVisitorConstructor;
function createBaseVisitorConstructorWithDefaults(grammarName, ruleNames, baseConstructor) {
var derivedConstructor = function () { };
// can be overwritten according to:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/
// name?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fname
lang_extensions_1.defineNameProp(derivedConstructor, grammarName + "BaseSemanticsWithDefaults");
var withDefaultsProto = Object.create(baseConstructor.prototype);
utils_1.forEach(ruleNames, function (ruleName) {
withDefaultsProto[ruleName] = defaultVisit;
});
derivedConstructor.prototype = withDefaultsProto;
derivedConstructor.prototype.constructor = derivedConstructor;
return derivedConstructor;
}
exports.createBaseVisitorConstructorWithDefaults = createBaseVisitorConstructorWithDefaults;
var CstVisitorDefinitionError;
(function (CstVisitorDefinitionError) {
CstVisitorDefinitionError[CstVisitorDefinitionError["REDUNDANT_METHOD"] = 0] = "REDUNDANT_METHOD";
CstVisitorDefinitionError[CstVisitorDefinitionError["MISSING_METHOD"] = 1] = "MISSING_METHOD";
})(CstVisitorDefinitionError = exports.CstVisitorDefinitionError || (exports.CstVisitorDefinitionError = {}));
function validateVisitor(visitorInstance, ruleNames) {
var missingErrors = validateMissingCstMethods(visitorInstance, ruleNames);
var redundantErrors = validateRedundantMethods(visitorInstance, ruleNames);
return missingErrors.concat(redundantErrors);
}
exports.validateVisitor = validateVisitor;
function validateMissingCstMethods(visitorInstance, ruleNames) {
var errors = utils_1.map(ruleNames, function (currRuleName) {
if (!utils_1.isFunction(visitorInstance[currRuleName])) {
return {
msg: "Missing visitor method: <" + currRuleName + "> on " + lang_extensions_1.functionName(visitorInstance.constructor) + " CST Visitor.",
type: CstVisitorDefinitionError.MISSING_METHOD,
methodName: currRuleName
};
}
});
return utils_1.compact(errors);
}
exports.validateMissingCstMethods = validateMissingCstMethods;
var VALID_PROP_NAMES = ["constructor", "visit", "validateVisitor"];
function validateRedundantMethods(visitorInstance, ruleNames) {
var errors = [];
for (var prop in visitorInstance) {
if (utils_1.isFunction(visitorInstance[prop]) &&
!utils_1.contains(VALID_PROP_NAMES, prop) &&
!utils_1.contains(ruleNames, prop)) {
errors.push({
msg: "Redundant visitor method: <" + prop + "> on " + lang_extensions_1.functionName(visitorInstance.constructor) + " CST Visitor\n" +
"There is no Grammar Rule corresponding to this method's name.\n",
type: CstVisitorDefinitionError.REDUNDANT_METHOD,
methodName: prop
});
}
}
return errors;
}
exports.validateRedundantMethods = validateRedundantMethods;
//# sourceMappingURL=cst_visitor.js.map
;