prettier 2.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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.