dprint / dprint Goto Github PK
View Code? Open in Web Editor NEWPluggable and configurable code formatting platform written in Rust.
Home Page: https://dprint.dev
License: MIT License
Pluggable and configurable code formatting platform written in Rust.
Home Page: https://dprint.dev
License: MIT License
The rust code should use a Path
when able.
Right now the library will remove files in node_modules after the result of globby, but some performance could be gained by inserting the check to skip node_modules into the glob itself.
Given incredible configuration options dprint has it would be highly desirable to be able to load configuration from a file (probably JSON, or JSONC). I guess using serde
is the way to go in this case.
I'm sure @dsherret already thought about it, but opening the issue for tracking purposes.
The latest release is about 10% slower than the previous. I'm not going to worry about that too much at the moment and will instead optimize it all once everything is stable, but it would be nice to get a performance chart going that shows the speed of the three main stages (ast parsing, IR generation, IR printing) between versions just to ensure it doesn't accidentally get super slow. I don't know the best way to do this though.
Hey, author of rust-analyzer here. Long term, rust-analyzer needs a code formatter, and I like the IR approach you are taking, so I thought I'll dump some of my thoughts on formatting in case they are useful.
To be clear, this is in no way a feature request or something like that, feel free to ignore completely! :)
In rust-analyzer, we sometimes have to synthesize new code and insert such generated code into something written by a user (mostly for refactorings). Our syntax trees represent whitespaces and comments explicitly, so we can represent properly formatted and indented code. However, just manually producing formatted code is a huge pain, so the ideal solution for authors of refactorings is to build code with bad formatting, pipe it through the formatter and insert the good version.
The specifics of IDE places some constraits on the formatting tool however (which are not met by rustfmt). Specifically:
fn example() {
let x = if bar
foo()
}
which is parsed into the following syntax tree:
FN_DEF@[0; 45)
FN_KW@[0; 2) "fn"
WHITESPACE@[2; 3) " "
NAME@[3; 10)
IDENT@[3; 10) "example"
PARAM_LIST@[10; 12)
L_PAREN@[10; 11) "("
R_PAREN@[11; 12) ")"
WHITESPACE@[12; 13) " "
BLOCK_EXPR@[13; 45)
BLOCK@[13; 45)
L_CURLY@[13; 14) "{"
WHITESPACE@[14; 19) "\n "
LET_STMT@[19; 33)
LET_KW@[19; 22) "let"
WHITESPACE@[22; 23) " "
BIND_PAT@[23; 24)
NAME@[23; 24)
IDENT@[23; 24) "x"
WHITESPACE@[24; 25) " "
EQ@[25; 26) "="
WHITESPACE@[26; 27) " "
IF_EXPR@[27; 33)
IF_KW@[27; 29) "if"
WHITESPACE@[29; 30) " "
CONDITION@[30; 33)
PATH_EXPR@[30; 33)
PATH@[30; 33)
PATH_SEGMENT@[30; 33)
NAME_REF@[30; 33)
IDENT@[30; 33) "bar"
WHITESPACE@[33; 38) "\n "
CALL_EXPR@[38; 43)
PATH_EXPR@[38; 41)
PATH@[38; 41)
PATH_SEGMENT@[38; 41)
NAME_REF@[38; 41)
IDENT@[38; 41) "foo"
ARG_LIST@[41; 43)
L_PAREN@[41; 42) "("
R_PAREN@[42; 43) ")"
WHITESPACE@[43; 44) "\n"
R_CURLY@[44; 45) "}"
fn foo() {
bar(1+1)
}
into
fn foo() {
let var = 1+1;
bar(var)
}
we want the formatter to handle spaces around =
and indentation of the whole let, but we do not want it to "fix" spaces around +
, as that's what the user originally written, and we should not "touch" that (but note that might have to re-indent it anyway)
So, this all leads me to the idea that rust-analyzer will be better off with a rule-based formatter, where you specify the rules like "a +
should always be surrounded by one space on each side", and let the formatting engine to figure out the necessary whitespace changes to satisfy all the rules. Possible alternatives are pretty-printers, where the formatter mostly disregards the original formatting and just pretty-prints the code in one true way (rustfmt works like this) or cost-optimization formatters, where there's a certain "pretiness" metric, and the formatter literary searches for the best layout that optimizes this metric (dartfmt works like this I think).
Your IR approach resembles in some aspects what I have in mind for rust-analyzer. In particular, rules like "insert spaces around +
" or "if function call is multiline, there should be a \n before )" could be expressed with conditionals. The main differnece is that I am thinking about tree-shaped, and not linear IR, for formatting, but perhaps lowering to a sequence migth be a better approach.
Overall, I am super excited about dprint, and would love to study its approach in more details :) Thanks for building it!
Support editor config?
Seems like this rust parser will help do the job:
https://github.com/kivikakk/comrak
Edit: Going with pulldown-cmark instead because it has an MIT licence. Comrak is 2-Clause BSD Licence along with some other copyright notices, which requires including a copyright notice in the final binary and that is a blocker for me.
Right now it's 1-indexed based on the columns.
Example:
const ustarStructure: Array<{ field: string; length: number }> = [
{
field: "fileName",
length: 100
},
{
field: "fileMode",
length: 8
}
];
Goes to:
const ustarStructure: Array<{ field: string; length: number }> = [
{
field: "fileName",
length: 100
},
{
field: "fileMode",
length: 8
}
];
This is due to the recent change to support blank lines between items. I stupidly only compared node starts rather than ends with starts.
> RUST_BACKTRACE=1 ./target/debug/deno fmt cli/js/web/streams/writable-internals.ts
thread 'main' panicked at 'Found a tab in the string. Before sending the string to the printer it needs to be broken up and the tab sent as a PrintItem::Tab. // // Assert: state is "writable" or "erroring".', /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-core-0.11.0/src/printer.rs:356:13
stack backtrace:
0: backtrace::backtrace::libunwind::trace
at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
1: backtrace::backtrace::trace_unsynchronized
at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
2: std::sys_common::backtrace::_print_fmt
at src/libstd/sys_common/backtrace.rs:84
3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
at src/libstd/sys_common/backtrace.rs:61
4: core::fmt::write
at src/libcore/fmt/mod.rs:1025
5: std::io::Write::write_fmt
at src/libstd/io/mod.rs:1426
6: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:65
7: std::sys_common::backtrace::print
at src/libstd/sys_common/backtrace.rs:50
8: std::panicking::default_hook::{{closure}}
at src/libstd/panicking.rs:193
9: std::panicking::default_hook
at src/libstd/panicking.rs:210
10: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:471
11: rust_begin_unwind
at src/libstd/panicking.rs:375
12: std::thread::local::fast::Key<T>::try_initialize
13: dprint_core::printer::Printer<TString,TInfo,TCondition>::validate_string
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/<::std::macros::panic macros>:9
14: dprint_core::printer::Printer<TString,TInfo,TCondition>::handle_string
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-core-0.11.0/src/printer.rs:337
15: dprint_core::printer::Printer<TString,TInfo,TCondition>::handle_print_node
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-core-0.11.0/src/printer.rs:133
16: dprint_core::printer::Printer<TString,TInfo,TCondition>::print
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-core-0.11.0/src/printer.rs:77
17: dprint_core::get_write_items::get_write_items
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-core-0.11.0/src/get_write_items.rs:22
18: dprint_core::print::print
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-core-0.11.0/src/print.rs:20
19: dprint_plugin_typescript::format_text::format_text::{{closure}}
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/format_text.rs:45
20: scoped_tls::ScopedKey<T>::set
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/scoped-tls-1.0.0/src/lib.rs:137
21: dprint_plugin_typescript::format_text::format_text
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/format_text.rs:35
22: deno::fmt::format_source_files::{{closure}}
at cli/fmt.rs:107
23: std::panicking::try::do_call
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/panicking.rs:292
24: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:78
25: std::panicking::try
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/panicking.rs:270
26: std::panic::catch_unwind
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/panic.rs:394
27: deno::fmt::format_source_files
at cli/fmt.rs:106
28: deno::fmt::format
at cli/fmt.rs:170
29: deno::main::{{closure}}
at cli/lib.rs:447
30: <std::future::GenFuture<T> as core::future::future::Future>::poll
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/future.rs:43
31: <core::pin::Pin<P> as core::future::future::Future>::poll
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/future/future.rs:119
32: tokio::runtime::basic_scheduler::BasicScheduler<P>::block_on
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/runtime/basic_scheduler.rs:138
33: tokio::runtime::Runtime::block_on::{{closure}}
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/runtime/mod.rs:413
34: tokio::runtime::context::enter
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/runtime/context.rs:72
35: tokio::runtime::handle::Handle::enter
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/runtime/handle.rs:34
36: tokio::runtime::Runtime::block_on
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/runtime/mod.rs:410
37: deno::tokio_util::run_basic
at cli/tokio_util.rs:18
38: deno::main
at cli/lib.rs:486
39: deno::main
at cli/main.rs:4
40: std::rt::lang_start::{{closure}}
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/rt.rs:67
41: std::rt::lang_start_internal::{{closure}}
at src/libstd/rt.rs:52
42: std::panicking::try::do_call
at src/libstd/panicking.rs:292
43: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:78
44: std::panicking::try
at src/libstd/panicking.rs:270
45: std::panic::catch_unwind
at src/libstd/panic.rs:394
46: std::rt::lang_start_internal
at src/libstd/rt.rs:51
47: std::rt::lang_start
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/rt.rs:67
48: deno::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
dprint panic cli/js/web/streams/writable-internals.ts
The current behaviour of param and arg lists is the following:
callExpr(1, 2, 3);
// formats as
callExpr(1, 2, 3);
// but...
callExpr(
1, 2, 3);
// formats as
callExpr(
1,
2,
3
);
But it might be useful to have configuration to force the following:
callExpr(
1, 2, 3);
// formats as
callExpr(1, 2, 3);
Perhaps:
forceSingleLineArguments
forceSingleLineParameterList
Or rename forceMultiLineArguments
and this new config to have IfAble
suffixes or perhaps forceMultiLineArgumentsWhenMultiLine
and forceSingleLineArgumentsWhenSingleLine
.
Overall, need to think about this more... there's probably a better solution that looks at the big picture. Note that this same behaviour happens with if and while statements, so this might need a more general name.
Edit: Most likely will probably will call this preferSingleLine
with downstream preferSingleLineArguments
, and preferSingleLineParameters
config.
Although the lines don't match exactly, the scrollbars in the playground should be synced.
As title.
It would be nice to parallelize formatting of files on the rust cli. That would speed things up a lot.
The fix to #67 introduces a new concept called "info dependent conditions" in the underlying printer that needs refinement.
Especially this todo:
// todo: this should definitely not use the condition context because the printer is not on the condition
Just logging this for now so I know to improve and fix this in the future.
I think most likely this will be a new print item kind.
Also, have a way for it to detect when infinite loops happen between the conditions in this case and return an error describing how the infinite loop is happening.
--
And finally: improve conditions so they don't always have to jump back once for look aheads.
Add some language independent printer specific tests to ensure all (or most) scenarios are tested.
I have a working prototype of a printer written in Rust here: https://github.com/dsherret/dprint/tree/master/packages/rust-core
It would be nice to experiment printing JS print items with the Rust printer to see if a performance improvement could be gained (using Wasm). I looked into this and it seems the bottle neck will be sending over strings over to Rust (since strings in Rust are UTF-8 and strings in JS are UTF-16 they need to be encoded then decoded).
The amazing thing is that the Rust printer could be redesigned so the strings remain in JS since the printer only really cares about string lengths. It seems using js_sys::String allows that.
Basically, instead of strings, the writer (used internally by the printer) would build up another IR called "write items":
String
- Represented by an object containing a reference to the JS string and holds the string length. The string value MUST not contain tabs or newlines... if it does then the provided string should be broken up before its reference is sent to Rust.Indent
(u8
value) - A single indent.NewLine
(u8
value) - A newline character.Tab
(u8
value) - A tab character. This is different than an indent as an indent may not be a tab. Tabs need their own item in the IR because they increase the column number by a value greater than 1 (ex. a tab increases the column number by 4 when the indent width is set to 4).The writer will then return this final write item IR to JS. When JS has it, it will then use a simple write item printer to print out the final string.
To compare the performance fairly, a version of the JS printer should be created that uses "Write Item" IR. That might be faster than both the Rust and previous JS versions, but I'm not sure—we shall see. I'm very skeptical that the Rust version will be faster than the JS.
I'm using [email protected]
async function* main() {
yield await 0;
}
Error formatting: /Users/keroxp/src/deno-pg/yield.ts
Line 2, column 9: Expected ';', '}' or <eof>
Right now token lookups are O(n), but this could be dramatically improved by having a class that starts searching from the last searched for token position. The consumers of this class would just tell it whether to start searching to the left or right then say when it's found the token.
It would be very useful to get some data about when each underlying "write item" is created ("write items" are the final very simple IR that the printer builds up).
This wouldn't be done in release mode obviously.
The end data could then be used to make a visualization that shows where the printer is slow. Probably just a single html file output that shows the file text going from a blue text colour (fast) to red (slow).
Add an --init
cli option that creates a dprint.config.js file and .format
npm script if it doesn't exist
I want some configuration for this (nothing that makes this unreasonable to maintain).
Notes:
semiColons
rule should resolve to importDeclaration.semiColon
, expressionStatement.semiColon
, etc... but those individual rules can be set to override the general rule. A resolution step should occur and expressionStatement.semiColon
rule doesn't appear in the parseImportDeclaration
function).Similar to the TypeScript compiler's --incremental
flag, it might be neat to have a similar flag that only bothers formatting files that haven't been formatted since the last time it ran.
Basically, if the second arg/param goes on a new line, then all of them should.
Apparently it's possible to parallelize code with wasm-bindgen, so this should be done for the TS and JSONC plugins.
Edit: Looks like it's not stable yet, but here's an example: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/raytrace-parallel -- I think I'll need to use worker threads in JS for now.
Need to add these features:
--init
-c
in addition to --config
--outputFilePaths
--allowNodeModuleFiles
(implement this magic)--outputResolvedConfig
includes
and excludes
JS CLI updates:
--check
flag--duration
as it's very easy for someone to check the time of a command on their ownEdit: Not going to bother with JS CLI changes as it's going to be phased out soon. See #194.
On a recent commit I accidentally committed an "only" in the test case:
== should not move comment (only) ==
declare module "ts-nameof" {
interface Api {
replaceInFiles(onFinished?: (err?: any /* NodeJS.ErrnoException */) => void): void;
}
}
[expect]
declare module "ts-nameof" {
interface Api {
replaceInFiles(onFinished?: (err?: any /* NodeJS.ErrnoException */) => void): void;
}
}
This meant that only that test was being run. From the output though, I had no clue this was happening because it's was not obvious. I thought I had removed the "only" and all the tests were passing (luckily nothing was broken and the tests would have passed had they run).
Something needs to be done to prevent that from happening again. I think:
This is really strange:
export class DocumentRegistry {
/** @inheritdoc */
releaseDocument() {
// ignore, handled by removeSourceFile
}
/** @inheritdoc */
releaseDocumentWithKey() {
// ignore, handled by removeSourceFile
}
//test
}
Formats as:
export class DocumentRegistry {
/** @inheritdoc */
releaseDocument() {
}
/** @inheritdoc */
releaseDocumentWithKey() {
}
}
For example:
dprint --config-package @ts-nameof/dprint-config
Avoids needing to have a dummy config file that re-exports the package.
Add back keywords "printer", "formatter", "typescript", "javascript"
to package.json.
Using jsx in a .js file will probably not work at the moment.
PrintItems::RcItems
There are certain cases where cloning is necessary in the IR generation:
Condition::new("debuggingName", ConditionProperties {
condition: Box::new(|context| true_or_false),
true_path: Some(with_indent(items.clone())),
false_path: Some(items),
});
It would be useful for performance reasons to instead write this as:
let items = Rc::new(items);
Condition::new("debuggingName", ConditionProperties {
condition: Box::new(|context| true_or_false),
true_path: Some(with_indent(items.into().clone())), // only an Rc clone, so should be fast
false_path: Some(items.into()),
});
PrintItems::Items
Instead of writing this:
items.extend(parse_node(...));
It might possibly be faster to write this:
items.push(parse_node(...).into());
// short for
items.push(PrintItem::Items(parse_node(...)));
This may make the printer run slower, but maybe it might make the parser run faster? I'm not sure how vectors are in rust and how they perform, but this would be good to test out.
There is currently a CliEnvironment
implementation of an Environment
that's actually a NodeEnvironment
. Right now the code only runs in Node...
It would be good to make an implementation of an Environment
that's a DenoEnvironment
, have a function that selects the appropriate environment, then support building for both Node and Deno.
Also, obviously with this change each package would need to be built into a file consumable by deno, but that should be trivial.
CI started failing today with the new 0,9.0 release of wasm-pack. I tried running a build that passed yesterday again and that failed.
Output:
[INFO]: Installing wasm-bindgen...
[INFO]: Installing wasm-opt...
[INFO]: Optimizing wasm binaries with `wasm-opt`...
Error: failed to execute `wasm-opt`: exited with signal: 11
full command: "/home/travis/.cache/.wasm-pack/wasm-opt-37dc6b0d9960f622/wasm-opt" "wasm/../src/wasm/dprint_rust_printer_bg.wasm" "-o" "wasm/../src/wasm/dprint_rust_printer_bg.wasm-opt.wasm" "-O"
To disable `wasm-opt`, add `wasm-opt = false` to your package metadata in your `Cargo.toml`.
Not going to deal with this for now because it's a time sink. Works fine on my machine.
For example:
// dprint-ignore
call(5, 6, 7,
8, 9, 10);
Also, change dprint:ignoreFile
to dprint-ignore-file
because it's more similar to eslint. The colon was originally done because it was similar to tslint, but doesn't make sense to copy tslint.
For example:
t.dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd;
Formats as:
t
.dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd;
On this file: https://github.com/denoland/deno/blob/2115b38fef654c2d7c5998f40967fcfe39d7c515/cli/js/compiler_imports.ts
> RUST_BACKTRACE=1 ./target/debug/deno fmt cli/js/compiler_imports.ts
thread 'main' panicked at 'Debug panic: Node comments retrieved out of order!', /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:336:13
stack backtrace:
0: backtrace::backtrace::libunwind::trace
at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
1: backtrace::backtrace::trace_unsynchronized
at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
2: std::sys_common::backtrace::_print_fmt
at src/libstd/sys_common/backtrace.rs:84
3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
at src/libstd/sys_common/backtrace.rs:61
4: core::fmt::write
at src/libcore/fmt/mod.rs:1025
5: std::io::Write::write_fmt
at src/libstd/io/mod.rs:1426
6: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:65
7: std::sys_common::backtrace::print
at src/libstd/sys_common/backtrace.rs:50
8: std::panicking::default_hook::{{closure}}
at src/libstd/panicking.rs:193
9: std::panicking::default_hook
at src/libstd/panicking.rs:210
10: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:471
11: parking_lot_core::word_lock::WordLock::unlock_slow
12: dprint_plugin_typescript::parser::parse_node_with_inner_parse::assert_parsed_in_order
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:336
13: dprint_plugin_typescript::parser::parse_node_with_inner_parse
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:48
14: dprint_plugin_typescript::parser::parse_comma_separated_value
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4418
15: dprint_plugin_typescript::parser::parse_separated_values::{{closure}}
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4386
16: dprint_plugin_typescript::helpers::parse_separated_values::parse_separated_values
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/helpers/parse_separated_values.rs:48
17: dprint_plugin_typescript::parser::parse_separated_values
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4379
18: dprint_plugin_typescript::parser::parse_parameters_or_arguments::{{closure}}
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4264
19: dprint_plugin_typescript::parser::parse_surrounded_by_tokens
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:5446
20: dprint_plugin_typescript::parser::parse_parameters_or_arguments
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4248
21: dprint_plugin_typescript::parser::parse_arrow_func_expr
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:1080
22: dprint_plugin_typescript::parser::parse_node_with_inner_parse::parse_node_inner
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:107
23: dprint_plugin_typescript::parser::parse_node_with_inner_parse
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:62
24: dprint_plugin_typescript::parser::parse_conditional_expr
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:1574
25: dprint_plugin_typescript::parser::parse_node_with_inner_parse::parse_node_inner
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:113
26: dprint_plugin_typescript::parser::parse_node_with_inner_parse
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:62
27: dprint_plugin_typescript::parser::parse_node
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:31
28: dprint_plugin_typescript::parser::parse_expr_or_spread
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:1630
29: dprint_plugin_typescript::parser::parse_node_with_inner_parse::parse_node_inner
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:114
30: dprint_plugin_typescript::parser::parse_node_with_inner_parse
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:62
31: dprint_plugin_typescript::parser::parse_comma_separated_value
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4418
32: dprint_plugin_typescript::parser::parse_separated_values::{{closure}}
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4386
33: dprint_plugin_typescript::helpers::parse_separated_values::parse_separated_values
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/helpers/parse_separated_values.rs:48
34: dprint_plugin_typescript::parser::parse_separated_values
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4379
35: dprint_plugin_typescript::parser::parse_parameters_or_arguments::{{closure}}
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4264
36: dprint_plugin_typescript::parser::parse_surrounded_by_tokens
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:5446
37: dprint_plugin_typescript::parser::parse_parameters_or_arguments
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4248
38: dprint_plugin_typescript::parser::parse_call_expr::inner_parse
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:1427
39: dprint_plugin_typescript::parser::parse_call_expr
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:1411
40: dprint_plugin_typescript::parser::parse_node_with_inner_parse::parse_node_inner
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:111
41: dprint_plugin_typescript::parser::parse_node_with_inner_parse
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:62
42: dprint_plugin_typescript::parser::parse_node
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:31
43: dprint_plugin_typescript::parser::parse_assignment
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:5346
44: dprint_plugin_typescript::parser::parse_var_declarator
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:3315
45: dprint_plugin_typescript::parser::parse_node_with_inner_parse::parse_node_inner
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:208
46: dprint_plugin_typescript::parser::parse_node_with_inner_parse
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:62
47: dprint_plugin_typescript::parser::parse_node
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:31
48: dprint_plugin_typescript::parser::parse_var_decl
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:3291
49: dprint_plugin_typescript::parser::parse_node_with_inner_parse::parse_node_inner
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:207
50: dprint_plugin_typescript::parser::parse_node_with_inner_parse
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:62
51: dprint_plugin_typescript::parser::parse_node
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:31
52: dprint_plugin_typescript::parser::parse_statements_or_members
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4192
53: dprint_plugin_typescript::parser::parse_statements
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4132
54: dprint_plugin_typescript::parser::parse_block_stmt::{{closure}}
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:2636
55: dprint_plugin_typescript::parser::parse_block::{{closure}}
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:5384
56: dprint_plugin_typescript::parser::parse_surrounded_by_tokens
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:5446
57: dprint_plugin_typescript::parser::parse_block
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:5375
58: dprint_plugin_typescript::parser::parse_block_stmt
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:2635
59: dprint_plugin_typescript::parser::parse_node_with_inner_parse::parse_node_inner
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:187
60: dprint_plugin_typescript::parser::parse_node_with_inner_parse
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:62
61: dprint_plugin_typescript::parser::parse_node
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:31
62: dprint_plugin_typescript::parser::parse_function_decl_or_expr
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:833
63: dprint_plugin_typescript::parser::parse_function_decl
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:772
64: dprint_plugin_typescript::parser::parse_node_with_inner_parse::parse_node_inner
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:95
65: dprint_plugin_typescript::parser::parse_node_with_inner_parse
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:62
66: dprint_plugin_typescript::parser::parse_node
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:31
67: dprint_plugin_typescript::parser::parse_export_decl
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:661
68: dprint_plugin_typescript::parser::parse_node_with_inner_parse::parse_node_inner
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:92
69: dprint_plugin_typescript::parser::parse_node_with_inner_parse
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:62
70: dprint_plugin_typescript::parser::parse_node
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:31
71: dprint_plugin_typescript::parser::parse_statements_or_members
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4192
72: dprint_plugin_typescript::parser::parse_statements
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:4132
73: dprint_plugin_typescript::parser::parse_module
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:2424
74: dprint_plugin_typescript::parser::parse_node_with_inner_parse::parse_node_inner
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:177
75: dprint_plugin_typescript::parser::parse_node_with_inner_parse
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:62
76: dprint_plugin_typescript::parser::parse_node
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:31
77: dprint_plugin_typescript::parser::parse
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/parser.rs:21
78: dprint_plugin_typescript::format_text::format_text::{{closure}}
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/format_text.rs:41
79: scoped_tls::ScopedKey<T>::set
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/scoped-tls-1.0.0/src/lib.rs:137
80: dprint_plugin_typescript::format_text::format_text
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.8.0/src/format_text.rs:35
81: deno::fmt::format_source_files::{{closure}}
at cli/fmt.rs:107
82: std::panicking::try::do_call
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/panicking.rs:292
83: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:78
84: std::panicking::try
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/panicking.rs:270
85: std::panic::catch_unwind
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/panic.rs:394
86: deno::fmt::format_source_files
at cli/fmt.rs:106
87: deno::fmt::format
at cli/fmt.rs:170
88: deno::main::{{closure}}
at cli/lib.rs:447
89: <std::future::GenFuture<T> as core::future::future::Future>::poll
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/future.rs:43
90: <core::pin::Pin<P> as core::future::future::Future>::poll
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/future/future.rs:119
91: tokio::runtime::basic_scheduler::BasicScheduler<P>::block_on
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/runtime/basic_scheduler.rs:138
92: tokio::runtime::Runtime::block_on::{{closure}}
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/runtime/mod.rs:413
93: tokio::runtime::context::enter
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/runtime/context.rs:72
94: tokio::runtime::handle::Handle::enter
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/runtime/handle.rs:34
95: tokio::runtime::Runtime::block_on
at /Users/rld/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.13/src/runtime/mod.rs:410
96: deno::tokio_util::run_basic
at cli/tokio_util.rs:18
97: deno::main
at cli/lib.rs:486
98: deno::main
at cli/main.rs:4
99: std::rt::lang_start::{{closure}}
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/rt.rs:67
100: std::rt::lang_start_internal::{{closure}}
at src/libstd/rt.rs:52
101: std::panicking::try::do_call
at src/libstd/panicking.rs:292
102: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:78
103: std::panicking::try
at src/libstd/panicking.rs:270
104: std::panic::catch_unwind
at src/libstd/panic.rs:394
105: std::rt::lang_start_internal
at src/libstd/rt.rs:51
106: std::rt::lang_start
at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/rt.rs:67
107: deno::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
dprint panic cli/js/compiler_imports.ts
Could save a trip to the file system by not running save on a file that hasn't changed.
Issue 1
function doTests(moveFile: (text: string, runChecks: (error?: any) => void) => void) {
}
Formats as:
function doTests(moveFile: (text: string, runChecks: (error?: any) => void)
=> void) {
}
Shouldn't this at least format as the following?
function doTests(moveFile: (text: string, runChecks: (error?: any) => void)
=> void)
{
}
Or should it be?
function doTests(moveFile: (text: string,
runChecks: (error?: any) => void) => void)
{
}
(It's definitely missing the indent if start of new line so that needs to be fixed regardless)
Issue 2
Edit: This is fine. Prettier formats this way.
this._languageService = opts.test ? new LanguageService(this, {
resolutionHost: opts.resolutionHost && opts.resolutionHost(this.getModuleResolutionHost(), () => this.compilerOptions.get())
}) : undefined;
Formats as:
this._languageService = opts.test
? new LanguageService(this, {
resolutionHost: opts.resolutionHost
&& opts.resolutionHost(this.getModuleResolutionHost(),
() => this.compilerOptions.get())
})
: undefined;
But it should probably be:
this._languageService = opts.test ? new LanguageService(this, {
resolutionHost: opts.resolutionHost
&& opts.resolutionHost(this.getModuleResolutionHost(),
() => this.compilerOptions.get())
}) : undefined;
See here:
Outputs:
Error: [dprint]: For some reason finishIndent was called without a corresponding startIndent.
Seems to have something to do with the member expression period being right on the line width index.
The graph is getting very complex for TypeScript. In the future, there needs to be a tool that quickly answers the following questions:
I'm thinking there are two tasks here:
This would be very cool and save me a lot of time. It would also be a good educational tool to explain how dprint works.
Checking out dprint
I hit a panic in Rust.
Panic:
RUST_BACKTRACE=1 ../../target/debug/deno fmt asdf
Checking "console_test.ts"
thread 'main' panicked at 'explicit panic', /Users/biwanczuk/.cargo/registry/src/github.com-1ecc6299db9ec823/swc_common-0.4.6/src/errors/diagnostic_builder.rs:333:13
stack backtrace:
0: backtrace::backtrace::libunwind::trace
at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
1: backtrace::backtrace::trace_unsynchronized
at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
2: std::sys_common::backtrace::_print_fmt
at src/libstd/sys_common/backtrace.rs:77
3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
at src/libstd/sys_common/backtrace.rs:61
4: core::fmt::write
at src/libcore/fmt/mod.rs:1028
5: std::io::Write::write_fmt
at src/libstd/io/mod.rs:1412
6: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:65
7: std::sys_common::backtrace::print
at src/libstd/sys_common/backtrace.rs:50
8: std::panicking::default_hook::{{closure}}
at src/libstd/panicking.rs:188
9: std::panicking::default_hook
at src/libstd/panicking.rs:205
10: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:464
11: parking_lot_core::word_lock::WordLock::unlock_slow
12: <swc_common::errors::diagnostic_builder::DiagnosticBuilder as core::ops::drop::Drop>::drop
at /Users/biwanczuk/.cargo/registry/src/github.com-1ecc6299db9ec823/swc_common-0.4.6/src/errors/diagnostic_builder.rs:333
13: core::ptr::real_drop_in_place
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libcore/ptr/mod.rs:175
14: dprint_plugin_typescript::parse_to_swc_ast::parse_to_swc_ast
at /Users/biwanczuk/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.2.1/src/parse_to_swc_ast.rs:51
15: dprint_plugin_typescript::format_text::format_text::{{closure}}
at /Users/biwanczuk/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.2.1/src/format_text.rs:29
16: scoped_tls::ScopedKey<T>::set
at /Users/biwanczuk/.cargo/registry/src/github.com-1ecc6299db9ec823/scoped-tls-1.0.0/src/lib.rs:137
17: dprint_plugin_typescript::format_text::format_text
at /Users/biwanczuk/.cargo/registry/src/github.com-1ecc6299db9ec823/dprint-plugin-typescript-0.2.1/src/format_text.rs:28
18: deno::formatter::check_source_files
at cli/formatter.rs:56
19: deno::formatter::format
at cli/formatter.rs:119
20: deno::format_command
at cli/lib.rs:422
21: deno::main
at cli/lib.rs:450
22: deno::main
at cli/main.rs:4
23: std::rt::lang_start::{{closure}}
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/rt.rs:61
24: std::rt::lang_start_internal::{{closure}}
at src/libstd/rt.rs:48
25: std::panicking::try::do_call
at src/libstd/panicking.rs:287
26: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:78
27: std::panicking::try
at src/libstd/panicking.rs:265
28: std::panic::catch_unwind
at src/libstd/panic.rs:396
29: std::rt::lang_start_internal
at src/libstd/rt.rs:47
30: std::rt::lang_start
at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libstd/rt.rs:61
31: deno::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
TypeScriptConfiguration
:
TypeScriptConfiguration::new()
.line_width(80)
.indent_width(2)
.resolve()
Link to file causing panic:
https://github.com/denoland/deno/blob/v0.31.0/cli/js/console_test.ts
Would be nice to have an includes
and excludes
property. The command globs would take priority.
dprint_plugin_typescript made the following edit
-export const BodyUsedError =
- "Failed to execute 'clone' on 'Body': body is already used";
+export const BodyUsedError = "Failed to execute 'clone' on 'Body': body is already used";
this was with this config:
.line_width(80)
.indent_width(2)
.next_control_flow_position(dprint::NextControlFlowPosition::SameLine)
.force_multi_line_parameters(true)
.force_multi_line_arguments(true)
.binary_expression_operator_position(dprint::OperatorPosition::SameLine)
Note that export const BodyUsedError = "Failed to execute 'clone' on 'Body': body is already used";
is 88 columns.
Thinking kind of late, but it might be useful to have the concept of a "condition trip". For example, if a newline ever occurs in a certain place then that immediately makes some condition true and the printer immediately goes back to that condition. This would help a lot with performance I think and probably simplify some code.
I may have to write my own jsonc parser for this, but luckily JSON is very simple.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.