prettier-plugin-java 2.6.0 → 2.6.1
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 +9 -4
- package/dist/base-cst-printer.js +0 -55
- package/dist/cst-printer.js +0 -29
- package/dist/index.js +0 -66
- package/dist/options.js +0 -254
- package/dist/parser.js +0 -4
- package/dist/printer.js +0 -6
- package/dist/printers/arrays.js +0 -25
- package/dist/printers/blocks-and-statements.js +0 -435
- package/dist/printers/classes.js +0 -698
- package/dist/printers/comments/comments-utils.js +0 -21
- package/dist/printers/comments/format-comments.js +0 -171
- package/dist/printers/comments/handle-comments.js +0 -73
- package/dist/printers/expressions.js +0 -543
- package/dist/printers/interfaces.js +0 -218
- package/dist/printers/lexical-structure.js +0 -31
- package/dist/printers/names.js +0 -29
- package/dist/printers/packages-and-modules.js +0 -171
- package/dist/printers/prettier-builder.js +0 -45
- package/dist/printers/printer-utils.js +0 -592
- package/dist/printers/types-values-and-variables.js +0 -153
- package/dist/types/utils.js +0 -20
- package/dist/utils/expressions-utils.js +0 -25
- package/dist/utils/index.js +0 -2
- package/dist/utils/isEmptyDoc.js +0 -4
- package/dist/utils/printArgumentListWithBraces.js +0 -31
- package/dist/utils/printSingleLambdaInvocation.js +0 -18
|
@@ -1,592 +0,0 @@
|
|
|
1
|
-
import findIndex from "lodash/findIndex.js";
|
|
2
|
-
import findLastIndex from "lodash/findLastIndex.js";
|
|
3
|
-
import forEach from "lodash/forEach.js";
|
|
4
|
-
import forEachRight from "lodash/forEachRight.js";
|
|
5
|
-
import includes from "lodash/includes.js";
|
|
6
|
-
import { builders } from "prettier/doc";
|
|
7
|
-
import { isCstNode } from "../types/utils.js";
|
|
8
|
-
import { isEmptyDoc } from "../utils/index.js";
|
|
9
|
-
import { hasComments, hasLeadingComments, hasTrailingComments } from "./comments/comments-utils.js";
|
|
10
|
-
import { getTokenLeadingComments, printTokenWithComments } from "./comments/format-comments.js";
|
|
11
|
-
import { concat, group, ifBreak, indentIfBreak, join } from "./prettier-builder.js";
|
|
12
|
-
const { indent, hardline, line } = builders;
|
|
13
|
-
const orderedModifiers = [
|
|
14
|
-
"Public",
|
|
15
|
-
"Protected",
|
|
16
|
-
"Private",
|
|
17
|
-
"Abstract",
|
|
18
|
-
"Default",
|
|
19
|
-
"Static",
|
|
20
|
-
"Final",
|
|
21
|
-
"Transient",
|
|
22
|
-
"Volatile",
|
|
23
|
-
"Synchronized",
|
|
24
|
-
"Native",
|
|
25
|
-
"Sealed",
|
|
26
|
-
"NonSealed",
|
|
27
|
-
"Strictfp"
|
|
28
|
-
];
|
|
29
|
-
export function buildFqn(tokens, dots) {
|
|
30
|
-
return rejectAndJoinSeps(dots ? dots : [], tokens);
|
|
31
|
-
}
|
|
32
|
-
export function rejectAndJoinSeps(sepTokens, elems, sep) {
|
|
33
|
-
if (!Array.isArray(sepTokens)) {
|
|
34
|
-
return rejectAndJoin(sepTokens, elems);
|
|
35
|
-
}
|
|
36
|
-
const actualElements = reject(elems);
|
|
37
|
-
const res = [];
|
|
38
|
-
for (let i = 0; i < sepTokens.length; i++) {
|
|
39
|
-
res.push(actualElements[i], sepTokens[i]);
|
|
40
|
-
if (sep) {
|
|
41
|
-
res.push(sep);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
res.push(...actualElements.slice(sepTokens.length));
|
|
45
|
-
return concat(res);
|
|
46
|
-
}
|
|
47
|
-
export function reject(elems) {
|
|
48
|
-
return elems.filter(item => {
|
|
49
|
-
if (typeof item === "string") {
|
|
50
|
-
return item !== "";
|
|
51
|
-
}
|
|
52
|
-
// eslint-ignore next - We want the conversion to boolean!
|
|
53
|
-
// @ts-ignore
|
|
54
|
-
return item != false && item !== undefined;
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
export function rejectSeparators(separators, elems) {
|
|
58
|
-
const realElements = reject(elems);
|
|
59
|
-
const realSeparators = [];
|
|
60
|
-
for (let i = 0; i < realElements.length - 1; i++) {
|
|
61
|
-
if (realElements[i] !== "") {
|
|
62
|
-
realSeparators.push(separators[i]);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return realSeparators;
|
|
66
|
-
}
|
|
67
|
-
export function rejectAndJoin(sep, elems) {
|
|
68
|
-
const actualElements = reject(elems);
|
|
69
|
-
return join(sep, actualElements);
|
|
70
|
-
}
|
|
71
|
-
export function rejectAndConcat(elems) {
|
|
72
|
-
const actualElements = reject(elems);
|
|
73
|
-
return concat(actualElements);
|
|
74
|
-
}
|
|
75
|
-
export function sortAnnotationIdentifier(annotations, identifiers) {
|
|
76
|
-
let tokens = [...identifiers];
|
|
77
|
-
if (annotations && annotations.length > 0) {
|
|
78
|
-
tokens = [...tokens, ...annotations];
|
|
79
|
-
}
|
|
80
|
-
return tokens.sort((a, b) => {
|
|
81
|
-
const startOffset1 = isCstNode(a)
|
|
82
|
-
? a.children.At[0].startOffset
|
|
83
|
-
: a.startOffset;
|
|
84
|
-
const startOffset2 = isCstNode(b)
|
|
85
|
-
? b.children.At[0].startOffset
|
|
86
|
-
: b.startOffset;
|
|
87
|
-
return startOffset1 - startOffset2;
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
export function sortTokens(values) {
|
|
91
|
-
let tokens = [];
|
|
92
|
-
forEach(values, argument => {
|
|
93
|
-
if (argument) {
|
|
94
|
-
tokens = tokens.concat(argument);
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
return tokens.sort((a, b) => {
|
|
98
|
-
return a.startOffset - b.startOffset;
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
export function sortNodes(values) {
|
|
102
|
-
let nodes = [];
|
|
103
|
-
forEach(values, argument => {
|
|
104
|
-
if (argument) {
|
|
105
|
-
nodes = nodes.concat(argument);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
return nodes.sort((a, b) => {
|
|
109
|
-
const aOffset = a.location.startOffset;
|
|
110
|
-
const bOffset = b.location.startOffset;
|
|
111
|
-
return aOffset - bOffset;
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
export function matchCategory(token, categoryName) {
|
|
115
|
-
const labels = (token.tokenType.CATEGORIES || []).map(category => {
|
|
116
|
-
return category.LABEL;
|
|
117
|
-
});
|
|
118
|
-
return labels.indexOf(categoryName) !== -1;
|
|
119
|
-
}
|
|
120
|
-
export function sortClassTypeChildren(annotations, typeArguments, identifiers, dots) {
|
|
121
|
-
let tokens = [...identifiers];
|
|
122
|
-
if (annotations && annotations.length > 0) {
|
|
123
|
-
tokens = [...tokens, ...annotations];
|
|
124
|
-
}
|
|
125
|
-
if (typeArguments && typeArguments.length > 0) {
|
|
126
|
-
tokens = [...tokens, ...typeArguments];
|
|
127
|
-
}
|
|
128
|
-
if (dots && dots.length > 0) {
|
|
129
|
-
tokens = [...tokens, ...dots];
|
|
130
|
-
}
|
|
131
|
-
return tokens.sort((a, b) => {
|
|
132
|
-
const startOffsetA = isCstNode(a)
|
|
133
|
-
? a.children.At
|
|
134
|
-
? a.children.At[0].startOffset
|
|
135
|
-
: a.children.Less[0].startOffset
|
|
136
|
-
: a.startOffset;
|
|
137
|
-
const startOffsetB = isCstNode(b)
|
|
138
|
-
? b.children.At
|
|
139
|
-
? b.children.At[0].startOffset
|
|
140
|
-
: b.children.Less[0].startOffset
|
|
141
|
-
: b.startOffset;
|
|
142
|
-
return startOffsetA - startOffsetB;
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
export function sortModifiers(modifiers) {
|
|
146
|
-
let firstAnnotations = [];
|
|
147
|
-
const otherModifiers = [];
|
|
148
|
-
let lastAnnotations = [];
|
|
149
|
-
let hasOtherModifier = false;
|
|
150
|
-
/**
|
|
151
|
-
* iterate in reverse order because we special-case
|
|
152
|
-
* type annotations which come after all other
|
|
153
|
-
* modifiers
|
|
154
|
-
*/
|
|
155
|
-
forEachRight(modifiers, modifier => {
|
|
156
|
-
const isAnnotation = modifier.children.annotation !== undefined;
|
|
157
|
-
const isTypeAnnotation = isAnnotation &&
|
|
158
|
-
(modifier.name === "methodModifier" ||
|
|
159
|
-
modifier.name === "interfaceMethodModifier" ||
|
|
160
|
-
modifier.name === "fieldModifier");
|
|
161
|
-
if (isAnnotation) {
|
|
162
|
-
if (isTypeAnnotation && !hasOtherModifier) {
|
|
163
|
-
lastAnnotations.unshift(modifier);
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
firstAnnotations.unshift(modifier);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
otherModifiers.unshift(modifier);
|
|
171
|
-
hasOtherModifier = true;
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
/**
|
|
175
|
-
* if there are only annotations, move everything from
|
|
176
|
-
* lastAnnotations to firstAnnotations
|
|
177
|
-
*/
|
|
178
|
-
if (!hasOtherModifier) {
|
|
179
|
-
firstAnnotations = firstAnnotations.concat(lastAnnotations);
|
|
180
|
-
lastAnnotations = [];
|
|
181
|
-
}
|
|
182
|
-
otherModifiers.sort((a, b) => {
|
|
183
|
-
const modifierIndexA = orderedModifiers.indexOf(Object.keys(a.children)[0]);
|
|
184
|
-
const modifierIndexB = orderedModifiers.indexOf(Object.keys(b.children)[0]);
|
|
185
|
-
return modifierIndexA - modifierIndexB;
|
|
186
|
-
});
|
|
187
|
-
return [firstAnnotations, otherModifiers.concat(lastAnnotations)];
|
|
188
|
-
}
|
|
189
|
-
export function findDeepElementInPartsArray(item, elt) {
|
|
190
|
-
if (Array.isArray(item)) {
|
|
191
|
-
if (includes(item, elt)) {
|
|
192
|
-
return true;
|
|
193
|
-
}
|
|
194
|
-
for (let i = 0; i < item.length; i++) {
|
|
195
|
-
if (findDeepElementInPartsArray(item[i], elt)) {
|
|
196
|
-
return true;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
for (const key in item) {
|
|
202
|
-
if (typeof item[key] === "object" &&
|
|
203
|
-
findDeepElementInPartsArray(item[key], elt)) {
|
|
204
|
-
return true;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return false;
|
|
209
|
-
}
|
|
210
|
-
export function displaySemicolon(token, params) {
|
|
211
|
-
if (params !== undefined && params.allowEmptyStatement) {
|
|
212
|
-
return printTokenWithComments(token);
|
|
213
|
-
}
|
|
214
|
-
if (!hasComments(token)) {
|
|
215
|
-
return "";
|
|
216
|
-
}
|
|
217
|
-
token.image = "";
|
|
218
|
-
return printTokenWithComments(token);
|
|
219
|
-
}
|
|
220
|
-
export function isExplicitLambdaParameter(ctx) {
|
|
221
|
-
return (ctx &&
|
|
222
|
-
ctx.lambdaParameterList &&
|
|
223
|
-
ctx.lambdaParameterList[0] &&
|
|
224
|
-
ctx.lambdaParameterList[0].children &&
|
|
225
|
-
ctx.lambdaParameterList[0].children.explicitLambdaParameterList);
|
|
226
|
-
}
|
|
227
|
-
export function getBlankLinesSeparator(ctx, separator = hardline) {
|
|
228
|
-
if (ctx === undefined) {
|
|
229
|
-
return [];
|
|
230
|
-
}
|
|
231
|
-
const separators = [];
|
|
232
|
-
for (let i = 0; i < ctx.length - 1; i++) {
|
|
233
|
-
const node = ctx[i];
|
|
234
|
-
const previousRuleEndLineWithComment = hasTrailingComments(node)
|
|
235
|
-
? node.trailingComments[node.trailingComments.length - 1].endLine
|
|
236
|
-
: node.location.endLine;
|
|
237
|
-
const nextNode = ctx[i + 1];
|
|
238
|
-
const nextRuleStartLineWithComment = hasLeadingComments(nextNode)
|
|
239
|
-
? nextNode.leadingComments[0].startLine
|
|
240
|
-
: nextNode.location.startLine;
|
|
241
|
-
if (nextRuleStartLineWithComment - previousRuleEndLineWithComment > 1) {
|
|
242
|
-
separators.push([hardline, hardline]);
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
separators.push(separator);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
return separators;
|
|
249
|
-
}
|
|
250
|
-
const isTwoHardLine = (userBlankLinesSeparator) => {
|
|
251
|
-
if (!Array.isArray(userBlankLinesSeparator)) {
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
return (userBlankLinesSeparator.length === 2 &&
|
|
255
|
-
userBlankLinesSeparator[0] === hardline &&
|
|
256
|
-
userBlankLinesSeparator[1] === hardline);
|
|
257
|
-
};
|
|
258
|
-
function getDeclarationsSeparator(declarations, needLineDeclaration, isSemicolon) {
|
|
259
|
-
const declarationsWithoutEmptyStatements = declarations.filter(declaration => !isSemicolon(declaration));
|
|
260
|
-
const userBlankLinesSeparators = getBlankLinesSeparator(declarationsWithoutEmptyStatements);
|
|
261
|
-
const additionalBlankLines = declarationsWithoutEmptyStatements.map(needLineDeclaration);
|
|
262
|
-
const separators = [];
|
|
263
|
-
let indexNextNotEmptyDeclaration = 0;
|
|
264
|
-
for (let i = 0; i < declarations.length - 1; i++) {
|
|
265
|
-
// if the empty statement has comments
|
|
266
|
-
// we want to print them on their own line
|
|
267
|
-
if (isSemicolon(declarations[i])) {
|
|
268
|
-
if (hasComments(declarations[i])) {
|
|
269
|
-
separators.push(hardline);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
else if (indexNextNotEmptyDeclaration <
|
|
273
|
-
declarationsWithoutEmptyStatements.length - 1) {
|
|
274
|
-
const isNextSeparatorTwoHardLine = isTwoHardLine(userBlankLinesSeparators[indexNextNotEmptyDeclaration]);
|
|
275
|
-
const additionalSep = !isNextSeparatorTwoHardLine &&
|
|
276
|
-
(additionalBlankLines[indexNextNotEmptyDeclaration + 1] ||
|
|
277
|
-
additionalBlankLines[indexNextNotEmptyDeclaration])
|
|
278
|
-
? hardline
|
|
279
|
-
: "";
|
|
280
|
-
separators.push(concat([
|
|
281
|
-
userBlankLinesSeparators[indexNextNotEmptyDeclaration],
|
|
282
|
-
additionalSep
|
|
283
|
-
]));
|
|
284
|
-
indexNextNotEmptyDeclaration += 1;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
return separators;
|
|
288
|
-
}
|
|
289
|
-
function needLineClassBodyDeclaration(declaration) {
|
|
290
|
-
if (declaration.children.classMemberDeclaration === undefined) {
|
|
291
|
-
return true;
|
|
292
|
-
}
|
|
293
|
-
const classMemberDeclaration = declaration.children.classMemberDeclaration[0];
|
|
294
|
-
if (classMemberDeclaration.children.fieldDeclaration !== undefined) {
|
|
295
|
-
const fieldDeclaration = classMemberDeclaration.children.fieldDeclaration[0];
|
|
296
|
-
if (fieldDeclaration.children.fieldModifier !== undefined &&
|
|
297
|
-
hasAnnotation(fieldDeclaration.children.fieldModifier) &&
|
|
298
|
-
hasNonTrailingAnnotation(fieldDeclaration.children.fieldModifier)) {
|
|
299
|
-
return true;
|
|
300
|
-
}
|
|
301
|
-
return false;
|
|
302
|
-
}
|
|
303
|
-
else if (classMemberDeclaration.children.Semicolon !== undefined) {
|
|
304
|
-
return false;
|
|
305
|
-
}
|
|
306
|
-
return true;
|
|
307
|
-
}
|
|
308
|
-
function needLineInterfaceMemberDeclaration(declaration) {
|
|
309
|
-
if (declaration.children.constantDeclaration !== undefined) {
|
|
310
|
-
const constantDeclaration = declaration.children.constantDeclaration[0];
|
|
311
|
-
if (constantDeclaration.children.constantModifier !== undefined &&
|
|
312
|
-
hasAnnotation(constantDeclaration.children.constantModifier) &&
|
|
313
|
-
hasNonTrailingAnnotation(constantDeclaration.children.constantModifier)) {
|
|
314
|
-
return true;
|
|
315
|
-
}
|
|
316
|
-
return false;
|
|
317
|
-
}
|
|
318
|
-
else if (declaration.children.interfaceMethodDeclaration !== undefined) {
|
|
319
|
-
const interfaceMethodDeclaration = declaration.children.interfaceMethodDeclaration[0];
|
|
320
|
-
if (interfaceMethodDeclaration.children.interfaceMethodModifier !==
|
|
321
|
-
undefined &&
|
|
322
|
-
hasNonTrailingAnnotation(interfaceMethodDeclaration.children.interfaceMethodModifier)) {
|
|
323
|
-
return true;
|
|
324
|
-
}
|
|
325
|
-
return false;
|
|
326
|
-
}
|
|
327
|
-
return true;
|
|
328
|
-
}
|
|
329
|
-
function isClassBodyDeclarationASemicolon(classBodyDeclaration) {
|
|
330
|
-
if (classBodyDeclaration.children.classMemberDeclaration) {
|
|
331
|
-
if (classBodyDeclaration.children.classMemberDeclaration[0].children
|
|
332
|
-
.Semicolon !== undefined) {
|
|
333
|
-
return true;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
return false;
|
|
337
|
-
}
|
|
338
|
-
function isInterfaceMemberASemicolon(interfaceMemberDeclaration) {
|
|
339
|
-
return interfaceMemberDeclaration.children.Semicolon !== undefined;
|
|
340
|
-
}
|
|
341
|
-
function hasAnnotation(modifiers) {
|
|
342
|
-
return modifiers.some(modifier => modifier.children.annotation !== undefined);
|
|
343
|
-
}
|
|
344
|
-
/**
|
|
345
|
-
* Return true if there is a modifier that does not come after all other modifiers
|
|
346
|
-
* It is useful to know if sortModifiers will add an annotation before other modifiers
|
|
347
|
-
*
|
|
348
|
-
* @param modifiers
|
|
349
|
-
* @returns {boolean}
|
|
350
|
-
*/
|
|
351
|
-
function hasNonTrailingAnnotation(modifiers) {
|
|
352
|
-
const firstAnnotationIndex = findIndex(modifiers, modifier => modifier.children.annotation !== undefined);
|
|
353
|
-
const lastNonAnnotationIndex = findLastIndex(modifiers, modifier => modifier.children.annotation === undefined);
|
|
354
|
-
return (firstAnnotationIndex < lastNonAnnotationIndex ||
|
|
355
|
-
lastNonAnnotationIndex === -1);
|
|
356
|
-
}
|
|
357
|
-
export function getClassBodyDeclarationsSeparator(classBodyDeclarationContext) {
|
|
358
|
-
return getDeclarationsSeparator(classBodyDeclarationContext, needLineClassBodyDeclaration, isClassBodyDeclarationASemicolon);
|
|
359
|
-
}
|
|
360
|
-
export function getInterfaceBodyDeclarationsSeparator(interfaceMemberDeclarationContext) {
|
|
361
|
-
return getDeclarationsSeparator(interfaceMemberDeclarationContext, needLineInterfaceMemberDeclaration, isInterfaceMemberASemicolon);
|
|
362
|
-
}
|
|
363
|
-
function getAndRemoveLeadingComment(doc) {
|
|
364
|
-
const isTokenWithLeadingComment = typeof doc !== "string" && "leadingComments" in doc;
|
|
365
|
-
if (!isTokenWithLeadingComment) {
|
|
366
|
-
return [];
|
|
367
|
-
}
|
|
368
|
-
const leadingComments = getTokenLeadingComments(doc);
|
|
369
|
-
delete doc.leadingComments;
|
|
370
|
-
return leadingComments;
|
|
371
|
-
}
|
|
372
|
-
export function putIntoBraces(argument, separator, LBrace, RBrace) {
|
|
373
|
-
const rightBraceLeadingComments = getAndRemoveLeadingComment(RBrace);
|
|
374
|
-
const lastBreakLine =
|
|
375
|
-
// check if last element of the array is a line
|
|
376
|
-
rightBraceLeadingComments.length !== 0 &&
|
|
377
|
-
rightBraceLeadingComments[rightBraceLeadingComments.length - 1] === hardline
|
|
378
|
-
? rightBraceLeadingComments.pop()
|
|
379
|
-
: separator;
|
|
380
|
-
let contentInsideBraces;
|
|
381
|
-
if (isEmptyDoc(argument)) {
|
|
382
|
-
if (rightBraceLeadingComments.length === 0) {
|
|
383
|
-
return concat([LBrace, RBrace]);
|
|
384
|
-
}
|
|
385
|
-
contentInsideBraces = [separator, ...rightBraceLeadingComments];
|
|
386
|
-
}
|
|
387
|
-
else if (rightBraceLeadingComments.length !== 0) {
|
|
388
|
-
contentInsideBraces = [
|
|
389
|
-
separator,
|
|
390
|
-
argument,
|
|
391
|
-
separator,
|
|
392
|
-
...rightBraceLeadingComments
|
|
393
|
-
];
|
|
394
|
-
}
|
|
395
|
-
else {
|
|
396
|
-
contentInsideBraces = [separator, argument];
|
|
397
|
-
}
|
|
398
|
-
return group(rejectAndConcat([
|
|
399
|
-
LBrace,
|
|
400
|
-
indent(concat(contentInsideBraces)),
|
|
401
|
-
lastBreakLine,
|
|
402
|
-
RBrace
|
|
403
|
-
]));
|
|
404
|
-
}
|
|
405
|
-
export function binary(nodes, tokens, isRoot = false) {
|
|
406
|
-
let levelOperator;
|
|
407
|
-
let levelPrecedence;
|
|
408
|
-
let level = [];
|
|
409
|
-
while (tokens.length) {
|
|
410
|
-
const nextOperator = getOperator(tokens);
|
|
411
|
-
const nextPrecedence = getOperatorPrecedence(nextOperator);
|
|
412
|
-
if (levelPrecedence === undefined || nextPrecedence === levelPrecedence) {
|
|
413
|
-
const tokenLength = ["<<", ">>", ">>>"].includes(nextOperator)
|
|
414
|
-
? nextOperator.length
|
|
415
|
-
: 1;
|
|
416
|
-
const operator = concat(tokens.splice(0, tokenLength));
|
|
417
|
-
if (levelOperator !== undefined &&
|
|
418
|
-
needsParentheses(levelOperator, nextOperator)) {
|
|
419
|
-
level.push(nodes.shift());
|
|
420
|
-
level = [
|
|
421
|
-
concat(["(", group(indent(join(line, level))), ") ", operator])
|
|
422
|
-
];
|
|
423
|
-
}
|
|
424
|
-
else {
|
|
425
|
-
level.push(join(" ", [nodes.shift(), operator]));
|
|
426
|
-
}
|
|
427
|
-
levelOperator = nextOperator;
|
|
428
|
-
levelPrecedence = nextPrecedence;
|
|
429
|
-
}
|
|
430
|
-
else if (nextPrecedence < levelPrecedence) {
|
|
431
|
-
level.push(nodes.shift());
|
|
432
|
-
if (isRoot) {
|
|
433
|
-
const content = group(indent(join(line, level)));
|
|
434
|
-
nodes.unshift(levelOperator !== undefined &&
|
|
435
|
-
needsParentheses(levelOperator, nextOperator)
|
|
436
|
-
? concat(["(", content, ")"])
|
|
437
|
-
: content);
|
|
438
|
-
level = [];
|
|
439
|
-
levelOperator = undefined;
|
|
440
|
-
levelPrecedence = undefined;
|
|
441
|
-
}
|
|
442
|
-
else {
|
|
443
|
-
return group(join(line, level));
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
else {
|
|
447
|
-
const content = indent(binary(nodes, tokens));
|
|
448
|
-
nodes.unshift(levelOperator !== undefined &&
|
|
449
|
-
needsParentheses(nextOperator, levelOperator)
|
|
450
|
-
? concat(["(", content, ")"])
|
|
451
|
-
: content);
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
level.push(nodes.shift());
|
|
455
|
-
const lineGroupId = Symbol("line");
|
|
456
|
-
return group(levelOperator === "="
|
|
457
|
-
? [
|
|
458
|
-
level[0],
|
|
459
|
-
indent(group(line, { id: lineGroupId })),
|
|
460
|
-
indentIfBreak(level[1], { groupId: lineGroupId })
|
|
461
|
-
]
|
|
462
|
-
: join(line, level));
|
|
463
|
-
}
|
|
464
|
-
function getOperator(tokens) {
|
|
465
|
-
if (!tokens.length) {
|
|
466
|
-
return "";
|
|
467
|
-
}
|
|
468
|
-
const [{ image, startOffset }] = tokens;
|
|
469
|
-
if (!["<", ">"].includes(image)) {
|
|
470
|
-
return image;
|
|
471
|
-
}
|
|
472
|
-
let repeatedTokenCount = 1;
|
|
473
|
-
for (let i = 1; i < Math.min(3, tokens.length); i++) {
|
|
474
|
-
const token = tokens[i];
|
|
475
|
-
if (token.image !== image || token.startOffset !== startOffset + i) {
|
|
476
|
-
break;
|
|
477
|
-
}
|
|
478
|
-
repeatedTokenCount++;
|
|
479
|
-
}
|
|
480
|
-
if (repeatedTokenCount === 1) {
|
|
481
|
-
return image;
|
|
482
|
-
}
|
|
483
|
-
if (image === "<") {
|
|
484
|
-
return "<<";
|
|
485
|
-
}
|
|
486
|
-
else if (repeatedTokenCount == 2) {
|
|
487
|
-
return ">>";
|
|
488
|
-
}
|
|
489
|
-
else {
|
|
490
|
-
return ">>>";
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
const PRECEDENCES_BY_OPERATOR = new Map([
|
|
494
|
-
["||"],
|
|
495
|
-
["&&"],
|
|
496
|
-
["|"],
|
|
497
|
-
["^"],
|
|
498
|
-
["&"],
|
|
499
|
-
["==", "!="],
|
|
500
|
-
["<", ">", "<=", ">=", "instanceof"],
|
|
501
|
-
["<<", ">>", ">>>"],
|
|
502
|
-
["+", "-"],
|
|
503
|
-
["*", "/", "%"]
|
|
504
|
-
].flatMap((operators, index) => operators.map(operator => [operator, index])));
|
|
505
|
-
function getOperatorPrecedence(operator) {
|
|
506
|
-
var _a;
|
|
507
|
-
return (_a = PRECEDENCES_BY_OPERATOR.get(operator)) !== null && _a !== void 0 ? _a : -1;
|
|
508
|
-
}
|
|
509
|
-
function needsParentheses(operator, parentOperator) {
|
|
510
|
-
return ((operator === "&&" && parentOperator === "||") ||
|
|
511
|
-
(["|", "^", "&", "<<", ">>", ">>>"].includes(parentOperator) &&
|
|
512
|
-
getOperatorPrecedence(operator) >
|
|
513
|
-
getOperatorPrecedence(parentOperator)) ||
|
|
514
|
-
[operator, parentOperator].every(o => ["==", "!="].includes(o)) ||
|
|
515
|
-
[operator, parentOperator].every(o => ["<<", ">>", ">>>"].includes(o)) ||
|
|
516
|
-
(operator === "*" && parentOperator === "/") ||
|
|
517
|
-
(operator === "/" && parentOperator === "*") ||
|
|
518
|
-
(operator === "%" && ["+", "-", "*", "/"].includes(parentOperator)) ||
|
|
519
|
-
(["*", "/"].includes(operator) && parentOperator === "%"));
|
|
520
|
-
}
|
|
521
|
-
export function isStatementEmptyStatement(statement) {
|
|
522
|
-
return (statement === ";" || (Array.isArray(statement) && statement[0] === ";"));
|
|
523
|
-
}
|
|
524
|
-
export function sortImports(imports) {
|
|
525
|
-
const staticImports = [];
|
|
526
|
-
const nonStaticImports = [];
|
|
527
|
-
if (imports !== undefined) {
|
|
528
|
-
for (let i = 0; i < imports.length; i++) {
|
|
529
|
-
if (imports[i].children.Static !== undefined) {
|
|
530
|
-
staticImports.push(imports[i]);
|
|
531
|
-
}
|
|
532
|
-
else if (imports[i].children.emptyStatement === undefined) {
|
|
533
|
-
nonStaticImports.push(imports[i]);
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
// TODO: Could be optimized as we could expect that the array is already almost sorted
|
|
537
|
-
const comparator = (first, second) => compareFqn(first.children.packageOrTypeName[0], second.children.packageOrTypeName[0]);
|
|
538
|
-
staticImports.sort(comparator);
|
|
539
|
-
nonStaticImports.sort(comparator);
|
|
540
|
-
}
|
|
541
|
-
return {
|
|
542
|
-
staticImports,
|
|
543
|
-
nonStaticImports
|
|
544
|
-
};
|
|
545
|
-
}
|
|
546
|
-
function compareFqn(packageOrTypeNameFirst, packageOrTypeNameSecond) {
|
|
547
|
-
const identifiersFirst = packageOrTypeNameFirst.children.Identifier;
|
|
548
|
-
const identifiersSecond = packageOrTypeNameSecond.children.Identifier;
|
|
549
|
-
const minParts = Math.min(identifiersFirst.length, identifiersSecond.length);
|
|
550
|
-
for (let i = 0; i < minParts; i++) {
|
|
551
|
-
if (identifiersFirst[i].image < identifiersSecond[i].image) {
|
|
552
|
-
return -1;
|
|
553
|
-
}
|
|
554
|
-
else if (identifiersFirst[i].image > identifiersSecond[i].image) {
|
|
555
|
-
return 1;
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
if (identifiersFirst.length < identifiersSecond.length) {
|
|
559
|
-
return -1;
|
|
560
|
-
}
|
|
561
|
-
else if (identifiersFirst.length > identifiersSecond.length) {
|
|
562
|
-
return 1;
|
|
563
|
-
}
|
|
564
|
-
return 0;
|
|
565
|
-
}
|
|
566
|
-
export function isUniqueMethodInvocation(primarySuffixes) {
|
|
567
|
-
if (primarySuffixes === undefined) {
|
|
568
|
-
return 0;
|
|
569
|
-
}
|
|
570
|
-
let count = 0;
|
|
571
|
-
primarySuffixes.forEach(primarySuffix => {
|
|
572
|
-
if (primarySuffix.children.methodInvocationSuffix !== undefined) {
|
|
573
|
-
count++;
|
|
574
|
-
if (count > 1) {
|
|
575
|
-
return 2;
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
});
|
|
579
|
-
return count;
|
|
580
|
-
}
|
|
581
|
-
export function printArrayList({ list, extraComma, LCurly, RCurly, trailingComma }) {
|
|
582
|
-
let optionalComma;
|
|
583
|
-
if (trailingComma !== "none" && list !== "") {
|
|
584
|
-
optionalComma = extraComma
|
|
585
|
-
? ifBreak(extraComma[0], Object.assign(Object.assign({}, extraComma[0]), { image: "" }))
|
|
586
|
-
: ifBreak(",", "");
|
|
587
|
-
}
|
|
588
|
-
else {
|
|
589
|
-
optionalComma = extraComma ? Object.assign(Object.assign({}, extraComma[0]), { image: "" }) : "";
|
|
590
|
-
}
|
|
591
|
-
return putIntoBraces(rejectAndConcat([list, optionalComma]), line, LCurly, RCurly);
|
|
592
|
-
}
|