prettier 2.1.0 → 3.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -6
- data/README.md +16 -16
- data/exe/rbprettier +2 -2
- data/lib/prettier/rake/task.rb +5 -5
- data/lib/prettier.rb +11 -11
- data/package.json +9 -23
- data/rubocop.yml +6 -6
- data/{dist/parser → src}/getInfo.js +0 -1
- data/{dist/parser → src}/netcat.js +0 -1
- data/src/parseSync.js +212 -0
- data/src/plugin.js +161 -0
- data/{dist/parser → src}/server.rb +45 -31
- metadata +94 -78
- data/bin/console +0 -7
- data/dist/haml/embed.js +0 -53
- data/dist/haml/parser.js +0 -31
- data/dist/haml/parser.rb +0 -149
- data/dist/haml/printer.js +0 -336
- data/dist/parser/parseSync.js +0 -179
- data/dist/plugin.js +0 -143
- data/dist/prettier.js +0 -15
- data/dist/rbs/parser.js +0 -34
- data/dist/rbs/parser.rb +0 -155
- data/dist/rbs/printer.js +0 -525
- data/dist/ruby/embed.js +0 -115
- data/dist/ruby/location.js +0 -19
- data/dist/ruby/nodes/alias.js +0 -60
- data/dist/ruby/nodes/aref.js +0 -51
- data/dist/ruby/nodes/args.js +0 -138
- data/dist/ruby/nodes/arrays.js +0 -122
- data/dist/ruby/nodes/assign.js +0 -37
- data/dist/ruby/nodes/blocks.js +0 -90
- data/dist/ruby/nodes/calls.js +0 -263
- data/dist/ruby/nodes/case.js +0 -50
- data/dist/ruby/nodes/class.js +0 -54
- data/dist/ruby/nodes/commands.js +0 -138
- data/dist/ruby/nodes/conditionals.js +0 -246
- data/dist/ruby/nodes/constants.js +0 -35
- data/dist/ruby/nodes/flow.js +0 -59
- data/dist/ruby/nodes/hashes.js +0 -126
- data/dist/ruby/nodes/heredocs.js +0 -30
- data/dist/ruby/nodes/hooks.js +0 -35
- data/dist/ruby/nodes/ints.js +0 -27
- data/dist/ruby/nodes/lambdas.js +0 -70
- data/dist/ruby/nodes/loops.js +0 -75
- data/dist/ruby/nodes/massign.js +0 -60
- data/dist/ruby/nodes/methods.js +0 -50
- data/dist/ruby/nodes/operators.js +0 -68
- data/dist/ruby/nodes/params.js +0 -95
- data/dist/ruby/nodes/patterns.js +0 -119
- data/dist/ruby/nodes/regexp.js +0 -45
- data/dist/ruby/nodes/rescue.js +0 -86
- data/dist/ruby/nodes/return.js +0 -100
- data/dist/ruby/nodes/statements.js +0 -110
- data/dist/ruby/nodes/strings.js +0 -220
- data/dist/ruby/nodes/super.js +0 -26
- data/dist/ruby/nodes/undef.js +0 -31
- data/dist/ruby/nodes.js +0 -177
- data/dist/ruby/parser.js +0 -35
- data/dist/ruby/parser.rb +0 -9134
- data/dist/ruby/printer.js +0 -67
- data/dist/ruby/toProc.js +0 -91
- data/dist/types/haml.js +0 -4
- data/dist/types/plugin.js +0 -3
- data/dist/types/rbs.js +0 -4
- data/dist/types/ruby.js +0 -4
- data/dist/types/utils.js +0 -2
- data/dist/types.js +0 -34
- data/dist/utils/containsAssignment.js +0 -18
- data/dist/utils/getChildNodes.js +0 -305
- data/dist/utils/getTrailingComma.js +0 -6
- data/dist/utils/hasAncestor.js +0 -15
- data/dist/utils/inlineEnsureParens.js +0 -49
- data/dist/utils/isEmptyBodyStmt.js +0 -10
- data/dist/utils/isEmptyParams.js +0 -12
- data/dist/utils/isEmptyStmts.js +0 -10
- data/dist/utils/literal.js +0 -8
- data/dist/utils/literallineWithoutBreakParent.js +0 -8
- data/dist/utils/makeCall.js +0 -14
- data/dist/utils/noIndent.js +0 -11
- data/dist/utils/printEmptyCollection.js +0 -46
- data/dist/utils/skipAssignIndent.js +0 -19
- data/dist/utils.js +0 -32
data/dist/haml/parser.rb
DELETED
@@ -1,149 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'ripper'
|
4
|
-
|
5
|
-
begin
|
6
|
-
require 'haml'
|
7
|
-
rescue LoadError
|
8
|
-
# If we can't load the haml gem, then we're going to provide a shim parser
|
9
|
-
# that will warn and bail out.
|
10
|
-
class Prettier::HAMLParser
|
11
|
-
def self.parse(text)
|
12
|
-
warn(
|
13
|
-
'The `haml` gem could not be loaded. Please ensure you have it ' \
|
14
|
-
'installed and that it is available in the gem path.'
|
15
|
-
)
|
16
|
-
|
17
|
-
false
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
return
|
22
|
-
end
|
23
|
-
|
24
|
-
class Haml::Parser::ParseNode
|
25
|
-
class DeepAttributeParser
|
26
|
-
def parse(string)
|
27
|
-
Haml::AttributeParser.available? ? parse_value(string) : string
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def literal(string, level)
|
33
|
-
level == 0 ? string : "&#{string}"
|
34
|
-
end
|
35
|
-
|
36
|
-
def parse_value(string, level = 0)
|
37
|
-
response = Ripper.sexp(string)
|
38
|
-
return literal(string, level) unless response
|
39
|
-
|
40
|
-
case response[1][0][0]
|
41
|
-
when :hash
|
42
|
-
hash = Haml::AttributeParser.parse(string)
|
43
|
-
|
44
|
-
if hash
|
45
|
-
# Explicitly not using Enumerable#to_h here to support Ruby 2.5
|
46
|
-
hash.each_with_object({}) do |(key, value), response|
|
47
|
-
# For attributes that starts with @, wrap the attribute in quotes
|
48
|
-
# For other attributes, remove the quotes
|
49
|
-
# AlpineJS uses @-attributes
|
50
|
-
# {'type': 'submit'} => {type: 'submit'}
|
51
|
-
# {'@click': 'open'} => {'@click': 'open'}
|
52
|
-
key = "\'#{key}\'" if key.start_with?('@')
|
53
|
-
response[key] = parse_value(value, level + 1)
|
54
|
-
end
|
55
|
-
else
|
56
|
-
literal(string, level)
|
57
|
-
end
|
58
|
-
when :string_literal
|
59
|
-
string[1...-1]
|
60
|
-
else
|
61
|
-
literal(string, level)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
ESCAPE = /Haml::Helpers.html_escape\(\((.+)\)\)/.freeze
|
67
|
-
|
68
|
-
# If a node comes in as the plain type but starts with one of the special
|
69
|
-
# characters that haml parses, then we need to escape it with a \ when
|
70
|
-
# printing. So here we make a regexp pattern to check if the node needs to be
|
71
|
-
# escaped.
|
72
|
-
special_chars =
|
73
|
-
Haml::Parser::SPECIAL_CHARACTERS.map { |char| Regexp.escape(char) }
|
74
|
-
|
75
|
-
SPECIAL_START = /\A(?:#{special_chars.join('|')})/
|
76
|
-
|
77
|
-
def as_json
|
78
|
-
case type
|
79
|
-
when :comment, :doctype, :silent_script
|
80
|
-
to_h.tap do |json|
|
81
|
-
json.delete(:parent)
|
82
|
-
json[:children] = children.map(&:as_json)
|
83
|
-
end
|
84
|
-
when :filter, :haml_comment
|
85
|
-
to_h.tap { |json| json.delete(:parent) }
|
86
|
-
when :plain
|
87
|
-
to_h.tap do |json|
|
88
|
-
json.delete(:parent)
|
89
|
-
json[:children] = children.map(&:as_json)
|
90
|
-
|
91
|
-
text = json[:value][:text]
|
92
|
-
json[:value][:text] = "\\#{text}" if text.match?(SPECIAL_START)
|
93
|
-
end
|
94
|
-
when :root
|
95
|
-
to_h.tap do |json|
|
96
|
-
json[:children] = children.map(&:as_json)
|
97
|
-
|
98
|
-
# We need this information in the printer to know how to lay out
|
99
|
-
# multi-line attributes.
|
100
|
-
json[:supports_multiline] =
|
101
|
-
Gem::Version.new(Haml::VERSION) >= Gem::Version.new('5.2')
|
102
|
-
end
|
103
|
-
when :script
|
104
|
-
to_h.tap do |json|
|
105
|
-
json.delete(:parent)
|
106
|
-
json[:children] = children.map(&:as_json)
|
107
|
-
|
108
|
-
if json[:value][:text].match?(ESCAPE)
|
109
|
-
json[:value][:text].gsub!(ESCAPE) { $1 }
|
110
|
-
json[:value].merge!(escape_html: 'escape_html', interpolate: true)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
when :tag
|
114
|
-
to_h.tap do |json|
|
115
|
-
json.delete(:parent)
|
116
|
-
|
117
|
-
# For some reason this is actually using a symbol to represent a null
|
118
|
-
# object ref instead of nil itself, so just replacing it here for
|
119
|
-
# simplicity in the printer
|
120
|
-
json[:value][:object_ref] = nil if json[:value][:object_ref] == :nil
|
121
|
-
|
122
|
-
# Get a reference to the dynamic attributes hash
|
123
|
-
dynamic_attributes = value[:dynamic_attributes].to_h
|
124
|
-
|
125
|
-
# If we have any in the old style, then we're going to pass it through
|
126
|
-
# the deep attribute parser filter.
|
127
|
-
if dynamic_attributes[:old]
|
128
|
-
dynamic_attributes[:old] =
|
129
|
-
DeepAttributeParser.new.parse(dynamic_attributes[:old])
|
130
|
-
end
|
131
|
-
|
132
|
-
json.merge!(
|
133
|
-
children: children.map(&:as_json),
|
134
|
-
value: value.merge(dynamic_attributes: dynamic_attributes)
|
135
|
-
)
|
136
|
-
end
|
137
|
-
else
|
138
|
-
raise ArgumentError, "Unsupported type: #{type}"
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
module Prettier
|
144
|
-
class HAMLParser
|
145
|
-
def self.parse(source)
|
146
|
-
Haml::Parser.new({}).call(source).as_json
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
data/dist/haml/printer.js
DELETED
@@ -1,336 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
const prettier_1 = __importDefault(require("../prettier"));
|
7
|
-
const embed_1 = __importDefault(require("./embed"));
|
8
|
-
const { align, fill, group, hardline, ifBreak, indent, join, line, makeString, softline } = prettier_1.default;
|
9
|
-
const docTypes = {
|
10
|
-
basic: "Basic",
|
11
|
-
frameset: "Frameset",
|
12
|
-
mobile: "Mobile",
|
13
|
-
rdfa: "RDFa",
|
14
|
-
strict: "Strict",
|
15
|
-
xml: "XML"
|
16
|
-
};
|
17
|
-
const docVersions = ["1.1", "5"];
|
18
|
-
// Prints out a hash key according to the configured prettier options.
|
19
|
-
function printHashKey(key, opts) {
|
20
|
-
let quoted = key;
|
21
|
-
const joiner = opts.rubyHashLabel ? ":" : " =>";
|
22
|
-
if (key.includes(":") || key.includes("-")) {
|
23
|
-
const quote = opts.rubySingleQuote ? "'" : '"';
|
24
|
-
quoted = `${quote}${key}${quote}`;
|
25
|
-
}
|
26
|
-
return `${opts.rubyHashLabel ? "" : ":"}${quoted}${joiner}`;
|
27
|
-
}
|
28
|
-
// Prints out the value inside of a hash key-value pair according to the
|
29
|
-
// configured prettier options.
|
30
|
-
function printHashValue(value, opts) {
|
31
|
-
if (typeof value !== "string") {
|
32
|
-
return value.toString();
|
33
|
-
}
|
34
|
-
// This is a very special syntax created by the parser to let us know that
|
35
|
-
// this should be printed literally instead of as a string.
|
36
|
-
if (value.startsWith("&")) {
|
37
|
-
return value.slice(1);
|
38
|
-
}
|
39
|
-
const quote = opts.rubySingleQuote && !value.includes("#{") && !value.includes("'")
|
40
|
-
? "'"
|
41
|
-
: '"';
|
42
|
-
return makeString(value, quote);
|
43
|
-
}
|
44
|
-
// This will print an attributes object to a Doc node. It handles nesting on
|
45
|
-
// multiple levels and will print out according to whether or not the version of
|
46
|
-
// HAML being used supports multi-line attributes.
|
47
|
-
function printAttributes(object, opts, level = 0) {
|
48
|
-
if (typeof object !== "object") {
|
49
|
-
return printHashValue(object, opts);
|
50
|
-
}
|
51
|
-
const boundary = level === 0 ? softline : line;
|
52
|
-
const parts = Object.keys(object).map((key) => [
|
53
|
-
printHashKey(key, opts),
|
54
|
-
" ",
|
55
|
-
printAttributes(object[key], opts, level + 1)
|
56
|
-
]);
|
57
|
-
// If we have support for multi-line attributes laid out like a regular hash,
|
58
|
-
// then we print them that way here.
|
59
|
-
if (opts.supportsMultiline) {
|
60
|
-
return group([
|
61
|
-
"{",
|
62
|
-
indent(group([boundary, join([",", line], parts)])),
|
63
|
-
boundary,
|
64
|
-
"}"
|
65
|
-
]);
|
66
|
-
}
|
67
|
-
// Otherwise, if we only have one attribute, then just print it inline
|
68
|
-
// regardless of how long it is.
|
69
|
-
if (parts.length === 0) {
|
70
|
-
return group(["{", parts[0], "}"]);
|
71
|
-
}
|
72
|
-
// Otherwise, depending on how long the line is it will split the content into
|
73
|
-
// multi-line attributes that old Haml understands.
|
74
|
-
return group([
|
75
|
-
"{",
|
76
|
-
parts[0],
|
77
|
-
",",
|
78
|
-
align(opts.headerLength + 1, [line, join([",", line], parts.slice(1))]),
|
79
|
-
"}"
|
80
|
-
]);
|
81
|
-
}
|
82
|
-
// A utility function used in a silent script that is meant to determine if a
|
83
|
-
// child node is a continuation of a parent node (as in a when clause within a
|
84
|
-
// case statement or an else clause within an if).
|
85
|
-
function isContinuation(parentNode, childNode) {
|
86
|
-
if (childNode.type !== "silent_script") {
|
87
|
-
return false;
|
88
|
-
}
|
89
|
-
const parent = parentNode.value.keyword;
|
90
|
-
const child = childNode.value.keyword;
|
91
|
-
return ((parent === "case" && ["when", "else"].includes(child)) ||
|
92
|
-
(["if", "unless"].includes(parent) && ["elsif", "else"].includes(child)));
|
93
|
-
}
|
94
|
-
const printer = {
|
95
|
-
embed: embed_1.default,
|
96
|
-
// This is our printer's main print function that will switch on the type of
|
97
|
-
// node and print it out by returning a Doc tree.
|
98
|
-
print(path, opts, print) {
|
99
|
-
const node = path.getValue();
|
100
|
-
switch (node.type) {
|
101
|
-
// https://haml.info/docs/yardoc/file.REFERENCE.html#html-comments-
|
102
|
-
case "comment": {
|
103
|
-
const { value } = node;
|
104
|
-
const parts = ["/"];
|
105
|
-
if (value.revealed) {
|
106
|
-
parts.push("!");
|
107
|
-
}
|
108
|
-
if (value.conditional) {
|
109
|
-
parts.push(value.conditional);
|
110
|
-
}
|
111
|
-
else if (value.text) {
|
112
|
-
parts.push(" ", value.text);
|
113
|
-
}
|
114
|
-
return printWithChildren(node, group(parts));
|
115
|
-
}
|
116
|
-
// https://haml.info/docs/yardoc/file.REFERENCE.html#doctype-
|
117
|
-
case "doctype": {
|
118
|
-
const { value } = node;
|
119
|
-
const parts = ["!!!"];
|
120
|
-
if (value.type in docTypes) {
|
121
|
-
parts.push(docTypes[value.type]);
|
122
|
-
}
|
123
|
-
else if (value.version && docVersions.includes(value.version)) {
|
124
|
-
parts.push(value.version);
|
125
|
-
}
|
126
|
-
else {
|
127
|
-
parts.push(value.type);
|
128
|
-
}
|
129
|
-
if (value.encoding) {
|
130
|
-
parts.push(value.encoding);
|
131
|
-
}
|
132
|
-
return group(join(" ", parts));
|
133
|
-
}
|
134
|
-
// https://haml.info/docs/yardoc/file.REFERENCE.html#filters
|
135
|
-
case "filter":
|
136
|
-
return group([
|
137
|
-
":",
|
138
|
-
node.value.name,
|
139
|
-
indent([hardline, join(hardline, node.value.text.trim().split("\n"))])
|
140
|
-
]);
|
141
|
-
// https://haml.info/docs/yardoc/file.REFERENCE.html#haml-comments--
|
142
|
-
case "haml_comment": {
|
143
|
-
const { value } = node;
|
144
|
-
const parts = ["-#"];
|
145
|
-
if (value.text) {
|
146
|
-
if (opts.originalText.split("\n")[node.line - 1].trim() === "-#") {
|
147
|
-
const lines = value.text.trim().split("\n");
|
148
|
-
parts.push(indent([hardline, join(hardline, lines)]));
|
149
|
-
}
|
150
|
-
else {
|
151
|
-
parts.push(" ", value.text.trim());
|
152
|
-
}
|
153
|
-
}
|
154
|
-
return parts;
|
155
|
-
}
|
156
|
-
// https://haml.info/docs/yardoc/file.REFERENCE.html#plain-text
|
157
|
-
case "plain":
|
158
|
-
return node.value.text;
|
159
|
-
// The root node in the AST that we build in the parser.
|
160
|
-
case "root": {
|
161
|
-
const nodePath = path;
|
162
|
-
return [join(hardline, nodePath.map(print, "children")), hardline];
|
163
|
-
}
|
164
|
-
// https://haml.info/docs/yardoc/file.REFERENCE.html#inserting_ruby
|
165
|
-
case "script": {
|
166
|
-
const { value } = node;
|
167
|
-
const parts = [];
|
168
|
-
if (value.escape_html) {
|
169
|
-
parts.unshift("&");
|
170
|
-
}
|
171
|
-
if (value.preserve) {
|
172
|
-
parts.push("~");
|
173
|
-
}
|
174
|
-
else if (!value.interpolate) {
|
175
|
-
parts.push("=");
|
176
|
-
}
|
177
|
-
if (value.escape_html && !value.preserve && value.interpolate) {
|
178
|
-
parts.push(" ", value.text.trim().slice(1, -1));
|
179
|
-
}
|
180
|
-
else {
|
181
|
-
parts.push(" ", value.text.trim());
|
182
|
-
}
|
183
|
-
return printWithChildren(node, group(parts));
|
184
|
-
}
|
185
|
-
// https://haml.info/docs/yardoc/file.REFERENCE.html#running-ruby--
|
186
|
-
case "silent_script": {
|
187
|
-
const parts = [`- ${node.value.text.trim()}`];
|
188
|
-
if (node.children.length > 0) {
|
189
|
-
const nodePath = path;
|
190
|
-
parts.push(nodePath.map((childPath) => {
|
191
|
-
const child = childPath.getValue();
|
192
|
-
const concated = [hardline, print(childPath)];
|
193
|
-
return isContinuation(node, child) ? concated : indent(concated);
|
194
|
-
}, "children"));
|
195
|
-
}
|
196
|
-
return group(parts);
|
197
|
-
}
|
198
|
-
// https://haml.info/docs/yardoc/file.REFERENCE.html#element-name-
|
199
|
-
case "tag": {
|
200
|
-
const { value } = node;
|
201
|
-
const { attributes, dynamic_attributes } = value;
|
202
|
-
const parts = [];
|
203
|
-
// If we have a tag that isn't a div, then we need to print out that
|
204
|
-
// name of that tag first. If it is a div, first we'll check if there
|
205
|
-
// are any other things that would force us to print out the div
|
206
|
-
// explicitly, and otherwise we'll leave it off.
|
207
|
-
if (value.name !== "div") {
|
208
|
-
parts.push(`%${value.name}`);
|
209
|
-
}
|
210
|
-
// If we have a class attribute, then we're going to print that here
|
211
|
-
// using the special class syntax.
|
212
|
-
if (attributes.class) {
|
213
|
-
parts.push(`.${attributes.class.replace(/ /g, ".")}`);
|
214
|
-
}
|
215
|
-
// If we have an id attribute, then we're going to print that here using
|
216
|
-
// the special id syntax.
|
217
|
-
if (attributes.id) {
|
218
|
-
parts.push(`#${attributes.id}`);
|
219
|
-
}
|
220
|
-
// If we're using dynamic attributes on this tag, then they come in as a
|
221
|
-
// string that looks like the output of Hash#inspect from Ruby. So here
|
222
|
-
// we're going to split it all up and print it out nicely.
|
223
|
-
if (dynamic_attributes.new) {
|
224
|
-
const docs = [];
|
225
|
-
dynamic_attributes.new
|
226
|
-
.slice(1, -2)
|
227
|
-
.split(",")
|
228
|
-
.forEach((pair, index) => {
|
229
|
-
if (index !== 0) {
|
230
|
-
docs.push(line);
|
231
|
-
}
|
232
|
-
docs.push(join("=", pair.slice(1).split('" => ')));
|
233
|
-
});
|
234
|
-
parts.push(group(["(", align(parts.join("").length + 1, fill(docs)), ")"]));
|
235
|
-
}
|
236
|
-
// If there are any static attributes that are not class or id (because
|
237
|
-
// we already took care of those), then we're going to print them out
|
238
|
-
// here.
|
239
|
-
const staticAttributes = Object.keys(attributes).filter((name) => !["class", "id"].includes(name));
|
240
|
-
if (staticAttributes.length > 0) {
|
241
|
-
const docs = staticAttributes.reduce((accum, key) => {
|
242
|
-
const doc = `${printHashKey(key, opts)} ${printHashValue(attributes[key], opts)}`;
|
243
|
-
return accum.length === 0 ? [doc] : [...accum, ",", line, doc];
|
244
|
-
}, []);
|
245
|
-
parts.push(group(["{", align(parts.join("").length + 1, fill(docs)), "}"]));
|
246
|
-
}
|
247
|
-
// If there are dynamic attributes that don't use the newer syntax, then
|
248
|
-
// we're going to print them out here.
|
249
|
-
if (dynamic_attributes.old) {
|
250
|
-
if (parts.length === 0) {
|
251
|
-
parts.push("%div");
|
252
|
-
}
|
253
|
-
if (typeof dynamic_attributes.old === "string") {
|
254
|
-
parts.push(dynamic_attributes.old);
|
255
|
-
}
|
256
|
-
else {
|
257
|
-
// This is kind of a total hack in that I don't think you're
|
258
|
-
// really supposed to directly use `path.stack`, but it's the
|
259
|
-
// easiest way to get the root node without having to know how
|
260
|
-
// many levels deep we are.
|
261
|
-
const root = path.stack[0];
|
262
|
-
parts.push(printAttributes(dynamic_attributes.old, {
|
263
|
-
...opts,
|
264
|
-
supportsMultiline: root.supports_multiline,
|
265
|
-
headerLength: parts.join("").length
|
266
|
-
}));
|
267
|
-
}
|
268
|
-
}
|
269
|
-
// https://haml.info/docs/yardoc/file.REFERENCE.html#object-reference-
|
270
|
-
if (value.object_ref) {
|
271
|
-
if (parts.length === 0) {
|
272
|
-
parts.push("%div");
|
273
|
-
}
|
274
|
-
parts.push(value.object_ref);
|
275
|
-
}
|
276
|
-
// https://haml.info/docs/yardoc/file.REFERENCE.html#whitespace-removal--and-
|
277
|
-
if (value.nuke_outer_whitespace) {
|
278
|
-
parts.push(">");
|
279
|
-
}
|
280
|
-
if (value.nuke_inner_whitespace) {
|
281
|
-
parts.push("<");
|
282
|
-
}
|
283
|
-
// https://haml.info/docs/yardoc/file.REFERENCE.html#empty-void-tags-
|
284
|
-
if (value.self_closing) {
|
285
|
-
parts.push("/");
|
286
|
-
}
|
287
|
-
if (value.value) {
|
288
|
-
let contents;
|
289
|
-
if (value.parse && value.value.match(/#[{$@]/)) {
|
290
|
-
// There's a weird case here where if the value includes
|
291
|
-
// interpolation and it's marked as { parse: true }, then we don't
|
292
|
-
// actually want the = prefix, and we want to remove extra escaping.
|
293
|
-
contents = [
|
294
|
-
ifBreak("", " "),
|
295
|
-
value.value.slice(1, -1).replace(/\\"/g, '"')
|
296
|
-
];
|
297
|
-
}
|
298
|
-
else if (value.parse) {
|
299
|
-
contents = ["= ", value.value];
|
300
|
-
}
|
301
|
-
else {
|
302
|
-
contents = [ifBreak("", " "), value.value];
|
303
|
-
}
|
304
|
-
return printWithChildren(node, group([group(parts), indent([softline, ...contents])]));
|
305
|
-
}
|
306
|
-
// In case none of the other if statements have matched and we're
|
307
|
-
// printing a div, we need to explicitly add it back into the array.
|
308
|
-
if (parts.length === 0 && value.name === "div") {
|
309
|
-
parts.push("%div");
|
310
|
-
}
|
311
|
-
return printWithChildren(node, group(parts));
|
312
|
-
}
|
313
|
-
default:
|
314
|
-
throw new Error(`Unsupported node encountered: ${node.type}`);
|
315
|
-
}
|
316
|
-
// It's common to a couple of nodes to attach nested child nodes on the
|
317
|
-
// children property. This utility prints them out grouped together with
|
318
|
-
// their parent node docs.
|
319
|
-
function printWithChildren(node, docs) {
|
320
|
-
if (node.children.length === 0) {
|
321
|
-
return docs;
|
322
|
-
}
|
323
|
-
const nodePath = path;
|
324
|
-
return group([
|
325
|
-
docs,
|
326
|
-
indent([hardline, join(hardline, nodePath.map(print, "children"))])
|
327
|
-
]);
|
328
|
-
}
|
329
|
-
},
|
330
|
-
// This function handles adding the format pragma to a source string. This is
|
331
|
-
// an optional workflow for incremental adoption.
|
332
|
-
insertPragma(text) {
|
333
|
-
return `-# @format${text.startsWith("-#") ? "\n" : "\n\n"}${text}`;
|
334
|
-
}
|
335
|
-
};
|
336
|
-
exports.default = printer;
|
data/dist/parser/parseSync.js
DELETED
@@ -1,179 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.getInfoFilepath = exports.getLang = void 0;
|
7
|
-
const child_process_1 = require("child_process");
|
8
|
-
const fs_1 = require("fs");
|
9
|
-
const os_1 = __importDefault(require("os"));
|
10
|
-
const path_1 = __importDefault(require("path"));
|
11
|
-
const process_1 = __importDefault(require("process"));
|
12
|
-
let parserArgs;
|
13
|
-
if (process_1.default.env.PRETTIER_RUBY_HOST) {
|
14
|
-
const [cmd, ...args] = process_1.default.env.PRETTIER_RUBY_HOST.split(" ");
|
15
|
-
parserArgs = { cmd, args };
|
16
|
-
}
|
17
|
-
// In order to properly parse ruby code, we need to tell the ruby process to
|
18
|
-
// parse using UTF-8. Unfortunately, the way that you accomplish this looks
|
19
|
-
// differently depending on your platform.
|
20
|
-
/* istanbul ignore next */
|
21
|
-
function getLang() {
|
22
|
-
const { env, platform } = process_1.default;
|
23
|
-
const envValue = env.LC_ALL || env.LC_CTYPE || env.LANG;
|
24
|
-
// If an env var is set for the locale that already includes UTF-8 in the
|
25
|
-
// name, then assume we can go with that.
|
26
|
-
if (envValue && envValue.includes("UTF-8")) {
|
27
|
-
return envValue;
|
28
|
-
}
|
29
|
-
// Otherwise, we're going to guess which encoding to use based on the system.
|
30
|
-
// This is probably not the best approach in the world, as you could be on
|
31
|
-
// linux and not have C.UTF-8, but in that case you're probably passing an env
|
32
|
-
// var for it. This object below represents all of the possible values of
|
33
|
-
// process.platform per:
|
34
|
-
// https://nodejs.org/api/process.html#process_process_platform
|
35
|
-
return {
|
36
|
-
aix: "C.UTF-8",
|
37
|
-
android: "C.UTF-8",
|
38
|
-
cygwin: "C.UTF-8",
|
39
|
-
darwin: "en_US.UTF-8",
|
40
|
-
freebsd: "C.UTF-8",
|
41
|
-
haiku: "C.UTF-8",
|
42
|
-
linux: "C.UTF-8",
|
43
|
-
netbsd: "C.UTF-8",
|
44
|
-
openbsd: "C.UTF-8",
|
45
|
-
sunos: "C.UTF-8",
|
46
|
-
win32: ".UTF-8"
|
47
|
-
}[platform];
|
48
|
-
}
|
49
|
-
exports.getLang = getLang;
|
50
|
-
// Generate the filepath that should be used to communicate the connection
|
51
|
-
// information between this process and the parser server.
|
52
|
-
function getInfoFilepath() {
|
53
|
-
return path_1.default.join(os_1.default.tmpdir(), `prettier-ruby-parser-${process_1.default.pid}.info`);
|
54
|
-
}
|
55
|
-
exports.getInfoFilepath = getInfoFilepath;
|
56
|
-
// Create a file that will act as a communication mechanism, spawn a parser
|
57
|
-
// server with that filepath as an argument, then spawn another process that
|
58
|
-
// will read that information in order to enable us to connect to it in the
|
59
|
-
// spawnSync function.
|
60
|
-
function spawnServer() {
|
61
|
-
const tempDir = (0, fs_1.mkdtempSync)(path_1.default.join(os_1.default.tmpdir(), "prettier-plugin-ruby-"));
|
62
|
-
const filepath = getInfoFilepath();
|
63
|
-
let serverRbPath = path_1.default.join(__dirname, "./server.rb");
|
64
|
-
let getInfoJsPath = path_1.default.join(__dirname, "./getInfo.js");
|
65
|
-
let cleanupTempFiles;
|
66
|
-
if (runningInPnPZip()) {
|
67
|
-
// If we're running in a Yarn PnP environment inside a ZIP file, it's not possible to run
|
68
|
-
// the Ruby server or the getInfo.js script directly. Instead, we need to copy them and all
|
69
|
-
// the files they depend on to a temporary directory.
|
70
|
-
const sourceFiles = [
|
71
|
-
"parser/server.rb",
|
72
|
-
"parser/getInfo.js",
|
73
|
-
"parser/netcat.js",
|
74
|
-
"ruby/parser.rb",
|
75
|
-
"rbs/parser.rb",
|
76
|
-
"haml/parser.rb"
|
77
|
-
];
|
78
|
-
serverRbPath = path_1.default.join(tempDir, "parser", "server.rb");
|
79
|
-
getInfoJsPath = path_1.default.join(tempDir, "parser", "getInfo.js");
|
80
|
-
sourceFiles.forEach((rubyFile) => {
|
81
|
-
const destDir = path_1.default.join(tempDir, path_1.default.dirname(rubyFile));
|
82
|
-
if (!(0, fs_1.existsSync)(destDir)) {
|
83
|
-
(0, fs_1.mkdirSync)(destDir);
|
84
|
-
}
|
85
|
-
(0, fs_1.copyFileSync)(path_1.default.join(__dirname, "..", rubyFile), path_1.default.join(tempDir, rubyFile));
|
86
|
-
});
|
87
|
-
cleanupTempFiles = () => {
|
88
|
-
[
|
89
|
-
getInfoJsPath,
|
90
|
-
...sourceFiles.map((rubyFile) => path_1.default.join(tempDir, rubyFile))
|
91
|
-
].forEach((tmpFilePath) => {
|
92
|
-
if ((0, fs_1.existsSync)(tmpFilePath)) {
|
93
|
-
(0, fs_1.unlinkSync)(tmpFilePath);
|
94
|
-
}
|
95
|
-
});
|
96
|
-
sourceFiles.forEach((rubyFile) => {
|
97
|
-
const tempSubdir = path_1.default.join(tempDir, path_1.default.dirname(rubyFile));
|
98
|
-
if ((0, fs_1.existsSync)(tempSubdir)) {
|
99
|
-
(0, fs_1.rmdirSync)(tempSubdir);
|
100
|
-
}
|
101
|
-
});
|
102
|
-
if ((0, fs_1.existsSync)(tempDir)) {
|
103
|
-
(0, fs_1.rmdirSync)(tempDir);
|
104
|
-
}
|
105
|
-
};
|
106
|
-
}
|
107
|
-
const server = (0, child_process_1.spawn)("ruby", [serverRbPath, filepath], {
|
108
|
-
env: Object.assign({}, process_1.default.env, { LANG: getLang() }),
|
109
|
-
detached: true,
|
110
|
-
stdio: "inherit"
|
111
|
-
});
|
112
|
-
server.unref();
|
113
|
-
process_1.default.on("exit", () => {
|
114
|
-
if ((0, fs_1.existsSync)(filepath)) {
|
115
|
-
(0, fs_1.unlinkSync)(filepath);
|
116
|
-
}
|
117
|
-
if (cleanupTempFiles != null) {
|
118
|
-
cleanupTempFiles();
|
119
|
-
}
|
120
|
-
try {
|
121
|
-
if (server.pid) {
|
122
|
-
process_1.default.kill(-server.pid);
|
123
|
-
}
|
124
|
-
}
|
125
|
-
catch (e) {
|
126
|
-
if (process_1.default.env.PLUGIN_RUBY_CI) {
|
127
|
-
throw new Error(`Failed to kill the parser server: ${e}`);
|
128
|
-
}
|
129
|
-
}
|
130
|
-
});
|
131
|
-
const info = (0, child_process_1.spawnSync)("node", [getInfoJsPath, filepath]);
|
132
|
-
if (info.status !== 0) {
|
133
|
-
throw new Error(`
|
134
|
-
We failed to spawn our parser server. Please report this error on GitHub
|
135
|
-
at https://github.com/prettier/plugin-ruby. The error message was:
|
136
|
-
|
137
|
-
${info.stderr.toString()}.
|
138
|
-
`);
|
139
|
-
}
|
140
|
-
const [cmd, ...args] = info.stdout.toString().split(" ");
|
141
|
-
return { cmd, args };
|
142
|
-
}
|
143
|
-
// If we're in a yarn Plug'n'Play environment, then the relative paths being
|
144
|
-
// used by the parser server and the various scripts used to communicate
|
145
|
-
// therein are not going to work with its virtual file system.
|
146
|
-
function runningInPnPZip() {
|
147
|
-
return process_1.default.versions.pnp && __dirname.includes(".zip");
|
148
|
-
}
|
149
|
-
// Formats and sends a request to the parser server. We use netcat (or something
|
150
|
-
// like it) here since Prettier requires the results of `parse` to be
|
151
|
-
// synchronous and Node.js does not offer a mechanism for synchronous socket
|
152
|
-
// requests.
|
153
|
-
function parseSync(parser, source) {
|
154
|
-
if (!parserArgs) {
|
155
|
-
parserArgs = spawnServer();
|
156
|
-
}
|
157
|
-
const response = (0, child_process_1.spawnSync)(parserArgs.cmd, parserArgs.args, {
|
158
|
-
input: `${parser}|${source}`,
|
159
|
-
maxBuffer: 15 * 1024 * 1024
|
160
|
-
});
|
161
|
-
const stdout = response.stdout.toString();
|
162
|
-
const stderr = response.stderr.toString();
|
163
|
-
const { status } = response;
|
164
|
-
// If we didn't receive anything over stdout or we have a bad exit status,
|
165
|
-
// then throw whatever we can.
|
166
|
-
if (stdout.length === 0 || (status !== null && status !== 0)) {
|
167
|
-
throw new Error(stderr || "An unknown error occurred");
|
168
|
-
}
|
169
|
-
const parsed = JSON.parse(stdout);
|
170
|
-
if (parsed.error) {
|
171
|
-
const error = new Error(parsed.error);
|
172
|
-
if (parsed.loc) {
|
173
|
-
error.loc = parsed.loc;
|
174
|
-
}
|
175
|
-
throw error;
|
176
|
-
}
|
177
|
-
return parsed;
|
178
|
-
}
|
179
|
-
exports.default = parseSync;
|