@prettier/plugin-php 0.20.0 → 0.20.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/src/printer.js CHANGED
@@ -1,5 +1,4 @@
1
- "use strict";
2
-
1
+ import { util as prettierUtil, doc } from "prettier";
3
2
  const {
4
3
  breakParent,
5
4
  join,
@@ -15,14 +14,22 @@ const {
15
14
  literalline,
16
15
  align,
17
16
  dedentToRoot,
18
- } = require("prettier").doc.builders;
19
- const { willBreak } = require("prettier").doc.utils;
17
+ } = doc.builders;
18
+ const { willBreak } = doc.utils;
20
19
  const { isNextLineEmptyAfterIndex, hasNewline, hasNewlineInRange } =
21
- require("prettier").util;
22
- const comments = require("./comments");
23
- const pathNeedsParens = require("./needs-parens");
24
-
25
- const {
20
+ prettierUtil;
21
+ import {
22
+ printAllComments,
23
+ hasTrailingComment,
24
+ hasLeadingComment,
25
+ printDanglingComments,
26
+ printComments,
27
+ isBlockComment,
28
+ hasLeadingOwnLineComment,
29
+ } from "./comments.js";
30
+ import pathNeedsParens from "./needs-parens.js";
31
+
32
+ import {
26
33
  getLast,
27
34
  getPenultimate,
28
35
  isLastStatement,
@@ -32,8 +39,6 @@ const {
32
39
  maybeStripLeadingSlashFromUse,
33
40
  fileShouldEndWithHardline,
34
41
  hasDanglingComments,
35
- hasLeadingComment,
36
- hasTrailingComment,
37
42
  docShouldHaveTrailingNewline,
38
43
  isLookupNode,
39
44
  isFirstChildrenInlineNode,
@@ -54,7 +59,7 @@ const {
54
59
  getNextNonSpaceNonCommentCharacterIndex,
55
60
  isNextLineEmpty,
56
61
  isPreviousLineEmpty,
57
- } = require("./util");
62
+ } from "./util.js";
58
63
 
59
64
  function isMinVersion(actualVersion, requiredVersion) {
60
65
  return parseFloat(actualVersion) >= parseFloat(requiredVersion);
@@ -80,11 +85,9 @@ function shouldPrintHardlineForOpenBrace(options) {
80
85
  }
81
86
 
82
87
  function genericPrint(path, options, print) {
83
- const node = path.getValue();
88
+ const { node } = path;
84
89
 
85
- if (!node) {
86
- return "";
87
- } else if (typeof node === "string") {
90
+ if (typeof node === "string") {
88
91
  return node;
89
92
  }
90
93
 
@@ -123,14 +126,14 @@ function printNullsafePropertyLookup(path, options, print) {
123
126
  }
124
127
 
125
128
  function printStaticLookup(path, options, print) {
126
- const node = path.getValue();
129
+ const { node } = path;
127
130
  const needCurly = !["variable", "identifier"].includes(node.offset.kind);
128
131
 
129
132
  return ["::", needCurly ? "{" : "", print("offset"), needCurly ? "}" : ""];
130
133
  }
131
134
 
132
135
  function printOffsetLookup(path, options, print) {
133
- const node = path.getValue();
136
+ const { node } = path;
134
137
  const shouldInline =
135
138
  (node.offset && node.offset.kind === "number") ||
136
139
  getAncestorNode(path, "encapsed");
@@ -212,7 +215,7 @@ function printMemberChain(path, options, print) {
212
215
  }
213
216
 
214
217
  function traverse(path) {
215
- const node = path.getValue();
218
+ const { node } = path;
216
219
 
217
220
  if (
218
221
  node.kind === "call" &&
@@ -221,7 +224,7 @@ function printMemberChain(path, options, print) {
221
224
  printedNodes.unshift({
222
225
  node,
223
226
  printed: [
224
- comments.printAllComments(
227
+ printAllComments(
225
228
  path,
226
229
  () => printArgumentsList(path, options, print),
227
230
  options
@@ -247,11 +250,7 @@ function printMemberChain(path, options, print) {
247
250
  printedNodes.unshift({
248
251
  node,
249
252
  needsParens: pathNeedsParens(path, options),
250
- printed: comments.printAllComments(
251
- path,
252
- () => printedMemberish,
253
- options
254
- ),
253
+ printed: printAllComments(path, () => printedMemberish, options),
255
254
  });
256
255
  path.call((what) => traverse(what), "what");
257
256
  } else {
@@ -262,7 +261,7 @@ function printMemberChain(path, options, print) {
262
261
  }
263
262
  }
264
263
 
265
- const node = path.getValue();
264
+ const { node } = path;
266
265
 
267
266
  printedNodes.unshift({
268
267
  node,
@@ -365,7 +364,7 @@ function printMemberChain(path, options, print) {
365
364
 
366
365
  if (
367
366
  printedNodes[i].node.comments &&
368
- comments.hasTrailingComment(printedNodes[i].node)
367
+ hasTrailingComment(printedNodes[i].node)
369
368
  ) {
370
369
  groups.push(currentGroup);
371
370
  currentGroup = [];
@@ -426,8 +425,7 @@ function printMemberChain(path, options, print) {
426
425
  );
427
426
  }
428
427
 
429
- const isExpressionStatement =
430
- path.getParentNode().kind === "expressionstatement";
428
+ const isExpressionStatement = path.parent.kind === "expressionstatement";
431
429
  const shouldMerge =
432
430
  groups.length >= 2 && !groups[1][0].node.comments && shouldNotWrap(groups);
433
431
 
@@ -479,13 +477,9 @@ function printMemberChain(path, options, print) {
479
477
  const flatGroups = groups.slice(0, cutoff).flat();
480
478
 
481
479
  const hasComment =
482
- flatGroups
483
- .slice(1, -1)
484
- .some((node) => comments.hasLeadingComment(node.node)) ||
485
- flatGroups
486
- .slice(0, -1)
487
- .some((node) => comments.hasTrailingComment(node.node)) ||
488
- (groups[cutoff] && comments.hasLeadingComment(groups[cutoff][0].node));
480
+ flatGroups.slice(1, -1).some((node) => hasLeadingComment(node.node)) ||
481
+ flatGroups.slice(0, -1).some((node) => hasTrailingComment(node.node)) ||
482
+ (groups[cutoff] && hasLeadingComment(groups[cutoff][0].node));
489
483
 
490
484
  const hasEncapsedAncestor = getAncestorNode(path, "encapsed");
491
485
 
@@ -579,12 +573,12 @@ function shouldGroupFirstArg(args) {
579
573
  }
580
574
 
581
575
  function printArgumentsList(path, options, print, argumentsKey = "arguments") {
582
- const args = path.getValue()[argumentsKey];
576
+ const args = path.node[argumentsKey];
583
577
 
584
578
  if (args.length === 0) {
585
579
  return [
586
580
  "(",
587
- comments.printDanglingComments(path, options, /* sameIndent */ true),
581
+ printDanglingComments(path, options, /* sameIndent */ true),
588
582
  ")",
589
583
  ];
590
584
  }
@@ -592,15 +586,13 @@ function printArgumentsList(path, options, print, argumentsKey = "arguments") {
592
586
  let anyArgEmptyLine = false;
593
587
  let hasEmptyLineFollowingFirstArg = false;
594
588
 
595
- const lastArgIndex = args.length - 1;
596
- const printedArguments = path.map((argPath, index) => {
597
- const arg = argPath.getNode();
598
- const parts = [print(argPath)];
589
+ const printedArguments = path.map(({ node: arg, isLast, isFirst }) => {
590
+ const parts = [print()];
599
591
 
600
- if (index === lastArgIndex) {
592
+ if (isLast) {
601
593
  // do nothing
602
594
  } else if (isNextLineEmpty(options.originalText, arg, options)) {
603
- if (index === 0) {
595
+ if (isFirst) {
604
596
  hasEmptyLineFollowingFirstArg = true;
605
597
  }
606
598
 
@@ -613,7 +605,7 @@ function printArgumentsList(path, options, print, argumentsKey = "arguments") {
613
605
  return parts;
614
606
  }, argumentsKey);
615
607
 
616
- const node = path.getValue();
608
+ const { node } = path;
617
609
  const lastArg = getLast(args);
618
610
 
619
611
  const maybeTrailingComma =
@@ -649,12 +641,11 @@ function printArgumentsList(path, options, print, argumentsKey = "arguments") {
649
641
 
650
642
  // We want to print the last argument with a special flag
651
643
  let printedExpanded;
652
- let i = 0;
653
644
 
654
- path.each((argPath) => {
655
- if (shouldGroupFirst && i === 0) {
645
+ path.each(({ isLast, isFirst }) => {
646
+ if (shouldGroupFirst && isFirst) {
656
647
  printedExpanded = [
657
- argPath.call(() => print([], { expandFirstArg: true })),
648
+ print([], { expandFirstArg: true }),
658
649
  printedArguments.length > 1 ? "," : "",
659
650
  hasEmptyLineFollowingFirstArg ? hardline : line,
660
651
  hasEmptyLineFollowingFirstArg ? hardline : "",
@@ -662,14 +653,12 @@ function printArgumentsList(path, options, print, argumentsKey = "arguments") {
662
653
  ];
663
654
  }
664
655
 
665
- if (shouldGroupLast && i === args.length - 1) {
656
+ if (shouldGroupLast && isLast) {
666
657
  printedExpanded = [
667
658
  ...printedArguments.slice(0, -1),
668
- argPath.call(() => print([], { expandLastArg: true })),
659
+ print([], { expandLastArg: true }),
669
660
  ];
670
661
  }
671
-
672
- i++;
673
662
  }, argumentsKey);
674
663
 
675
664
  const somePrintedArgumentsWillBreak = printedArguments.some(willBreak);
@@ -751,7 +740,7 @@ function printBinaryExpression(
751
740
  isInsideParenthesis
752
741
  ) {
753
742
  let parts = [];
754
- const node = path.getValue();
743
+ const { node } = path;
755
744
 
756
745
  if (node.kind === "bin") {
757
746
  // Put all operators with the same precedence level in the same
@@ -790,7 +779,7 @@ function printBinaryExpression(
790
779
 
791
780
  // If there's only a single binary expression, we want to create a group
792
781
  // in order to avoid having a small right part like -1 be on its own line.
793
- const parent = path.getParentNode();
782
+ const { parent } = path;
794
783
  const shouldGroup =
795
784
  !(isInsideParenthesis && ["||", "&&"].includes(node.type)) &&
796
785
  getNodeKindIncludingLogical(parent) !==
@@ -813,7 +802,7 @@ function printBinaryExpression(
813
802
  // the other ones since we don't call the normal print on bin,
814
803
  // only for the left and right parts
815
804
  if (isNested && node.comments) {
816
- parts = comments.printAllComments(path, () => parts, options);
805
+ parts = printAllComments(path, () => parts, options);
817
806
  }
818
807
  } else {
819
808
  // Our stopping case. Simply print the node normally.
@@ -824,7 +813,7 @@ function printBinaryExpression(
824
813
  }
825
814
 
826
815
  function printLookupNodes(path, options, print) {
827
- const node = path.getValue();
816
+ const { node } = path;
828
817
 
829
818
  switch (node.kind) {
830
819
  case "propertylookup":
@@ -863,16 +852,13 @@ function printArrayItems(path, options, print) {
863
852
  const printedElements = [];
864
853
  let separatorParts = [];
865
854
 
866
- path.each((childPath) => {
855
+ path.each(({ node }) => {
867
856
  printedElements.push(separatorParts);
868
- printedElements.push(group(print(childPath)));
857
+ printedElements.push(group(print()));
869
858
 
870
859
  separatorParts = [",", line];
871
860
 
872
- if (
873
- childPath.getValue() &&
874
- isNextLineEmpty(options.originalText, childPath.getValue(), options)
875
- ) {
861
+ if (node && isNextLineEmpty(options.originalText, node, options)) {
876
862
  separatorParts.push(softline);
877
863
  }
878
864
  }, "items");
@@ -925,22 +911,26 @@ function wrapPartsIntoGroups(parts, indexes) {
925
911
  }
926
912
 
927
913
  function printLines(path, options, print, childrenAttribute = "children") {
928
- const node = path.getValue();
929
- const parentNode = path.getParentNode();
914
+ const { node, parent: parentNode } = path;
930
915
 
931
916
  let lastInlineIndex = -1;
932
917
 
933
918
  const parts = [];
934
919
  const groupIndexes = [];
935
920
 
936
- path.map((childPath, index) => {
937
- const childNode = childPath.getValue();
921
+ path.map(() => {
922
+ const {
923
+ node: childNode,
924
+ next: nextNode,
925
+ isFirst: isFirstNode,
926
+ isLast: isLastNode,
927
+ index,
928
+ } = path;
929
+
938
930
  const isInlineNode = childNode.kind === "inline";
939
- const printedPath = print(childPath);
940
- const children = node[childrenAttribute];
941
- const nextNode = children[index + 1];
931
+ const printedPath = print();
942
932
  const canPrintBlankLine =
943
- !isLastStatement(childPath) &&
933
+ !isLastStatement(path) &&
944
934
  !isInlineNode &&
945
935
  (nextNode && nextNode.kind === "case"
946
936
  ? !isFirstChildrenInlineNode(path)
@@ -955,8 +945,6 @@ function printLines(path, options, print, childrenAttribute = "children") {
955
945
  : "",
956
946
  ];
957
947
 
958
- const isFirstNode = index === 0;
959
- const isLastNode = children.length - 1 === index;
960
948
  const isBlockNestedNode =
961
949
  node.kind === "block" &&
962
950
  parentNode &&
@@ -981,7 +969,7 @@ function printLines(path, options, print, childrenAttribute = "children") {
981
969
  (isInlineNode ? prevLastInlineIndex : lastInlineIndex) + 1;
982
970
  const end = isLastNode && !isInlineNode ? index + 1 : index;
983
971
  const prevInlineNode =
984
- children[isInlineNode ? prevLastInlineIndex : lastInlineIndex];
972
+ path.siblings[isInlineNode ? prevLastInlineIndex : lastInlineIndex];
985
973
  const alignment = prevInlineNode
986
974
  ? getAlignment(prevInlineNode.raw)
987
975
  : "";
@@ -1019,7 +1007,7 @@ function printLines(path, options, print, childrenAttribute = "children") {
1019
1007
  ? "<?php"
1020
1008
  : "",
1021
1009
  node.kind === "namespace" || !isBlockNestedNode ? hardline : "",
1022
- comments.printComments(childNode.leadingComments, options),
1010
+ printComments(childNode.leadingComments, options),
1023
1011
  hardline,
1024
1012
  "?>",
1025
1013
  ]
@@ -1027,6 +1015,7 @@ function printLines(path, options, print, childrenAttribute = "children") {
1027
1015
  ? ""
1028
1016
  : [beforeCloseTagInlineNode, "?>"];
1029
1017
 
1018
+ //FIXME getNode is used to get ancestors, but it seems this means to get next sibling?
1030
1019
  const nextV = path.getNode(index + 1);
1031
1020
  const skipLastComment = nextV && nextV.children && nextV.children.length;
1032
1021
 
@@ -1035,9 +1024,7 @@ function printLines(path, options, print, childrenAttribute = "children") {
1035
1024
  ? [
1036
1025
  openTag,
1037
1026
  hardline,
1038
- skipLastComment
1039
- ? comments.printComments(childNode.comments, options)
1040
- : "",
1027
+ skipLastComment ? printComments(childNode.comments, options) : "",
1041
1028
  hardline,
1042
1029
  ]
1043
1030
  : isProgramLikeNode(node) && isLastNode
@@ -1064,7 +1051,7 @@ function printLines(path, options, print, childrenAttribute = "children") {
1064
1051
  between && between[2] && between[2].includes("\n")
1065
1052
  ? [hardline, between[2].split("\n").length > 2 ? hardline : ""]
1066
1053
  : " ",
1067
- node.comments ? comments.printComments(node.comments, options) : "",
1054
+ node.comments ? printComments(node.comments, options) : "",
1068
1055
  ];
1069
1056
 
1070
1057
  const shortEcho =
@@ -1111,17 +1098,15 @@ function printLines(path, options, print, childrenAttribute = "children") {
1111
1098
  }
1112
1099
 
1113
1100
  function printStatements(path, options, print, childrenAttribute) {
1114
- return path.map((childPath) => {
1101
+ return path.map(() => {
1115
1102
  const parts = [];
1116
1103
 
1117
- parts.push(print(childPath));
1104
+ parts.push(print());
1118
1105
 
1119
- if (!isLastStatement(childPath)) {
1106
+ if (!isLastStatement(path)) {
1120
1107
  parts.push(hardline);
1121
1108
 
1122
- if (
1123
- isNextLineEmpty(options.originalText, childPath.getValue(), options)
1124
- ) {
1109
+ if (isNextLineEmpty(options.originalText, path.node, options)) {
1125
1110
  parts.push(hardline);
1126
1111
  }
1127
1112
  }
@@ -1138,28 +1123,25 @@ function printClassPart(
1138
1123
  beforePart = " ",
1139
1124
  afterPart = " "
1140
1125
  ) {
1141
- const node = path.getValue();
1142
- const printedBeforePart = hasDanglingComments(node[part])
1126
+ const value = path.node[part];
1127
+ const printedBeforePart = hasDanglingComments(value)
1143
1128
  ? [
1144
1129
  hardline,
1145
- path.call(
1146
- () => comments.printDanglingComments(path, options, true),
1147
- part
1148
- ),
1130
+ path.call(() => printDanglingComments(path, options, true), part),
1149
1131
  hardline,
1150
1132
  ]
1151
1133
  : beforePart;
1152
- const printedPartItems = Array.isArray(node[part])
1134
+ const printedPartItems = Array.isArray(value)
1153
1135
  ? group(
1154
1136
  join(
1155
1137
  ",",
1156
- path.map((itemPartPath) => {
1157
- const printedPart = print(itemPartPath);
1138
+ path.map(({ node }) => {
1139
+ const printedPart = print();
1158
1140
  // Check if any of the implements nodes have comments
1159
- return hasDanglingComments(itemPartPath.getValue())
1141
+ return hasDanglingComments(node)
1160
1142
  ? [
1161
1143
  hardline,
1162
- comments.printDanglingComments(itemPartPath, options, true),
1144
+ printDanglingComments(path, options, true),
1163
1145
  hardline,
1164
1146
  printedPart,
1165
1147
  ]
@@ -1178,23 +1160,23 @@ function printClassPart(
1178
1160
 
1179
1161
  function printAttrs(path, options, print, { inline = false } = {}) {
1180
1162
  const allAttrs = [];
1181
- if (!path.getValue().attrGroups) {
1163
+ if (!path.node.attrGroups) {
1182
1164
  return [];
1183
1165
  }
1184
- path.each((agPath) => {
1166
+ path.each(() => {
1185
1167
  const attrGroup = ["#["];
1186
1168
  if (!inline && allAttrs.length > 0) {
1187
1169
  allAttrs.push(hardline);
1188
1170
  }
1189
1171
  attrGroup.push(softline);
1190
- agPath.each((attrPath) => {
1191
- const attrNode = attrPath.getValue();
1172
+ path.each(() => {
1173
+ const attrNode = path.node;
1192
1174
  if (attrGroup.length > 2) {
1193
1175
  attrGroup.push(",", line);
1194
1176
  }
1195
1177
  const attrStmt = [attrNode.name];
1196
1178
  if (attrNode.args.length > 0) {
1197
- attrStmt.push(printArgumentsList(attrPath, options, print, "args"));
1179
+ attrStmt.push(printArgumentsList(path, options, print, "args"));
1198
1180
  }
1199
1181
  attrGroup.push(group(attrStmt));
1200
1182
  }, "attrs");
@@ -1215,7 +1197,7 @@ function printAttrs(path, options, print, { inline = false } = {}) {
1215
1197
  }
1216
1198
 
1217
1199
  function printClass(path, options, print) {
1218
- const node = path.getValue();
1200
+ const { node } = path;
1219
1201
  const isAnonymousClass = node.kind === "class" && node.isAnonymous;
1220
1202
  const attrs = printAttrs(path, options, print, { inline: isAnonymousClass });
1221
1203
  const declaration = isAnonymousClass ? [] : [...attrs];
@@ -1326,7 +1308,7 @@ function printClass(path, options, print) {
1326
1308
  hasEmptyClassBody ? "" : hardline,
1327
1309
  printStatements(path, options, print, "body"),
1328
1310
  ]),
1329
- comments.printDanglingComments(path, options, true),
1311
+ printDanglingComments(path, options, true),
1330
1312
  isAnonymousClass && hasEmptyClassBody ? softline : hardline,
1331
1313
  "}",
1332
1314
  ];
@@ -1335,7 +1317,7 @@ function printClass(path, options, print) {
1335
1317
  }
1336
1318
 
1337
1319
  function printFunction(path, options, print) {
1338
- const node = path.getValue();
1320
+ const { node } = path;
1339
1321
  const declAttrs = printAttrs(path, options, print, {
1340
1322
  inline: node.kind === "closure",
1341
1323
  });
@@ -1380,10 +1362,7 @@ function printFunction(path, options, print) {
1380
1362
  ": ",
1381
1363
  hasDanglingComments(node.type)
1382
1364
  ? [
1383
- path.call(
1384
- () => comments.printDanglingComments(path, options, true),
1385
- "type"
1386
- ),
1365
+ path.call(() => printDanglingComments(path, options, true), "type"),
1387
1366
  " ",
1388
1367
  ]
1389
1368
  : "",
@@ -1444,7 +1423,7 @@ function printBodyControlStructure(
1444
1423
  print,
1445
1424
  bodyProperty = "body"
1446
1425
  ) {
1447
- const node = path.getValue();
1426
+ const { node } = path;
1448
1427
 
1449
1428
  if (!node[bodyProperty]) {
1450
1429
  return ";";
@@ -1523,9 +1502,7 @@ function printAssignmentRight(
1523
1502
  ) {
1524
1503
  const ref = hasRef ? "&" : "";
1525
1504
 
1526
- if (
1527
- comments.hasLeadingOwnLineComment(options.originalText, rightNode, options)
1528
- ) {
1505
+ if (hasLeadingOwnLineComment(options.originalText, rightNode, options)) {
1529
1506
  return indent([hardline, ref, printedRight]);
1530
1507
  }
1531
1508
 
@@ -1561,7 +1538,7 @@ function needsHardlineAfterDanglingComment(node) {
1561
1538
  node.comments.filter((comment) => !comment.leading && !comment.trailing)
1562
1539
  );
1563
1540
 
1564
- return lastDanglingComment && !comments.isBlockComment(lastDanglingComment);
1541
+ return lastDanglingComment && !isBlockComment(lastDanglingComment);
1565
1542
  }
1566
1543
 
1567
1544
  function stringHasNewLines(node) {
@@ -1580,18 +1557,18 @@ function isStringOnItsOwnLine(node, text, options) {
1580
1557
 
1581
1558
  function printComposedTypes(path, print, glue) {
1582
1559
  return group(
1583
- path.map((uPath, i) => (i === 0 ? [print()] : [glue, print()]), "types")
1560
+ path.map(({ isFirst }) => (isFirst ? [print()] : [glue, print()]), "types")
1584
1561
  );
1585
1562
  }
1586
1563
 
1587
1564
  function printNode(path, options, print) {
1588
- const node = path.getValue();
1565
+ const { node } = path;
1589
1566
 
1590
1567
  switch (node.kind) {
1591
1568
  case "program": {
1592
1569
  return group([
1593
1570
  printLines(path, options, print),
1594
- comments.printDanglingComments(
1571
+ printDanglingComments(
1595
1572
  path,
1596
1573
  options,
1597
1574
  /* sameIndent */ true,
@@ -1604,14 +1581,11 @@ function printNode(path, options, print) {
1604
1581
  case "block":
1605
1582
  return [
1606
1583
  printLines(path, options, print),
1607
- comments.printDanglingComments(path, options, true),
1584
+ printDanglingComments(path, options, true),
1608
1585
  ];
1609
1586
  case "declare": {
1610
1587
  const printDeclareArguments = (path) => {
1611
- return join(
1612
- ", ",
1613
- path.map((directive) => print(directive), "directives")
1614
- );
1588
+ return join(", ", path.map(print, "directives"));
1615
1589
  };
1616
1590
 
1617
1591
  if (["block", "short"].includes(node.mode)) {
@@ -1623,7 +1597,7 @@ function printNode(path, options, print) {
1623
1597
  node.children.length > 0
1624
1598
  ? indent([hardline, printLines(path, options, print)])
1625
1599
  : "",
1626
- comments.printDanglingComments(path, options),
1600
+ printDanglingComments(path, options),
1627
1601
  hardline,
1628
1602
  node.mode === "block" ? "}" : "enddeclare;",
1629
1603
  ];
@@ -1648,7 +1622,7 @@ function printNode(path, options, print) {
1648
1622
  : "",
1649
1623
  node.withBrackets ? "{" : ";",
1650
1624
  hasDanglingComments(node)
1651
- ? [" ", comments.printDanglingComments(path, options, true)]
1625
+ ? [" ", printDanglingComments(path, options, true)]
1652
1626
  : "",
1653
1627
  node.children.length > 0
1654
1628
  ? node.withBrackets
@@ -1679,10 +1653,7 @@ function printNode(path, options, print) {
1679
1653
  node.name
1680
1654
  ? [maybeStripLeadingSlashFromUse(node.name), "\\{", softline]
1681
1655
  : "",
1682
- join(
1683
- [",", line],
1684
- path.map((item) => print(item), "items")
1685
- ),
1656
+ join([",", line], path.map(print, "items")),
1686
1657
  ]),
1687
1658
  node.name
1688
1659
  ? [
@@ -1697,7 +1668,7 @@ function printNode(path, options, print) {
1697
1668
  node.type ? [node.type, " "] : "",
1698
1669
  maybeStripLeadingSlashFromUse(node.name),
1699
1670
  hasDanglingComments(node)
1700
- ? [" ", comments.printDanglingComments(path, options, true)]
1671
+ ? [" ", printDanglingComments(path, options, true)]
1701
1672
  : "",
1702
1673
  node.alias ? [" as ", print("alias")] : "",
1703
1674
  ];
@@ -1740,11 +1711,7 @@ function printNode(path, options, print) {
1740
1711
  hardline,
1741
1712
  ]
1742
1713
  : hasDanglingComments(node)
1743
- ? [
1744
- line,
1745
- comments.printDanglingComments(path, options, true),
1746
- line,
1747
- ]
1714
+ ? [line, printDanglingComments(path, options, true), line]
1748
1715
  : "",
1749
1716
  "}",
1750
1717
  ]
@@ -1794,7 +1761,7 @@ function printNode(path, options, print) {
1794
1761
  // no node to attach comments that fall in between the parameter name
1795
1762
  // and value, we store them as dangling comments
1796
1763
  hasDanglingComments(node) ? " " : "",
1797
- comments.printDanglingComments(path, options, true),
1764
+ printDanglingComments(path, options, true),
1798
1765
  " =",
1799
1766
  printAssignmentRight(
1800
1767
  node.name,
@@ -1831,13 +1798,10 @@ function printNode(path, options, print) {
1831
1798
  ]);
1832
1799
  case "propertystatement": {
1833
1800
  const attrs = [];
1834
- path.map(
1835
- (propPath) => attrs.push(...printAttrs(propPath, options, print)),
1836
- "properties"
1837
- );
1838
- const printed = path.map((childPath) => {
1839
- return print(childPath);
1801
+ path.each(() => {
1802
+ attrs.push(...printAttrs(path, options, print));
1840
1803
  }, "properties");
1804
+ const printed = path.map(print, "properties");
1841
1805
 
1842
1806
  const hasValue = node.properties.some((property) => property.value);
1843
1807
 
@@ -1885,7 +1849,7 @@ function printNode(path, options, print) {
1885
1849
  const commentOnOwnLine =
1886
1850
  (hasTrailingComment(node.body) &&
1887
1851
  node.body.comments.some(
1888
- (comment) => comment.trailing && !comments.isBlockComment(comment)
1852
+ (comment) => comment.trailing && !isBlockComment(comment)
1889
1853
  )) ||
1890
1854
  needsHardlineAfterDanglingComment(node);
1891
1855
  const elseOnSameLine = !commentOnOwnLine;
@@ -1896,7 +1860,7 @@ function printNode(path, options, print) {
1896
1860
  isNextLineEmpty(options.originalText, node.body, options)
1897
1861
  ? hardline
1898
1862
  : "",
1899
- comments.printDanglingComments(path, options, true),
1863
+ printDanglingComments(path, options, true),
1900
1864
  commentOnOwnLine ? hardline : " "
1901
1865
  );
1902
1866
  }
@@ -1938,7 +1902,7 @@ function printNode(path, options, print) {
1938
1902
  // We want to keep dangling comments above the loop to stay consistent.
1939
1903
  // Any comment positioned between the for statement and the parentheses
1940
1904
  // is going to be printed before the statement.
1941
- const dangling = comments.printDanglingComments(
1905
+ const dangling = printDanglingComments(
1942
1906
  path,
1943
1907
  options,
1944
1908
  /* sameLine */ true
@@ -1977,7 +1941,7 @@ function printNode(path, options, print) {
1977
1941
  // We want to keep dangling comments above the loop to stay consistent.
1978
1942
  // Any comment positioned between the for statement and the parentheses
1979
1943
  // is going to be printed before the statement.
1980
- const dangling = comments.printDanglingComments(
1944
+ const dangling = printDanglingComments(
1981
1945
  path,
1982
1946
  options,
1983
1947
  /* sameLine */ true
@@ -2120,7 +2084,7 @@ function printNode(path, options, print) {
2120
2084
  parts.push(
2121
2085
  node.what.leadingComments &&
2122
2086
  node.what.leadingComments[0].kind === "commentblock"
2123
- ? [comments.printComments(node.what.leadingComments, options), " "]
2087
+ ? [printComments(node.what.leadingComments, options), " "]
2124
2088
  : "",
2125
2089
  ...path.call(
2126
2090
  () => printAttrs(path, options, print, { inline: true }),
@@ -2155,11 +2119,11 @@ function printNode(path, options, print) {
2155
2119
  case "nullsafepropertylookup":
2156
2120
  case "staticlookup":
2157
2121
  case "offsetlookup": {
2158
- const parent = path.getParentNode();
2122
+ const { parent } = path;
2159
2123
 
2124
+ // TODO: Use `AstPath.findAncestor` when it's stable
2160
2125
  let firstNonMemberParent;
2161
2126
  let i = 0;
2162
-
2163
2127
  do {
2164
2128
  firstNonMemberParent = path.getParentNode(i);
2165
2129
  i++;
@@ -2195,7 +2159,7 @@ function printNode(path, options, print) {
2195
2159
  ? isStringOnItsOwnLine(node.expression, options.originalText, options)
2196
2160
  ? print("expression")
2197
2161
  : [indent([softline, print("expression")]), softline]
2198
- : comments.printDanglingComments(path, options),
2162
+ : printDanglingComments(path, options),
2199
2163
  ")",
2200
2164
  ]);
2201
2165
  case "global":
@@ -2225,11 +2189,7 @@ function printNode(path, options, print) {
2225
2189
  return [
2226
2190
  hasDanglingComments(node)
2227
2191
  ? [
2228
- comments.printDanglingComments(
2229
- path,
2230
- options,
2231
- /* sameIndent */ true
2232
- ),
2192
+ printDanglingComments(path, options, /* sameIndent */ true),
2233
2193
  hardline,
2234
2194
  ]
2235
2195
  : "",
@@ -2245,9 +2205,7 @@ function printNode(path, options, print) {
2245
2205
  ")",
2246
2206
  ]);
2247
2207
  case "echo": {
2248
- const printedArguments = path.map((childPath) => {
2249
- return print(childPath);
2250
- }, "expressions");
2208
+ const printedArguments = path.map(print, "expressions");
2251
2209
 
2252
2210
  let firstVariable;
2253
2211
 
@@ -2288,7 +2246,7 @@ function printNode(path, options, print) {
2288
2246
  if (hasDanglingComments(node)) {
2289
2247
  parts.push(
2290
2248
  " ",
2291
- comments.printDanglingComments(path, options, /* sameIndent */ true)
2249
+ printDanglingComments(path, options, /* sameIndent */ true)
2292
2250
  );
2293
2251
  }
2294
2252
 
@@ -2308,8 +2266,7 @@ function printNode(path, options, print) {
2308
2266
  ")",
2309
2267
  ]);
2310
2268
  case "variable": {
2311
- const parent = path.getParentNode();
2312
- const parentParent = path.getParentNode(1);
2269
+ const { parent, grandparent: parentParent } = path;
2313
2270
  const ampersand = parent.kind === "assign" ? "" : node.byref ? "&" : "";
2314
2271
  const dollar =
2315
2272
  (parent.kind === "encapsedpart" &&
@@ -2330,7 +2287,7 @@ function printNode(path, options, print) {
2330
2287
  case "constantstatement":
2331
2288
  case "classconstant": {
2332
2289
  const attrs = printAttrs(path, options, print);
2333
- const printed = path.map((childPath) => print(childPath), "constants");
2290
+ const printed = path.map(print, "constants");
2334
2291
 
2335
2292
  let firstVariable;
2336
2293
 
@@ -2361,9 +2318,7 @@ function printNode(path, options, print) {
2361
2318
  options
2362
2319
  );
2363
2320
  case "static": {
2364
- const printed = path.map((childPath) => {
2365
- return print(childPath);
2366
- }, "variables");
2321
+ const printed = path.map(print, "variables");
2367
2322
 
2368
2323
  const hasValue = node.variables.some((item) => item.defaultValue);
2369
2324
 
@@ -2411,7 +2366,7 @@ function printNode(path, options, print) {
2411
2366
 
2412
2367
  return group([
2413
2368
  open,
2414
- comments.printDanglingComments(path, options),
2369
+ printDanglingComments(path, options),
2415
2370
  softline,
2416
2371
  close,
2417
2372
  ]);
@@ -2459,7 +2414,7 @@ function printNode(path, options, print) {
2459
2414
  ]
2460
2415
  : ""
2461
2416
  ),
2462
- comments.printDanglingComments(path, options, true),
2417
+ printDanglingComments(path, options, true),
2463
2418
  softline,
2464
2419
  close,
2465
2420
  ],
@@ -2528,8 +2483,7 @@ function printNode(path, options, print) {
2528
2483
  );
2529
2484
  }
2530
2485
  case "bin": {
2531
- const parent = path.getParentNode();
2532
- const parentParent = path.getParentNode(1);
2486
+ const { parent, grandparent: parentParent } = path;
2533
2487
  const isInsideParenthesis =
2534
2488
  node !== parent.body &&
2535
2489
  (parent.kind === "if" ||
@@ -2612,8 +2566,9 @@ function printNode(path, options, print) {
2612
2566
  }
2613
2567
  case "retif": {
2614
2568
  const parts = [];
2615
- const parent = path.getParentNode();
2569
+ const { parent } = path;
2616
2570
 
2571
+ // TODO: Use `AstPath.findAncestor` when it's stable
2617
2572
  // Find the outermost non-retif parent, and the outermost retif parent.
2618
2573
  let currentParent;
2619
2574
  let i = 0;
@@ -2660,7 +2615,7 @@ function printNode(path, options, print) {
2660
2615
  // ? $b
2661
2616
  // : $c
2662
2617
  // )->call()
2663
- const parentParent = path.getParentNode(1);
2618
+ const parentParent = path.grandparent;
2664
2619
  const pureParent =
2665
2620
  parent.kind === "cast" && parentParent ? parentParent : parent;
2666
2621
  const breakLookupNodes = [
@@ -2712,10 +2667,10 @@ function printNode(path, options, print) {
2712
2667
  case "number":
2713
2668
  return printNumber(node.value);
2714
2669
  case "string": {
2715
- const parent = path.getParentNode();
2670
+ const { parent } = path;
2716
2671
 
2717
2672
  if (parent.kind === "encapsedpart") {
2718
- const parentParent = path.getParentNode(1);
2673
+ const parentParent = path.grandparent;
2719
2674
  let closingTagIndentation = 0;
2720
2675
  const flexible = isMinVersion(options.phpVersion, "7.3");
2721
2676
  let linebreak = literalline;
@@ -2839,7 +2794,7 @@ function printNode(path, options, print) {
2839
2794
  case "nullkeyword":
2840
2795
  return "null";
2841
2796
  case "identifier": {
2842
- const parent = path.getParentNode();
2797
+ const { parent } = path;
2843
2798
 
2844
2799
  if (parent.kind === "method") {
2845
2800
  node.name = normalizeMagicMethodName(node.name);
@@ -2848,19 +2803,18 @@ function printNode(path, options, print) {
2848
2803
  return print("name");
2849
2804
  }
2850
2805
  case "match": {
2851
- const lastArmIndex = node.arms.length - 1;
2852
- const arms = path.map((armPath, armIdx) => {
2853
- const armNode = armPath.getValue();
2806
+ const arms = path.map(() => {
2807
+ const armNode = path.node;
2854
2808
 
2855
- const maybeLeadingComment = comments.hasLeadingComment(armNode)
2856
- ? [comments.printComments(armNode.leadingComments, options), hardline]
2809
+ const maybeLeadingComment = hasLeadingComment(armNode)
2810
+ ? [printComments(armNode.leadingComments, options), hardline]
2857
2811
  : [];
2858
2812
  const maybeTrailingComma =
2859
- armIdx < lastArmIndex || options.trailingCommaPHP ? "," : "";
2860
- const maybeTrailingComment = comments.hasTrailingComment(armNode)
2813
+ !path.isLast || options.trailingCommaPHP ? "," : "";
2814
+ const maybeTrailingComment = hasTrailingComment(armNode)
2861
2815
  ? [
2862
2816
  " ",
2863
- comments.printComments(
2817
+ printComments(
2864
2818
  armNode.comments.filter((c) => c.trailing),
2865
2819
  options
2866
2820
  ),
@@ -2870,14 +2824,13 @@ function printNode(path, options, print) {
2870
2824
  const conds =
2871
2825
  armNode.conds === null
2872
2826
  ? "default"
2873
- : armPath.map(
2874
- (condPath, condIdx) =>
2875
- [",", line, print(condPath)].slice(condIdx === 0 ? 2 : 0),
2827
+ : path.map(
2828
+ ({ isFirst }) => [",", line, print()].slice(isFirst ? 2 : 0),
2876
2829
  "conds"
2877
2830
  );
2878
2831
  const body = print("body");
2879
2832
  const maybeEmptyLineBetweenArms =
2880
- armIdx > 0 &&
2833
+ !path.isFirst &&
2881
2834
  isPreviousLineEmpty(options.originalText, armNode, options)
2882
2835
  ? hardline
2883
2836
  : "";
@@ -2894,7 +2847,7 @@ function printNode(path, options, print) {
2894
2847
  maybeTrailingComma,
2895
2848
  ...maybeTrailingComment,
2896
2849
  ]),
2897
- ].slice(armIdx > 0 ? 0 : 1);
2850
+ ].slice(!path.isFirst ? 0 : 1);
2898
2851
  }, "arms");
2899
2852
  return group([
2900
2853
  "match (",
@@ -2908,9 +2861,7 @@ function printNode(path, options, print) {
2908
2861
  }
2909
2862
 
2910
2863
  case "noop":
2911
- return node.comments
2912
- ? comments.printComments(path.getValue().comments, options)
2913
- : "";
2864
+ return node.comments ? printComments(node.comments, options) : "";
2914
2865
  case "namedargument":
2915
2866
  return [node.name, ": ", print("value")];
2916
2867
 
@@ -2941,4 +2892,4 @@ function printNode(path, options, print) {
2941
2892
  }
2942
2893
  }
2943
2894
 
2944
- module.exports = genericPrint;
2895
+ export default genericPrint;