Actualizacion maquina principal
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / padded-blocks.js
diff --git a/.config/coc/extensions/node_modules/coc-prettier/node_modules/eslint/lib/rules/padded-blocks.js b/.config/coc/extensions/node_modules/coc-prettier/node_modules/eslint/lib/rules/padded-blocks.js
new file mode 100644 (file)
index 0000000..dafa881
--- /dev/null
@@ -0,0 +1,282 @@
+/**
+ * @fileoverview A rule to ensure blank lines within blocks.
+ * @author Mathias Schreck <https://github.com/lo1tuma>
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const astUtils = require("./utils/ast-utils");
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+    meta: {
+        type: "layout",
+
+        docs: {
+            description: "require or disallow padding within blocks",
+            category: "Stylistic Issues",
+            recommended: false,
+            url: "https://eslint.org/docs/rules/padded-blocks"
+        },
+
+        fixable: "whitespace",
+
+        schema: [
+            {
+                oneOf: [
+                    {
+                        enum: ["always", "never"]
+                    },
+                    {
+                        type: "object",
+                        properties: {
+                            blocks: {
+                                enum: ["always", "never"]
+                            },
+                            switches: {
+                                enum: ["always", "never"]
+                            },
+                            classes: {
+                                enum: ["always", "never"]
+                            }
+                        },
+                        additionalProperties: false,
+                        minProperties: 1
+                    }
+                ]
+            },
+            {
+                type: "object",
+                properties: {
+                    allowSingleLineBlocks: {
+                        type: "boolean"
+                    }
+                }
+            }
+        ]
+    },
+
+    create(context) {
+        const options = {};
+        const typeOptions = context.options[0] || "always";
+        const exceptOptions = context.options[1] || {};
+
+        if (typeof typeOptions === "string") {
+            const shouldHavePadding = typeOptions === "always";
+
+            options.blocks = shouldHavePadding;
+            options.switches = shouldHavePadding;
+            options.classes = shouldHavePadding;
+        } else {
+            if (Object.prototype.hasOwnProperty.call(typeOptions, "blocks")) {
+                options.blocks = typeOptions.blocks === "always";
+            }
+            if (Object.prototype.hasOwnProperty.call(typeOptions, "switches")) {
+                options.switches = typeOptions.switches === "always";
+            }
+            if (Object.prototype.hasOwnProperty.call(typeOptions, "classes")) {
+                options.classes = typeOptions.classes === "always";
+            }
+        }
+
+        if (Object.prototype.hasOwnProperty.call(exceptOptions, "allowSingleLineBlocks")) {
+            options.allowSingleLineBlocks = exceptOptions.allowSingleLineBlocks === true;
+        }
+
+        const ALWAYS_MESSAGE = "Block must be padded by blank lines.",
+            NEVER_MESSAGE = "Block must not be padded by blank lines.";
+
+        const sourceCode = context.getSourceCode();
+
+        /**
+         * Gets the open brace token from a given node.
+         * @param {ASTNode} node A BlockStatement or SwitchStatement node from which to get the open brace.
+         * @returns {Token} The token of the open brace.
+         */
+        function getOpenBrace(node) {
+            if (node.type === "SwitchStatement") {
+                return sourceCode.getTokenBefore(node.cases[0]);
+            }
+            return sourceCode.getFirstToken(node);
+        }
+
+        /**
+         * Checks if the given parameter is a comment node
+         * @param {ASTNode|Token} node An AST node or token
+         * @returns {boolean} True if node is a comment
+         */
+        function isComment(node) {
+            return node.type === "Line" || node.type === "Block";
+        }
+
+        /**
+         * Checks if there is padding between two tokens
+         * @param {Token} first The first token
+         * @param {Token} second The second token
+         * @returns {boolean} True if there is at least a line between the tokens
+         */
+        function isPaddingBetweenTokens(first, second) {
+            return second.loc.start.line - first.loc.end.line >= 2;
+        }
+
+
+        /**
+         * Checks if the given token has a blank line after it.
+         * @param {Token} token The token to check.
+         * @returns {boolean} Whether or not the token is followed by a blank line.
+         */
+        function getFirstBlockToken(token) {
+            let prev,
+                first = token;
+
+            do {
+                prev = first;
+                first = sourceCode.getTokenAfter(first, { includeComments: true });
+            } while (isComment(first) && first.loc.start.line === prev.loc.end.line);
+
+            return first;
+        }
+
+        /**
+         * Checks if the given token is preceeded by a blank line.
+         * @param {Token} token The token to check
+         * @returns {boolean} Whether or not the token is preceeded by a blank line
+         */
+        function getLastBlockToken(token) {
+            let last = token,
+                next;
+
+            do {
+                next = last;
+                last = sourceCode.getTokenBefore(last, { includeComments: true });
+            } while (isComment(last) && last.loc.end.line === next.loc.start.line);
+
+            return last;
+        }
+
+        /**
+         * Checks if a node should be padded, according to the rule config.
+         * @param {ASTNode} node The AST node to check.
+         * @returns {boolean} True if the node should be padded, false otherwise.
+         */
+        function requirePaddingFor(node) {
+            switch (node.type) {
+                case "BlockStatement":
+                    return options.blocks;
+                case "SwitchStatement":
+                    return options.switches;
+                case "ClassBody":
+                    return options.classes;
+
+                /* istanbul ignore next */
+                default:
+                    throw new Error("unreachable");
+            }
+        }
+
+        /**
+         * Checks the given BlockStatement node to be padded if the block is not empty.
+         * @param {ASTNode} node The AST node of a BlockStatement.
+         * @returns {void} undefined.
+         */
+        function checkPadding(node) {
+            const openBrace = getOpenBrace(node),
+                firstBlockToken = getFirstBlockToken(openBrace),
+                tokenBeforeFirst = sourceCode.getTokenBefore(firstBlockToken, { includeComments: true }),
+                closeBrace = sourceCode.getLastToken(node),
+                lastBlockToken = getLastBlockToken(closeBrace),
+                tokenAfterLast = sourceCode.getTokenAfter(lastBlockToken, { includeComments: true }),
+                blockHasTopPadding = isPaddingBetweenTokens(tokenBeforeFirst, firstBlockToken),
+                blockHasBottomPadding = isPaddingBetweenTokens(lastBlockToken, tokenAfterLast);
+
+            if (options.allowSingleLineBlocks && astUtils.isTokenOnSameLine(tokenBeforeFirst, tokenAfterLast)) {
+                return;
+            }
+
+            if (requirePaddingFor(node)) {
+                if (!blockHasTopPadding) {
+                    context.report({
+                        node,
+                        loc: { line: tokenBeforeFirst.loc.start.line, column: tokenBeforeFirst.loc.start.column },
+                        fix(fixer) {
+                            return fixer.insertTextAfter(tokenBeforeFirst, "\n");
+                        },
+                        message: ALWAYS_MESSAGE
+                    });
+                }
+                if (!blockHasBottomPadding) {
+                    context.report({
+                        node,
+                        loc: { line: tokenAfterLast.loc.end.line, column: tokenAfterLast.loc.end.column - 1 },
+                        fix(fixer) {
+                            return fixer.insertTextBefore(tokenAfterLast, "\n");
+                        },
+                        message: ALWAYS_MESSAGE
+                    });
+                }
+            } else {
+                if (blockHasTopPadding) {
+
+                    context.report({
+                        node,
+                        loc: { line: tokenBeforeFirst.loc.start.line, column: tokenBeforeFirst.loc.start.column },
+                        fix(fixer) {
+                            return fixer.replaceTextRange([tokenBeforeFirst.range[1], firstBlockToken.range[0] - firstBlockToken.loc.start.column], "\n");
+                        },
+                        message: NEVER_MESSAGE
+                    });
+                }
+
+                if (blockHasBottomPadding) {
+
+                    context.report({
+                        node,
+                        loc: { line: tokenAfterLast.loc.end.line, column: tokenAfterLast.loc.end.column - 1 },
+                        message: NEVER_MESSAGE,
+                        fix(fixer) {
+                            return fixer.replaceTextRange([lastBlockToken.range[1], tokenAfterLast.range[0] - tokenAfterLast.loc.start.column], "\n");
+                        }
+                    });
+                }
+            }
+        }
+
+        const rule = {};
+
+        if (Object.prototype.hasOwnProperty.call(options, "switches")) {
+            rule.SwitchStatement = function(node) {
+                if (node.cases.length === 0) {
+                    return;
+                }
+                checkPadding(node);
+            };
+        }
+
+        if (Object.prototype.hasOwnProperty.call(options, "blocks")) {
+            rule.BlockStatement = function(node) {
+                if (node.body.length === 0) {
+                    return;
+                }
+                checkPadding(node);
+            };
+        }
+
+        if (Object.prototype.hasOwnProperty.call(options, "classes")) {
+            rule.ClassBody = function(node) {
+                if (node.body.length === 0) {
+                    return;
+                }
+                checkPadding(node);
+            };
+        }
+
+        return rule;
+    }
+};