prettier 0.21.0 → 0.22.0

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.
@@ -0,0 +1,88 @@
1
+ const { concat, trim } = require("./prettier");
2
+
3
+ const embed = require("./embed");
4
+ const nodes = require("./nodes");
5
+
6
+ // This is the generic node print function, used to convert any node in the AST
7
+ // into its equivalent Doc representation.
8
+ function printNode(path, opts, print) {
9
+ const { type, body } = path.getValue();
10
+
11
+ if (type in nodes) {
12
+ return nodes[type](path, opts, print);
13
+ }
14
+
15
+ if (type[0] === "@") {
16
+ return body;
17
+ }
18
+
19
+ const ast = JSON.stringify(body, null, 2);
20
+ throw new Error(`Unsupported node encountered: ${type}\n${ast}`);
21
+ }
22
+
23
+ const noComments = [
24
+ "args",
25
+ "args_add_block",
26
+ "args_add_star",
27
+ "mlhs",
28
+ "mlhs_add_post",
29
+ "mlhs_add_star"
30
+ ];
31
+
32
+ // Certain nodes are used more for organizational purposed than for actually
33
+ // displaying content, so we tell prettier that we don't want comments attached
34
+ // to them.
35
+ function canAttachComment(node) {
36
+ return !noComments.includes(node.type);
37
+ }
38
+
39
+ // This function tells prettier how to recurse down our AST so that it can find
40
+ // where it needs to attach the comments.
41
+ function getCommentChildNodes(node) {
42
+ switch (node.type) {
43
+ case "rescue":
44
+ return node.body[0].concat(node.body.slice(1));
45
+ case "aryptn":
46
+ return [node.body[0]]
47
+ .concat(node.body[1])
48
+ .concat(node.body[2])
49
+ .concat(node.body[3]);
50
+ case "hshptn": {
51
+ const pairs = node.body[1];
52
+ const values = pairs.reduce((left, right) => left.concat(right), []);
53
+
54
+ return [node.body[0]].concat(values).concat(node.body[2]);
55
+ }
56
+ default:
57
+ return node.body;
58
+ }
59
+ }
60
+
61
+ // This is the generic print function for any comment in the AST. It handles
62
+ // both regular comments that begin with a # and embdoc comments, which are
63
+ // surrounded by =begin..=end.
64
+ function printComment(path, _opts) {
65
+ const comment = path.getValue();
66
+
67
+ if (comment.type === "@comment") {
68
+ return `#${comment.value}`;
69
+ }
70
+
71
+ return concat([trim, comment.value]);
72
+ }
73
+
74
+ // To be honest I'm not 100% sure this function is actually necessary, but it
75
+ // *feels* like a block comment equivalent in JavaScript so I'm going to leave
76
+ // it in place for now.
77
+ function isBlockComment(comment) {
78
+ return comment.type === "@embdoc";
79
+ }
80
+
81
+ module.exports = {
82
+ embed,
83
+ print: printNode,
84
+ canAttachComment,
85
+ getCommentChildNodes,
86
+ printComment,
87
+ isBlockComment
88
+ };
@@ -1,12 +1,5 @@
1
- const embed = require("./embed");
2
- const parse = require("./parse");
3
- const print = require("./print");
4
-
5
- const pragmaPattern = /#\s*@(prettier|format)/;
6
- const hasPragma = (text) => pragmaPattern.test(text);
7
-
8
- const locStart = (node) => node.char_start;
9
- const locEnd = (node) => node.char_end;
1
+ const printer = require("./printer");
2
+ const parser = require("./parser");
10
3
 
