Skip to content

Commit 01740e0

Browse files
Feature/formater on off (jhipster#323)
* add formatter off-on * add rules for last is formatter:off * change tests * rework code * add jsdoc and rearrange methods * add tests * refactor code * fix test
1 parent e7648a2 commit 01740e0

15 files changed

Lines changed: 376 additions & 16 deletions

File tree

packages/java-parser/src/comments.js

Lines changed: 92 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"use strict";
22

3+
const _ = require("lodash");
4+
35
/**
46
* Search where is the position of the comment in the token array by
57
* using dichotomic search.
@@ -34,6 +36,12 @@ function isPrettierIgnoreComment(comment) {
3436
);
3537
}
3638

39+
function isFormatterOffOnComment(comment) {
40+
return comment.image.match(
41+
/(\/\/(\s*)@formatter:(off|on)(\s*))|(\/\*(\s*)@formatter:(off|on)(\s*)\*\/)/gm
42+
);
43+
}
44+
3745
/**
3846
* Pre-processing of tokens in order to
3947
* complete the parser's mostEnclosiveCstNodeByStartOffset and mostEnclosiveCstNodeByEndOffset structures.
@@ -58,20 +66,7 @@ function completeMostEnclosiveCSTNodeByOffset(
5866
});
5967
}
6068

61-
/**
62-
* Create two data structures we use to know at which offset a comment can be attached.
63-
* - commentsByExtendedStartOffset: map a comment by the endOffset of the previous token.
64-
* - commentsByExtendedEndOffset: map a comment by the startOffset of the next token
65-
*
66-
* @param {ITokens[]} tokens - array of tokens
67-
* @param {[]} comments - array of comments
68-
*
69-
* @return {{commentsByExtendedStartOffset: {[extendedStartOffset: number]: Comment[]}, commentsByExtendedEndOffset: {[extendedEndOffset: number]: Comment[]}}}
70-
*/
71-
function mapCommentsByExtendedRange(tokens, comments) {
72-
const commentsByExtendedEndOffset = {};
73-
const commentsByExtendedStartOffset = {};
74-
69+
function extendRangeOffset(comments, tokens) {
7570
let position;
7671
comments.forEach(comment => {
7772
position = findUpperBoundToken(tokens, comment);
@@ -83,8 +78,28 @@ function mapCommentsByExtendedRange(tokens, comments) {
8378
? comment.endOffset
8479
: tokens[position].startOffset;
8580
comment.extendedOffset = {
81+
startOffset: extendedStartOffset,
8682
endOffset: extendedEndOffset
8783
};
84+
});
85+
}
86+
87+
/**
88+
* Create two data structures we use to know at which offset a comment can be attached.
89+
* - commentsByExtendedStartOffset: map a comment by the endOffset of the previous token.
90+
* - commentsByExtendedEndOffset: map a comment by the startOffset of the next token
91+
*
92+
* @param {ITokens[]} tokens - array of tokens
93+
*
94+
* @return {{commentsByExtendedStartOffset: {[extendedStartOffset: number]: Comment[]}, commentsByExtendedEndOffset: {[extendedEndOffset: number]: Comment[]}}}
95+
*/
96+
function mapCommentsByExtendedRange(comments) {
97+
const commentsByExtendedEndOffset = {};
98+
const commentsByExtendedStartOffset = {};
99+
100+
comments.forEach(comment => {
101+
const extendedStartOffset = comment.extendedOffset.startOffset;
102+
const extendedEndOffset = comment.extendedOffset.endOffset;
88103

89104
if (commentsByExtendedEndOffset[extendedEndOffset] === undefined) {
90105
commentsByExtendedEndOffset[extendedEndOffset] = [comment];
@@ -169,10 +184,12 @@ function attachComments(
169184
mostEnclosiveCstNodeByStartOffset,
170185
mostEnclosiveCstNodeByEndOffset
171186
);
187+
188+
extendRangeOffset(comments, tokens);
172189
const {
173190
commentsByExtendedStartOffset,
174191
commentsByExtendedEndOffset
175-
} = mapCommentsByExtendedRange(tokens, comments);
192+
} = mapCommentsByExtendedRange(comments);
176193

177194
/*
178195
This set is here to ensure that we attach comments only once
@@ -233,6 +250,66 @@ function attachComments(
233250
});
234251
}
235252

253+
/**
254+
* Create pairs of formatter:off and formatter:on
255+
* @param comments
256+
* @returns pairs of formatter:off and formatter:on
257+
*/
258+
function matchFormatterOffOnPairs(comments) {
259+
const onOffComments = comments.filter(comment =>
260+
isFormatterOffOnComment(comment)
261+
);
262+
263+
let isPreviousCommentOff = false;
264+
let isCurrentCommentOff = true;
265+
const pairs = [];
266+
let paired = {};
267+
onOffComments.forEach(comment => {
268+
isCurrentCommentOff = comment.image.slice(-3) === "off";
269+
270+
if (!isPreviousCommentOff) {
271+
if (isCurrentCommentOff) {
272+
paired.off = comment;
273+
}
274+
} else {
275+
if (!isCurrentCommentOff) {
276+
paired.on = comment;
277+
pairs.push(paired);
278+
paired = {};
279+
}
280+
}
281+
isPreviousCommentOff = isCurrentCommentOff;
282+
});
283+
284+
if (onOffComments.length > 0 && isCurrentCommentOff) {
285+
paired.on = undefined;
286+
pairs.push(paired);
287+
}
288+
289+
return pairs;
290+
}
291+
292+
/**
293+
* Check if the node is between formatter:off and formatter:on and change his ignore state
294+
* @param node
295+
* @param commentPairs
296+
*/
297+
function shouldNotFormat(node, commentPairs) {
298+
const matchingPair = _.findLast(
299+
commentPairs,
300+
comment => comment.off.endOffset < node.location.startOffset
301+
);
302+
if (
303+
matchingPair !== undefined &&
304+
(matchingPair.on === undefined ||
305+
matchingPair.on.startOffset > node.location.endOffset)
306+
) {
307+
node.ignore = true;
308+
}
309+
}
310+
236311
module.exports = {
312+
matchFormatterOffOnPairs,
313+
shouldNotFormat,
237314
attachComments
238315
};

packages/java-parser/src/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"use strict";
22
const JavaLexer = require("./lexer");
33
const JavaParser = require("./parser");
4-
const { attachComments } = require("./comments");
4+
const { attachComments, matchFormatterOffOnPairs } = require("./comments");
55

66
const parser = new JavaParser();
77

@@ -28,6 +28,10 @@ function parse(inputText, entryPoint = "compilationUnit") {
2828
parser.mostEnclosiveCstNodeByStartOffset = {};
2929
parser.mostEnclosiveCstNodeByEndOffset = {};
3030

31+
parser.setOnOffCommentPairs(
32+
matchFormatterOffOnPairs(lexResult.groups.comments)
33+
);
34+
3135
// Automatic CST created when parsing
3236
const cst = parser[entryPoint]();
3337

packages/java-parser/src/parser.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const arrays = require("./productions/arrays");
1111
const blocksStatements = require("./productions/blocks-and-statements");
1212
const expressions = require("./productions/expressions");
1313
const { getSkipValidations } = require("./utils");
14+
const { shouldNotFormat } = require("./comments");
1415

1516
/**
1617
* This parser attempts to strongly align with the specs style at:
@@ -85,6 +86,8 @@ class JavaParser extends Parser {
8586
this.mostEnclosiveCstNodeByEndOffset[
8687
ruleCstResult.location.endOffset
8788
] = ruleCstResult;
89+
90+
shouldNotFormat(ruleCstResult, this.onOffCommentPairs);
8891
}
8992
}
9093

@@ -109,6 +112,10 @@ class JavaParser extends Parser {
109112
}
110113
});
111114
}
115+
116+
setOnOffCommentPairs(onOffCommentPairs) {
117+
this.onOffCommentPairs = onOffCommentPairs;
118+
}
112119
}
113120

114121
module.exports = JavaParser;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// @formatter:on
2+
public class PrettierIgnoreClass {
3+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
4+
5+
}
6+
}
7+
8+
// @formatter:off
9+
public class PrettierIgnoreClass {
10+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
11+
12+
}
13+
}
14+
// @formatter:on
15+
public class PrettierIgnoreClass {
16+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
17+
18+
}
19+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// @formatter:on
2+
public class PrettierIgnoreClass {
3+
4+
public void myMethod(
5+
int param1,
6+
int param2,
7+
int param3,
8+
int param4,
9+
int param5,
10+
int param6,
11+
int param7,
12+
int param8,
13+
int param9,
14+
int param10
15+
) {}
16+
}
17+
18+
// @formatter:off
19+
public class PrettierIgnoreClass {
20+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
21+
22+
}
23+
}
24+
25+
// @formatter:on
26+
public class PrettierIgnoreClass {
27+
28+
public void myMethod(
29+
int param1,
30+
int param2,
31+
int param3,
32+
int param4,
33+
int param5,
34+
int param6,
35+
int param7,
36+
int param8,
37+
int param9,
38+
int param10
39+
) {}
40+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @formatter:off
2+
public class PrettierIgnoreClass {
3+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
4+
5+
}
6+
}
7+
// @formatter:on
8+
public class PrettierIgnoreClass {
9+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
10+
11+
}
12+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// @formatter:off
2+
public class PrettierIgnoreClass {
3+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
4+
5+
}
6+
}
7+
8+
// @formatter:on
9+
public class PrettierIgnoreClass {
10+
11+
public void myMethod(
12+
int param1,
13+
int param2,
14+
int param3,
15+
int param4,
16+
int param5,
17+
int param6,
18+
int param7,
19+
int param8,
20+
int param9,
21+
int param10
22+
) {}
23+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// @formatter:off
2+
public class PrettierIgnoreClass {
3+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
4+
5+
}
6+
}
7+
// @formatter:on
8+
public class PrettierIgnoreClass {
9+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
10+
11+
}
12+
}
13+
14+
// @formatter:off
15+
public class PrettierIgnoreClass {
16+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
17+
18+
}
19+
}
20+
21+
public class PrettierIgnoreClass {
22+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
23+
24+
}
25+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// @formatter:off
2+
public class PrettierIgnoreClass {
3+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
4+
5+
}
6+
}
7+
8+
// @formatter:on
9+
public class PrettierIgnoreClass {
10+
11+
public void myMethod(
12+
int param1,
13+
int param2,
14+
int param3,
15+
int param4,
16+
int param5,
17+
int param6,
18+
int param7,
19+
int param8,
20+
int param9,
21+
int param10
22+
) {}
23+
}
24+
25+
// @formatter:off
26+
public class PrettierIgnoreClass {
27+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
28+
29+
}
30+
}
31+
32+
public class PrettierIgnoreClass {
33+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
34+
35+
}
36+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
public class PrettierIgnoreClass {
2+
public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) {
3+
// @formatter:off
4+
System.out.println("This operation with two very long string should not break because the formatter is off");
5+
// @formatter:on
6+
System.out.println("This operation with two very long string should break because the formatter is on");
7+
}
8+
}

0 commit comments

Comments
 (0)