eslint-plugin-stylistic-compat
Version:
Compatibility version of @stylistic/eslint-plugin for Node.js >= 12 and ESLint v8
368 lines (364 loc) • 14.7 kB
JavaScript
'use strict';
var _includesInstanceProperty = require('/runtime-corejs3/core-js/instance/includes');
var _Object$assign = require('/runtime-corejs3/core-js/object/assign');
var _sliceInstanceProperty = require('/runtime-corejs3/core-js/instance/slice');
var utils = require('../utils.js');
require('/runtime-corejs3/core-js/object/from-entries');
require('/runtime-corejs3/core-js/instance/map');
require('/runtime-corejs3/core-js/instance/filter');
require('/runtime-corejs3/core-js/object/entries');
require('/runtime-corejs3/core-js/set');
require('/runtime-corejs3/core-js/instance/flags');
require('/runtime-corejs3/core-js/instance/starts-with');
require('../vendor.js');
require('/runtime-corejs3/core-js/object/create');
require('/runtime-corejs3/core-js/object/freeze');
require('/runtime-corejs3/core-js/array/is-array');
require('/runtime-corejs3/core-js/instance/last-index-of');
require('/runtime-corejs3/core-js/object/define-properties');
require('/runtime-corejs3/core-js/object/keys');
require('/runtime-corejs3/core-js/instance/index-of');
require('/runtime-corejs3/core-js/instance/at');
require('/runtime-corejs3/core-js/symbol');
require('/runtime-corejs3/core-js/symbol/iterator');
require('/runtime-corejs3/core-js/parse-int');
require('/runtime-corejs3/core-js/parse-float');
require('/runtime-corejs3/core-js/weak-map');
require('/runtime-corejs3/core-js/object/define-property');
require('/runtime-corejs3/core-js/global-this');
require('/runtime-corejs3/core-js/instance/for-each');
require('/runtime-corejs3/core-js/array/from');
require('eslint/use-at-your-own-risk');
require('eslint');
require('/runtime-corejs3/core-js/object/get-own-property-descriptor');
require('/runtime-corejs3/core-js/map');
require('/runtime-corejs3/core-js/instance/some');
require('/runtime-corejs3/core-js/instance/find');
require('/runtime-corejs3/core-js/instance/every');
require('/runtime-corejs3/core-js/instance/sort');
require('/runtime-corejs3/core-js/array/of');
require('/runtime-corejs3/core-js/instance/concat');
require('/runtime-corejs3/core-js/instance/entries');
require('/runtime-corejs3/core-js/instance/find-index');
require('/runtime-corejs3/core-js/instance/flat');
require('/runtime-corejs3/core-js/instance/keys');
require('/runtime-corejs3/core-js/instance/values');
require('/runtime-corejs3/core-js/object/get-own-property-names');
require('/runtime-corejs3/core-js/number/is-finite');
require('/runtime-corejs3/core-js/number/is-nan');
require('/runtime-corejs3/core-js/number/parse-float');
require('/runtime-corejs3/core-js/number/parse-int');
require('/runtime-corejs3/core-js/object/is');
require('/runtime-corejs3/core-js/object/is-extensible');
require('/runtime-corejs3/core-js/object/is-frozen');
require('/runtime-corejs3/core-js/object/is-sealed');
require('/runtime-corejs3/core-js/object/values');
require('/runtime-corejs3/core-js/string/from-code-point');
require('/runtime-corejs3/core-js/string/raw');
require('/runtime-corejs3/core-js/instance/code-point-at');
require('/runtime-corejs3/core-js/instance/ends-with');
require('/runtime-corejs3/core-js/instance/pad-end');
require('/runtime-corejs3/core-js/instance/pad-start');
require('/runtime-corejs3/core-js/instance/trim');
require('/runtime-corejs3/core-js/instance/trim-end');
require('/runtime-corejs3/core-js/instance/trim-left');
require('/runtime-corejs3/core-js/instance/trim-right');
require('/runtime-corejs3/core-js/instance/trim-start');
require('/runtime-corejs3/core-js/symbol/for');
require('/runtime-corejs3/core-js/symbol/key-for');
require('/runtime-corejs3/core-js/object/prevent-extensions');
require('/runtime-corejs3/core-js/object/seal');
require('/runtime-corejs3/core-js/object/get-prototype-of');
require('/runtime-corejs3/core-js/symbol/replace');
require('/runtime-corejs3/core-js/instance/bind');
require('/runtime-corejs3/core-js/instance/splice');
require('/runtime-corejs3/core-js/instance/repeat');
require('/runtime-corejs3/core-js/instance/reduce');
require('/runtime-corejs3/core-js/instance/reverse');
const SPACING = {
always: "always",
never: "never"
};
const SPACING_VALUES = [SPACING.always, SPACING.never];
const messages = {
noNewlineAfter: "There should be no newline after '{{token}}'",
noNewlineBefore: "There should be no newline before '{{token}}'",
noSpaceAfter: "There should be no space after '{{token}}'",
noSpaceBefore: "There should be no space before '{{token}}'",
spaceNeededAfter: "A space is required after '{{token}}'",
spaceNeededBefore: "A space is required before '{{token}}'"
};
var jsxCurlySpacing = utils.createRule({
name: "jsx-curly-spacing",
package: "jsx",
meta: {
type: "layout",
docs: {
description: "Enforce or disallow spaces inside of curly braces in JSX attributes and expressions"
},
fixable: "code",
messages,
schema: {
definitions: {
basicConfig: {
type: "object",
properties: {
when: {
type: "string",
enum: SPACING_VALUES
},
allowMultiline: {
type: "boolean"
},
spacing: {
type: "object",
properties: {
objectLiterals: {
type: "string",
enum: SPACING_VALUES
}
}
}
}
},
basicConfigOrBoolean: {
anyOf: [{
$ref: "#/definitions/basicConfig"
}, {
type: "boolean"
}]
}
},
type: "array",
items: [{
anyOf: [{
allOf: [{
$ref: "#/definitions/basicConfig"
}, {
type: "object",
properties: {
attributes: {
$ref: "#/definitions/basicConfigOrBoolean"
},
children: {
$ref: "#/definitions/basicConfigOrBoolean"
}
}
}]
}, {
type: "string",
enum: SPACING_VALUES
}]
}, {
type: "object",
properties: {
allowMultiline: {
type: "boolean"
},
spacing: {
type: "object",
properties: {
objectLiterals: {
type: "string",
enum: SPACING_VALUES
}
}
}
},
additionalProperties: false
}]
}
},
create(context) {
function normalizeConfig(configOrTrue, defaults, lastPass = false) {
const config = configOrTrue === true ? {} : configOrTrue;
const when = config.when || defaults.when;
const allowMultiline = "allowMultiline" in config ? config.allowMultiline : defaults.allowMultiline;
const spacing = config.spacing || {};
let objectLiteralSpaces = spacing.objectLiterals || defaults.objectLiteralSpaces;
if (lastPass) {
objectLiteralSpaces = objectLiteralSpaces || when;
}
return {
when,
allowMultiline,
objectLiteralSpaces
};
}
const DEFAULT_WHEN = SPACING.never;
const DEFAULT_ALLOW_MULTILINE = true;
const DEFAULT_ATTRIBUTES = true;
const DEFAULT_CHILDREN = false;
let originalConfig = context.options[0] || {};
if (_includesInstanceProperty(SPACING_VALUES).call(SPACING_VALUES, originalConfig)) originalConfig = _Object$assign({
when: context.options[0]
}, context.options[1]);
originalConfig = originalConfig;
const defaultConfig = normalizeConfig(originalConfig, {
when: DEFAULT_WHEN,
allowMultiline: DEFAULT_ALLOW_MULTILINE
});
const attributes = "attributes" in originalConfig ? originalConfig.attributes : DEFAULT_ATTRIBUTES;
const attributesConfig = attributes ? normalizeConfig(attributes, defaultConfig, true) : null;
const children = "children" in originalConfig ? originalConfig.children : DEFAULT_CHILDREN;
const childrenConfig = children ? normalizeConfig(children, defaultConfig, true) : null;
function isMultiline(left, right) {
return left.loc.end.line !== right.loc.start.line;
}
function fixByTrimmingWhitespace(fixer, fromLoc, toLoc, mode, spacing = "") {
var _context;
let replacementText = _sliceInstanceProperty(_context = context.sourceCode.text).call(_context, fromLoc, toLoc);
if (mode === "start") replacementText = replacementText.replace(/^\s+/gm, "");else replacementText = replacementText.replace(/\s+$/gm, "");
if (spacing === SPACING.always) {
if (mode === "start") replacementText += " ";else replacementText = ` ${replacementText}`;
}
return fixer.replaceTextRange([fromLoc, toLoc], replacementText);
}
function reportNoBeginningNewline(node, token, spacing) {
context.report({
node,
loc: token.loc.start,
messageId: "noNewlineAfter",
data: {
token: token.value
},
fix(fixer) {
const nextToken = context.sourceCode.getTokenAfter(token);
return fixByTrimmingWhitespace(fixer, token.range[1], nextToken.range[0], "start", spacing);
}
});
}
function reportNoEndingNewline(node, token, spacing) {
context.report({
node,
loc: token.loc.start,
messageId: "noNewlineBefore",
data: {
token: token.value
},
fix(fixer) {
const previousToken = context.sourceCode.getTokenBefore(token);
return fixByTrimmingWhitespace(fixer, previousToken.range[1], token.range[0], "end", spacing);
}
});
}
function reportNoBeginningSpace(node, token) {
context.report({
node,
loc: token.loc.start,
messageId: "noSpaceAfter",
data: {
token: token.value
},
fix(fixer) {
const sourceCode = context.sourceCode;
const nextToken = sourceCode.getTokenAfter(token);
const nextComment = sourceCode.getCommentsAfter(token);
if (nextComment.length > 0) return fixByTrimmingWhitespace(fixer, token.range[1], Math.min(nextToken.range[0], nextComment[0].range[0]), "start");
return fixByTrimmingWhitespace(fixer, token.range[1], nextToken.range[0], "start");
}
});
}
function reportNoEndingSpace(node, token) {
context.report({
node,
loc: token.loc.start,
messageId: "noSpaceBefore",
data: {
token: token.value
},
fix(fixer) {
const sourceCode = context.sourceCode;
const previousToken = sourceCode.getTokenBefore(token);
const previousComment = sourceCode.getCommentsBefore(token);
if (previousComment.length > 0) return fixByTrimmingWhitespace(fixer, Math.max(previousToken.range[1], previousComment[0].range[1]), token.range[0], "end");
return fixByTrimmingWhitespace(fixer, previousToken.range[1], token.range[0], "end");
}
});
}
function reportRequiredBeginningSpace(node, token) {
context.report({
node,
loc: token.loc.start,
messageId: "spaceNeededAfter",
data: {
token: token.value
},
fix(fixer) {
return fixer.insertTextAfter(token, " ");
}
});
}
function reportRequiredEndingSpace(node, token) {
context.report({
node,
loc: token.loc.start,
messageId: "spaceNeededBefore",
data: {
token: token.value
},
fix(fixer) {
return fixer.insertTextBefore(token, " ");
}
});
}
function validateBraceSpacing(node) {
var _node$parent;
let config;
switch ((_node$parent = node.parent) == null ? undefined : _node$parent.type) {
case "JSXAttribute":
case "JSXOpeningElement":
config = attributesConfig;
break;
case "JSXElement":
case "JSXFragment":
config = childrenConfig;
break;
default:
return;
}
if (config === null) return;
const sourceCode = context.sourceCode;
const first = sourceCode.getFirstToken(node);
const last = sourceCode.getLastToken(node);
let second = sourceCode.getTokenAfter(first, {
includeComments: true
});
let penultimate = sourceCode.getTokenBefore(last, {
includeComments: true
});
if (!second) {
second = sourceCode.getTokenAfter(first);
const leadingComments = sourceCode.getCommentsBefore(second);
second = leadingComments ? leadingComments[0] : second;
}
if (!penultimate) {
penultimate = sourceCode.getTokenBefore(last);
const trailingComments = sourceCode.getCommentsAfter(penultimate);
penultimate = trailingComments ? trailingComments[trailingComments.length - 1] : penultimate;
}
const isObjectLiteral = first.value === second.value;
const spacing = isObjectLiteral ? config.objectLiteralSpaces : config.when;
if (spacing === SPACING.always) {
if (!sourceCode.isSpaceBetween(first, second)) reportRequiredBeginningSpace(node, first);else if (!config.allowMultiline && isMultiline(first, second)) reportNoBeginningNewline(node, first, spacing);
if (!sourceCode.isSpaceBetween(penultimate, last)) reportRequiredEndingSpace(node, last);else if (!config.allowMultiline && isMultiline(penultimate, last)) reportNoEndingNewline(node, last, spacing);
} else if (spacing === SPACING.never) {
if (isMultiline(first, second)) {
if (!config.allowMultiline) reportNoBeginningNewline(node, first, spacing);
} else if (sourceCode.isSpaceBetween(first, second)) {
reportNoBeginningSpace(node, first);
}
if (isMultiline(penultimate, last)) {
if (!config.allowMultiline) reportNoEndingNewline(node, last, spacing);
} else if (sourceCode.isSpaceBetween(penultimate, last)) {
reportNoEndingSpace(node, last);
}
}
}
return {
JSXExpressionContainer: validateBraceSpacing,
JSXSpreadAttribute: validateBraceSpacing
};
}
});
module.exports = jsxCurlySpacing;