@prettier/plugin-ruby
Advanced tools
Comparing version 0.10.0 to 0.11.0
@@ -18,3 +18,3 @@ { | ||
"prefer-spread": "off", | ||
"quotes": ["error", "double"] | ||
"quotes": "off" | ||
}, | ||
@@ -21,0 +21,0 @@ "globals": { |
@@ -9,2 +9,25 @@ # Changelog | ||
## [0.11.0] - 2019-04-18 | ||
### Added | ||
- Support for parsing things with a ruby shebang (e.g., `#!/usr/bin/env ruby` or `#!/usr/bin/ruby`). | ||
- [INTERNAL] Big tests refactor. | ||
- Make multiple `when` predicates break at 80 chars and then wrap to be inline with the other predicates. | ||
- Automatically add underscores in large numbers that aren't already formatted. | ||
- Better support for inline access control modifiers. (Thanks for @AlanFoster.) | ||
- Better support for heredocs in hash literals. (Thanks to @jpickwell for the report.) | ||
- Better support for heredocs in array literals. | ||
- Support automatically transforming `def/begin/rescue/end/end` into `def/rescue/end`. | ||
### Changed | ||
- Fixed support for dynamic string hash keys. (Thanks to @deecewan.) | ||
- [INTERNAL] Moved `case/when` into its own file and added better documentation. | ||
- [INTERNAL] Moved `begin/rescue` into its own file. | ||
- Automatically add newlines around access modifiers. (Thanks for @AlanFoster.) | ||
- Alignment of command calls with arguments is fixed. | ||
- Alignment of `to` is explicitly allowed to not indent to better support rspec. (Thanks to @aaronjensen for the report.) | ||
- Fix up the `to_proc` transform so that it works with other argument handling appropriately. | ||
- Fixed regression on regexp comments. | ||
- Fix up block delimiters when nested inside a `command` or `command_call` node. (Thanks to @CodingItWrong for the report.) | ||
- [INTERNAL] Moved hashes into its own file. | ||
## [0.10.0] - 2019-03-25 | ||
@@ -228,3 +251,4 @@ ### Added | ||
[Unreleased]: https://github.com/prettier/plugin-ruby/compare/v0.10.0...HEAD | ||
[Unreleased]: https://github.com/prettier/plugin-ruby/compare/v0.11.0...HEAD | ||
[0.11.0]: https://github.com/prettier/plugin-ruby/compare/v0.10.0...v0.11.0 | ||
[0.10.0]: https://github.com/prettier/plugin-ruby/compare/v0.9.1...v0.10.0 | ||
@@ -231,0 +255,0 @@ [0.9.1]: https://github.com/prettier/plugin-ruby/compare/v0.9.0...v0.9.1 |
{ | ||
"name": "@prettier/plugin-ruby", | ||
"version": "0.10.0", | ||
"version": "0.11.0", | ||
"description": "prettier plugin for the Ruby programming language", | ||
@@ -8,3 +8,3 @@ "main": "src/ruby.js", | ||
"build": "pkg --output pkg/prettier --targets=linux,macos,win node_modules/prettier/bin-prettier.js", | ||
"lint": "eslint .", | ||
"lint": "eslint --cache .", | ||
"print": "prettier --plugin=.", | ||
@@ -36,4 +36,4 @@ "rubocop": "run() { prettier --plugin=. $@ | bundle exec rubocop --stdin $1; }; run", | ||
"jest": { | ||
"setupFiles": [ | ||
"./test/testRunner.js" | ||
"setupFilesAfterEnv": [ | ||
"./test/js/setupTests.js" | ||
], | ||
@@ -40,0 +40,0 @@ "testRegex": ".test.js$" |
@@ -86,8 +86,6 @@ <div align="center"> | ||
After that you can add `prettier` and `@prettier/plugin-ruby` to your `package.json` `devDependencies` by running `npm install --save-dev prettier @prettier/plugin-ruby` if you are using `npm` or `yarn add --dev prettier @prettier/plugin-ruby` if you are using `yarn`. | ||
After that you can add `prettier` and `@prettier/plugin-ruby` to your `package.json`'s `devDependencies` by running `npm install --save-dev prettier @prettier/plugin-ruby` if you are using `npm` or `yarn add --dev prettier @prettier/plugin-ruby` if you are using `yarn`. | ||
Finally, you can install your dependencies using either `npm install` for `npm` or `yarn install` for `yarn`. | ||
Now, you can run `prettier` to tidy up your `ruby` files! Verify by running against one single file: | ||
Now, you can run `prettier` to tidy up your `ruby` files! Verify by running against a file: | ||
```bash | ||
@@ -103,3 +101,3 @@ ./node_modules/.bin/prettier --write path/to/file.rb | ||
Note that you can also install `prettier` globally with `npm install -g prettier` or you can add `./node_modules/.bin` to your `$PATH` so you don't need to reference the executable from the directory each time. | ||
Note that you can also install `prettier` globally with `npm install -g prettier @prettier/plugin-ruby` or you can add `./node_modules/.bin` to your `$PATH` so you don't need to reference the executable from the directory each time. | ||
@@ -150,6 +148,6 @@ ## Configuration | ||
<!-- prettier-ignore --> | ||
<table><tr><td align="center"><a href="https://kevindeisz.com"><img src="https://avatars2.githubusercontent.com/u/5093358?v=4" width="100px;" alt="Kevin Deisz"/><br /><sub><b>Kevin Deisz</b></sub></a><br /><a href="https://github.com/kddeisz/plugin-ruby/commits?author=kddeisz" title="Code">💻</a> <a href="https://github.com/kddeisz/plugin-ruby/commits?author=kddeisz" title="Documentation">📖</a> <a href="#maintenance-kddeisz" title="Maintenance">🚧</a> <a href="#review-kddeisz" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/kddeisz/plugin-ruby/commits?author=kddeisz" title="Tests">⚠️</a></td><td align="center"><a href="https://www.alanfoster.me/"><img src="https://avatars2.githubusercontent.com/u/1271782?v=4" width="100px;" alt="Alan Foster"/><br /><sub><b>Alan Foster</b></sub></a><br /><a href="https://github.com/kddeisz/plugin-ruby/commits?author=AlanFoster" title="Code">💻</a> <a href="https://github.com/kddeisz/plugin-ruby/commits?author=AlanFoster" title="Documentation">📖</a> <a href="#review-AlanFoster" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/kddeisz/plugin-ruby/commits?author=AlanFoster" title="Tests">⚠️</a></td><td align="center"><a href="https://github.com/johnschoeman"><img src="https://avatars0.githubusercontent.com/u/16049495?v=4" width="100px;" alt="johnschoeman"/><br /><sub><b>johnschoeman</b></sub></a><br /><a href="https://github.com/kddeisz/plugin-ruby/commits?author=johnschoeman" title="Tests">⚠️</a></td><td align="center"><a href="https://twitter.com/aaronjensen"><img src="https://avatars3.githubusercontent.com/u/8588?v=4" width="100px;" alt="Aaron Jensen"/><br /><sub><b>Aaron Jensen</b></sub></a><br /><a href="https://github.com/kddeisz/plugin-ruby/commits?author=aaronjensen" title="Documentation">📖</a></td><td align="center"><a href="http://cameronbothner.com"><img src="https://avatars1.githubusercontent.com/u/4642599?v=4" width="100px;" alt="Cameron Bothner"/><br /><sub><b>Cameron Bothner</b></sub></a><br /><a href="https://github.com/kddeisz/plugin-ruby/commits?author=cbothner" title="Code">💻</a></td></tr></table> | ||
<table><tr><td align="center"><a href="https://kevindeisz.com"><img src="https://avatars2.githubusercontent.com/u/5093358?v=4" width="100px;" alt="Kevin Deisz"/><br /><sub><b>Kevin Deisz</b></sub></a><br /><a href="https://github.com/kddeisz/plugin-ruby/commits?author=kddeisz" title="Code">💻</a> <a href="https://github.com/kddeisz/plugin-ruby/commits?author=kddeisz" title="Documentation">📖</a> <a href="#maintenance-kddeisz" title="Maintenance">🚧</a> <a href="#review-kddeisz" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/kddeisz/plugin-ruby/commits?author=kddeisz" title="Tests">⚠️</a></td><td align="center"><a href="https://www.alanfoster.me/"><img src="https://avatars2.githubusercontent.com/u/1271782?v=4" width="100px;" alt="Alan Foster"/><br /><sub><b>Alan Foster</b></sub></a><br /><a href="https://github.com/kddeisz/plugin-ruby/commits?author=AlanFoster" title="Code">💻</a> <a href="https://github.com/kddeisz/plugin-ruby/commits?author=AlanFoster" title="Documentation">📖</a> <a href="#review-AlanFoster" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/kddeisz/plugin-ruby/commits?author=AlanFoster" title="Tests">⚠️</a></td><td align="center"><a href="https://github.com/johnschoeman"><img src="https://avatars0.githubusercontent.com/u/16049495?v=4" width="100px;" alt="johnschoeman"/><br /><sub><b>johnschoeman</b></sub></a><br /><a href="https://github.com/kddeisz/plugin-ruby/commits?author=johnschoeman" title="Tests">⚠️</a></td><td align="center"><a href="https://twitter.com/aaronjensen"><img src="https://avatars3.githubusercontent.com/u/8588?v=4" width="100px;" alt="Aaron Jensen"/><br /><sub><b>Aaron Jensen</b></sub></a><br /><a href="https://github.com/kddeisz/plugin-ruby/commits?author=aaronjensen" title="Documentation">📖</a></td><td align="center"><a href="http://cameronbothner.com"><img src="https://avatars1.githubusercontent.com/u/4642599?v=4" width="100px;" alt="Cameron Bothner"/><br /><sub><b>Cameron Bothner</b></sub></a><br /><a href="https://github.com/kddeisz/plugin-ruby/commits?author=cbothner" title="Code">💻</a></td><td align="center"><a href="https://localhost.dev"><img src="https://avatars3.githubusercontent.com/u/47308085?v=4" width="100px;" alt="localhost.dev"/><br /><sub><b>localhost.dev</b></sub></a><br /><a href="https://github.com/kddeisz/plugin-ruby/issues?q=author%3Alocalhostdotdev" title="Bug reports">🐛</a> <a href="https://github.com/kddeisz/plugin-ruby/commits?author=localhostdotdev" title="Code">💻</a></td><td align="center"><a href="https://deecewan.github.io"><img src="https://avatars0.githubusercontent.com/u/4755785?v=4" width="100px;" alt="David Buchan-Swanson"/><br /><sub><b>David Buchan-Swanson</b></sub></a><br /><a href="https://github.com/kddeisz/plugin-ruby/issues?q=author%3Adeecewan" title="Bug reports">🐛</a> <a href="https://github.com/kddeisz/plugin-ruby/commits?author=deecewan" title="Code">💻</a></td></tr><tr><td align="center"><a href="https://github.com/jpickwell"><img src="https://avatars1.githubusercontent.com/u/4682321?v=4" width="100px;" alt="Jordan Pickwell"/><br /><sub><b>Jordan Pickwell</b></sub></a><br /><a href="https://github.com/kddeisz/plugin-ruby/issues?q=author%3Ajpickwell" title="Bug reports">🐛</a></td></tr></table> | ||
<!-- ALL-CONTRIBUTORS-LIST:END --> | ||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! | ||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! |
213
src/nodes.js
const { align, breakParent, concat, dedent, group, hardline, ifBreak, indent, join, line, literalline, markAsRoot, softline, trim } = require("prettier").doc.builders; | ||
const { removeLines } = require("prettier").doc.utils; | ||
const { concatBody, empty, first, literal, makeArgs, makeCall, makeList, prefix, printComments, skipAssignIndent } = require("./utils"); | ||
const toProc = require("./toProc"); | ||
const { concatBody, empty, first, literal, makeArgs, makeCall, makeList, prefix, skipAssignIndent } = require("./utils"); | ||
const nodes = { | ||
"@int": (path, _opts, _print) => { | ||
const { body } = path.getValue(); | ||
return /^0[0-9]/.test(body) ? `0o${body.slice(1)}` : body; | ||
// If the number is octal and does not contain the optional "o" character | ||
// after the leading 0, add it in. | ||
if (/^0[0-9]/.test(body)) { | ||
return `0o${body.slice(1)}`; | ||
} | ||
// If the number is a decimal number, is sufficiently large, and is not | ||
// already formatted with underscores, then add them in in between the | ||
// numbers every three characters starting from the right. | ||
if (!body.startsWith("0") && body.length >= 4 && !body.includes("_")) { | ||
return ` ${body}`.slice((body.length + 2) % 3).match(/.{3}/g).join("_").trim(); | ||
} | ||
return body; | ||
}, | ||
@@ -14,2 +30,3 @@ "@__end__": (path, _opts, _print) => { | ||
}, | ||
access_ctrl: first, | ||
arg_paren: (path, opts, print) => { | ||
@@ -46,3 +63,19 @@ if (path.getValue().body[0] === null) { | ||
}, | ||
args: makeList, | ||
args: (path, opts, print) => { | ||
const args = path.map(print, "body"); | ||
let blockNode = null; | ||
[1, 2, 3].find(parent => { | ||
const parentNode = path.getParentNode(parent); | ||
blockNode = parentNode && parentNode.type === "method_add_block" && parentNode.body[1]; | ||
return blockNode; | ||
}); | ||
const proc = blockNode && toProc(blockNode); | ||
if (proc) { | ||
args.push(proc); | ||
} | ||
return args; | ||
}, | ||
args_add_block: (path, opts, print) => { | ||
@@ -63,46 +96,3 @@ const parts = path.call(print, "body", 0); | ||
}, | ||
assoc_new: (path, { preferHashLabels }, print) => { | ||
const parts = []; | ||
const [printedLabel, printedValue] = path.map(print, "body"); | ||
switch (path.getValue().body[0].type) { | ||
case "@label": | ||
if (preferHashLabels) { | ||
parts.push(printedLabel); | ||
} else { | ||
parts.push(`:${printedLabel.slice(0, printedLabel.length - 1)} =>`); | ||
} | ||
break; | ||
case "symbol_literal": | ||
if (preferHashLabels && path.getValue().body[0].body.length === 1) { | ||
const { comments, start } = path.getValue().body[0]; | ||
const node = concat([path.call(print, "body", 0, "body", 0, "body", 0), ":"]); | ||
if (comments) { | ||
parts.push(printComments(node, start, comments)); | ||
} else { | ||
parts.push(node); | ||
} | ||
} else { | ||
parts.push(concat([printedLabel, " =>"])); | ||
} | ||
break; | ||
default: | ||
parts.push(concat([printedLabel, " =>"])); | ||
break; | ||
} | ||
if (skipAssignIndent(path.getValue().body[1])) { | ||
parts.push(" ", printedValue); | ||
} else { | ||
parts.push(indent(concat([line, printedValue]))); | ||
} | ||
return group(concat(parts)); | ||
}, | ||
assoc_splat: prefix("**"), | ||
assoclist_from_args: (path, opts, print) => group(join( | ||
concat([",", line]), | ||
path.map(print, "body", 0) | ||
)), | ||
assign: (path, opts, print) => { | ||
@@ -129,10 +119,2 @@ const [printedTarget, printedValue] = path.map(print, "body"); | ||
}, | ||
bare_assoc_hash: (path, opts, print) => group( | ||
join(concat([",", line]), path.map(print, "body", 0)) | ||
), | ||
begin: (path, opts, print) => group(concat([ | ||
"begin", | ||
indent(concat([hardline, concat(path.map(print, "body"))])), | ||
group(concat([hardline, "end"])) | ||
])), | ||
binary: (path, opts, print) => { | ||
@@ -194,16 +176,2 @@ const operator = path.getValue().body[1]; | ||
}, | ||
case: (path, opts, print) => { | ||
const parts = ["case "]; | ||
if (path.getValue().body[0]) { | ||
parts.push(path.call(print, "body", 0)); | ||
} | ||
parts.push( | ||
group(concat([hardline, path.call(print, "body", 1)])), | ||
group(concat([hardline, "end"])) | ||
); | ||
return group(concat(parts)); | ||
}, | ||
class: (path, opts, print) => { | ||
@@ -253,3 +221,3 @@ const [_constant, superclass, statements] = path.getValue().body; | ||
return concat([`:${quote}`, concat(path.call(print, "body", 0)), quote]); | ||
return concat([":", quote, concat(path.call(print, "body", 0)), quote]); | ||
}, | ||
@@ -266,6 +234,2 @@ else: (path, opts, print) => { | ||
embdoc: (path, _opts, _print) => concat([trim, path.getValue().body]), | ||
ensure: (path, opts, print) => group(concat([ | ||
"ensure", | ||
indent(concat([hardline, concat(path.map(print, "body"))])) | ||
])), | ||
excessed_comma: empty, | ||
@@ -277,17 +241,2 @@ fcall: concatBody, | ||
])), | ||
hash: (path, { addTrailingCommas }, print) => { | ||
if (path.getValue().body[0] === null) { | ||
return "{}"; | ||
} | ||
return group(concat([ | ||
"{", | ||
indent(concat([ | ||
line, | ||
concat(path.map(print, "body")), | ||
addTrailingCommas ? ifBreak(",", "") : "" | ||
])), | ||
concat([line, "}"]) | ||
])); | ||
}, | ||
lambda: (path, opts, print) => { | ||
@@ -350,4 +299,22 @@ let params = path.getValue().body[0]; | ||
}, | ||
method_add_arg: concatBody, | ||
method_add_block: concatBody, | ||
method_add_arg: (path, opts, print) => { | ||
const [method, args] = path.map(print, "body"); | ||
const argNode = path.getValue().body[1]; | ||
// This case will ONLY be hit if we can successfully turn the block into a | ||
// to_proc call. In that case, we just explicitly add the parens around it. | ||
if (argNode.type === "args" && args.length > 0) { | ||
return concat([method, "("].concat(args).concat(")")); | ||
} | ||
return concat([method, args]); | ||
}, | ||
method_add_block: (path, opts, print) => { | ||
const [_method, block] = path.getValue().body; | ||
if (toProc(block)) { | ||
return path.call(print, "body", 0); | ||
} | ||
return concat(path.map(print, "body")); | ||
}, | ||
methref: (path, opts, print) => join(".:", path.map(print, "body")), | ||
@@ -447,44 +414,2 @@ mlhs: makeList, | ||
])), | ||
redo: literal("redo"), | ||
rescue: (path, opts, print) => { | ||
const [exception, variable, _statements, addition] = path.getValue().body; | ||
const parts = ["rescue"]; | ||
if (exception || variable) { | ||
if (exception) { | ||
if (Array.isArray(exception)) { | ||
parts.push(" ", path.call(print, "body", 0, 0)); | ||
} else { | ||
parts.push( | ||
" ", | ||
align("rescue ".length, group(join(concat([",", line]), path.call(print, "body", 0)))) | ||
); | ||
} | ||
} | ||
if (variable) { | ||
parts.push(group(concat([" => ", path.call(print, "body", 1)]))); | ||
} | ||
} else { | ||
parts.push(" StandardError"); | ||
} | ||
parts.push(indent(concat([hardline, path.call(print, "body", 2)]))); | ||
if (addition) { | ||
parts.push(concat([hardline, path.call(print, "body", 3)])); | ||
} | ||
return group(concat(parts)); | ||
}, | ||
rescue_mod: (path, opts, print) => group(concat([ | ||
"begin", | ||
indent(concat([hardline, path.call(print, "body", 0)])), | ||
hardline, | ||
"rescue StandardError", | ||
indent(concat([hardline, path.call(print, "body", 1)])), | ||
hardline, | ||
"end" | ||
])), | ||
retry: literal("retry"), | ||
return: (path, opts, print) => { | ||
@@ -511,6 +436,7 @@ const args = path.getValue().body[0].body[0]; | ||
stmts: (path, opts, print) => { | ||
const stmts = path.getValue().body; | ||
const parts = []; | ||
let lineNo = null; | ||
path.getValue().body.forEach((stmt, index) => { | ||
stmts.forEach((stmt, index) => { | ||
if (stmt.type === "void_stmt") { | ||
@@ -524,3 +450,3 @@ return; | ||
parts.push(printed); | ||
} else if (stmt.start - lineNo > 1) { | ||
} else if (stmt.start - lineNo > 1 || [stmt.type, stmts[index - 1].type].includes("access_ctrl")) { | ||
parts.push(hardline, hardline, printed); | ||
@@ -576,18 +502,2 @@ } else if (stmt.start !== lineNo || path.getParentNode().type !== "string_embexpr") { | ||
vcall: first, | ||
when: (path, opts, print) => { | ||
const [_predicates, _statements, addition] = path.getValue().body; | ||
const stmts = path.call(print, "body", 1); | ||
const parts = [group(concat(["when ", join(", ", path.call(print, "body", 0))]))]; | ||
if (!stmts.parts.every(part => !part)) { | ||
parts.push(indent(concat([hardline, stmts]))); | ||
} | ||
if (addition) { | ||
parts.push(concat([hardline, path.call(print, "body", 2)])); | ||
} | ||
return group(concat(parts)); | ||
}, | ||
yield: (path, opts, print) => { | ||
@@ -610,4 +520,6 @@ if (path.getValue().body[0].type === "paren") { | ||
require("./nodes/calls"), | ||
require("./nodes/case"), | ||
require("./nodes/commands"), | ||
require("./nodes/conditionals"), | ||
require("./nodes/hashes"), | ||
require("./nodes/hooks"), | ||
@@ -618,4 +530,5 @@ require("./nodes/loops"), | ||
require("./nodes/regexp"), | ||
require("./nodes/rescue"), | ||
require("./nodes/strings"), | ||
nodes | ||
); |
@@ -1,2 +0,2 @@ | ||
const { concat, group, ifBreak, indent, join, line, softline } = require("prettier").doc.builders; | ||
const { concat, group, ifBreak, indent, join, line, literalline, softline } = require("prettier").doc.builders; | ||
@@ -39,2 +39,21 @@ const isStringArray = args => args.body.every(arg => ( | ||
// Extract out the actual elements, taking into account nesting with | ||
// `args_add_star` nodes. The only nodes that get passed into this function are | ||
// `args` or `args_add_star`. | ||
const getElements = (node, elementPath) => { | ||
if (node.type === "args") { | ||
return node.body.map((element, index) => ({ | ||
element, | ||
elementPath: elementPath.concat(["body", index]) | ||
})); | ||
} | ||
return getElements(node.body[0], elementPath.concat(["body", 0])).concat( | ||
node.body.slice(1).map((element, index) => ({ | ||
element, | ||
elementPath: elementPath.concat(["body", index + 1]) | ||
})) | ||
); | ||
}; | ||
module.exports = { | ||
@@ -64,15 +83,52 @@ aref: (path, opts, print) => { | ||
if (["args", "args_add_star"].includes(args.type)) { | ||
return group(concat([ | ||
"[", | ||
indent(concat([ | ||
softline, | ||
join(concat([",", line]), path.call(print, "body", 0)), | ||
addTrailingCommas ? ifBreak(",", "") : "" | ||
])), | ||
concat([softline, "]"]) | ||
])); | ||
if (!["args", "args_add_star"].includes(args.type)) { | ||
return printSpecialArray(path.call(print, "body", 0)); | ||
} | ||
return printSpecialArray(path.call(print, "body", 0)); | ||
const normalDocs = []; | ||
const elementDocs = path.call(print, "body", 0); | ||
const elements = getElements(path.getValue().body[0], ["body", 0]); | ||
// We need to manually loop through the elements in the array in order to | ||
// take care of heredocs printing (their commas go after the opening, as | ||
// opposed to at the end). | ||
elements.forEach(({ element, elementPath }, index) => { | ||
const isInner = index !== elements.length - 1; | ||
const isStraightHeredoc = element.type === "heredoc"; | ||
const isSquigglyHeredoc = element.type === "string_literal" && element.body[0].type === "heredoc"; | ||
if (isStraightHeredoc || isSquigglyHeredoc) { | ||
const heredocNode = isStraightHeredoc ? element : element.body[0]; | ||
const heredocPath = [print].concat(elementPath); | ||
if (isSquigglyHeredoc) { | ||
heredocPath.push("body", 0); | ||
} | ||
normalDocs.push( | ||
heredocNode.beging, | ||
(isInner || addTrailingCommas) ? "," : "", | ||
literalline, | ||
concat(path.map.apply(path, heredocPath.concat("body"))), | ||
heredocNode.ending, | ||
isInner ? line : "" | ||
); | ||
} else { | ||
normalDocs.push(elementDocs[index]); | ||
if (isInner) { | ||
normalDocs.push(concat([",", line])); | ||
} else if (addTrailingCommas) { | ||
normalDocs.push(ifBreak(",", "")); | ||
} | ||
} | ||
}); | ||
return group(concat([ | ||
"[", | ||
indent(concat([softline].concat(normalDocs))), | ||
concat([softline, "]"]) | ||
])); | ||
}, | ||
@@ -79,0 +135,0 @@ qsymbols: makeArray("%i"), |
const { breakParent, concat, group, ifBreak, indent, softline } = require("prettier").doc.builders; | ||
const { hasAncestor } = require("../utils"); | ||
const isCall = node => ["::", "."].includes(node) || node.type === "@period"; | ||
// If you have a simple block that only calls a method on the single required | ||
// parameter that is passed to it, then you can replace that block with the | ||
// simpler `Symbol#to_proc`. Meaning, it would go from: | ||
// | ||
// [1, 2, 3].map { |i| i.to_s } | ||
// | ||
// to: | ||
// | ||
// [1, 2, 3].map(&:to_s) | ||
// | ||
// This additionally works with `do` blocks as well. | ||
const toProcTransform = path => { | ||
const [variables, blockContents] = path.getValue().body; | ||
// Ensure that there are variables being passed to this block. | ||
const params = variables && variables.body[0]; | ||
if (!params || params.type !== "params") { | ||
return null; | ||
} | ||
// Ensure there is one and only one parameter, and that it is required. | ||
const reqParams = params.body[0]; | ||
const otherParams = params.body.slice(1); | ||
if (!Array.isArray(reqParams) || reqParams.length !== 1 || otherParams.some(Boolean)) { | ||
return null; | ||
} | ||
let statements; | ||
if (blockContents.type === "bodystmt") { | ||
// We’re in a `do` block | ||
const blockStatements = blockContents.body[0]; | ||
const rescueElseEnsure = blockStatements.body.slice(1); | ||
// You can’t use the to_proc shortcut if you’re rescuing | ||
if (rescueElseEnsure.some(Boolean)) { | ||
return null; | ||
} | ||
statements = blockStatements; | ||
} else { | ||
// We’re in a brace block | ||
statements = blockContents; | ||
} | ||
// Ensure the block contains only one statement | ||
if (statements.body.length !== 1) { | ||
return null; | ||
} | ||
// Ensure that statement is a call | ||
const [statement] = statements.body; | ||
if (statement.type !== "call") { | ||
return null; | ||
} | ||
// Ensure the call is a method of the block argument | ||
const [varRef, call, method, args] = statement.body; | ||
if ( | ||
varRef.type === "var_ref" | ||
&& varRef.body[0].body === reqParams[0].body | ||
&& isCall(call) | ||
&& method.type === "@ident" | ||
&& !args | ||
) { | ||
if (["command", "command_call"].includes(path.getParentNode().body[0].type)) { | ||
return `, &:${method.body}`; | ||
} | ||
return `(&:${method.body})`; | ||
} | ||
return null; | ||
}; | ||
const printBlock = (path, opts, print) => { | ||
const toProcResponse = toProcTransform(path); | ||
if (toProcResponse) { | ||
return toProcResponse; | ||
} | ||
const [variables, statements] = path.getValue().body; | ||
@@ -94,7 +13,14 @@ const stmts = statements.type === "stmts" ? statements.body : statements.body[0].body; | ||
// If this block is nested underneath a command or command_call node, then we | ||
// can't use `do...end` because that will get associated with the parent node | ||
// as opposed to the current node (because of the difference in operator | ||
// precedence). Instead, we still use a multi-line format but switch to using | ||
// braces instead. | ||
const useBraces = hasAncestor(path, ["command", "command_call"]); | ||
const doBlock = concat([ | ||
" do", | ||
useBraces ? " {" : " do", | ||
variables ? concat([" ", path.call(print, "body", 0)]) : "", | ||
doBlockBody, | ||
concat([softline, "end"]) | ||
concat([softline, useBraces ? "}" : "end"]) | ||
]); | ||
@@ -114,7 +40,10 @@ | ||
const hasBody = stmts.some(({ type }) => type !== "void_stmt"); | ||
const braceBlock = concat([ | ||
" { ", | ||
" {", | ||
(hasBody || variables) ? " " : "", | ||
variables ? path.call(print, "body", 0) : "", | ||
path.call(print, "body", 1), | ||
" }" | ||
hasBody ? " " : "", | ||
"}" | ||
]); | ||
@@ -121,0 +50,0 @@ |
const { align, concat, group, ifBreak, join, line } = require("prettier").doc.builders; | ||
const { docLength, makeArgs, makeCall } = require("../utils"); | ||
const hasDef = node => ( | ||
node.body[1].type === "args_add_block" | ||
&& node.body[1].body[0].type === "args" | ||
&& node.body[1].body[0].body[0].type === "def" | ||
); | ||
module.exports = { | ||
@@ -14,4 +20,6 @@ command: (path, opts, print) => { | ||
const joinedArgs = join(concat([",", line]), args); | ||
const breakArgs = hasDef(path.getValue()) ? joinedArgs : align(command.length + 1, joinedArgs); | ||
const commandDoc = group(ifBreak( | ||
concat([command, " ", align(command.length + 1, joinedArgs)]), | ||
concat([command, " ", breakArgs]), | ||
concat([command, " ", joinedArgs]) | ||
@@ -45,5 +53,9 @@ )); | ||
const joinedArgs = join(concat([",", line]), args); | ||
const breakArgs = path.getValue().body[2].body === "to" | ||
? joinedArgs | ||
: align(docLength(concat(parts)), joinedArgs); | ||
const commandDoc = group(ifBreak( | ||
concat(parts.concat([align(docLength(concat(parts)), joinedArgs)])), | ||
concat(parts.concat([joinedArgs])) | ||
concat(parts.concat(breakArgs)), | ||
concat(parts.concat(joinedArgs)) | ||
)); | ||
@@ -50,0 +62,0 @@ |
@@ -8,2 +8,3 @@ const { concat } = require("prettier").doc.builders; | ||
const [contents, ending] = path.map(print, "body"); | ||
const useBraces = contents.some(content => typeof content === "string" && content.includes("/")); | ||
@@ -10,0 +11,0 @@ const parts = [useBraces ? "%r{" : "/"].concat(contents).concat([useBraces ? "}" : "/", ending.slice(1)]); |
@@ -7,2 +7,8 @@ const parse = require("./parse"); | ||
/* | ||
* metadata mostly pulled from linguist and rubocop: | ||
* https://github.com/github/linguist/blob/master/lib/linguist/languages.yml | ||
* https://github.com/rubocop-hq/rubocop/blob/master/spec/rubocop/target_finder_spec.rb | ||
*/ | ||
module.exports = { | ||
@@ -13,7 +19,26 @@ languages: [{ | ||
extensions: [ | ||
".arb", | ||
".axlsx", | ||
".builder", | ||
".eye", | ||
".fcgi", | ||
".gemfile", | ||
".gemspec", | ||
".god", | ||
".jb", | ||
".jbuilder", | ||
".mspec", | ||
".opal", | ||
".pluginspec", | ||
".podspec", | ||
".rabl", | ||
".rake", | ||
".rb", | ||
".ru" | ||
".rbuild", | ||
".rbw", | ||
".rbx", | ||
".ru", | ||
".ruby", | ||
".thor", | ||
".watchr" | ||
], | ||
@@ -23,8 +48,31 @@ filenames: [ | ||
".pryrc", | ||
"Appraisals", | ||
"Berksfile", | ||
"Brewfile", | ||
"Buildfile", | ||
"Capfile", | ||
"Cheffile", | ||
"Dangerfile", | ||
"Deliverfile", | ||
"Fastfile", | ||
"Gemfile", | ||
"Guardfile", | ||
"Jarfile", | ||
"Mavenfile", | ||
"Podfile", | ||
"Rakefile" | ||
"Puppetfile", | ||
"Rakefile", | ||
"Snapfile", | ||
"Thorfile", | ||
"Vagabondfile", | ||
"Vagrantfile", | ||
"buildfile" | ||
], | ||
interpreters: [ | ||
"jruby", | ||
"macruby", | ||
"rake", | ||
"rbx", | ||
"ruby" | ||
], | ||
linguistLanguageId: 326, | ||
@@ -31,0 +79,0 @@ vscodeLanguageIds: ["ruby"] |
@@ -14,2 +14,6 @@ const { breakParent, concat, hardline, lineSuffix, literalline } = require("prettier").doc.builders; | ||
if (doc.contents) { | ||
return docLength(doc.contents); | ||
} | ||
return 0; | ||
@@ -22,2 +26,18 @@ }; | ||
const hasAncestor = (path, types) => { | ||
let parent = 0; | ||
let parentNode = path.getParentNode(); | ||
while (parentNode) { | ||
if (types.includes(parentNode.type)) { | ||
return true; | ||
} | ||
parent += 1; | ||
parentNode = path.getParentNode(parent); | ||
} | ||
return false; | ||
}; | ||
const literal = value => () => value; | ||
@@ -116,2 +136,3 @@ | ||
first, | ||
hasAncestor, | ||
literal, | ||
@@ -118,0 +139,0 @@ makeArgs, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
269064
47
1650
151
2