prettier 2.0.0 → 3.1.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.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +52 -6
  3. data/README.md +17 -16
  4. data/exe/rbprettier +2 -2
  5. data/lib/prettier/rake/task.rb +5 -5
  6. data/lib/prettier.rb +12 -11
  7. data/node_modules/prettier/bin-prettier.js +48 -18924
  8. data/node_modules/prettier/cli.js +12335 -0
  9. data/node_modules/prettier/doc.js +1306 -4755
  10. data/node_modules/prettier/index.js +37468 -57614
  11. data/node_modules/prettier/package.json +3 -2
  12. data/node_modules/prettier/parser-angular.js +2 -66
  13. data/node_modules/prettier/parser-babel.js +27 -22
  14. data/node_modules/prettier/parser-espree.js +26 -22
  15. data/node_modules/prettier/parser-flow.js +26 -22
  16. data/node_modules/prettier/parser-glimmer.js +27 -1
  17. data/node_modules/prettier/parser-graphql.js +15 -1
  18. data/node_modules/prettier/parser-html.js +21 -117
  19. data/node_modules/prettier/parser-markdown.js +61 -19
  20. data/node_modules/prettier/parser-meriyah.js +19 -22
  21. data/node_modules/prettier/parser-postcss.js +76 -22
  22. data/node_modules/prettier/parser-typescript.js +280 -22
  23. data/node_modules/prettier/parser-yaml.js +150 -15
  24. data/node_modules/prettier/third-party.js +8660 -11030
  25. data/package.json +11 -25
  26. data/rubocop.yml +6 -6
  27. data/src/getInfo.js +23 -0
  28. data/{dist/parser → src}/netcat.js +0 -1
  29. data/src/parseSync.js +216 -0
  30. data/src/plugin.js +170 -0
  31. data/{dist/parser → src}/server.rb +50 -27
  32. metadata +95 -75
  33. data/bin/console +0 -7
  34. data/dist/haml/embed.js +0 -53
  35. data/dist/haml/parser.js +0 -31
  36. data/dist/haml/parser.rb +0 -143
  37. data/dist/haml/printer.js +0 -336
  38. data/dist/parser/getInfo.js +0 -17
  39. data/dist/parser/parseSync.js +0 -179
  40. data/dist/plugin.js +0 -143
  41. data/dist/prettier.js +0 -15
  42. data/dist/rbs/parser.js +0 -34
  43. data/dist/rbs/parser.rb +0 -98
  44. data/dist/rbs/printer.js +0 -517
  45. data/dist/ruby/embed.js +0 -110
  46. data/dist/ruby/nodes/alias.js +0 -59
  47. data/dist/ruby/nodes/aref.js +0 -53
  48. data/dist/ruby/nodes/args.js +0 -165
  49. data/dist/ruby/nodes/arrays.js +0 -126
  50. data/dist/ruby/nodes/assign.js +0 -41
  51. data/dist/ruby/nodes/blocks.js +0 -87
  52. data/dist/ruby/nodes/calls.js +0 -260
  53. data/dist/ruby/nodes/case.js +0 -50
  54. data/dist/ruby/nodes/class.js +0 -54
  55. data/dist/ruby/nodes/commands.js +0 -124
  56. data/dist/ruby/nodes/conditionals.js +0 -242
  57. data/dist/ruby/nodes/constants.js +0 -38
  58. data/dist/ruby/nodes/flow.js +0 -66
  59. data/dist/ruby/nodes/hashes.js +0 -130
  60. data/dist/ruby/nodes/heredocs.js +0 -30
  61. data/dist/ruby/nodes/hooks.js +0 -35
  62. data/dist/ruby/nodes/ints.js +0 -27
  63. data/dist/ruby/nodes/lambdas.js +0 -69
  64. data/dist/ruby/nodes/loops.js +0 -73
  65. data/dist/ruby/nodes/massign.js +0 -73
  66. data/dist/ruby/nodes/methods.js +0 -70
  67. data/dist/ruby/nodes/operators.js +0 -70
  68. data/dist/ruby/nodes/params.js +0 -89
  69. data/dist/ruby/nodes/patterns.js +0 -122
  70. data/dist/ruby/nodes/regexp.js +0 -45
  71. data/dist/ruby/nodes/rescue.js +0 -85
  72. data/dist/ruby/nodes/return.js +0 -75
  73. data/dist/ruby/nodes/statements.js +0 -111
  74. data/dist/ruby/nodes/strings.js +0 -218
  75. data/dist/ruby/nodes/super.js +0 -30
  76. data/dist/ruby/nodes/undef.js +0 -26
  77. data/dist/ruby/nodes.js +0 -151
  78. data/dist/ruby/parser.js +0 -34
  79. data/dist/ruby/parser.rb +0 -3636
  80. data/dist/ruby/printer.js +0 -129
  81. data/dist/ruby/toProc.js +0 -93
  82. data/dist/types/haml.js +0 -4
  83. data/dist/types/plugin.js +0 -3
  84. data/dist/types/rbs.js +0 -4
  85. data/dist/types/ruby.js +0 -4
  86. data/dist/types/utils.js +0 -2
  87. data/dist/types.js +0 -30
  88. data/dist/utils/containsAssignment.js +0 -15
  89. data/dist/utils/getTrailingComma.js +0 -6
  90. data/dist/utils/hasAncestor.js +0 -15
  91. data/dist/utils/inlineEnsureParens.js +0 -49
  92. data/dist/utils/isEmptyBodyStmt.js +0 -10
  93. data/dist/utils/isEmptyStmts.js +0 -10
  94. data/dist/utils/literal.js +0 -8
  95. data/dist/utils/literallineWithoutBreakParent.js +0 -8
  96. data/dist/utils/makeCall.js +0 -13
  97. data/dist/utils/noIndent.js +0 -11
  98. data/dist/utils/printEmptyCollection.js +0 -44
  99. data/dist/utils/skipAssignIndent.js +0 -15
  100. data/dist/utils.js +0 -30
