"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _lodash = _interopRequireDefault(require("lodash"));
var _eslint = require("eslint");
var _iterateJsdoc = _interopRequireDefault(require("../iterateJsdoc"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
var zeroBasedLineIndexAdjust = -1;
var likelyNestedJSDocIndentSpace = 1;
var preTagSpaceLength = 1;
var hasCaptionRegex = /^\s*
.*?<\/caption>/;
var escapeStringRegexp = function escapeStringRegexp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
};
var countChars = function countChars(str, ch) {
return (str.match(new RegExp(escapeStringRegexp(ch), 'g')) || []).length;
};
var _default = (0, _iterateJsdoc.default)(function (_ref) {
var jsdoc = _ref.jsdoc,
report = _ref.report,
utils = _ref.utils;
var exampleCodeRegex = utils.getExampleCodeRegex();
var rejectExampleCodeRegex = utils.getRejectExampleCodeRegex();
var noDefaultExampleRules = utils.hasNoDefaultExampleRules();
var eslintrcForExamples = utils.useEslintrcForExamples();
var filename = utils.getMatchingFileName();
var baseConfig = utils.getBaseConfig();
var configFile = utils.getConfigFile();
var allowInlineConfig = utils.allowInlineConfig();
var reportUnusedDisableDirectives = utils.reportUnusedDisableDirectives(); // Make this configurable?
var rulePaths = [];
var rules = noDefaultExampleRules ? undefined : {
// "always" newline rule at end unlikely in sample code
'eol-last': 0,
// Wouldn't generally expect example paths to resolve relative to JS file
'import/no-unresolved': 0,
// Snippets likely too short to always include import/export info
'import/unambiguous': 0,
// Unlikely to have inadvertent debugging within examples
'no-console': 0,
// Many variables in examples will be `undefined`
'no-undef': 0,
// Common to define variables for clarity without always using them
'no-unused-vars': 0,
// See import/no-unresolved
'node/no-missing-import': 0,
'node/no-missing-require': 0,
// Can generally look nicer to pad a little even if code imposes more stringency
'padded-blocks': 0
};
exampleCodeRegex = exampleCodeRegex && new RegExp(exampleCodeRegex, '');
rejectExampleCodeRegex = rejectExampleCodeRegex && new RegExp(rejectExampleCodeRegex, '');
_lodash.default.forEach(jsdoc.tags, function (tag) {
if (tag.tag !== 'example') {
return;
} // If a space is present, we should ignore it
var initialTag = tag.source.match(/^@example ?/);
var initialTagLength = initialTag[0].length;
var firstLinePrefixLength = preTagSpaceLength + initialTagLength;
var source = tag.source.slice(initialTagLength);
var match = source.match(hasCaptionRegex);
if (utils.isCaptionRequired() && !match) {
report('Caption is expected for examples.', null, tag);
} // If we allow newlines in hasCaptionRegex, we should add to line count
source = source.replace(hasCaptionRegex, '');
if (exampleCodeRegex && !exampleCodeRegex.test(source) || rejectExampleCodeRegex && rejectExampleCodeRegex.test(source)) {
return;
}
var nonJSPrefacingLines = 0;
var nonJSPrefacingCols = 0;
if (exampleCodeRegex) {
var idx = source.search(exampleCodeRegex); // Strip out anything preceding user regex match (can affect line numbering)
var preMatchLines = 0;
var preMatch = source.slice(0, idx);
preMatchLines = countChars(preMatch, '\n');
nonJSPrefacingLines = preMatchLines;
var colDelta = preMatchLines ? preMatch.slice(preMatch.lastIndexOf('\n') + 1).length - initialTagLength : preMatch.length; // Get rid of text preceding user regex match (even if it leaves valid JS, it
// could cause us to count newlines twice)
source = source.slice(idx);
source = source.replace(exampleCodeRegex, function (n0, n1) {
if (!n1) {
return n0;
}
var index = n0.indexOf(n1);
var nonJSPreface = n0.slice(0, index);
var nonJSPrefaceLineCount = countChars(nonJSPreface, '\n');
nonJSPrefacingLines += nonJSPrefaceLineCount; // Ignore `preMatch` delta if newlines here
if (nonJSPrefaceLineCount) {
var charsInLastLine = nonJSPreface.slice(nonJSPreface.lastIndexOf('\n') + 1).length;
nonJSPrefacingCols += charsInLastLine - initialTagLength;
} else {
nonJSPrefacingCols += colDelta + nonJSPreface.length;
}
return n1;
});
} // Programmatic ESLint API: https://eslint.org/docs/developer-guide/nodejs-api
var cli = new _eslint.CLIEngine({
allowInlineConfig,
baseConfig,
configFile,
reportUnusedDisableDirectives,
rulePaths,
rules,
useEslintrc: eslintrcForExamples
});
var messages;
if (filename) {
var config = cli.getConfigForFile(filename);
var linter = new _eslint.Linter();
var linterRules = _toConsumableArray(cli.getRules().entries()).reduce(function (obj, _ref2) {
var _ref3 = _slicedToArray(_ref2, 2),
key = _ref3[0],
val = _ref3[1];
obj[key] = val;
return obj;
}, {});
linter.defineRules(linterRules);
messages = linter.verify(source, config, {
filename,
reportUnusedDisableDirectives
});
} else {
var _cli$executeOnText = cli.executeOnText(source);
var _cli$executeOnText$re = _slicedToArray(_cli$executeOnText.results, 1);
messages = _cli$executeOnText$re[0].messages;
} // NOTE: `tag.line` can be 0 if of form `/** @tag ... */`
var codeStartLine = tag.line + nonJSPrefacingLines;
var codeStartCol = likelyNestedJSDocIndentSpace;
messages.forEach(function (_ref4) {
var message = _ref4.message,
line = _ref4.line,
column = _ref4.column,
severity = _ref4.severity,
ruleId = _ref4.ruleId;
var startLine = codeStartLine + line + zeroBasedLineIndexAdjust;
var startCol = codeStartCol + ( // This might not work for line 0, but line 0 is unlikely for examples
line <= 1 ? nonJSPrefacingCols + firstLinePrefixLength : preTagSpaceLength) + column; // Could perhaps make fixable
report('@example ' + (severity === 2 ? 'error' : 'warning') + (ruleId ? ' (' + ruleId + ')' : '') + ': ' + message, null, {
column: startCol,
line: startLine
});
});
});
});
exports.default = _default;
module.exports = exports.default;
//# sourceMappingURL=checkExamples.js.map