@ripple-ts/prettier-plugin 0.2.192 → 0.2.193
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/index.js +138 -3
- package/src/index.test.js +52 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ripple-ts/prettier-plugin",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.193",
|
|
4
4
|
"description": "Ripple plugin for Prettier",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "src/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"prettier": "^3.6.2",
|
|
28
|
-
"ripple": "0.2.
|
|
28
|
+
"ripple": "0.2.193"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {},
|
|
31
31
|
"files": [
|
package/src/index.js
CHANGED
|
@@ -688,6 +688,10 @@ function printRippleNode(node, path, options, print, args) {
|
|
|
688
688
|
nodeContent = printForStatement(node, path, options, print);
|
|
689
689
|
break;
|
|
690
690
|
|
|
691
|
+
case 'ForInStatement':
|
|
692
|
+
nodeContent = printForInStatement(node, path, options, print);
|
|
693
|
+
break;
|
|
694
|
+
|
|
691
695
|
case 'WhileStatement':
|
|
692
696
|
nodeContent = printWhileStatement(node, path, options, print);
|
|
693
697
|
break;
|
|
@@ -2345,7 +2349,8 @@ function printVariableDeclaration(node, path, options, print) {
|
|
|
2345
2349
|
const parentNode = path.getParentNode();
|
|
2346
2350
|
const isForLoopInit =
|
|
2347
2351
|
(parentNode && parentNode.type === 'ForStatement' && parentNode.init === node) ||
|
|
2348
|
-
(parentNode && parentNode.type === 'ForOfStatement' && parentNode.left === node)
|
|
2352
|
+
(parentNode && parentNode.type === 'ForOfStatement' && parentNode.left === node) ||
|
|
2353
|
+
(parentNode && parentNode.type === 'ForInStatement' && parentNode.left === node);
|
|
2349
2354
|
|
|
2350
2355
|
const declarations = path.map(print, 'declarations');
|
|
2351
2356
|
const declarationParts = join(', ', declarations);
|
|
@@ -2880,6 +2885,19 @@ function printIfStatement(node, path, options, print) {
|
|
|
2880
2885
|
return concat(parts);
|
|
2881
2886
|
}
|
|
2882
2887
|
|
|
2888
|
+
function printForInStatement(node, path, options, print) {
|
|
2889
|
+
const parts = [];
|
|
2890
|
+
parts.push('for (');
|
|
2891
|
+
parts.push(path.call(print, 'left'));
|
|
2892
|
+
parts.push(' in ');
|
|
2893
|
+
parts.push(path.call(print, 'right'));
|
|
2894
|
+
|
|
2895
|
+
parts.push(') ');
|
|
2896
|
+
parts.push(path.call(print, 'body'));
|
|
2897
|
+
|
|
2898
|
+
return parts;
|
|
2899
|
+
}
|
|
2900
|
+
|
|
2883
2901
|
function printForOfStatement(node, path, options, print) {
|
|
2884
2902
|
const parts = [];
|
|
2885
2903
|
parts.push('for (');
|
|
@@ -4404,6 +4422,14 @@ function createElementLevelCommentParts(comments) {
|
|
|
4404
4422
|
return parts;
|
|
4405
4423
|
}
|
|
4406
4424
|
|
|
4425
|
+
function createElementLevelCommentPartsTrimmed(comments) {
|
|
4426
|
+
const parts = createElementLevelCommentParts(comments);
|
|
4427
|
+
if (parts.length > 0 && parts[parts.length - 1] === hardline) {
|
|
4428
|
+
parts.pop();
|
|
4429
|
+
}
|
|
4430
|
+
return parts;
|
|
4431
|
+
}
|
|
4432
|
+
|
|
4407
4433
|
function printTsxCompat(node, path, options, print) {
|
|
4408
4434
|
const tagName = `<tsx:${node.kind}>`;
|
|
4409
4435
|
const closingTagName = `</tsx:${node.kind}>`;
|
|
@@ -4701,10 +4727,37 @@ function printElement(node, path, options, print) {
|
|
|
4701
4727
|
const tagName = printMemberExpressionSimple(node.id, options);
|
|
4702
4728
|
|
|
4703
4729
|
const elementLeadingComments = getElementLeadingComments(node);
|
|
4730
|
+
const openingTagEndIndex =
|
|
4731
|
+
node?.metadata && typeof node.metadata.openingTagEnd === 'number'
|
|
4732
|
+
? node.metadata.openingTagEnd
|
|
4733
|
+
: null;
|
|
4734
|
+
const nodeStartIndex = typeof node.start === 'number' ? node.start : null;
|
|
4735
|
+
const nodeEndIndex = typeof node.end === 'number' ? node.end : null;
|
|
4736
|
+
|
|
4737
|
+
// `metadata.elementLeadingComments` may include comments that actually appear *inside* the element
|
|
4738
|
+
// body (after the opening tag). Those must not be hoisted before the element.
|
|
4739
|
+
const outerElementLeadingComments =
|
|
4740
|
+
openingTagEndIndex == null || nodeStartIndex == null
|
|
4741
|
+
? elementLeadingComments
|
|
4742
|
+
: elementLeadingComments.filter(
|
|
4743
|
+
(comment) => typeof comment.start !== 'number' || comment.start < nodeStartIndex,
|
|
4744
|
+
);
|
|
4745
|
+
const innerElementBodyComments =
|
|
4746
|
+
openingTagEndIndex != null && nodeEndIndex != null
|
|
4747
|
+
? elementLeadingComments.filter(
|
|
4748
|
+
(comment) =>
|
|
4749
|
+
typeof comment.start === 'number' &&
|
|
4750
|
+
comment.start >= openingTagEndIndex &&
|
|
4751
|
+
comment.start < nodeEndIndex,
|
|
4752
|
+
)
|
|
4753
|
+
: [];
|
|
4754
|
+
|
|
4704
4755
|
const metadataCommentParts =
|
|
4705
|
-
|
|
4756
|
+
outerElementLeadingComments.length > 0
|
|
4757
|
+
? createElementLevelCommentParts(outerElementLeadingComments)
|
|
4758
|
+
: [];
|
|
4706
4759
|
const fallbackElementComments = [];
|
|
4707
|
-
const shouldLiftTextLevelComments =
|
|
4760
|
+
const shouldLiftTextLevelComments = outerElementLeadingComments.length === 0;
|
|
4708
4761
|
|
|
4709
4762
|
const hasChildren = Array.isArray(node.children) && node.children.length > 0;
|
|
4710
4763
|
const hasInnerComments = Array.isArray(node.innerComments) && node.innerComments.length > 0;
|
|
@@ -4787,10 +4840,41 @@ function printElement(node, path, options, print) {
|
|
|
4787
4840
|
// Has children - use unified children processing
|
|
4788
4841
|
// Build children with whitespace preservation
|
|
4789
4842
|
const finalChildren = [];
|
|
4843
|
+
const sortedInnerElementBodyComments =
|
|
4844
|
+
innerElementBodyComments.length > 0
|
|
4845
|
+
? innerElementBodyComments
|
|
4846
|
+
.slice()
|
|
4847
|
+
.sort((a, b) => (a.start ?? 0) - (b.start ?? 0))
|
|
4848
|
+
: [];
|
|
4849
|
+
let innerElementBodyCommentIndex = 0;
|
|
4790
4850
|
|
|
4791
4851
|
for (let i = 0; i < node.children.length; i++) {
|
|
4792
4852
|
const currentChild = node.children[i];
|
|
4793
4853
|
const nextChild = node.children[i + 1];
|
|
4854
|
+
|
|
4855
|
+
// Insert any element-body comments that appear before this child.
|
|
4856
|
+
if (innerElementBodyCommentIndex < sortedInnerElementBodyComments.length) {
|
|
4857
|
+
const currentChildStart = typeof currentChild.start === 'number' ? currentChild.start : null;
|
|
4858
|
+
if (currentChildStart != null) {
|
|
4859
|
+
const commentsBefore = [];
|
|
4860
|
+
while (innerElementBodyCommentIndex < sortedInnerElementBodyComments.length) {
|
|
4861
|
+
const comment = sortedInnerElementBodyComments[innerElementBodyCommentIndex];
|
|
4862
|
+
if (typeof comment.start !== 'number' || comment.start >= currentChildStart) {
|
|
4863
|
+
break;
|
|
4864
|
+
}
|
|
4865
|
+
commentsBefore.push(comment);
|
|
4866
|
+
innerElementBodyCommentIndex++;
|
|
4867
|
+
}
|
|
4868
|
+
if (commentsBefore.length > 0) {
|
|
4869
|
+
if (finalChildren.length > 0) {
|
|
4870
|
+
finalChildren.push(hardline);
|
|
4871
|
+
}
|
|
4872
|
+
finalChildren.push(...createElementLevelCommentPartsTrimmed(commentsBefore));
|
|
4873
|
+
finalChildren.push(hardline);
|
|
4874
|
+
}
|
|
4875
|
+
}
|
|
4876
|
+
}
|
|
4877
|
+
|
|
4794
4878
|
const isTextLikeChild = currentChild.type === 'Text' || currentChild.type === 'Html';
|
|
4795
4879
|
const hasTextLeadingComments =
|
|
4796
4880
|
shouldLiftTextLevelComments &&
|
|
@@ -4827,7 +4911,58 @@ function printElement(node, path, options, print) {
|
|
|
4827
4911
|
: printedChild;
|
|
4828
4912
|
finalChildren.push(childDoc);
|
|
4829
4913
|
|
|
4914
|
+
// Insert element-body comments that fall between this child and the next child (or the closing tag).
|
|
4915
|
+
let insertedBodyCommentsBetween = false;
|
|
4916
|
+
if (innerElementBodyCommentIndex < sortedInnerElementBodyComments.length) {
|
|
4917
|
+
const currentChildEnd = getNodeEndIndex(currentChild);
|
|
4918
|
+
const nextChildStart = nextChild && typeof nextChild.start === 'number' ? nextChild.start : null;
|
|
4919
|
+
if (typeof currentChildEnd === 'number') {
|
|
4920
|
+
const commentsBetween = [];
|
|
4921
|
+
while (innerElementBodyCommentIndex < sortedInnerElementBodyComments.length) {
|
|
4922
|
+
const comment = sortedInnerElementBodyComments[innerElementBodyCommentIndex];
|
|
4923
|
+
if (typeof comment.start !== 'number') {
|
|
4924
|
+
innerElementBodyCommentIndex++;
|
|
4925
|
+
continue;
|
|
4926
|
+
}
|
|
4927
|
+
if (comment.start < currentChildEnd) {
|
|
4928
|
+
break;
|
|
4929
|
+
}
|
|
4930
|
+
if (nextChildStart != null && comment.start >= nextChildStart) {
|
|
4931
|
+
break;
|
|
4932
|
+
}
|
|
4933
|
+
commentsBetween.push(comment);
|
|
4934
|
+
innerElementBodyCommentIndex++;
|
|
4935
|
+
}
|
|
4936
|
+
if (commentsBetween.length > 0) {
|
|
4937
|
+
const firstComment = commentsBetween[0];
|
|
4938
|
+
const lastComment = commentsBetween[commentsBetween.length - 1];
|
|
4939
|
+
|
|
4940
|
+
// Preserve any blank line(s) that existed between the previous child and the comment block.
|
|
4941
|
+
const blankLinesBefore = getBlankLinesBetweenNodes(currentChild, firstComment);
|
|
4942
|
+
finalChildren.push(hardline);
|
|
4943
|
+
if (blankLinesBefore > 0) {
|
|
4944
|
+
finalChildren.push(hardline);
|
|
4945
|
+
}
|
|
4946
|
+
|
|
4947
|
+
finalChildren.push(...createElementLevelCommentPartsTrimmed(commentsBetween));
|
|
4948
|
+
|
|
4949
|
+
if (nextChild) {
|
|
4950
|
+
// Preserve any blank line(s) that existed between the comment block and the next child.
|
|
4951
|
+
const blankLinesAfter = getBlankLinesBetweenNodes(lastComment, nextChild);
|
|
4952
|
+
finalChildren.push(hardline);
|
|
4953
|
+
if (blankLinesAfter > 0) {
|
|
4954
|
+
finalChildren.push(hardline);
|
|
4955
|
+
}
|
|
4956
|
+
}
|
|
4957
|
+
insertedBodyCommentsBetween = true;
|
|
4958
|
+
}
|
|
4959
|
+
}
|
|
4960
|
+
}
|
|
4961
|
+
|
|
4830
4962
|
if (nextChild) {
|
|
4963
|
+
if (insertedBodyCommentsBetween) {
|
|
4964
|
+
continue;
|
|
4965
|
+
}
|
|
4831
4966
|
const whitespaceLinesCount = getBlankLinesBetweenNodes(currentChild, nextChild);
|
|
4832
4967
|
const isTextOrHtmlChild =
|
|
4833
4968
|
currentChild.type === 'Text' ||
|
package/src/index.test.js
CHANGED
|
@@ -17,11 +17,15 @@ expect.extend({
|
|
|
17
17
|
message: () => {
|
|
18
18
|
const { matcherHint, EXPECTED_COLOR, RECEIVED_COLOR } = this.utils;
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* @param {string} str
|
|
22
|
+
* @param {(str: string) => string} colorFn
|
|
23
|
+
*/
|
|
21
24
|
const formatWithColor = (str, colorFn) => {
|
|
22
25
|
return colorFn(str);
|
|
23
26
|
};
|
|
24
27
|
|
|
28
|
+
// Just apply color without modifying the string
|
|
25
29
|
return (
|
|
26
30
|
matcherHint('toBeWithNewline') +
|
|
27
31
|
'\n\nExpected:\n' +
|
|
@@ -1903,6 +1907,53 @@ function test() {
|
|
|
1903
1907
|
expect(result).toBeWithNewline(expected);
|
|
1904
1908
|
});
|
|
1905
1909
|
|
|
1910
|
+
it('should preserve the exact order with a commented out component a text literal sibling', async () => {
|
|
1911
|
+
const expected = `component Something({ children }) {
|
|
1912
|
+
const test = 'yo';
|
|
1913
|
+
<Another>
|
|
1914
|
+
{\`Content inside \${test} Another component\`}
|
|
1915
|
+
// component children() {
|
|
1916
|
+
// <span>{'Child Component'}</span>
|
|
1917
|
+
// }
|
|
1918
|
+
</Another>
|
|
1919
|
+
}`;
|
|
1920
|
+
|
|
1921
|
+
const result = await format(expected, { singleQuote: true });
|
|
1922
|
+
expect(result).toBeWithNewline(expected);
|
|
1923
|
+
});
|
|
1924
|
+
|
|
1925
|
+
it('should preserve the blank line between a commented out component and text literal sibling', async () => {
|
|
1926
|
+
const expected = `component Something({ children }) {
|
|
1927
|
+
const test = 'yo';
|
|
1928
|
+
<Another>
|
|
1929
|
+
{\`Content inside \${test} Another component\`}
|
|
1930
|
+
|
|
1931
|
+
// component children() {
|
|
1932
|
+
// <span>{'Child Component'}</span>
|
|
1933
|
+
// }
|
|
1934
|
+
</Another>
|
|
1935
|
+
}`;
|
|
1936
|
+
|
|
1937
|
+
const result = await format(expected, { singleQuote: true });
|
|
1938
|
+
expect(result).toBeWithNewline(expected);
|
|
1939
|
+
});
|
|
1940
|
+
|
|
1941
|
+
it('should preserve the blank line between a component and text literal sibling inside element', async () => {
|
|
1942
|
+
const expected = `component Something({ children }) {
|
|
1943
|
+
const test = 'yo';
|
|
1944
|
+
<Another>
|
|
1945
|
+
{\`Content inside \${test} Another component\`}
|
|
1946
|
+
|
|
1947
|
+
component children() {
|
|
1948
|
+
<span>{'Child Component'}</span>
|
|
1949
|
+
}
|
|
1950
|
+
</Another>
|
|
1951
|
+
}`;
|
|
1952
|
+
|
|
1953
|
+
const result = await format(expected, { singleQuote: true });
|
|
1954
|
+
expect(result).toBeWithNewline(expected);
|
|
1955
|
+
});
|
|
1956
|
+
|
|
1906
1957
|
it('should preserve trailing comments in function parameters', async () => {
|
|
1907
1958
|
const expected = `function test(
|
|
1908
1959
|
// comment in params
|