prettier 2.0.0.pre.rc4 → 3.0.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 +58 -10
  3. data/README.md +16 -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 +10 -24
  26. data/rubocop.yml +14 -8
  27. data/src/getInfo.js +23 -0
  28. data/{dist/parser → src}/netcat.js +0 -1
  29. data/src/parseSync.js +212 -0
  30. data/src/plugin.js +161 -0
  31. data/{dist/parser → src}/server.rb +45 -27
  32. metadata +97 -77
  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 -109
  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-rc4",
3
+ "version": "3.0.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": "^4.31.2",
30
- "@typescript-eslint/parser": "^4.31.2",
31
- "eslint": "^7.22.0",
25
+ "eslint": "^8.1.0",
32
26
  "eslint-config-prettier": "^8.0.0",
33
27
  "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"
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,26 +13,32 @@ Layout:
13
13
  Layout/LineLength:
14
14
  Enabled: true
15
15
 
16
- # Disabling all of the following options because they could conflict with a
17
- # prettier configuration setting.
16
+ Style/MultilineIfModifier:
17
+ Enabled: false
18
18
 
19
- Style/MultilineIfModifier: # rubyModifier
19
+ # When method chains with multiple blocks are chained together, rubocop will let
20
+ # them pass if they're using braces but not if they're using do and end
21
+ # keywords. Because we will break individual blocks down to using keywords if
22
+ # they are multiline, this conflicts with rubocop.
23
+ Style/MultilineBlockChain:
20
24
  Enabled: false
21
25
 
22
- Style/SymbolArray: # rubyArrayLiteral
26
+ Style/SymbolArray:
23
27
  Enabled: false
24
28
 
25
- Style/WordArray: # rubyArrayLiteral
29
+ Style/WordArray:
26
30
  Enabled: false
27
31
 
28
- Style/TrailingCommaInArguments: # trailingComma
32
+ Style/TrailingCommaInArguments:
29
33
  Enabled: false
30
34
 
31
- Style/TrailingCommaInArrayLiteral: # trailingComma
35
+ Style/TrailingCommaInArrayLiteral:
32
36
  Enabled: false
33
37
 
34
- Style/TrailingCommaInHashLiteral: # trailingComma
38
+ Style/TrailingCommaInHashLiteral:
35
39
  Enabled: false
36
40
 
41
+ # lambdas that are constructed with the lambda method call cannot be safely
42
+ # turned into lambda literals without removing a method call.
37
43
  Style/Lambda:
38
44
  Enabled: false
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,212 @@
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() {
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("ruby", [serverRbPath, filepath], {
118
+ env: Object.assign({}, process.env, { LANG: getLang() }),
119
+ detached: true,
120
+ stdio: "inherit"
121
+ });
122
+
123
+ server.unref();
124
+ process.on("exit", () => {
125
+ if (existsSync(filepath)) {
126
+ unlinkSync(filepath);
127
+ }
128
+
129
+ if (cleanupTempFiles != null) {
130
+ cleanupTempFiles();
131
+ }
132
+
133
+ try {
134
+ if (server.pid) {
135
+ // Kill the server process if it's still running. If we're on windows
136
+ // we're going to use the process ID number. If we're not, we're going
137
+ // to use the negative process ID to indicate the group.
138
+ const pid = process.platform === "win32" ? server.pid : -server.pid;
139
+ process.kill(pid);
140
+ }
141
+ } catch (e) {
142
+ if (process.env.PLUGIN_RUBY_CI) {
143
+ throw new Error(`Failed to kill the parser server: ${e}`);
144
+ }
145
+ }
146
+ });
147
+
148
+ const info = spawnSync("node", [getInfoJsPath, filepath]);
149
+
150
+ if (info.status !== 0) {
151
+ throw new Error(`
152
+ We failed to spawn our parser server. Please report this error on GitHub
153
+ at https://github.com/prettier/plugin-ruby. The error message was:
154
+
155
+ ${info.stderr.toString()}.
156
+ `);
157
+ }
158
+
159
+ const [cmd, ...args] = info.stdout.toString().split(" ");
160
+ return { cmd, args };
161
+ }
162
+
163
+ // If we're in a yarn Plug'n'Play environment, then the relative paths being
164
+ // used by the parser server and the various scripts used to communicate
165
+ // therein are not going to work with its virtual file system.
166
+ function runningInPnPZip() {
167
+ return process.versions.pnp && __dirname.includes(".zip");
168
+ }
169
+
170
+ // Formats and sends a request to the parser server. We use netcat (or something
171
+ // like it) here since Prettier requires the results of `parse` to be
172
+ // synchronous and Node.js does not offer a mechanism for synchronous socket
173
+ // requests.
174
+ function parseSync(parser, source) {
175
+ if (!parserArgs) {
176
+ parserArgs = spawnServer();
177
+ }
178
+
179
+ const response = spawnSync(parserArgs.cmd, parserArgs.args, {
180
+ input: `${parser}|${source}`,
181
+ maxBuffer: 15 * 1024 * 1024
182
+ });
183
+
184
+ const stdout = response.stdout.toString();
185
+ const stderr = response.stderr.toString();
186
+ const { status } = response;
187
+
188
+ // If we didn't receive anything over stdout or we have a bad exit status,
189
+ // then throw whatever we can.
190
+ if (stdout.length === 0 || (status !== null && status !== 0)) {
191
+ throw new Error(stderr || "An unknown error occurred");
192
+ }
193
+
194
+ const parsed = JSON.parse(stdout);
195
+
196
+ if (parsed.error) {
197
+ const error = new Error(parsed.error);
198
+ if (parsed.loc) {
199
+ error.loc = parsed.loc;
200
+ }
201
+
202
+ throw error;
203
+ }
204
+
205
+ return parsed;
206
+ }
207
+
208
+ module.exports = {
209
+ getLang,
210
+ getInfoFilepath,
211
+ parseSync
212
+ };
data/src/plugin.js ADDED
@@ -0,0 +1,161 @@
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) {
85
+ return parseSync("ruby", text);
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) {
100
+ return parseSync("rbs", text);
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) {
115
+ return parseSync("haml", text);
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
+ defaultOptions: {
156
+ printWidth: 80,
157
+ tabWidth: 2
158
+ }
159
+ };
160
+
161
+ module.exports = plugin;
@@ -1,25 +1,28 @@
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
12
 
