| "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 experimental_utils_1 = require("@typescript-eslint/experimental-utils"); |
| const util = __importStar(require("../util")); |
| const definition = { |
| type: 'object', |
| properties: { |
| multiline: { |
| type: 'object', |
| properties: { |
| delimiter: { enum: ['none', 'semi', 'comma'] }, |
| requireLast: { type: 'boolean' }, |
| }, |
| additionalProperties: false, |
| }, |
| singleline: { |
| type: 'object', |
| properties: { |
| // note can't have "none" for single line delimiter as it's invalid syntax |
| delimiter: { enum: ['semi', 'comma'] }, |
| requireLast: { type: 'boolean' }, |
| }, |
| additionalProperties: false, |
| }, |
| }, |
| additionalProperties: false, |
| }; |
| exports.default = util.createRule({ |
| name: 'member-delimiter-style', |
| meta: { |
| type: 'suggestion', |
| docs: { |
| description: 'Require a specific member delimiter style for interfaces and type literals', |
| category: 'Stylistic Issues', |
| recommended: false, |
| }, |
| fixable: 'code', |
| messages: { |
| unexpectedComma: 'Unexpected separator (,).', |
| unexpectedSemi: 'Unexpected separator (;).', |
| expectedComma: 'Expected a comma.', |
| expectedSemi: 'Expected a semicolon.', |
| }, |
| schema: [ |
| { |
| type: 'object', |
| properties: Object.assign({}, definition.properties, { |
| overrides: { |
| type: 'object', |
| properties: { |
| interface: definition, |
| typeLiteral: definition, |
| }, |
| additionalProperties: false, |
| }, |
| }), |
| additionalProperties: false, |
| }, |
| ], |
| }, |
| defaultOptions: [ |
| { |
| multiline: { |
| delimiter: 'semi', |
| requireLast: true, |
| }, |
| singleline: { |
| delimiter: 'semi', |
| requireLast: false, |
| }, |
| }, |
| ], |
| create(context, [options]) { |
| var _a; |
| const sourceCode = context.getSourceCode(); |
| // use the base options as the defaults for the cases |
| const baseOptions = options; |
| const overrides = (_a = baseOptions.overrides) !== null && _a !== void 0 ? _a : {}; |
| const interfaceOptions = util.deepMerge(baseOptions, overrides.interface); |
| const typeLiteralOptions = util.deepMerge(baseOptions, overrides.typeLiteral); |
| /** |
| * Check the last token in the given member. |
| * @param member the member to be evaluated. |
| * @param opts the options to be validated. |
| * @param isLast a flag indicating `member` is the last in the interface or type literal. |
| */ |
| function checkLastToken(member, opts, isLast) { |
| /** |
| * Resolves the boolean value for the given setting enum value |
| * @param type the option name |
| */ |
| function getOption(type) { |
| if (isLast && !opts.requireLast) { |
| // only turn the option on if its expecting no delimiter for the last member |
| return type === 'none'; |
| } |
| return opts.delimiter === type; |
| } |
| let messageId = null; |
| let missingDelimiter = false; |
| const lastToken = sourceCode.getLastToken(member, { |
| includeComments: false, |
| }); |
| if (!lastToken) { |
| return; |
| } |
| const optsSemi = getOption('semi'); |
| const optsComma = getOption('comma'); |
| const optsNone = getOption('none'); |
| if (lastToken.value === ';') { |
| if (optsComma) { |
| messageId = 'expectedComma'; |
| } |
| else if (optsNone) { |
| missingDelimiter = true; |
| messageId = 'unexpectedSemi'; |
| } |
| } |
| else if (lastToken.value === ',') { |
| if (optsSemi) { |
| messageId = 'expectedSemi'; |
| } |
| else if (optsNone) { |
| missingDelimiter = true; |
| messageId = 'unexpectedComma'; |
| } |
| } |
| else { |
| if (optsSemi) { |
| missingDelimiter = true; |
| messageId = 'expectedSemi'; |
| } |
| else if (optsComma) { |
| missingDelimiter = true; |
| messageId = 'expectedComma'; |
| } |
| } |
| if (messageId) { |
| context.report({ |
| node: lastToken, |
| loc: { |
| start: { |
| line: lastToken.loc.end.line, |
| column: lastToken.loc.end.column, |
| }, |
| end: { |
| line: lastToken.loc.end.line, |
| column: lastToken.loc.end.column, |
| }, |
| }, |
| messageId, |
| fix(fixer) { |
| if (optsNone) { |
| // remove the unneeded token |
| return fixer.remove(lastToken); |
| } |
| const token = optsSemi ? ';' : ','; |
| if (missingDelimiter) { |
| // add the missing delimiter |
| return fixer.insertTextAfter(lastToken, token); |
| } |
| // correct the current delimiter |
| return fixer.replaceText(lastToken, token); |
| }, |
| }); |
| } |
| } |
| /** |
| * Check the member separator being used matches the delimiter. |
| * @param {ASTNode} node the node to be evaluated. |
| */ |
| function checkMemberSeparatorStyle(node) { |
| const isSingleLine = node.loc.start.line === node.loc.end.line; |
| const members = node.type === experimental_utils_1.AST_NODE_TYPES.TSInterfaceBody ? node.body : node.members; |
| const typeOpts = node.type === experimental_utils_1.AST_NODE_TYPES.TSInterfaceBody |
| ? interfaceOptions |
| : typeLiteralOptions; |
| const opts = isSingleLine ? typeOpts.singleline : typeOpts.multiline; |
| members.forEach((member, index) => { |
| checkLastToken(member, opts !== null && opts !== void 0 ? opts : {}, index === members.length - 1); |
| }); |
| } |
| return { |
| TSInterfaceBody: checkMemberSeparatorStyle, |
| TSTypeLiteral: checkMemberSeparatorStyle, |
| }; |
| }, |
| }); |
| //# sourceMappingURL=member-delimiter-style.js.map |