| "use strict"; |
| var __importStar = (this && this.__importStar) || function (mod) { |
| if (mod && mod.__esModule) return mod; |
| var result = {}; |
| if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; |
| result["default"] = 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, _b, _c, _d, _e, _f, _g, _h, _j, _k; |
| const globals = Object.assign(Object.assign({}, (((_a = options) === null || _a === void 0 ? void 0 : _a.before) !== undefined ? { before: options.before } : {})), (((_b = options) === null || _b === void 0 ? void 0 : _b.after) !== undefined ? { after: options.after } : {})); |
| const override = (_d = (_c = options) === null || _c === void 0 ? void 0 : _c.overrides, (_d !== null && _d !== void 0 ? _d : {})); |
| const colon = Object.assign(Object.assign({ before: false, after: true }, globals), (_e = override) === null || _e === void 0 ? void 0 : _e.colon); |
| const arrow = Object.assign(Object.assign({ before: true, after: true }, globals), (_f = override) === null || _f === void 0 ? void 0 : _f.arrow); |
| return { |
| colon: colon, |
| arrow: arrow, |
| variable: Object.assign(Object.assign({}, colon), (_g = override) === null || _g === void 0 ? void 0 : _g.variable), |
| property: Object.assign(Object.assign({}, colon), (_h = override) === null || _h === void 0 ? void 0 : _h.property), |
| parameter: Object.assign(Object.assign({}, colon), (_j = override) === null || _j === void 0 ? void 0 : _j.parameter), |
| returnType: Object.assign(Object.assign({}, colon), (_k = override) === null || _k === void 0 ? void 0 : _k.returnType), |
| }; |
| } |
| function getIdentifierRules(rules, node) { |
| var _a; |
| const scope = (_a = node) === null || _a === void 0 ? void 0 : _a.parent; |
| if (util_1.isVariableDeclarator(scope)) { |
| return rules.variable; |
| } |
| else if (util_1.isFunctionOrFunctionType(scope)) { |
| return rules.parameter; |
| } |
| else { |
| return rules.colon; |
| } |
| } |
| function getRules(rules, node) { |
| var _a, _b; |
| const scope = (_b = (_a = node) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.parent; |
| if (util_1.isTSFunctionType(scope)) { |
| return rules.arrow; |
| } |
| else if (util_1.isIdentifier(scope)) { |
| return getIdentifierRules(rules, scope); |
| } |
| else if (util_1.isClassOrTypeElement(scope)) { |
| return rules.property; |
| } |
| else if (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', |
| category: 'Stylistic Issues', |
| recommended: 'error', |
| }, |
| 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}}'.", |
| }, |
| 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 === '?') { |
| // 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 |