| "use strict"; |
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { |
| if (k2 === undefined) k2 = k; |
| Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); |
| }) : (function(o, m, k, k2) { |
| if (k2 === undefined) k2 = k; |
| o[k2] = m[k]; |
| })); |
| var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { |
| Object.defineProperty(o, "default", { enumerable: true, value: v }); |
| }) : function(o, v) { |
| o["default"] = v; |
| }); |
| var __importStar = (this && this.__importStar) || function (mod) { |
| if (mod && mod.__esModule) return mod; |
| var result = {}; |
| if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); |
| __setModuleDefault(result, mod); |
| return result; |
| }; |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| const util = __importStar(require("../util")); |
| const util_1 = require("../util"); |
| const definition = { |
| type: 'object', |
| properties: { |
| before: { type: 'boolean' }, |
| after: { type: 'boolean' }, |
| }, |
| additionalProperties: false, |
| }; |
| function createRules(options) { |
| var _a; |
| const globals = Object.assign(Object.assign({}, ((options === null || options === void 0 ? void 0 : options.before) !== undefined ? { before: options.before } : {})), ((options === null || options === void 0 ? void 0 : options.after) !== undefined ? { after: options.after } : {})); |
| const override = (_a = options === null || options === void 0 ? void 0 : options.overrides) !== null && _a !== void 0 ? _a : {}; |
| const colon = Object.assign(Object.assign({ before: false, after: true }, globals), override === null || override === void 0 ? void 0 : override.colon); |
| const arrow = Object.assign(Object.assign({ before: true, after: true }, globals), override === null || override === void 0 ? void 0 : override.arrow); |
| return { |
| colon: colon, |
| arrow: arrow, |
| variable: Object.assign(Object.assign({}, colon), override === null || override === void 0 ? void 0 : override.variable), |
| property: Object.assign(Object.assign({}, colon), override === null || override === void 0 ? void 0 : override.property), |
| parameter: Object.assign(Object.assign({}, colon), override === null || override === void 0 ? void 0 : override.parameter), |
| returnType: Object.assign(Object.assign({}, colon), override === null || override === void 0 ? void 0 : override.returnType), |
| }; |
| } |
| function getIdentifierRules(rules, node) { |
| const scope = node === null || node === void 0 ? void 0 : node.parent; |
| if ((0, util_1.isVariableDeclarator)(scope)) { |
| return rules.variable; |
| } |
| else if ((0, util_1.isFunctionOrFunctionType)(scope)) { |
| return rules.parameter; |
| } |
| else { |
| return rules.colon; |
| } |
| } |
| function getRules(rules, node) { |
| var _a; |
| const scope = (_a = node === null || node === void 0 ? void 0 : node.parent) === null || _a === void 0 ? void 0 : _a.parent; |
| if ((0, util_1.isTSFunctionType)(scope) || (0, util_1.isTSConstructorType)(scope)) { |
| return rules.arrow; |
| } |
| else if ((0, util_1.isIdentifier)(scope)) { |
| return getIdentifierRules(rules, scope); |
| } |
| else if ((0, util_1.isClassOrTypeElement)(scope)) { |
| return rules.property; |
| } |
| else if ((0, util_1.isFunction)(scope)) { |
| return rules.returnType; |
| } |
| else { |
| return rules.colon; |
| } |
| } |
| exports.default = util.createRule({ |
| name: 'type-annotation-spacing', |
| meta: { |
| type: 'layout', |
| docs: { |
| description: 'Require consistent spacing around type annotations', |
| recommended: false, |
| }, |
| fixable: 'whitespace', |
| messages: { |
| expectedSpaceAfter: "Expected a space after the '{{type}}'.", |
| expectedSpaceBefore: "Expected a space before the '{{type}}'.", |
| unexpectedSpaceAfter: "Unexpected space after the '{{type}}'.", |
| unexpectedSpaceBefore: "Unexpected space before the '{{type}}'.", |
| unexpectedSpaceBetween: "Unexpected space between the '{{previousToken}}' and the '{{type}}'.", |
| }, |
| schema: [ |
| { |
| type: 'object', |
| properties: { |
| before: { type: 'boolean' }, |
| after: { type: 'boolean' }, |
| overrides: { |
| type: 'object', |
| properties: { |
| colon: definition, |
| arrow: definition, |
| variable: definition, |
| parameter: definition, |
| property: definition, |
| returnType: definition, |
| }, |
| additionalProperties: false, |
| }, |
| }, |
| additionalProperties: false, |
| }, |
| ], |
| }, |
| defaultOptions: [ |
| // technically there is a default, but the overrides mean |
| // that if we apply them here, it will break the no override case. |
| {}, |
| ], |
| create(context, [options]) { |
| const punctuators = [':', '=>']; |
| const sourceCode = context.getSourceCode(); |
| const ruleSet = createRules(options); |
| /** |
| * Checks if there's proper spacing around type annotations (no space |
| * before colon, one space after). |
| */ |
| function checkTypeAnnotationSpacing(typeAnnotation) { |
| const nextToken = typeAnnotation; |
| const punctuatorTokenEnd = sourceCode.getTokenBefore(nextToken); |
| let punctuatorTokenStart = punctuatorTokenEnd; |
| let previousToken = sourceCode.getTokenBefore(punctuatorTokenEnd); |
| let type = punctuatorTokenEnd.value; |
| if (!punctuators.includes(type)) { |
| return; |
| } |
| const { before, after } = getRules(ruleSet, typeAnnotation); |
| if (type === ':' && previousToken.value === '?') { |
| if (sourceCode.isSpaceBetweenTokens(previousToken, punctuatorTokenStart)) { |
| context.report({ |
| node: punctuatorTokenStart, |
| messageId: 'unexpectedSpaceBetween', |
| data: { |
| type, |
| previousToken: previousToken.value, |
| }, |
| fix(fixer) { |
| return fixer.removeRange([ |
| previousToken.range[1], |
| punctuatorTokenStart.range[0], |
| ]); |
| }, |
| }); |
| } |
| // shift the start to the ? |
| type = '?:'; |
| punctuatorTokenStart = previousToken; |
| previousToken = sourceCode.getTokenBefore(previousToken); |
| // handle the +/- modifiers for optional modification operators |
| if (previousToken.value === '+' || previousToken.value === '-') { |
| type = `${previousToken.value}?:`; |
| punctuatorTokenStart = previousToken; |
| previousToken = sourceCode.getTokenBefore(previousToken); |
| } |
| } |
| const previousDelta = punctuatorTokenStart.range[0] - previousToken.range[1]; |
| const nextDelta = nextToken.range[0] - punctuatorTokenEnd.range[1]; |
| if (after && nextDelta === 0) { |
| context.report({ |
| node: punctuatorTokenEnd, |
| messageId: 'expectedSpaceAfter', |
| data: { |
| type, |
| }, |
| fix(fixer) { |
| return fixer.insertTextAfter(punctuatorTokenEnd, ' '); |
| }, |
| }); |
| } |
| else if (!after && nextDelta > 0) { |
| context.report({ |
| node: punctuatorTokenEnd, |
| messageId: 'unexpectedSpaceAfter', |
| data: { |
| type, |
| }, |
| fix(fixer) { |
| return fixer.removeRange([ |
| punctuatorTokenEnd.range[1], |
| nextToken.range[0], |
| ]); |
| }, |
| }); |
| } |
| if (before && previousDelta === 0) { |
| context.report({ |
| node: punctuatorTokenStart, |
| messageId: 'expectedSpaceBefore', |
| data: { |
| type, |
| }, |
| fix(fixer) { |
| return fixer.insertTextAfter(previousToken, ' '); |
| }, |
| }); |
| } |
| else if (!before && previousDelta > 0) { |
| context.report({ |
| node: punctuatorTokenStart, |
| messageId: 'unexpectedSpaceBefore', |
| data: { |
| type, |
| }, |
| fix(fixer) { |
| return fixer.removeRange([ |
| previousToken.range[1], |
| punctuatorTokenStart.range[0], |
| ]); |
| }, |
| }); |
| } |
| } |
| return { |
| TSMappedType(node) { |
| if (node.typeAnnotation) { |
| checkTypeAnnotationSpacing(node.typeAnnotation); |
| } |
| }, |
| TSTypeAnnotation(node) { |
| checkTypeAnnotationSpacing(node.typeAnnotation); |
| }, |
| }; |
| }, |
| }); |
| //# sourceMappingURL=type-annotation-spacing.js.map |