data/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "@prettier/plugin-ruby",
3
- "version": "2.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "prettier plugin for the Ruby programming language",
5
- "main": "dist/plugin.js",
5
+ "main": "src/plugin.js",
6
6
  "scripts": {
7
7
  "checkFormat": "prettier --check '**/*'",
8
8
  "lint": "eslint --cache .",
9
- "prepublishOnly": "tsc -p tsconfig.build.json && cp src/parser/getInfo.js dist/parser && cp src/parser/netcat.js dist/parser && cp src/parser/server.rb dist/parser && cp src/haml/parser.rb dist/haml && cp src/rbs/parser.rb dist/rbs && cp src/ruby/parser.rb dist/ruby",
10
9
  "test": "jest"
11
10
  },
12
11
  "repository": {
@@ -23,24 +22,15 @@
23
22
  "prettier": ">=2.3.0"
24
23
  },
25
24
  "devDependencies": {
26
- "@types/jest": "^27.0.1",
27
- "@types/node": "^16.9.1",
28
- "@types/prettier": "^2.3.2",
29
- "@typescript-eslint/eslint-plugin": "^5.2.0",
30
- "@typescript-eslint/parser": "^5.2.0",
31
- "eslint": "^8.1.0",
25
+ "eslint": "^8.15.0",
32
26
  "eslint-config-prettier": "^8.0.0",
33
- "husky": "^7.0.0",
34
- "jest": "^27.0.1",
35
- "pretty-quick": "^3.1.0",
36
- "ts-jest": "^27.0.5",
37
- "ts-node": "^10.2.1",
38
- "typescript": "^4.4.3"
27
+ "husky": "^8.0.1",
28
+ "jest": "^28.0.1",
29
+ "pretty-quick": "^3.1.2"
39
30
  },
