-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add array.items-linebreak rule
- Loading branch information
1 parent
b7de12a
commit 6aecaf6
Showing
12 changed files
with
353 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
/** | ||
* Break array items into multiple lines or group them into a single line | ||
* based on the position of the first item | ||
*/ | ||
import type { AstArray, RuleContext, RuleDataOptional } from '@taqwim/types'; | ||
class ArrayItemsLineBreak { | ||
/** | ||
* Rule context | ||
*/ | ||
context = {} as RuleContext; | ||
|
||
/** | ||
* Break array items into multiple lines | ||
* | ||
* @param {AstArray['items']} items Array items to process | ||
*/ | ||
reportAndFixBreaking(items: AstArray['items']) { | ||
const { report, node } = this.context; | ||
const { loc: arrayLoc } = node as AstArray; | ||
|
||
for (const [index, item] of items.entries()) { | ||
const { loc } = item; | ||
const nextItem = items[index + 1]; | ||
let endLoc = nextItem?.loc.start; | ||
if (endLoc === undefined) { | ||
// -1 to remove location of ) or ] from the end of the array | ||
endLoc = { | ||
line: arrayLoc.end.line, | ||
column: arrayLoc.end.column - 1, | ||
offset: arrayLoc.end.offset - 1, | ||
}; | ||
} | ||
|
||
// If current item and the next item are not on the same line | ||
// then there is no need to add a line break | ||
if (loc.end.line !== endLoc.line) { | ||
continue; | ||
} | ||
|
||
const fixPoisition = { | ||
start: loc.end, | ||
end: endLoc, | ||
}; | ||
|
||
report({ | ||
message: 'There should be a line break after this item.', | ||
position: { | ||
start: { | ||
line: loc.end.line, | ||
column: loc.end.column - 2, | ||
offset: loc.end.offset - 2, | ||
}, | ||
end: { | ||
line: loc.end.line, | ||
column: loc.end.column, | ||
offset: loc.end.offset, | ||
}, | ||
}, | ||
fix(fixer) { | ||
return fixer.after(fixPoisition, '\n'); | ||
}, | ||
}); | ||
} | ||
} | ||
|
||
/** | ||
* Group array items into a single line | ||
* | ||
* @param {AstArray['items']} items Array items to process | ||
*/ | ||
reportAndFixGrouping(items: AstArray['items']) { | ||
const { report, sourceLines, node, sourceCode } = this.context; | ||
const { loc: arrayLoc } = node as AstArray; | ||
for (const [index, item] of items.entries()) { | ||
const { loc } = item; | ||
const nextItem = items[index + 1]; | ||
let endLoc = nextItem?.loc.start; | ||
if (endLoc === undefined) { | ||
// -1 to remove location of ) or ] from the end of the array | ||
endLoc = { | ||
line: arrayLoc.end.line, | ||
column: arrayLoc.end.column - 1, | ||
offset: arrayLoc.end.offset - 1, | ||
}; | ||
} | ||
|
||
if (loc.end.line === endLoc.line) { | ||
continue; | ||
} | ||
|
||
const lastLine = sourceLines[loc.end.line]; | ||
const postItemContent = lastLine.slice(loc.end.column); | ||
|
||
// Check for comma after the item, because last item might not | ||
// have a dangling comma | ||
const hasComma = postItemContent.match(/\s*,/u); | ||
const commaIndex = hasComma?.index === undefined ? 0 : hasComma.index + 1; | ||
|
||
const fixerPosition = { | ||
start: { | ||
line: loc.end.line, | ||
column: loc.end.column + commaIndex, | ||
offset: loc.end.offset + commaIndex, | ||
}, | ||
end: endLoc, | ||
}; | ||
|
||
// Make sure that the content removed in fixer is only whitespace | ||
const contentToReplace = sourceCode.slice( | ||
fixerPosition.start.offset, | ||
fixerPosition.end.offset | ||
); | ||
const isOnlyWhitespace = contentToReplace.trim() === ''; | ||
if (!isOnlyWhitespace) { | ||
continue; | ||
} | ||
report({ | ||
message: 'There should not be a line break after this item.', | ||
|
||
// Show the message at the end of the item | ||
position: { | ||
start: { | ||
line: loc.end.line, | ||
column: loc.end.column - 2, | ||
offset: loc.end.offset - 2, | ||
}, | ||
end: { | ||
line: loc.end.line, | ||
column: loc.end.column + commaIndex, | ||
offset: loc.end.offset + commaIndex, | ||
}, | ||
}, | ||
fix(fixer) { | ||
return fixer.replaceRange(fixerPosition, ' '); | ||
}, | ||
}); | ||
} | ||
} | ||
|
||
/** | ||
* Process the rule | ||
* | ||
* @param {RuleContext} context Rule context | ||
*/ | ||
process (context: RuleContext) { | ||
this.context = context; | ||
const { node } = context; | ||
const { items, loc: arrayLoc } = node as AstArray; | ||
|
||
if (items.length === 0) { | ||
return; | ||
} | ||
|
||
const firstItem = items[0]; | ||
const isSameLine = arrayLoc.start.line === firstItem.loc.start.line; | ||
|
||
if (isSameLine !== true) { | ||
this.reportAndFixBreaking(items); | ||
return; | ||
} | ||
|
||
// If array start and end lines are on the same line | ||
// then there is no need to group them into a single line | ||
// as it will be a single line array | ||
if (arrayLoc.start.line === arrayLoc.end.line) { | ||
return; | ||
} | ||
this.reportAndFixGrouping(items); | ||
} | ||
} | ||
|
||
export default (): RuleDataOptional => { | ||
return { | ||
meta: { | ||
description: 'Break array items into multiple lines or group them into a single line based on the position of the first item', | ||
fixable: true, | ||
preset: 'taqwim', | ||
}, | ||
name: 'array.items-linebreak', | ||
register: ['array'], | ||
bindClass: ArrayItemsLineBreak, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
$months = array( | ||
"january", | ||
"february", | ||
"march", | ||
"april", | ||
"may", | ||
"june", | ||
"july", | ||
"august", | ||
"september", | ||
"october", | ||
"november", | ||
"december", | ||
); | ||
|
||
$seasons = array( | ||
"summer", | ||
"winter", | ||
"spring", | ||
"autumn", | ||
); | ||
|
||
$array = array( | ||
"foo" => "bar", | ||
"bar" => "foo", | ||
100 => -100, | ||
-100 => 100, | ||
); | ||
|
||
$bigone = [ | ||
'name' => 'bigone', | ||
'children' => [ | ||
'1a' => 'child', | ||
'11b' => 'child', | ||
'111c' => 'child', | ||
'children' => [ | ||
'child' => 'aaa', | ||
], | ||
], | ||
'short_name' => 'big' | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?php | ||
$array = array("foo", "bar", "hello", "world"); | ||
$seasons = array("summer","winter","spring","autumn"); | ||
$months = array("january","february","march","april","may","june","july","august","september","october","november","december"); | ||
$args = array('"' . $this->id . '"', (int) $has_sessions,); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"default": { | ||
"correct-1": { | ||
"description": "Array items are on separate lines", | ||
"expected": 0 | ||
}, | ||
"correct-2": { | ||
"description": "Arrays items are on the same line", | ||
"expected": 0 | ||
}, | ||
"incorrect-1": { | ||
"description": "Array items do not have consistent line breaks", | ||
"expected": 16 | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php | ||
$months = array( "january", | ||
"february", | ||
"march", "april", | ||
"may", | ||
"june", "july", "august", "september", | ||
"october", | ||
"november", "december", | ||
); | ||
|
||
$seasons = array( | ||
"summer", "winter", | ||
"spring", "autumn", | ||
); | ||
|
||
$seasons = array("summer", | ||
// Comment, fixer should add a line break here | ||
"winter", "spring", | ||
"autumn", | ||
"fall", | ||
"one", | ||
"two", | ||
); | ||
|
||
$array = array( "foo" => "bar", | ||
"bar" => "foo", | ||
100 => -100, -100 => 100, | ||
); | ||
|
||
$bigone = ['name' => 'bigone', | ||
'children' => [ | ||
'1a' => 'child', '11b' => 'child', | ||
'111c' => 'child', | ||
'children' => [ 'child' => 'aaa', | ||
], | ||
],'short_name' => 'big' | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
$months = array( "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december", ); | ||
|
||
$seasons = array( | ||
"summer", | ||
"winter", | ||
"spring", | ||
"autumn", | ||
); | ||
|
||
$seasons = array("summer", | ||
// Comment, fixer should add a line break here | ||
"winter", "spring", "autumn", "fall", "one", "two", ); | ||
|
||
$array = array( "foo" => "bar", "bar" => "foo", 100 => -100, -100 => 100, ); | ||
|
||
$bigone = ['name' => 'bigone', 'children' => [ | ||
'1a' => 'child', | ||
'11b' => 'child', | ||
'111c' => 'child', | ||
'children' => [ 'child' => 'aaa', ], | ||
],'short_name' => 'big' ]; |
Oops, something went wrong.