UNPKG

chevrotain

Version:

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

129 lines 6.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var utils_1 = require("../../utils/utils"); var lang_extensions_1 = require("../../lang/lang_extensions"); var checks_1 = require("../grammar/checks"); 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) { if (currChild.fullName !== undefined) { this[currChild.fullName](currChild.children, param); } else { 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)) { if (cstNode.length > 0) { cstNode = cstNode[0]; } else { // enables passing optional CstNodes concisely. return undefined; } } if (cstNode.fullName !== undefined) { return this[cstNode.fullName](cstNode.children, param); } else { 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 (checks_1.validTermsPattern.test(prop) && 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" + ("For utility methods on visitor classes use methods names that do not match /" + checks_1.validTermsPattern.source + "/."), type: CstVisitorDefinitionError.REDUNDANT_METHOD, methodName: prop }); } } return errors; } exports.validateRedundantMethods = validateRedundantMethods; //# sourceMappingURL=cst_visitor.js.map