2020-08-25 23:57:08 +00:00
'use strict' ;
var _staticRequire = require ( '../core/staticRequire' ) ; var _staticRequire2 = _interopRequireDefault ( _staticRequire ) ;
var _docsUrl = require ( '../docsUrl' ) ; var _docsUrl2 = _interopRequireDefault ( _docsUrl ) ;
2022-11-10 10:43:16 +00:00
var _debug = require ( 'debug' ) ; var _debug2 = _interopRequireDefault ( _debug ) ; function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { 'default' : obj } ; }
var log = ( 0 , _debug2 [ 'default' ] ) ( 'eslint-plugin-import:rules:newline-after-import' ) ;
2020-08-25 23:57:08 +00:00
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/ * *
* @ fileoverview Rule to enforce new line after import not followed by another import .
* @ author Radek Benkel
* / f u n c t i o n c o n t a i n s N o d e O r E q u a l ( o u t e r N o d e , i n n e r N o d e ) { r e t u r n o u t e r N o d e . r a n g e [ 0 ] < = i n n e r N o d e . r a n g e [ 0 ] & & o u t e r N o d e . r a n g e [ 1 ] > = i n n e r N o d e . r a n g e [ 1 ] ; }
function getScopeBody ( scope ) {
if ( scope . block . type === 'SwitchStatement' ) {
log ( 'SwitchStatement scopes not supported' ) ;
return null ;
2022-11-10 10:43:16 +00:00
} var
2020-08-25 23:57:08 +00:00
body = scope . block . body ;
if ( body && body . type === 'BlockStatement' ) {
return body . body ;
}
return body ;
}
function findNodeIndexInScopeBody ( body , nodeToFind ) {
2022-11-10 10:43:16 +00:00
return body . findIndex ( function ( node ) { return containsNodeOrEqual ( node , nodeToFind ) ; } ) ;
2020-08-25 23:57:08 +00:00
}
function getLineDifference ( node , nextNode ) {
return nextNode . loc . start . line - node . loc . end . line ;
}
function isClassWithDecorator ( node ) {
return node . type === 'ClassDeclaration' && node . decorators && node . decorators . length ;
}
function isExportDefaultClass ( node ) {
return node . type === 'ExportDefaultDeclaration' && node . declaration . type === 'ClassDeclaration' ;
}
2022-11-10 10:43:16 +00:00
function isExportNameClass ( node ) {
return node . type === 'ExportNamedDeclaration' && node . declaration && node . declaration . type === 'ClassDeclaration' ;
}
2020-08-25 23:57:08 +00:00
module . exports = {
meta : {
type : 'layout' ,
docs : {
2024-03-28 02:25:32 +00:00
category : 'Style guide' ,
description : 'Enforce a newline after import statements.' ,
2022-11-10 10:43:16 +00:00
url : ( 0 , _docsUrl2 [ 'default' ] ) ( 'newline-after-import' ) } ,
2020-08-25 23:57:08 +00:00
fixable : 'whitespace' ,
schema : [
{
2024-03-28 02:25:32 +00:00
type : 'object' ,
properties : {
count : {
type : 'integer' ,
minimum : 1 } ,
2020-08-25 23:57:08 +00:00
2024-03-28 02:25:32 +00:00
exactCount : { type : 'boolean' } ,
considerComments : { type : 'boolean' } } ,
2020-08-25 23:57:08 +00:00
2024-03-28 02:25:32 +00:00
additionalProperties : false } ] } ,
2020-08-25 23:57:08 +00:00
2022-11-10 10:43:16 +00:00
create : function ( ) { function create ( context ) {
var level = 0 ;
var requireCalls = [ ] ;
2024-03-28 02:25:32 +00:00
var options = Object . assign ( {
count : 1 ,
exactCount : false ,
considerComments : false } ,
context . options [ 0 ] ) ;
2020-08-25 23:57:08 +00:00
2022-11-10 10:43:16 +00:00
function checkForNewLine ( node , nextNode , type ) {
if ( isExportDefaultClass ( nextNode ) || isExportNameClass ( nextNode ) ) {
var classNode = nextNode . declaration ;
2020-08-25 23:57:08 +00:00
2022-11-10 10:43:16 +00:00
if ( isClassWithDecorator ( classNode ) ) {
nextNode = classNode . decorators [ 0 ] ;
}
} else if ( isClassWithDecorator ( nextNode ) ) {
nextNode = nextNode . decorators [ 0 ] ;
2020-08-25 23:57:08 +00:00
}
2022-11-10 10:43:16 +00:00
var lineDifference = getLineDifference ( node , nextNode ) ;
var EXPECTED _LINE _DIFFERENCE = options . count + 1 ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:25:32 +00:00
if (
lineDifference < EXPECTED _LINE _DIFFERENCE ||
options . exactCount && lineDifference !== EXPECTED _LINE _DIFFERENCE )
{
var column = node . loc . start . column ;
if ( node . loc . start . line !== node . loc . end . line ) {
column = 0 ;
}
context . report ( {
loc : {
line : node . loc . end . line ,
column : column } ,
message : 'Expected ' + String ( options . count ) + ' empty line' + ( options . count > 1 ? 's' : '' ) + ' after ' + String ( type ) + ' statement not followed by another ' + String ( type ) + '.' ,
fix : options . exactCount && EXPECTED _LINE _DIFFERENCE < lineDifference ? undefined : function ( fixer ) { return fixer . insertTextAfter (
node ,
'\n' . repeat ( EXPECTED _LINE _DIFFERENCE - lineDifference ) ) ; } } ) ;
}
}
function commentAfterImport ( node , nextComment ) {
var lineDifference = getLineDifference ( node , nextComment ) ;
var EXPECTED _LINE _DIFFERENCE = options . count + 1 ;
2022-11-10 10:43:16 +00:00
if ( lineDifference < EXPECTED _LINE _DIFFERENCE ) {
var column = node . loc . start . column ;
2020-08-25 23:57:08 +00:00
2022-11-10 10:43:16 +00:00
if ( node . loc . start . line !== node . loc . end . line ) {
column = 0 ;
}
2020-08-25 23:57:08 +00:00
2022-11-10 10:43:16 +00:00
context . report ( {
loc : {
line : node . loc . end . line ,
column : column } ,
2020-08-25 23:57:08 +00:00
2024-03-28 02:25:32 +00:00
message : 'Expected ' + String ( options . count ) + ' empty line' + ( options . count > 1 ? 's' : '' ) + ' after import statement not followed by another import.' ,
fix : options . exactCount && EXPECTED _LINE _DIFFERENCE < lineDifference ? undefined : function ( fixer ) { return fixer . insertTextAfter (
node ,
'\n' . repeat ( EXPECTED _LINE _DIFFERENCE - lineDifference ) ) ; } } ) ;
2020-08-25 23:57:08 +00:00
2022-11-10 10:43:16 +00:00
}
2020-08-25 23:57:08 +00:00
}
2022-11-10 10:43:16 +00:00
function incrementLevel ( ) {
level ++ ;
}
function decrementLevel ( ) {
level -- ;
2020-08-25 23:57:08 +00:00
}
2022-11-10 10:43:16 +00:00
function checkImport ( node ) { var
parent = node . parent ;
2024-03-28 02:25:32 +00:00
if ( ! parent || ! parent . body ) {
return ;
}
2022-11-10 10:43:16 +00:00
var nodePosition = parent . body . indexOf ( node ) ;
var nextNode = parent . body [ nodePosition + 1 ] ;
2024-03-28 02:25:32 +00:00
var endLine = node . loc . end . line ;
var nextComment = void 0 ;
if ( typeof parent . comments !== 'undefined' && options . considerComments ) {
nextComment = parent . comments . find ( function ( o ) { return o . loc . start . line >= endLine && o . loc . start . line <= endLine + options . count + 1 ; } ) ;
}
2022-11-10 10:43:16 +00:00
// skip "export import"s
if ( node . type === 'TSImportEqualsDeclaration' && node . isExport ) {
return ;
2020-08-25 23:57:08 +00:00
}
2024-03-28 02:25:32 +00:00
if ( nextComment && typeof nextComment !== 'undefined' ) {
commentAfterImport ( node , nextComment ) ;
} else if ( nextNode && nextNode . type !== 'ImportDeclaration' && ( nextNode . type !== 'TSImportEqualsDeclaration' || nextNode . isExport ) ) {
2022-11-10 10:43:16 +00:00
checkForNewLine ( node , nextNode , 'import' ) ;
}
}
2020-08-25 23:57:08 +00:00
2022-11-10 10:43:16 +00:00
return {
ImportDeclaration : checkImport ,
TSImportEqualsDeclaration : checkImport ,
CallExpression : function ( ) { function CallExpression ( node ) {
if ( ( 0 , _staticRequire2 [ 'default' ] ) ( node ) && level === 0 ) {
requireCalls . push ( node ) ;
}
} return CallExpression ; } ( ) ,
'Program:exit' : function ( ) { function ProgramExit ( ) {
log ( 'exit processing for' , context . getPhysicalFilename ? context . getPhysicalFilename ( ) : context . getFilename ( ) ) ;
var scopeBody = getScopeBody ( context . getScope ( ) ) ;
log ( 'got scope:' , scopeBody ) ;
requireCalls . forEach ( function ( node , index ) {
var nodePosition = findNodeIndexInScopeBody ( scopeBody , node ) ;
log ( 'node position in scope:' , nodePosition ) ;
var statementWithRequireCall = scopeBody [ nodePosition ] ;
var nextStatement = scopeBody [ nodePosition + 1 ] ;
var nextRequireCall = requireCalls [ index + 1 ] ;
if ( nextRequireCall && containsNodeOrEqual ( statementWithRequireCall , nextRequireCall ) ) {
return ;
}
2024-03-28 02:25:32 +00:00
if (
nextStatement && (
! nextRequireCall ||
! containsNodeOrEqual ( nextStatement , nextRequireCall ) ) )
{
2022-11-10 10:43:16 +00:00
checkForNewLine ( statementWithRequireCall , nextStatement , 'require' ) ;
}
} ) ;
} return ProgramExit ; } ( ) ,
FunctionDeclaration : incrementLevel ,
FunctionExpression : incrementLevel ,
ArrowFunctionExpression : incrementLevel ,
BlockStatement : incrementLevel ,
ObjectExpression : incrementLevel ,
Decorator : incrementLevel ,
'FunctionDeclaration:exit' : decrementLevel ,
'FunctionExpression:exit' : decrementLevel ,
'ArrowFunctionExpression:exit' : decrementLevel ,
'BlockStatement:exit' : decrementLevel ,
'ObjectExpression:exit' : decrementLevel ,
'Decorator:exit' : decrementLevel } ;
} return create ; } ( ) } ;
2024-03-28 02:25:32 +00:00
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uZXdsaW5lLWFmdGVyLWltcG9ydC5qcyJdLCJuYW1lcyI6WyJsb2ciLCJjb250YWluc05vZGVPckVxdWFsIiwib3V0ZXJOb2RlIiwiaW5uZXJOb2RlIiwicmFuZ2UiLCJnZXRTY29wZUJvZHkiLCJzY29wZSIsImJsb2NrIiwidHlwZSIsImJvZHkiLCJmaW5kTm9kZUluZGV4SW5TY29wZUJvZHkiLCJub2RlVG9GaW5kIiwiZmluZEluZGV4Iiwibm9kZSIsImdldExpbmVEaWZmZXJlbmNlIiwibmV4dE5vZGUiLCJsb2MiLCJzdGFydCIsImxpbmUiLCJlbmQiLCJpc0NsYXNzV2l0aERlY29yYXRvciIsImRlY29yYXRvcnMiLCJsZW5ndGgiLCJpc0V4cG9ydERlZmF1bHRDbGFzcyIsImRlY2xhcmF0aW9uIiwiaXNFeHBvcnROYW1lQ2xhc3MiLCJtb2R1bGUiLCJleHBvcnRzIiwibWV0YSIsImRvY3MiLCJjYXRlZ29yeSIsImRlc2NyaXB0aW9uIiwidXJsIiwiZml4YWJsZSIsInNjaGVtYSIsInByb3BlcnRpZXMiLCJjb3VudCIsIm1pbmltdW0iLCJleGFjdENvdW50IiwiY29uc2lkZXJDb21tZW50cyIsImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiwiY3JlYXRlIiwiY29udGV4dCIsImxldmVsIiwicmVxdWlyZUNhbGxzIiwib3B0aW9ucyIsImNoZWNrRm9yTmV3TGluZSIsImNsYXNzTm9kZSIsImxpbmVEaWZmZXJlbmNlIiwiRVhQRUNURURfTElORV9ESUZGRVJFTkNFIiwiY29sdW1uIiwicmVwb3J0IiwibWVzc2FnZSIsImZpeCIsInVuZGVmaW5lZCIsImZpeGVyIiwiaW5zZXJ0VGV4dEFmdGVyIiwicmVwZWF0IiwiY29tbWVudEFmdGVySW1wb3J0IiwibmV4dENvbW1lbnQiLCJpbmNyZW1lbnRMZXZlbCIsImRlY3JlbWVudExldmVsIiwiY2hlY2tJbXBvcnQiLCJwYXJlbnQiLCJub2RlUG9zaXRpb24iLCJpbmRleE9mIiwiZW5kTGluZSIsImNvbW1lbnRzIiwiZmluZCIsIm8iLCJpc0V4cG9ydCIsIkltcG9ydERlY2xhcmF0aW9uIiwiVFNJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbiIsIkNhbGxFeHByZXNzaW9uIiwicHVzaCIsImdldFBoeXNpY2FsRmlsZW5hbWUiLCJnZXRGaWxlbmFtZSIsInNjb3BlQm9keSIsImdldFNjb3BlIiwiZm9yRWFjaCIsImluZGV4Iiwic3RhdGVtZW50V2l0aFJlcXVpcmVDYWxsIiwibmV4dFN0YXRlbWVudCIsIm5leHRSZXF1aXJlQ2FsbCIsIkZ1bmN0aW9uRGVjbGFyYXRpb24iLCJGdW5jdGlvbkV4cHJlc3Npb24iLCJBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbiIsIkJsb2NrU3RhdGVtZW50IiwiT2JqZWN0RXhwcmVzc2lvbiIsIkRlY29yYXRvciJdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFLQSxzRDtBQUNBLHFDOztBQUVBLDhCO0FBQ0EsSUFBTUEsTUFBTSx3QkFBTSxpREFBTixDQUFaOztBQUVBO0FBQ0E7QUFDQTtBQWJBOzs7R0FlQSxTQUFTQyxtQkFBVCxDQUE2QkMsU0FBN0IsRUFBd0NDLFNBQXhDLEVBQW1ELENBQ2pELE9BQU9ELFVBQVVFLEtBQVYsQ0FBZ0IsQ0FBaEIsS0FBc0JELFVBQVVDLEtBQVYsQ0FBZ0IsQ0FBaEIsQ0FBdEIsSUFBNENGLFVBQVVFLEtBQVYsQ0FBZ0IsQ0FBaEIsS0FBc0JELFVBQVVDLEtBQVYsQ0FBZ0IsQ0FBaEIsQ0FBekUsQ0FDRDs7QUFFRCxTQUFTQyxZQUFULENBQXNCQyxLQUF0QixFQUE2QjtBQUMzQixNQUFJQSxNQUFNQyxLQUFOLENBQVlDLElBQVosS0FBcUIsaUJBQXpCLEVBQTRDO0FBQzFDUixRQUFJLHNDQUFKO0FBQ0EsV0FBTyxJQUFQO0FBQ0QsR0FKMEI7O0FBTW5CUyxNQU5tQixHQU1WSCxNQUFNQyxLQU5JLENBTW5CRSxJQU5tQjtBQU8zQixNQUFJQSxRQUFRQSxLQUFLRCxJQUFMLEtBQWMsZ0JBQTFCLEVBQTRDO0FBQzFDLFdBQU9DLEtBQUtBLElBQVo7QUFDRDs7QUFFRCxTQUFPQSxJQUFQO0FBQ0Q7O0FBRUQsU0FBU0Msd0JBQVQsQ0FBa0NELElBQWxDLEVBQXdDRSxVQUF4QyxFQUFvRDtBQUNsRCxTQUFPRixLQUFLRyxTQUFMLENBQWUsVUFBQ0MsSUFBRCxVQUFVWixvQkFBb0JZLElBQXBCLEVBQTBCRixVQUExQixDQUFWLEVBQWYsQ0FBUDtBQUNEOztBQUVELFNBQVNHLGlCQUFULENBQTJCRCxJQUEzQixFQUFpQ0UsUUFBakMsRUFBMkM7QUFDekMsU0FBT0EsU0FBU0MsR0FBVCxDQUFhQyxLQUFiLENBQW1CQyxJQUFuQixHQUEwQkwsS0FBS0csR0FBTCxDQUFTRyxHQUFULENBQWFELElBQTlDO0FBQ0Q7O0FBRUQsU0FBU0Usb0JBQVQsQ0FBOEJQLElBQTlCLEVBQW9DO0FBQ2xDLFNBQU9BLEtBQUtMLElBQUwsS0FBYyxrQkFBZCxJQUFvQ0ssS0FBS1EsVUFBekMsSUFBdURSLEtBQUtRLFVBQUwsQ0FBZ0JDLE1BQTlFO0FBQ0Q7O0FBRUQsU0FBU0Msb0JBQVQsQ0FBOEJWLElBQTlCLEVBQW9DO0FBQ2xDLFNBQU9BLEtBQUtMLElBQUwsS0FBYywwQkFBZCxJQUE0Q0ssS0FBS1csV0FBTCxDQUFpQmhCLElBQWpCLEtBQTBCLGtCQUE3RTtBQUNEOztBQUVELFNBQVNpQixpQkFBVCxDQUEyQlosSUFBM0IsRUFBaUM7O0FBRS9CLFNBQU9BLEtBQUtMLElBQUwsS0FBYyx3QkFBZCxJQUEwQ0ssS0FBS1csV0FBL0MsSUFBOERYLEtBQUtXLFdBQUwsQ0FBaUJoQixJQUFqQixLQUEwQixrQkFBL0Y7QUFDRDs7QUFFRGtCLE9BQU9DLE9BQVAsR0FBaUI7QUFDZkMsUUFBTTtBQUNKcEIsVUFBTSxRQURGO0FBRUpxQixVQUFNO0FBQ0pDLGdCQUFVLGFBRE47QUFFSkMsbUJBQWEsNENBRlQ7QUFHSkMsV0FBSywwQkFBUSxzQkFBUixDQUhELEVBRkY7O0FBT0pDLGFBQVMsWUFQTDtBQVFKQyxZQUFRO0FBQ047QUFDRTFCLFlBQU0sUUFEUjtBQUVFMkIsa0JBQVk7QUFDVkMsZUFBTztBQUNMNUIsZ0JBQU0sU0FERDtBQUVMNkIsbUJBQVMsQ0FGSixFQURHOztBQUtWQyxvQkFBWSxFQUFFOUIsTUFBTSxTQUFSLEVBTEY7QUFNVitCLDBCQUFrQixFQUFFL0IsTUFBTSxTQUFSLEVBTlIsRUFGZDs7QUFVRWdDLDRCQUFzQixLQVZ4QixFQURNLENBUkosRUFEUzs7OztBQXdCZkMsUUF4QmUsK0JBd0JSQyxPQXhCUSxFQXdCQztBQUNkLFVBQUlDLFFBQVEsQ0FBWjtBQUNBLFVBQU1DLGVBQWUsRUFBckI7QUFDQSxVQUFNQztBQUNKVCxlQUFPLENBREg7QUFFSkUsb0JBQVksS0FGUjtBQUdKQywwQkFBa0IsS0FIZDtBQUlERyxjQUFRRyxPQUFSLENBQWd