Permalink
Cannot retrieve contributors at this time
151 lines (129 sloc)
6.17 KB
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
codeql-action/node_modules/eslint/lib/rules/no-multiple-empty-lines.js
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @fileoverview Disallows multiple blank lines. | |
* implementation adapted from the no-trailing-spaces rule. | |
* @author Greg Cochard | |
*/ | |
"use strict"; | |
//------------------------------------------------------------------------------ | |
// Rule Definition | |
//------------------------------------------------------------------------------ | |
/** @type {import('../shared/types').Rule} */ | |
module.exports = { | |
meta: { | |
type: "layout", | |
docs: { | |
description: "Disallow multiple empty lines", | |
recommended: false, | |
url: "https://eslint.org/docs/latest/rules/no-multiple-empty-lines" | |
}, | |
fixable: "whitespace", | |
schema: [ | |
{ | |
type: "object", | |
properties: { | |
max: { | |
type: "integer", | |
minimum: 0 | |
}, | |
maxEOF: { | |
type: "integer", | |
minimum: 0 | |
}, | |
maxBOF: { | |
type: "integer", | |
minimum: 0 | |
} | |
}, | |
required: ["max"], | |
additionalProperties: false | |
} | |
], | |
messages: { | |
blankBeginningOfFile: "Too many blank lines at the beginning of file. Max of {{max}} allowed.", | |
blankEndOfFile: "Too many blank lines at the end of file. Max of {{max}} allowed.", | |
consecutiveBlank: "More than {{max}} blank {{pluralizedLines}} not allowed." | |
} | |
}, | |
create(context) { | |
// Use options.max or 2 as default | |
let max = 2, | |
maxEOF = max, | |
maxBOF = max; | |
if (context.options.length) { | |
max = context.options[0].max; | |
maxEOF = typeof context.options[0].maxEOF !== "undefined" ? context.options[0].maxEOF : max; | |
maxBOF = typeof context.options[0].maxBOF !== "undefined" ? context.options[0].maxBOF : max; | |
} | |
const sourceCode = context.sourceCode; | |
// Swallow the final newline, as some editors add it automatically and we don't want it to cause an issue | |
const allLines = sourceCode.lines[sourceCode.lines.length - 1] === "" ? sourceCode.lines.slice(0, -1) : sourceCode.lines; | |
const templateLiteralLines = new Set(); | |
//-------------------------------------------------------------------------- | |
// Public | |
//-------------------------------------------------------------------------- | |
return { | |
TemplateLiteral(node) { | |
node.quasis.forEach(literalPart => { | |
// Empty lines have a semantic meaning if they're inside template literals. Don't count these as empty lines. | |
for (let ignoredLine = literalPart.loc.start.line; ignoredLine < literalPart.loc.end.line; ignoredLine++) { | |
templateLiteralLines.add(ignoredLine); | |
} | |
}); | |
}, | |
"Program:exit"(node) { | |
return allLines | |
// Given a list of lines, first get a list of line numbers that are non-empty. | |
.reduce((nonEmptyLineNumbers, line, index) => { | |
if (line.trim() || templateLiteralLines.has(index + 1)) { | |
nonEmptyLineNumbers.push(index + 1); | |
} | |
return nonEmptyLineNumbers; | |
}, []) | |
// Add a value at the end to allow trailing empty lines to be checked. | |
.concat(allLines.length + 1) | |
// Given two line numbers of non-empty lines, report the lines between if the difference is too large. | |
.reduce((lastLineNumber, lineNumber) => { | |
let messageId, maxAllowed; | |
if (lastLineNumber === 0) { | |
messageId = "blankBeginningOfFile"; | |
maxAllowed = maxBOF; | |
} else if (lineNumber === allLines.length + 1) { | |
messageId = "blankEndOfFile"; | |
maxAllowed = maxEOF; | |
} else { | |
messageId = "consecutiveBlank"; | |
maxAllowed = max; | |
} | |
if (lineNumber - lastLineNumber - 1 > maxAllowed) { | |
context.report({ | |
node, | |
loc: { | |
start: { line: lastLineNumber + maxAllowed + 1, column: 0 }, | |
end: { line: lineNumber, column: 0 } | |
}, | |
messageId, | |
data: { | |
max: maxAllowed, | |
pluralizedLines: maxAllowed === 1 ? "line" : "lines" | |
}, | |
fix(fixer) { | |
const rangeStart = sourceCode.getIndexFromLoc({ line: lastLineNumber + 1, column: 0 }); | |
/* | |
* The end of the removal range is usually the start index of the next line. | |
* However, at the end of the file there is no next line, so the end of the | |
* range is just the length of the text. | |
*/ | |
const lineNumberAfterRemovedLines = lineNumber - maxAllowed; | |
const rangeEnd = lineNumberAfterRemovedLines <= allLines.length | |
? sourceCode.getIndexFromLoc({ line: lineNumberAfterRemovedLines, column: 0 }) | |
: sourceCode.text.length; | |
return fixer.removeRange([rangeStart, rangeEnd]); | |
} | |
}); | |
} | |
return lineNumber; | |
}, 0); | |
} | |
}; | |
} | |
}; |