| "use strict"; |
| /** |
| * Note this file is rather type-unsafe in its current state. |
| * This is due to some really funky type conversions between different node types. |
| * This is done intentionally based on the internal implementation of the base indent rule. |
| */ |
| var __importDefault = (this && this.__importDefault) || function (mod) { |
| return (mod && mod.__esModule) ? mod : { "default": mod }; |
| }; |
| 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 experimental_utils_1 = require("@typescript-eslint/experimental-utils"); |
| const indent_1 = __importDefault(require("eslint/lib/rules/indent")); |
| const util = __importStar(require("../util")); |
| const KNOWN_NODES = new Set([ |
| // Class properties aren't yet supported by eslint... |
| experimental_utils_1.AST_NODE_TYPES.ClassProperty, |
| // ts keywords |
| experimental_utils_1.AST_NODE_TYPES.TSAbstractKeyword, |
| experimental_utils_1.AST_NODE_TYPES.TSAnyKeyword, |
| experimental_utils_1.AST_NODE_TYPES.TSBooleanKeyword, |
| experimental_utils_1.AST_NODE_TYPES.TSNeverKeyword, |
| experimental_utils_1.AST_NODE_TYPES.TSNumberKeyword, |
| experimental_utils_1.AST_NODE_TYPES.TSStringKeyword, |
| experimental_utils_1.AST_NODE_TYPES.TSSymbolKeyword, |
| experimental_utils_1.AST_NODE_TYPES.TSUndefinedKeyword, |
| experimental_utils_1.AST_NODE_TYPES.TSUnknownKeyword, |
| experimental_utils_1.AST_NODE_TYPES.TSVoidKeyword, |
| experimental_utils_1.AST_NODE_TYPES.TSNullKeyword, |
| // ts specific nodes we want to support |
| experimental_utils_1.AST_NODE_TYPES.TSAbstractClassProperty, |
| experimental_utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition, |
| experimental_utils_1.AST_NODE_TYPES.TSArrayType, |
| experimental_utils_1.AST_NODE_TYPES.TSAsExpression, |
| experimental_utils_1.AST_NODE_TYPES.TSCallSignatureDeclaration, |
| experimental_utils_1.AST_NODE_TYPES.TSConditionalType, |
| experimental_utils_1.AST_NODE_TYPES.TSConstructorType, |
| experimental_utils_1.AST_NODE_TYPES.TSConstructSignatureDeclaration, |
| experimental_utils_1.AST_NODE_TYPES.TSDeclareFunction, |
| experimental_utils_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression, |
| experimental_utils_1.AST_NODE_TYPES.TSEnumDeclaration, |
| experimental_utils_1.AST_NODE_TYPES.TSEnumMember, |
| experimental_utils_1.AST_NODE_TYPES.TSExportAssignment, |
| experimental_utils_1.AST_NODE_TYPES.TSExternalModuleReference, |
| experimental_utils_1.AST_NODE_TYPES.TSFunctionType, |
| experimental_utils_1.AST_NODE_TYPES.TSImportType, |
| experimental_utils_1.AST_NODE_TYPES.TSIndexedAccessType, |
| experimental_utils_1.AST_NODE_TYPES.TSIndexSignature, |
| experimental_utils_1.AST_NODE_TYPES.TSInferType, |
| experimental_utils_1.AST_NODE_TYPES.TSInterfaceBody, |
| experimental_utils_1.AST_NODE_TYPES.TSInterfaceDeclaration, |
| experimental_utils_1.AST_NODE_TYPES.TSInterfaceHeritage, |
| experimental_utils_1.AST_NODE_TYPES.TSIntersectionType, |
| experimental_utils_1.AST_NODE_TYPES.TSImportEqualsDeclaration, |
| experimental_utils_1.AST_NODE_TYPES.TSLiteralType, |
| experimental_utils_1.AST_NODE_TYPES.TSMappedType, |
| experimental_utils_1.AST_NODE_TYPES.TSMethodSignature, |
| 'TSMinusToken', |
| experimental_utils_1.AST_NODE_TYPES.TSModuleBlock, |
| experimental_utils_1.AST_NODE_TYPES.TSModuleDeclaration, |
| experimental_utils_1.AST_NODE_TYPES.TSNonNullExpression, |
| experimental_utils_1.AST_NODE_TYPES.TSParameterProperty, |
| experimental_utils_1.AST_NODE_TYPES.TSParenthesizedType, |
| 'TSPlusToken', |
| experimental_utils_1.AST_NODE_TYPES.TSPropertySignature, |
| experimental_utils_1.AST_NODE_TYPES.TSQualifiedName, |
| experimental_utils_1.AST_NODE_TYPES.TSQuestionToken, |
| experimental_utils_1.AST_NODE_TYPES.TSRestType, |
| experimental_utils_1.AST_NODE_TYPES.TSThisType, |
| experimental_utils_1.AST_NODE_TYPES.TSTupleType, |
| experimental_utils_1.AST_NODE_TYPES.TSTypeAnnotation, |
| experimental_utils_1.AST_NODE_TYPES.TSTypeLiteral, |
| experimental_utils_1.AST_NODE_TYPES.TSTypeOperator, |
| experimental_utils_1.AST_NODE_TYPES.TSTypeParameter, |
| experimental_utils_1.AST_NODE_TYPES.TSTypeParameterDeclaration, |
| experimental_utils_1.AST_NODE_TYPES.TSTypeParameterInstantiation, |
| experimental_utils_1.AST_NODE_TYPES.TSTypeReference, |
| experimental_utils_1.AST_NODE_TYPES.TSUnionType, |
| ]); |
| exports.default = util.createRule({ |
| name: 'indent', |
| meta: { |
| type: 'layout', |
| docs: { |
| description: 'Enforce consistent indentation', |
| category: 'Stylistic Issues', |
| recommended: 'error', |
| }, |
| fixable: 'whitespace', |
| schema: indent_1.default.meta.schema, |
| messages: indent_1.default.meta.messages, |
| }, |
| defaultOptions: [ |
| // typescript docs and playground use 4 space indent |
| 4, |
| { |
| // typescript docs indent the case from the switch |
| // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-1-8.html#example-4 |
| SwitchCase: 1, |
| flatTernaryExpressions: false, |
| ignoredNodes: [], |
| }, |
| ], |
| create(context, optionsWithDefaults) { |
| // because we extend the base rule, have to update opts on the context |
| // the context defines options as readonly though... |
| const contextWithDefaults = Object.create(context, { |
| options: { |
| writable: false, |
| configurable: false, |
| value: optionsWithDefaults, |
| }, |
| }); |
| const rules = indent_1.default.create(contextWithDefaults); |
| /** |
| * Converts from a TSPropertySignature to a Property |
| * @param node a TSPropertySignature node |
| * @param [type] the type to give the new node |
| * @returns a Property node |
| */ |
| function TSPropertySignatureToProperty(node, type = experimental_utils_1.AST_NODE_TYPES.Property) { |
| const base = { |
| // indent doesn't actually use these |
| key: null, |
| value: null, |
| // Property flags |
| computed: false, |
| method: false, |
| kind: 'init', |
| // this will stop eslint from interrogating the type literal |
| shorthand: true, |
| // location data |
| parent: node.parent, |
| range: node.range, |
| loc: node.loc, |
| }; |
| if (type === experimental_utils_1.AST_NODE_TYPES.Property) { |
| return Object.assign({ type }, base); |
| } |
| else { |
| return Object.assign({ type, static: false, readonly: false }, base); |
| } |
| } |
| return Object.assign({}, rules, { |
| // overwrite the base rule here so we can use our KNOWN_NODES list instead |
| '*:exit'(node) { |
| // For nodes we care about, skip the default handling, because it just marks the node as ignored... |
| if (!KNOWN_NODES.has(node.type)) { |
| rules['*:exit'](node); |
| } |
| }, |
| VariableDeclaration(node) { |
| // https://github.com/typescript-eslint/typescript-eslint/issues/441 |
| if (node.declarations.length === 0) { |
| return; |
| } |
| return rules.VariableDeclaration(node); |
| }, |
| TSAsExpression(node) { |
| // transform it to a BinaryExpression |
| return rules['BinaryExpression, LogicalExpression']({ |
| type: experimental_utils_1.AST_NODE_TYPES.BinaryExpression, |
| operator: 'as', |
| left: node.expression, |
| // the first typeAnnotation includes the as token |
| right: node.typeAnnotation, |
| // location data |
| parent: node.parent, |
| range: node.range, |
| loc: node.loc, |
| }); |
| }, |
| TSConditionalType(node) { |
| // transform it to a ConditionalExpression |
| return rules.ConditionalExpression({ |
| type: experimental_utils_1.AST_NODE_TYPES.ConditionalExpression, |
| test: { |
| type: experimental_utils_1.AST_NODE_TYPES.BinaryExpression, |
| operator: 'extends', |
| left: node.checkType, |
| right: node.extendsType, |
| // location data |
| range: [node.checkType.range[0], node.extendsType.range[1]], |
| loc: { |
| start: node.checkType.loc.start, |
| end: node.extendsType.loc.end, |
| }, |
| }, |
| consequent: node.trueType, |
| alternate: node.falseType, |
| // location data |
| parent: node.parent, |
| range: node.range, |
| loc: node.loc, |
| }); |
| }, |
| 'TSEnumDeclaration, TSTypeLiteral'(node) { |
| // transform it to an ObjectExpression |
| return rules['ObjectExpression, ObjectPattern']({ |
| type: experimental_utils_1.AST_NODE_TYPES.ObjectExpression, |
| properties: node.members.map(member => TSPropertySignatureToProperty(member)), |
| // location data |
| parent: node.parent, |
| range: node.range, |
| loc: node.loc, |
| }); |
| }, |
| TSImportEqualsDeclaration(node) { |
| // transform it to an VariableDeclaration |
| // use VariableDeclaration instead of ImportDeclaration because it's essentially the same thing |
| const { id, moduleReference } = node; |
| return rules.VariableDeclaration({ |
| type: experimental_utils_1.AST_NODE_TYPES.VariableDeclaration, |
| kind: 'const', |
| declarations: [ |
| { |
| type: experimental_utils_1.AST_NODE_TYPES.VariableDeclarator, |
| range: [id.range[0], moduleReference.range[1]], |
| loc: { |
| start: id.loc.start, |
| end: moduleReference.loc.end, |
| }, |
| id: id, |
| init: { |
| type: experimental_utils_1.AST_NODE_TYPES.CallExpression, |
| callee: { |
| type: experimental_utils_1.AST_NODE_TYPES.Identifier, |
| name: 'require', |
| range: [ |
| moduleReference.range[0], |
| moduleReference.range[0] + 'require'.length, |
| ], |
| loc: { |
| start: moduleReference.loc.start, |
| end: { |
| line: moduleReference.loc.end.line, |
| column: moduleReference.loc.start.line + 'require'.length, |
| }, |
| }, |
| }, |
| arguments: 'expression' in moduleReference |
| ? [moduleReference.expression] |
| : [], |
| // location data |
| range: moduleReference.range, |
| loc: moduleReference.loc, |
| }, |
| }, |
| ], |
| // location data |
| parent: node.parent, |
| range: node.range, |
| loc: node.loc, |
| }); |
| }, |
| TSIndexedAccessType(node) { |
| // convert to a MemberExpression |
| return rules['MemberExpression, JSXMemberExpression, MetaProperty']({ |
| type: experimental_utils_1.AST_NODE_TYPES.MemberExpression, |
| object: node.objectType, |
| property: node.indexType, |
| // location data |
| parent: node.parent, |
| range: node.range, |
| loc: node.loc, |
| }); |
| }, |
| TSInterfaceBody(node) { |
| // transform it to an ClassBody |
| return rules['BlockStatement, ClassBody']({ |
| type: experimental_utils_1.AST_NODE_TYPES.ClassBody, |
| body: node.body.map(p => TSPropertySignatureToProperty(p, experimental_utils_1.AST_NODE_TYPES.ClassProperty)), |
| // location data |
| parent: node.parent, |
| range: node.range, |
| loc: node.loc, |
| }); |
| }, |
| 'TSInterfaceDeclaration[extends.length > 0]'(node) { |
| // transform it to a ClassDeclaration |
| return rules['ClassDeclaration[superClass], ClassExpression[superClass]']({ |
| type: experimental_utils_1.AST_NODE_TYPES.ClassDeclaration, |
| body: node.body, |
| id: undefined, |
| // TODO: This is invalid, there can be more than one extends in interface |
| superClass: node.extends[0].expression, |
| // location data |
| parent: node.parent, |
| range: node.range, |
| loc: node.loc, |
| }); |
| }, |
| TSMappedType(node) { |
| const sourceCode = context.getSourceCode(); |
| const squareBracketStart = sourceCode.getTokenBefore(node.typeParameter); |
| // transform it to an ObjectExpression |
| return rules['ObjectExpression, ObjectPattern']({ |
| type: experimental_utils_1.AST_NODE_TYPES.ObjectExpression, |
| properties: [ |
| { |
| type: experimental_utils_1.AST_NODE_TYPES.Property, |
| key: node.typeParameter, |
| value: node.typeAnnotation, |
| // location data |
| range: [ |
| squareBracketStart.range[0], |
| node.typeAnnotation |
| ? node.typeAnnotation.range[1] |
| : squareBracketStart.range[0], |
| ], |
| loc: { |
| start: squareBracketStart.loc.start, |
| end: node.typeAnnotation |
| ? node.typeAnnotation.loc.end |
| : squareBracketStart.loc.end, |
| }, |
| kind: 'init', |
| computed: false, |
| method: false, |
| shorthand: false, |
| }, |
| ], |
| // location data |
| parent: node.parent, |
| range: node.range, |
| loc: node.loc, |
| }); |
| }, |
| TSModuleBlock(node) { |
| // transform it to a BlockStatement |
| return rules['BlockStatement, ClassBody']({ |
| type: experimental_utils_1.AST_NODE_TYPES.BlockStatement, |
| body: node.body, |
| // location data |
| parent: node.parent, |
| range: node.range, |
| loc: node.loc, |
| }); |
| }, |
| TSQualifiedName(node) { |
| return rules['MemberExpression, JSXMemberExpression, MetaProperty']({ |
| type: experimental_utils_1.AST_NODE_TYPES.MemberExpression, |
| object: node.left, |
| property: node.right, |
| // location data |
| parent: node.parent, |
| range: node.range, |
| loc: node.loc, |
| }); |
| }, |
| TSTupleType(node) { |
| // transform it to an ArrayExpression |
| return rules['ArrayExpression, ArrayPattern']({ |
| type: experimental_utils_1.AST_NODE_TYPES.ArrayExpression, |
| elements: node.elementTypes, |
| // location data |
| parent: node.parent, |
| range: node.range, |
| loc: node.loc, |
| }); |
| }, |
| TSTypeParameterDeclaration(node) { |
| const [name, ...attributes] = node.params; |
| // JSX is about the closest we can get because the angle brackets |
| // it's not perfect but it works! |
| return rules.JSXOpeningElement({ |
| type: experimental_utils_1.AST_NODE_TYPES.JSXOpeningElement, |
| selfClosing: false, |
| name: name, |
| attributes: attributes, |
| // location data |
| parent: node.parent, |
| range: node.range, |
| loc: node.loc, |
| }); |
| }, |
| }); |
| }, |
| }); |
| //# sourceMappingURL=indent.js.map |