UNPKG

chevrotain

Version:

Chevrotain is a high performance fault tolerant javascript parsing DSL for building recursive decent parsers

116 lines 6.26 kB
"use strict"; 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