13
13
  # Make sure we trap these signals to be sure we get the quit command coming from
14
14
  # the parent node process
15
15
  quit = false
16
16
  trap(:INT) { quit = true }
17
17
  trap(:TERM) { quit = true }
18
- trap(:QUIT) { quit = true } if Signal.list.key?('QUIT')
18
+
19
+ if Signal.list.key?("QUIT") && RUBY_ENGINE != "jruby"
20
+ trap(:QUIT) { quit = true }
21
+ end
19
22
 
20
23
  # The information variable stores the actual connection information, which will
21
24
  # either be an IP address and port or a path to a unix socket file.
22
- information = ''
25
+ information = ""
23
26
 
24
27
  # The candidates array is a list of potential programs that could be used to
25
28
  # connect to our server. We'll run through them after the server starts to find
@@ -29,7 +32,7 @@ candidates = []
29
32
  if Gem.win_platform?
30
33
  # If we're on windows, we're going to start up a TCP server. The 0 here means
31
34
  # to bind to some available port.
32
- server = TCPServer.new('127.0.0.1', 0)
35
+ server = TCPServer.new("127.0.0.1", 0)
33
36
  address = server.local_address
34
37
 
35
38
  # Ensure that we close the server when this process exits.
@@ -51,7 +54,7 @@ else
51
54
  end
52
55
 
53
56
  information = server.local_address.unix_path
54
- candidates = ['nc -w 3 -U', 'ncat -w 3 -U']
57
+ candidates = ["nc -w 3 -U", "ncat -w 3 -U"]
55
58
  end
56
59
 
57
60
  # This is the actual listening thread that will be acting as our server. We have
@@ -65,26 +68,41 @@ listener =
65
68
 
66
69
  # Start up a new thread that will handle each successive connection.
67
70
  Thread.new(server.accept_nonblock) do |socket|
68
- parser, source = socket.read.force_encoding('UTF-8').split('|', 2)
71
+ parser, source = socket.read.force_encoding("UTF-8").split("|", 2)
72
+
73
+ source.each_line do |line|
74
+ case line
75
+ when /^\s*#.+?coding/
76
+ # If we've found an encoding comment, then we're going to take that
77
+ # into account and reclassify the encoding for the source.
78
+ encoding = Ripper.new(line).tap(&:parse).encoding
79
+ source = source.force_encoding(encoding)
80
+ break
81
+ when /^\s*#/
82
+ # continue
83
+ else
84
+ break
85
+ end
86
+ end
69
87
 
70
88
  response =
71
89
  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)
90
+ when "ping"
91
+ "pong"
92
+ when "ruby"
93
+ SyntaxTree.format(source)
94
+ when "rbs"
95
+ SyntaxTree::RBS.format(source)
96
+ when "haml"
97
+ SyntaxTree::Haml.format(source)
80
98
  end
81
99
 
82
100
  if response
83
- socket.write(JSON.fast_generate(response))
101
+ socket.write(JSON.fast_generate(response.force_encoding("UTF-8")))
84
102
  else
85
- socket.write('{ "error": true }')
103
+ socket.write("{ \"error\": true }")
86
104
  end
87
- rescue Prettier::Parser::ParserError => error
105
+ rescue SyntaxTree::Parser::ParseError => error
88
106
  loc = { start: { line: error.lineno, column: error.column } }
89
107
  socket.write(JSON.fast_generate(error: error.message, loc: loc))
90
108
  rescue StandardError => error
@@ -114,9 +132,9 @@ candidates.map! do |candidate|
114
132
 
115
133
  # We do not care about stderr here, so throw it away
116
134
  stdout, _stderr, status =
117
- Open3.capture3("#{candidate} #{information}", stdin_data: 'ping')
135
+ Open3.capture3("#{candidate} #{information}", stdin_data: "ping")
118
136
 
119
- candidate if JSON.parse(stdout) == 'pong' && status.exitstatus == 0
137
+ candidate if JSON.parse(stdout) == "pong" && status.exitstatus == 0
120
138
  rescue StandardError
121
139
  # We don't actually care if this fails, because we'll just skip that
122
140
  # connection option.
@@ -132,7 +150,7 @@ prefix =
132
150
 
133
151
  # Default to running the netcat.js script that we ship with the plugin. It's a
134
152
  # good fallback as it will always work, but it is slower than the other options.
135
- prefix ||= "node #{File.expand_path('netcat.js', __dir__)}"
153
+ prefix ||= "node #{File.expand_path("netcat.js", __dir__)}"
136
154
 
137
155
  # Write out our connection information to the file given as the first argument
138
156
  # to this script.