40
31
  "eslintConfig": {
41
32
  "extends": [
42
33
  "eslint:recommended",
43
- "plugin:@typescript-eslint/recommended",
44
34
  "prettier"
45
35
  ],
46
36
  "env": {
@@ -48,21 +38,17 @@
48
38
  "jest": true,
49
39
  "node": true
50
40
  },
51
- "parser": "@typescript-eslint/parser",
52
41
  "rules": {
53
- "no-unused-vars": "off",
54
- "@typescript-eslint/explicit-module-boundary-types": "off",
55
- "@typescript-eslint/no-explicit-any": "off"
42
+ "no-unused-vars": "off"
56
43
  }
57
44
  },
58
45
  "jest": {
59
- "globalSetup": "./test/js/globalSetup.ts",
60
- "globalTeardown": "./test/js/globalTeardown.ts",
61
- "preset": "ts-jest",
46
+ "globalSetup": "./test/js/globalSetup.js",
47
+ "globalTeardown": "./test/js/globalTeardown.js",
62
48
  "setupFilesAfterEnv": [
63
- "./test/js/setupTests.ts"
49
+ "./test/js/setupTests.js"
64
50
  ],
65
- "testRegex": ".test.ts$"
51
+ "testRegex": ".test.js$"
66
52
  },
67
53
  "husky": {
68
54
  "hooks": {
data/rubocop.yml CHANGED
@@ -13,7 +13,7 @@ Layout:
13
13
  Layout/LineLength:
14
14
  Enabled: true
15
15
 
16
- Style/MultilineIfModifier: # rubyModifier
16
+ Style/MultilineIfModifier:
17
17
  Enabled: false
18
18
 
19
19
  # When method chains with multiple blocks are chained together, rubocop will let
@@ -23,19 +23,19 @@ Style/MultilineIfModifier: # rubyModifier
23
23
  Style/MultilineBlockChain:
24
24
  Enabled: false
25
25
 
26
- Style/SymbolArray: # rubyArrayLiteral
26
+ Style/SymbolArray:
27
27
  Enabled: false
28
28
 
29
- Style/WordArray: # rubyArrayLiteral
29
+ Style/WordArray:
30
30
  Enabled: false
31
31
 
32
- Style/TrailingCommaInArguments: # trailingComma
32
+ Style/TrailingCommaInArguments:
33
33
  Enabled: false
34
34
 
35
- Style/TrailingCommaInArrayLiteral: # trailingComma
35
+ Style/TrailingCommaInArrayLiteral:
36
36
  Enabled: false
37
37
 
38
- Style/TrailingCommaInHashLiteral: # trailingComma
38
+ Style/TrailingCommaInHashLiteral:
39
39
  Enabled: false
40
40
 
41
41
  # lambdas that are constructed with the lambda method call cannot be safely
data/src/getInfo.js ADDED
@@ -0,0 +1,23 @@
1
+ const { existsSync, readFileSync } = require("fs");
2
+
3
+ // This is how long to wait for the parser to spin up. For the most part, 5
4
+ // seconds is plenty of time. But in some environments, it may be necessary to
5
+ // increase this value.
6
+ const timeoutMs = parseInt(process.env.PRETTIER_RUBY_TIMEOUT_MS || "5000", 10);
7
+
8
+ const filepath = process.argv[process.argv.length - 1];
9
+
10
+ const timeout = setTimeout(() => {
11
+ clearInterval(interval);
12
+ throw new Error(`Failed to get information from parse server in time. If this
13
+ happens repeatedly, try increasing the PRETTIER_RUBY_TIMEOUT_MS environment
14
+ variable beyond 5000.`);
15
+ }, timeoutMs);
16
+
17
+ const interval = setInterval(() => {
18
+ if (existsSync(filepath)) {
19
+ process.stdout.write(readFileSync(filepath).toString("utf8"));
20
+ clearTimeout(timeout);
21
+ clearInterval(interval);
22
+ }
23
+ }, 100);
@@ -2,7 +2,6 @@
2
2
  // On average, this is 2-3x slower than netcat, but still much faster than
3
3
  // spawning a new Ruby process.
4
4
 
5
- // eslint-disable-next-line @typescript-eslint/no-var-requires
6
5
  const { createConnection } = require("net");
7
6
 
8
7
  const sock = process.argv[process.argv.length - 1];
data/src/parseSync.js ADDED
@@ -0,0 +1,216 @@
1
+ const { spawn, spawnSync } = require("child_process");
2
+ const {
3
+ existsSync,
4
+ unlinkSync,
5
+ mkdtempSync,
6
+ copyFileSync,
7
+ mkdirSync,
8
+ rmdirSync
9
+ } = require("fs");
10
+ const os = require("os");
11
+ const path = require("path");
12
+ const process = require("process");
13
+
14
+ let parserArgs;
15
+
16
+ if (process.env.PRETTIER_RUBY_HOST) {
17
+ const [cmd, ...args] = process.env.PRETTIER_RUBY_HOST.split(" ");
18
+ parserArgs = { cmd, args };
19
+ }
20
+
21
+ // In order to properly parse ruby code, we need to tell the ruby process to
22
+ // parse using UTF-8. Unfortunately, the way that you accomplish this looks
23
+ // differently depending on your platform.
24
+ /* istanbul ignore next */
25
+ function getLang() {
26
+ const { env, platform } = process;
27
+ const envValue = env.LC_ALL || env.LC_CTYPE || env.LANG;
28
+
29
+ // If an env var is set for the locale that already includes UTF-8 in the
30
+ // name, then assume we can go with that.
31
+ if (envValue && envValue.includes("UTF-8")) {
32
+ return envValue;
33
+ }
34
+
35
+ // Otherwise, we're going to guess which encoding to use based on the system.
36
+ // This is probably not the best approach in the world, as you could be on
37
+ // linux and not have C.UTF-8, but in that case you're probably passing an env
38
+ // var for it. This object below represents all of the possible values of
39
+ // process.platform per:
40
+ // https://nodejs.org/api/process.html#process_process_platform
41
+ return {
42
+ aix: "C.UTF-8",
43
+ android: "C.UTF-8",
44
+ cygwin: "C.UTF-8",
45
+ darwin: "en_US.UTF-8",
46
+ freebsd: "C.UTF-8",
47
+ haiku: "C.UTF-8",
48
+ linux: "C.UTF-8",
49
+ netbsd: "C.UTF-8",
50
+ openbsd: "C.UTF-8",
51
+ sunos: "C.UTF-8",
52
+ win32: ".UTF-8"
53
+ }[platform];
54
+ }
55
+
56
+ // Generate the filepath that should be used to communicate the connection
57
+ // information between this process and the parser server.
58
+ function getInfoFilepath() {
59
+ return path.join(os.tmpdir(), `prettier-ruby-parser-${process.pid}.info`);
60
+ }
61
+
62
+ // Create a file that will act as a communication mechanism, spawn a parser
63
+ // server with that filepath as an argument, then spawn another process that
64
+ // will read that information in order to enable us to connect to it in the
65
+ // spawnSync function.
66
+ function spawnServer(opts) {
67
+ const tempDir = mkdtempSync(path.join(os.tmpdir(), "prettier-plugin-ruby-"));
68
+ const filepath = getInfoFilepath();
69
+
70
+ let serverRbPath = path.join(__dirname, "./server.rb");
71
+ let getInfoJsPath = path.join(__dirname, "./getInfo.js");
72
+ let cleanupTempFiles;
73
+
74
+ if (runningInPnPZip()) {
75
+ // If we're running in a Yarn PnP environment inside a ZIP file, it's not possible to run
76
+ // the Ruby server or the getInfo.js script directly. Instead, we need to copy them and all
77
+ // the files they depend on to a temporary directory.
78
+
79
+ const sourceFiles = ["server.rb", "getInfo.js", "netcat.js"];
80
+ serverRbPath = path.join(tempDir, "server.rb");
81
+ getInfoJsPath = path.join(tempDir, "getInfo.js");
82
+
83
+ sourceFiles.forEach((rubyFile) => {
84
+ const destDir = path.join(tempDir, path.dirname(rubyFile));
85
+ if (!existsSync(destDir)) {
86
+ mkdirSync(destDir);
87
+ }
88
+ copyFileSync(
89
+ path.join(__dirname, "..", "src", rubyFile),
90
+ path.join(tempDir, rubyFile)
91
+ );
92
+ });
93
+
94
+ cleanupTempFiles = () => {
95
+ [
96
+ getInfoJsPath,
97
+ ...sourceFiles.map((rubyFile) => path.join(tempDir, rubyFile))
98
+ ].forEach((tmpFilePath) => {
99
+ if (existsSync(tmpFilePath)) {
100
+ unlinkSync(tmpFilePath);
101
+ }
102
+ });
103
+
104
+ sourceFiles.forEach((rubyFile) => {
105
+ const tempSubdir = path.join(tempDir, path.dirname(rubyFile));
106
+ if (existsSync(tempSubdir)) {
107
+ rmdirSync(tempSubdir);
108
+ }
109
+ });
110
+
111
+ if (existsSync(tempDir)) {
112
+ rmdirSync(tempDir);
113
+ }
114
+ };
115
+ }
116
+
117
+ const server = spawn(
118
+ "ruby",
119
+ [serverRbPath, `--plugins=${opts.rubyPlugins}`, filepath],
120
+ {
121
+ env: Object.assign({}, process.env, { LANG: getLang() }),
122
+ detached: true,
123
+ stdio: "inherit"
124
+ }
125
+ );
126
+
127
+ server.unref();
128
+ process.on("exit", () => {
129
+ if (existsSync(filepath)) {
130
+ unlinkSync(filepath);
131
+ }
132
+
133
+ if (cleanupTempFiles != null) {
134
+ cleanupTempFiles();
135
+ }
136
+
137
+ try {
138
+ if (server.pid) {
139
+ // Kill the server process if it's still running. If we're on windows
140
+ // we're going to use the process ID number. If we're not, we're going
141
+ // to use the negative process ID to indicate the group.
142
+ const pid = process.platform === "win32" ? server.pid : -server.pid;
143
+ process.kill(pid);
144
+ }
145
+ } catch (e) {
146
+ if (process.env.PLUGIN_RUBY_CI) {
147
+ throw new Error(`Failed to kill the parser server: ${e}`);
148
+ }
149
+ }
150
+ });
151
+
152
+ const info = spawnSync("node", [getInfoJsPath, filepath]);
153
+
154
+ if (info.status !== 0) {
155
+ throw new Error(`
156
+ We failed to spawn our parser server. Please report this error on GitHub
157
+ at https://github.com/prettier/plugin-ruby. The error message was:
158
+
159
+ ${info.stderr.toString()}.
160
+ `);
161
+ }
162
+
163
+ const [cmd, ...args] = info.stdout.toString().split(" ");
164
+ return { cmd, args };
165
+ }
166
+
167
+ // If we're in a yarn Plug'n'Play environment, then the relative paths being
168
+ // used by the parser server and the various scripts used to communicate
169
+ // therein are not going to work with its virtual file system.
170
+ function runningInPnPZip() {
171
+ return process.versions.pnp && __dirname.includes(".zip");
172
+ }
173
+
174
+ // Formats and sends a request to the parser server. We use netcat (or something
175
+ // like it) here since Prettier requires the results of `parse` to be
176
+ // synchronous and Node.js does not offer a mechanism for synchronous socket
177
+ // requests.
178
+ function parseSync(parser, source, opts) {
179
+ if (!parserArgs) {
180
+ parserArgs = spawnServer(opts);
181
+ }
182
+
183
+ const response = spawnSync(parserArgs.cmd, parserArgs.args, {
184
+ input: `${parser}|${source}`,
185
+ maxBuffer: 15 * 1024 * 1024
186
+ });
187
+
188
+ const stdout = response.stdout.toString();
189
+ const stderr = response.stderr.toString();
190
+ const { status } = response;
191
+
192
+ // If we didn't receive anything over stdout or we have a bad exit status,
193
+ // then throw whatever we can.
194
+ if (stdout.length === 0 || (status !== null && status !== 0)) {
195
+ throw new Error(stderr || "An unknown error occurred");
196
+ }
197
+
198
+ const parsed = JSON.parse(stdout);
199
+
200
+ if (parsed.error) {
201
+ const error = new Error(parsed.error);
202
+ if (parsed.loc) {
203
+ error.loc = parsed.loc;
204
+ }
205
+
206
+ throw error;
207
+ }
208
+
209
+ return parsed;
210
+ }
211
+
212
+ module.exports = {
213
+ getLang,
214
+ getInfoFilepath,
215
+ parseSync
216
+ };
data/src/plugin.js ADDED
@@ -0,0 +1,170 @@
1
+ const { parseSync } = require("./parseSync");
2
+
3
+ /*
4
+ * metadata mostly pulled from linguist and rubocop:
5
+ * https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
6
+ * https://github.com/rubocop/rubocop/blob/master/spec/rubocop/target_finder_spec.rb
7
+ */
8
+ const plugin = {
9
+ languages: [
10
+ {
11
+ name: "Ruby",
12
+ parsers: ["ruby"],
13
+ extensions: [
14
+ ".arb",
15
+ ".axlsx",
16
+ ".builder",
17
+ ".eye",
18
+ ".fcgi",
19
+ ".gemfile",
20
+ ".gemspec",
21
+ ".god",
22
+ ".jb",
23
+ ".jbuilder",
24
+ ".mspec",
25
+ ".opal",
26
+ ".pluginspec",
27
+ ".podspec",
28
+ ".rabl",
29
+ ".rake",
30
+ ".rb",
31
+ ".rbi",
32
+ ".rbuild",
33
+ ".rbw",
34
+ ".rbx",
35
+ ".ru",
36
+ ".ruby",
37
+ ".thor",
38
+ ".watchr"
39
+ ],
40
+ filenames: [
41
+ ".irbrc",
42
+ ".pryrc",
43
+ ".simplecov",
44
+ "Appraisals",
45
+ "Berksfile",
46
+ "Brewfile",
47
+ "Buildfile",
48
+ "Capfile",
49
+ "Cheffile",
50
+ "Dangerfile",
51
+ "Deliverfile",
52
+ "Fastfile",
53
+ "Gemfile",
54
+ "Guardfile",
55
+ "Jarfile",
56
+ "Mavenfile",
57
+ "Podfile",
58
+ "Puppetfile",
59
+ "Rakefile",
60
+ "Snapfile",
61
+ "Thorfile",
62
+ "Vagabondfile",
63
+ "Vagrantfile",
64
+ "buildfile"
65
+ ],
66
+ interpreters: ["jruby", "macruby", "rake", "rbx", "ruby"],
67
+ linguistLanguageId: 326,
68
+ vscodeLanguageIds: ["ruby"]
69
+ },
70
+ {
71
+ name: "RBS",
72
+ parsers: ["rbs"],
73
+ extensions: [".rbs"]
74
+ },
75
+ {
76
+ name: "HAML",
77
+ parsers: ["haml"],
78
+ extensions: [".haml"],
79
+ vscodeLanguageIds: ["haml"]
80
+ }
81
+ ],
82
+ parsers: {
83
+ ruby: {
84
+ parse(text, _parsers, opts) {
85
+ return parseSync("ruby", text, opts);
86
+ },
87
+ astFormat: "ruby",
88
+ hasPragma(text) {
89
+ return /^\s*#[^\S\n]*@(?:prettier|format)\s*?(?:\n|$)/m.test(text);
90
+ },
91
+ locStart() {
92
+ return 0;
93
+ },
94
+ locEnd() {
95
+ return 0;
96
+ }
97
+ },
98
+ rbs: {
99
+ parse(text, _parsers, opts) {
100
+ return parseSync("rbs", text, opts);
101
+ },
102
+ astFormat: "rbs",
103
+ hasPragma(text) {
104
+ return /^\s*#[^\S\n]*@(prettier|format)\s*(\n|$)/.test(text);
105
+ },
106
+ locStart() {
107
+ return 0;
108
+ },
109
+ locEnd() {
110
+ return 0;
111
+ }
112
+ },
113
+ haml: {
114
+ parse(text, _parsers, opts) {
115
+ return parseSync("haml", text, opts);
116
+ },
117
+ astFormat: "haml",
118
+ hasPragma(text) {
119
+ return /^\s*-#\s*@(prettier|format)/.test(text);
120
+ },
121
+ locStart() {
122
+ return 0;
123
+ },
124
+ locEnd() {
125
+ return 0;
126
+ }
127
+ }
128
+ },
129
+ printers: {
130
+ ruby: {
131
+ print(path) {
132
+ return path.getValue();
133
+ },
134
+ insertPragma(text) {
135
+ return `# @format${text.startsWith("#") ? "\n" : "\n\n"}${text}`;
136
+ }
137
+ },
138
+ rbs: {
139
+ print(path) {
140
+ return path.getValue();
141
+ },
142
+ insertPragma(text) {
143
+ return `# @format${text.startsWith("#") ? "\n" : "\n\n"}${text}`;
144
+ }
145
+ },
146
+ haml: {
147
+ print(path) {
148
+ return path.getValue();
149
+ },
150
+ insertPragma(text) {
151
+ return `-# @format${text.startsWith("-#") ? "\n" : "\n\n"}${text}`;
152
+ }
153
+ }
154
+ },
155
+ options: {
156
+ rubyPlugins: {
157
+ type: "string",
158
+ category: "Ruby",
159
+ default: "",
160
+ description: "The comma-separated list of plugins to require",
161
+ since: "3.1.0"
162
+ }
163
+ },
164
+ defaultOptions: {
165
+ printWidth: 80,
166
+ tabWidth: 2
167
+ }
168
+ };
169
+
170
+ module.exports = plugin;
@@ -1,25 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bundler/setup' if ENV['PLUGIN_RUBY_CI']
4
- require 'socket'
5
- require 'json'
6
- require 'fileutils'
7
- require 'open3'
3
+ require "bundler/setup"
4
+ require "socket"
5
+ require "json"
6
+ require "fileutils"
7
+ require "open3"
8
8
 
9
- require_relative '../ruby/parser'
10
- require_relative '../rbs/parser'
11
- require_relative '../haml/parser'
9
+ require "syntax_tree"
10
+ require "syntax_tree/haml"
11
+ require "syntax_tree/rbs"
12
+
13
+ # First, require all of the plugins that the user specified.
14
+ ARGV.shift[/^--plugins=(.*)$/, 1]
15
+ .split(",")
16
+ .each { |plugin| require "syntax_tree/#{plugin}" }
12
17
 
13
18
  # Make sure we trap these signals to be sure we get the quit command coming from
14
19
  # the parent node process
15
20
  quit = false
16
21
  trap(:INT) { quit = true }
17
22
  trap(:TERM) { quit = true }
18
- trap(:QUIT) { quit = true } if Signal.list.key?('QUIT')
23
+
24
+ if Signal.list.key?("QUIT") && RUBY_ENGINE != "jruby"
25
+ trap(:QUIT) { quit = true }
26
+ end
19
27
 
20
28
  # The information variable stores the actual connection information, which will
21
29
  # either be an IP address and port or a path to a unix socket file.
22
- information = ''
30
+ information = ""
23
31
 
24
32
  # The candidates array is a list of potential programs that could be used to
25
33
  # connect to our server. We'll run through them after the server starts to find
@@ -29,7 +37,7 @@ candidates = []
29
37
  if Gem.win_platform?
30
38
  # If we're on windows, we're going to start up a TCP server. The 0 here means
31
39
  # to bind to some available port.
32
- server = TCPServer.new('127.0.0.1', 0)
40
+ server = TCPServer.new("127.0.0.1", 0)
33
41
  address = server.local_address
34
42
 
35
43
  # Ensure that we close the server when this process exits.
@@ -51,7 +59,7 @@ else
51
59
  end
52
60
 
53
61
  information = server.local_address.unix_path
54
- candidates = ['nc -w 3 -U', 'ncat -w 3 -U']
62
+ candidates = ["nc -w 3 -U", "ncat -w 3 -U"]
55
63
  end
56
64
 
57
65
  # This is the actual listening thread that will be acting as our server. We have
@@ -65,26 +73,41 @@ listener =
65
73
 
66
74
  # Start up a new thread that will handle each successive connection.
67
75
  Thread.new(server.accept_nonblock) do |socket|
68
- parser, source = socket.read.force_encoding('UTF-8').split('|', 2)
76
+ parser, source = socket.read.force_encoding("UTF-8").split("|", 2)
77
+
78
+ source.each_line do |line|
79
+ case line
80
+ when /^\s*#.+?coding/
81
+ # If we've found an encoding comment, then we're going to take that
82
+ # into account and reclassify the encoding for the source.
83
+ encoding = Ripper.new(line).tap(&:parse).encoding
84
+ source = source.force_encoding(encoding)
85
+ break
86
+ when /^\s*#/
87
+ # continue
88
+ else
89
+ break
90
+ end
91
+ end
69
92
 
70
93
  response =
71
94
  case parser
72
- when 'ping'
73
- 'pong'
74
- when 'ruby'
75
- Prettier::Parser.parse(source)
76
- when 'rbs'
77
- Prettier::RBSParser.parse(source)
78
- when 'haml'
79
- Prettier::HAMLParser.parse(source)
95
+ when "ping"
96
+ "pong"
97
+ when "ruby"
98
+ SyntaxTree.format(source)
99
+ when "rbs"
100
+ SyntaxTree::RBS.format(source)
101
+ when "haml"
102
+ SyntaxTree::Haml.format(source)
80
103
  end
81
104
 
82
105
  if response
83
- socket.write(JSON.fast_generate(response))
106
+ socket.write(JSON.fast_generate(response.force_encoding("UTF-8")))
84
107
  else
85
- socket.write('{ "error": true }')
108
+ socket.write("{ \"error\": true }")
86
109
  end
87
- rescue Prettier::Parser::ParserError => error
110
+ rescue SyntaxTree::Parser::ParseError => error
88
111
  loc = { start: { line: error.lineno, column: error.column } }
89
112
  socket.write(JSON.fast_generate(error: error.message, loc: loc))
90
113
  rescue StandardError => error
@@ -114,9 +137,9 @@ candidates.map! do |candidate|
114
137
 
115
138
  # We do not care about stderr here, so throw it away
116
139
  stdout, _stderr, status =
117
- Open3.capture3("#{candidate} #{information}", stdin_data: 'ping')
140
+ Open3.capture3("#{candidate} #{information}", stdin_data: "ping")
118
141
 
119
- candidate if JSON.parse(stdout) == 'pong' && status.exitstatus == 0
142
+ candidate if JSON.parse(stdout) == "pong" && status.exitstatus == 0
120
143
  rescue StandardError
121
144
  # We don't actually care if this fails, because we'll just skip that
122
145
  # connection option.
@@ -132,7 +155,7 @@ prefix =
132
155
 
133
156
  # Default to running the netcat.js script that we ship with the plugin. It's a
134
157
  # good fallback as it will always work, but it is slower than the other options.
135
- prefix ||= "node #{File.expand_path('netcat.js', __dir__)}"
158
+ prefix ||= "node #{File.expand_path("netcat.js", __dir__)}"
136
159
 
137
160
  # Write out our connection information to the file given as the first argument
138
161
  # to this script.