11
4
  /*
12
5
  * metadata mostly pulled from linguist and rubocop:
@@ -77,19 +70,10 @@ module.exports = {
77
70
  }
78
71
  ],
79
72
  parsers: {
80
- ruby: {
81
- parse,
82
- astFormat: "ruby",
83
- hasPragma,
84
- locStart,
85
- locEnd
86
- }
73
+ ruby: parser
87
74
  },
88
75
  printers: {
89
- ruby: {
90
- embed,
91
- print
92
- }
76
+ ruby: printer
93
77
  },
94
78
  options: {
95
79
  addTrailingCommas: {
@@ -57,9 +57,9 @@ const toProc = (path, opts, node) => {
57
57
  return null;
58
58
  }
59
59
 
60
- // Ensure that statement is a call
60
+ // Ensure that statement is a call and that it has no comments attached
61
61
  const [statement] = statements.body;
62
- if (statement.type !== "call") {
62
+ if (statement.type !== "call" || statement.comments) {
63
63
  return null;
64
64
  }
65
65
 
@@ -1,19 +1,15 @@
1
- const {
2
- breakParent,
3
- concat,
4
- hardline,
5
- lineSuffix,
6
- literalline
7
- } = require("./prettier");
1
+ const { concat } = require("./prettier");
8
2
  const isEmptyStmts = require("./utils/isEmptyStmts");
3
+ const literalLineNoBreak = require("./utils/literalLineNoBreak");
9
4
 
10
5
  const concatBody = (path, opts, print) => concat(path.map(print, "body"));
11
6
 
12
7
  // If the node is a type of assignment or if the node is a paren and nested
13
8
  // inside that paren is a node that is a type of assignment.
14
9
  const containsAssignment = (node) =>
15
- ["assign", "massign"].includes(node.type) ||
16
- (node.type === "paren" && node.body[0].body.some(containsAssignment));
10
+ node &&
11
+ (["assign", "massign", "opassign"].includes(node.type) ||
12
+ (Array.isArray(node.body) && node.body.some(containsAssignment)));
17
13
 
18
14
  const docLength = (doc) => {
19
15
  if (doc.length) {
@@ -53,34 +49,6 @@ const hasAncestor = (path, types) => {
53
49
 
54
50
  const literal = (value) => () => value;
55
51
 
56
- const makeArgs = (path, opts, print, argsIndex) => {
57
- let argNodes = path.getValue().body[argsIndex];
58
- const argPattern = [print, "body", argsIndex, "body"];
59
-
60
- if (argNodes.type === "args_add_block") {
61
- [argNodes] = argNodes.body;
62
- argPattern.push(0, "body");
63
- }
64
-
65
- const args = path.call(print, "body", argsIndex);
66
- const heredocs = [];
67
-
68
- argNodes.body.forEach((argNode, index) => {
69
- if (argNode.type === "heredoc") {
70
- const content = path.map.apply(
71
- path,
72
- argPattern.slice().concat([index, "body"])
73
- );
74
- heredocs.push(
75
- concat([literalline].concat(content).concat([argNode.ending]))
76
- );
77
- args[index] = argNode.beging;
78
- }
79
- });
80
-
81
- return { args, heredocs };
82
- };
83
-
84
52
  const makeCall = (path, opts, print) => {
85
53
  const operation = path.getValue().body[1];
86
54
 
@@ -91,53 +59,13 @@ const makeCall = (path, opts, print) => {
91
59
  return operation === "::" ? "." : path.call(print, "body", 1);
92
60
  };
93
61
 
94
- const makeList = (path, opts, print) => path.map(print, "body");
95
-
96
- const nodeDive = (node, steps) => {
97
- let current = node;
98
-
99
- steps.forEach((step) => {
100
- current = current[step];
101
- });
102
-
103
- return current;
104
- };
105
-
106
62
  const prefix = (value) => (path, opts, print) =>
107
63
  concat([value, path.call(print, "body", 0)]);
108
64
 
109
- const printComments = (printed, start, comments) => {
110
- let node = printed;
111
-
112
- comments.forEach((comment) => {
113
- if (comment.start < start) {
114
- node = concat([
115
- comment.break ? breakParent : "",
116
- comment.body,
117
- hardline,
118
- node
119
- ]);
120
- } else {
121
- node = concat([
122
- node,
123
- comment.break ? breakParent : "",
124
- lineSuffix(` ${comment.body}`)
125
- ]);
126
- }
127
- });
128
-
129
- return node;
130
- };
131
-
65
+ const skippable = ["array", "hash", "heredoc", "lambda", "regexp_literal"];
132
66
  const skipAssignIndent = (node) =>
133
- ["array", "hash", "heredoc", "lambda", "regexp_literal"].includes(
134
- node.type
135
- ) ||
136
- (node.type === "call" && skipAssignIndent(node.body[0])) ||
137
- (node.type === "string_literal" && node.body[0].type === "heredoc");
138
-
139
- const surround = (left, right) => (path, opts, print) =>
140
- concat([left, path.call(print, "body", 0), right]);
67
+ skippable.includes(node.type) ||
68
+ (node.type === "call" && skipAssignIndent(node.body[0]));
141
69
 
142
70
  module.exports = {
143
71
  concatBody,
@@ -148,12 +76,8 @@ module.exports = {
148
76
  hasAncestor,
149
77
  isEmptyStmts,
150
78
  literal,
151
- makeArgs,
79
+ literalLineNoBreak,
152
80
  makeCall,
153
- makeList,
154
- nodeDive,
155
81
  prefix,
156
- printComments,
157
- skipAssignIndent,
158
- surround
82
+ skipAssignIndent
159
83
  };
@@ -0,0 +1,7 @@
1
+ const literalLineNoBreak = {
2
+ type: "line",
3
+ hard: true,
4
+ literal: true
5
+ };
6
+
7
+ module.exports = literalLineNoBreak;
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prettier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.0
4
+ version: 0.22.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Deisz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-02 00:00:00.000000000 Z
11
+ date: 2020-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -82,11 +82,13 @@ files:
82
82
  - src/nodes/blocks.js
83
83
  - src/nodes/calls.js
84
84
  - src/nodes/case.js
85
+ - src/nodes/class.js
85
86
  - src/nodes/commands.js
86
87
  - src/nodes/conditionals.js
87
88
  - src/nodes/constants.js
88
89
  - src/nodes/flow.js
89
90
  - src/nodes/hashes.js
91
+ - src/nodes/heredocs.js
90
92
  - src/nodes/hooks.js
91
93
  - src/nodes/ints.js
92
94
  - src/nodes/lambdas.js
@@ -99,18 +101,20 @@ files:
99
101
  - src/nodes/regexp.js
100
102
  - src/nodes/rescue.js
101
103
  - src/nodes/return.js
102
- - src/nodes/scopes.js
103
104
  - src/nodes/statements.js
104
105
  - src/nodes/strings.js
105
- - src/parse.js
106
+ - src/nodes/super.js
107
+ - src/nodes/undef.js
108
+ - src/parser.js
106
109
  - src/parser.rb
107
110
  - src/prettier.js
108
- - src/print.js
111
+ - src/printer.js
109
112
  - src/ruby.js
110
113
  - src/toProc.js
111
114
  - src/utils.js
112
115
  - src/utils/inlineEnsureParens.js
113
116
  - src/utils/isEmptyStmts.js
117
+ - src/utils/literalLineNoBreak.js
114
118
  homepage: https://github.com/prettier/plugin-ruby#readme
115
119
  licenses:
116
120
  - MIT
@@ -1,61 +0,0 @@
1
- const {
2
- concat,
3
- group,
4
- hardline,
5
- ifBreak,
6
- indent,
7
- line
8
- } = require("../prettier");
9
-
10
- module.exports = {
11
- class: (path, opts, print) => {
12
- const [_constant, superclass, statements] = path.getValue().body;
13
-
14
- const parts = ["class ", path.call(print, "body", 0)];
15
- if (superclass) {
16
- parts.push(" < ", path.call(print, "body", 1));
17
- }
18
-
19
- // If the body is empty, we can replace with a ;
20
- const stmts = statements.body[0].body;
21
- if (stmts.length === 1 && stmts[0].type === "void_stmt") {
22
- return group(concat([concat(parts), ifBreak(line, "; "), "end"]));
23
- }
24
-
25
- return group(
26
- concat([
27
- concat(parts),
28
- indent(concat([hardline, path.call(print, "body", 2)])),
29
- concat([hardline, "end"])
30
- ])
31
- );
32
- },
33
- class_name_error: (_path, _opts, _print) => {
34
- throw new Error("class/module name must be CONSTANT");
35
- },
36
- module: (path, opts, print) => {
37
- const declaration = group(concat(["module ", path.call(print, "body", 0)]));
38
-
39
- // If the body is empty, we can replace with a ;
40
- const stmts = path.getValue().body[1].body[0].body;
41
- if (stmts.length === 1 && stmts[0].type === "void_stmt") {
42
- return group(concat([declaration, ifBreak(line, "; "), "end"]));
43
- }
44
-
45
- return group(
46
- concat([
47
- declaration,
48
- indent(concat([hardline, path.call(print, "body", 1)])),
49
- concat([hardline, "end"])
50
- ])
51
- );
52
- },
53
- sclass: (path, opts, print) =>
54
- group(
55
- concat([
56
- concat(["class << ", path.call(print, "body", 0)]),
57
- indent(concat([hardline, path.call(print, "body", 1)])),
58
- concat([hardline, "end"])
59
- ])
60
- )
61
- };
@@ -1,37 +0,0 @@
1
- const { spawnSync } = require("child_process");
2
- const path = require("path");
3
-
4
- // In order to properly parse ruby code, we need to tell the ruby process to
5
- // parse using UTF-8. Unfortunately, the way that you accomplish this looks
6
- // differently depending on your platform. This object below represents all of
7
- // the possible values of process.platform per:
8
- // https://nodejs.org/api/process.html#process_process_platform
9
- const LANG = {
10
- aix: "C.UTF-8",
11
- darwin: "en_US.UTF-8",
12
- freebsd: "C.UTF-8",
13
- linux: "C.UTF-8",
14
- openbsd: "C.UTF-8",
15
- sunos: "C.UTF-8",
16
- win32: ".UTF-8"
17
- }[process.platform];
18
-
19
- module.exports = (text, _parsers, _opts) => {
20
- const child = spawnSync(
21
- "ruby",
22
- ["--disable-gems", path.join(__dirname, "./parser.rb")],
23
- {
24
- env: Object.assign({}, process.env, { LANG }),
25
- input: text,
26
- maxBuffer: 10 * 1024 * 1024 // 10MB
27
- }
28
- );
29
-
30
- const error = child.stderr.toString();
31
- if (error) {
32
- throw new Error(error);
33
- }
34
-
35
- const response = child.stdout.toString();
36
- return JSON.parse(response);
37
- };
@@ -1,23 +0,0 @@
1
- const { printComments } = require("./utils");
2
- const nodes = require("./nodes");
3
-
4
- module.exports = (path, opts, print) => {
5
- const { type, body, comments, start } = path.getValue();
6
-
7
- if (type in nodes) {
8
- const printed = nodes[type](path, opts, print);
9
-
10
- if (comments) {
11
- return printComments(printed, start, comments);
12
- }
13
- return printed;
14
- }
15
-
16
- if (type[0] === "@") {
17
- return body;
18
- }
19
-
20
- throw new Error(
21
- `Unsupported node encountered: ${type}\n${JSON.stringify(body, null, 2)}`
22
- );
23
- };