Merge branch 'master' of github.com:prettier/prettier into next
* 'master' of github.com:prettier/prettier: (43 commits) Update `postcss-less` to v2 (#6778) Show invalid config filename in error message (#6865) Change external links to https (#6874) Bump @babel/parser from 7.7.0 to 7.7.2 (#6862) Fix nullish coalescing parenthesis with mixed logical operators (#6863) Remove handlebars@4.4.5 requirement in yarn.lock (#6867) Update browerslist in yarn.lock (#6868) fix formatting of comments in flow enums (#6860) better formatting for AwaitExpression in CallExpression/MemberExpression (#6856) Bump @typescript-eslint/typescript-estree from 2.6.0 to 2.6.1 (#6805) test: issue #6283 (#6855) audit(critical): handlebars@4.4.5 in package resolutions (#6853) Flow enums (#6833) Add mongo as a VS Code supported language (#6848) Bump `eslint` from 6.5.1 to 6.6.0 (#6846) Upgrade flow-parser from 0.89 to 0.111 (#6830) Bump @babel/preset-react from 7.6.3 to 7.7.0 in /website (#6827) Bump typescript from 3.7.1-rc to 3.7.2 (#6832) Bump rollup from 1.26.0 to 1.26.3 (#6821) update Babel to 7.7.0 and enable error recovery (#6816) ...
This commit is contained in:
commit
ae1d9afb88
102 files changed
+2354
-1377
No files matched your search
@@ -3,6 +3,8 @@ steps:
|
||||
- template: ../steps/install-dependencies.yml
|
||||
- script: yarn check-deps
|
||||
displayName: "Check dependencies"
|
||||
- script: yarn check-types
|
||||
displayName: "Check JSDoc types"
|
||||
- script: yarn lint
|
||||
displayName: "Lint code"
|
||||
- script: yarn lint-docs
|
||||
|
||||
+182
-27
@@ -123,25 +123,28 @@ class C extends B {
|
||||
}
|
||||
```
|
||||
|
||||
#### TypeScript: Prettier removed `?` from optional computed class fields ([#6657] by [@cryrivers])
|
||||
#### TypeScript: Fix optional computed class fields and methods ([#6657] by [@cryrivers], [#6673] by [@thorn0])
|
||||
|
||||
Still happens if the field key is a complex expression, but has been fixed in this case:
|
||||
Still broken if the key is a complex expression, but has been fixed in these cases:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```ts
|
||||
// Input
|
||||
class Foo {
|
||||
[bar]?: number;
|
||||
protected [s]?() {}
|
||||
}
|
||||
|
||||
// Output (Prettier stable)
|
||||
class Foo {
|
||||
[bar]: number;
|
||||
protected [s?]() {};
|
||||
}
|
||||
|
||||
// Output (Prettier master)
|
||||
class Foo {
|
||||
[bar]?: number;
|
||||
protected [s]?() {}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -480,20 +483,23 @@ Previously, Prettier would sometimes ignore whitespace when formatting comments.
|
||||
</div>
|
||||
```
|
||||
|
||||
#### JavaScript: Update `??` precedence to match stage 3 proposal ([#6404] by [@vjeux])
|
||||
#### JavaScript: Update `??` precedence to match stage 3 proposal ([#6404] by [@vjeux], [#6863] by [@jridgewell])
|
||||
|
||||
We've updated Prettier's support for the nullish coalescing operator to match a spec update that no longer allows it to immediately contain, or be contained within an `&&` or `||` operation.
|
||||
We've updated Prettier's support for the nullish coalescing operator to match a spec update that no longer allows it to immediately contain, or be contained within, an `&&` or `||` operation.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```js
|
||||
// Input
|
||||
(foo ?? baz) || baz;
|
||||
(foo ?? bar) || baz;
|
||||
(foo || bar) ?? baz;
|
||||
|
||||
// Output (Prettier stable)
|
||||
foo ?? baz || baz;
|
||||
foo ?? bar || baz;
|
||||
foo || bar ?? baz;
|
||||
|
||||
// Output (Prettier master)
|
||||
(foo ?? baz) || baz;
|
||||
(foo ?? bar) || baz;
|
||||
(foo || bar) ?? baz;
|
||||
```
|
||||
|
||||
Please note, as we update our parsers with versions that support this spec update, code without the parenthesis will throw a parse error.
|
||||
@@ -676,6 +682,26 @@ Previously, even if the line length was shorter than `printWidth`, Prettier woul
|
||||
</template>
|
||||
```
|
||||
|
||||
#### HTML: Add support for `!` and other entities ([#6785] by [@lydell])
|
||||
|
||||
Previously, Prettier only supported the most common HTML entities, such as ` ` and `"`. Now, Prettier supports every HTML entity in the HTML spec, such as `!` and `⋔`.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<!-- Input -->
|
||||
<p>Hi!</p>
|
||||
|
||||
<!-- Output (Prettier stable)
|
||||
[error] stdin: SyntaxError: Unknown entity "excl" - use the "&#<decimal>;" or "&#x<hex>;" syntax (1:6)
|
||||
[error] > 1 | <p>Hi!</p>
|
||||
[error] | ^
|
||||
[error] 2 |
|
||||
-->
|
||||
|
||||
<!-- Output (Prettier master) -->
|
||||
<p>Hi!</p>
|
||||
```
|
||||
|
||||
#### JavaScript: Empty lines in destructured arrow function parameters could break indentation and idempotence ([#6301] & [#6382] by [@sosukesuzuki])
|
||||
|
||||
Previously, Prettier indented code strangely when an arrow function whose parameters included an object pattern was passed to a function call as an argument. Also, it broke idempotence. Please see [#6294](https://github.com/prettier/prettier/issues/6294) for details.
|
||||
@@ -1097,26 +1123,6 @@ class A {
|
||||
}
|
||||
```
|
||||
|
||||
#### TypeScript: Fix optional computed methods ([#6673] by [@thorn0])
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```ts
|
||||
// Input
|
||||
class A {
|
||||
protected [s]?() {}
|
||||
}
|
||||
|
||||
// Output (Prettier stable)
|
||||
class A {
|
||||
protected [s?]() {}
|
||||
}
|
||||
|
||||
// Output (Prettier master)
|
||||
class A {
|
||||
protected [s]?() {}
|
||||
}
|
||||
```
|
||||
|
||||
#### Angular: Put a closing parenthesis onto a new line after ternaries passed to pipes ([#5682] by [@selvazhagan])
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
@@ -1294,6 +1300,140 @@ export class User {
|
||||
}
|
||||
```
|
||||
|
||||
#### Flow: Parentheses around arrow functions' return types that have `FunctionTypeAnnotation` nested in `ObjectTypeAnnotation` ([#6717] by [@sosukesuzuki])
|
||||
|
||||
This is a workaround for a [bug](https://github.com/facebook/flow/pull/8163) in the Flow parser. Without the parentheses, the parser throws an error.
|
||||
|
||||
```js
|
||||
// Input
|
||||
const example1 = (): { p: (string => string) } => (0: any);
|
||||
|
||||
// Output (Prettier stable)
|
||||
const example1 = (): { p: string => string } => (0: any);
|
||||
|
||||
// Output (Prettier master)
|
||||
const example1 = (): ({ p: string => string }) => (0: any);
|
||||
```
|
||||
|
||||
#### CLI: Handle errors when reading stdin ([#6708] by [@andersk] and [@lydell])
|
||||
|
||||
If you had an error in your `.prettierrc` Prettier used to crash when formatting stdin. Such errors are now handled properly.
|
||||
|
||||
```
|
||||
# Prettier stable
|
||||
$ prettier --parser babel < test.js
|
||||
(node:21531) UnhandledPromiseRejectionWarning: Error: Invalid printWidth value. Expected an integer, but received "nope".
|
||||
at _loop (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:7887:63)
|
||||
at Normalizer._applyNormalization (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:8000:13)
|
||||
at applyNormalization (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:7817:49)
|
||||
at Normalizer.normalize (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:7823:9)
|
||||
at normalizeOptions$1 (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:8760:31)
|
||||
at Object.normalizeApiOptions (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:8918:10)
|
||||
at getOptionsForFile (/home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:44160:69)
|
||||
at /home/lydell/forks/prettier/node_modules/prettier/bin-prettier.js:44214:22
|
||||
at process._tickCallback (internal/process/next_tick.js:68:7)
|
||||
(node:21531) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
|
||||
(node:21531) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
|
||||
|
||||
# Prettier master
|
||||
$ prettier --parser babel < test.js
|
||||
[error] Invalid printWidth value. Expected an integer, but received "nope".
|
||||
```
|
||||
|
||||
#### CLI: Gracefully handle nonexistent paths passed to --stdin-filepath ([#6687] by [@voithos])
|
||||
|
||||
Previously, if you passed a nonexistent subdirectory to --stdin-filepath, Prettier would throw an error. Now, Prettier gracefully handles this.
|
||||
|
||||
```
|
||||
# Prettier stable
|
||||
$ prettier --stdin-filepath does/not/exist.js < test.js
|
||||
[error] Invalid configuration file: ENOENT: no such file or directory, scandir '/home/lydell/forks/prettier/does/not'
|
||||
|
||||
# Prettier master
|
||||
$ prettier --stdin-filepath does/not/exist.js < test.js
|
||||
test;
|
||||
```
|
||||
|
||||
#### JavaScript: Numeric separators were removed from BigInt literals ([#6796] by [@thorn0])
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```js
|
||||
// Input
|
||||
const bigints = [200_000n, 0x0000_000An, 0b0111_1111n];
|
||||
|
||||
// Output (Prettier stable)
|
||||
const bigints = [200000n, 0x0000000an, 0b01111111n];
|
||||
|
||||
// Output (Prettier master)
|
||||
const bigints = [200_000n, 0x0000_000an, 0b0111_1111n];
|
||||
```
|
||||
|
||||
#### VS Code: add support for .mongo files ([#6848] by [@aymericbouzy])
|
||||
|
||||
When using the Azure Cosmos DB extension for VS Code, you can create .mongo files to write MongoDB queries, which use Javascript syntax. This change allows VS Code to format your file using Prettier.
|
||||
|
||||
```js
|
||||
db.users.find({ someField: { $exists: true } });
|
||||
```
|
||||
|
||||
#### JavaScript: Better formatting for inline `await` expression nested in calls ([#6856] by [@thorn0])
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```js
|
||||
// Input
|
||||
async function f() {
|
||||
const admins = (await(db.select('*').from('admins').leftJoin('bla').where('id', 'in', [1,2,3,4]))).map(({id, name})=>({id, name}))
|
||||
}
|
||||
|
||||
// Output (Prettier stable)
|
||||
async function f() {
|
||||
const admins = (await db
|
||||
.select("*")
|
||||
.from("admins")
|
||||
.leftJoin("bla")
|
||||
.where("id", "in", [1, 2, 3, 4])).map(({ id, name }) => ({ id, name }));
|
||||
}
|
||||
|
||||
// Output (Prettier master)
|
||||
async function f() {
|
||||
const admins = (
|
||||
await db
|
||||
.select("*")
|
||||
.from("admins")
|
||||
.leftJoin("bla")
|
||||
.where("id", "in", [1, 2, 3, 4])
|
||||
).map(({ id, name }) => ({ id, name }));
|
||||
}
|
||||
```
|
||||
|
||||
#### CLI: Display invalid config filename in error message ([#6865] by [@fisker])
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```bash
|
||||
# Input
|
||||
$ prettier filename.js --config .invalid-config
|
||||
|
||||
# Output (Prettier stable)
|
||||
Invalid configuration file: ...
|
||||
|
||||
# Output (Prettier master)
|
||||
Invalid configuration file `.invalid-config`: ...
|
||||
```
|
||||
|
||||
#### Less: don't lowercase variable names, remove whitespace between variable and colon ([#6778] by [@fisker])
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```less
|
||||
// Input
|
||||
@FoO : bar;
|
||||
|
||||
// Output (Prettier stable)
|
||||
@foo : bar;
|
||||
|
||||
// Output (Prettier master)
|
||||
@FoO: bar;
|
||||
```
|
||||
|
||||
[#5682]: https://github.com/prettier/prettier/pull/5682
|
||||
[#6657]: https://github.com/prettier/prettier/pull/6657
|
||||
[#5910]: https://github.com/prettier/prettier/pull/5910
|
||||
@@ -1306,6 +1446,7 @@ export class User {
|
||||
[#6236]: https://github.com/prettier/prettier/pull/6236
|
||||
[#6270]: https://github.com/prettier/prettier/pull/6270
|
||||
[#6284]: https://github.com/prettier/prettier/pull/6284
|
||||
[#6785]: https://github.com/prettier/prettier/pull/6785
|
||||
[#6289]: https://github.com/prettier/prettier/pull/6289
|
||||
[#6301]: https://github.com/prettier/prettier/pull/6301
|
||||
[#6307]: https://github.com/prettier/prettier/pull/6307
|
||||
@@ -1336,7 +1477,16 @@ export class User {
|
||||
[#6673]: https://github.com/prettier/prettier/pull/6673
|
||||
[#6695]: https://github.com/prettier/prettier/pull/6695
|
||||
[#6694]: https://github.com/prettier/prettier/pull/6694
|
||||
[#6717]: https://github.com/prettier/prettier/pull/6717
|
||||
[#6728]: https://github.com/prettier/prettier/pull/6728
|
||||
[#6708]: https://github.com/prettier/prettier/pull/6708
|
||||
[#6687]: https://github.com/prettier/prettier/pull/6687
|
||||
[#6796]: https://github.com/prettier/prettier/pull/6796
|
||||
[#6778]: https://github.com/prettier/prettier/pull/6778
|
||||
[#6848]: https://github.com/prettier/prettier/pull/6848
|
||||
[#6856]: https://github.com/prettier/prettier/pull/6856
|
||||
[#6865]: https://github.com/prettier/prettier/pull/6865
|
||||
[#6863]: https://github.com/prettier/prettier/pull/6863
|
||||
[@brainkim]: https://github.com/brainkim
|
||||
[@duailibe]: https://github.com/duailibe
|
||||
[@gavinjoyce]: https://github.com/gavinjoyce
|
||||
@@ -1355,3 +1505,8 @@ export class User {
|
||||
[@kaicataldo]: https://github.com/kaicataldo
|
||||
[@cryrivers]: https://github.com/Cryrivers
|
||||
[@voithos]: https://github.com/voithos
|
||||
[@andersk]: https://github.com/andersk
|
||||
[@lydell]: https://github.com/lydell
|
||||
[@aymericbouzy]: https://github.com/aymericbouzy
|
||||
[@fisker]: https://github.com/fisker
|
||||
[@jridgewell]: https://github.com/jridgewell
|
||||
+18
-18
@@ -9,69 +9,69 @@ variables:
|
||||
|
||||
jobs:
|
||||
- job: Dev_Lint
|
||||
displayName: Dev Lint on Linux Node v10
|
||||
displayName: Dev Lint on Linux Node v12
|
||||
pool:
|
||||
vmImage: "Ubuntu 16.04"
|
||||
variables:
|
||||
node_version: 10
|
||||
node_version: 12
|
||||
steps:
|
||||
- template: .azure-pipelines/jobs/dev-lint.yml
|
||||
|
||||
- job: Dev_Test_Windows
|
||||
displayName: Dev Test on Windows Node v10
|
||||
displayName: Dev Test on Windows Node v12
|
||||
pool:
|
||||
vmImage: vs2017-win2016
|
||||
variables:
|
||||
node_version: 10
|
||||
node_version: 12
|
||||
TEST_CRLF: true
|
||||
steps:
|
||||
- template: .azure-pipelines/jobs/dev-test.yml
|
||||
|
||||
- job: Dev_Test_macOS
|
||||
displayName: Dev Test on macOS Node v10
|
||||
displayName: Dev Test on macOS Node v12
|
||||
pool:
|
||||
vmImage: macos-10.13
|
||||
variables:
|
||||
node_version: 10
|
||||
node_version: 12
|
||||
ENABLE_CODE_COVERAGE: true
|
||||
steps:
|
||||
- template: .azure-pipelines/jobs/dev-test.yml
|
||||
|
||||
- job: Dev_Test_Linux
|
||||
displayName: Dev Test on Linux Node v10
|
||||
displayName: Dev Test on Linux Node v12
|
||||
pool:
|
||||
vmImage: "Ubuntu 16.04"
|
||||
variables:
|
||||
node_version: 10
|
||||
node_version: 12
|
||||
steps:
|
||||
- template: .azure-pipelines/jobs/dev-test.yml
|
||||
|
||||
- job: Prod_Build
|
||||
displayName: Prod Build on Linux Node v10
|
||||
displayName: Prod Build on Linux Node v12
|
||||
pool:
|
||||
vmImage: "Ubuntu 16.04"
|
||||
variables:
|
||||
node_version: 10
|
||||
node_version: 12
|
||||
steps:
|
||||
- template: .azure-pipelines/jobs/prod-build.yml
|
||||
|
||||
- job: Prod_Pack
|
||||
dependsOn: Prod_Build
|
||||
displayName: Prod Pack on Linux Node v10
|
||||
displayName: Prod Pack on Linux Node v12
|
||||
pool:
|
||||
vmImage: "Ubuntu 16.04"
|
||||
variables:
|
||||
node_version: 10
|
||||
node_version: 12
|
||||
steps:
|
||||
- template: .azure-pipelines/jobs/prod-pack.yml
|
||||
|
||||
- job: Prod_Lint
|
||||
dependsOn: Prod_Build
|
||||
displayName: Prod Lint on Linux Node v10
|
||||
displayName: Prod Lint on Linux Node v12
|
||||
pool:
|
||||
vmImage: "Ubuntu 16.04"
|
||||
variables:
|
||||
node_version: 10
|
||||
node_version: 12
|
||||
steps:
|
||||
- template: .azure-pipelines/jobs/prod-lint.yml
|
||||
|
||||
@@ -85,10 +85,10 @@ jobs:
|
||||
Node_v4:
|
||||
node_version: 4
|
||||
ENABLE_TEST_RESULTS: "" # jest-junit requires node v6+
|
||||
Node_v10:
|
||||
node_version: 10
|
||||
Node_v10_standalone:
|
||||
node_version: 10
|
||||
Node_v12:
|
||||
node_version: 12
|
||||
Node_v12_standalone:
|
||||
node_version: 12
|
||||
TEST_STANDALONE: true
|
||||
steps:
|
||||
- template: .azure-pipelines/jobs/prod-test.yml
|
||||
+4
-1
@@ -92,6 +92,7 @@
|
||||
"ekkhus",
|
||||
"elektronik",
|
||||
"Eneman",
|
||||
"ENOENT",
|
||||
"ericsakmar",
|
||||
"Ericsburgh",
|
||||
"Esben",
|
||||
@@ -303,6 +304,7 @@
|
||||
"ruleset",
|
||||
"Sapegin",
|
||||
"sbdchd",
|
||||
"scandir",
|
||||
"schemastore",
|
||||
"serializer",
|
||||
"setlocal",
|
||||
@@ -391,6 +393,7 @@
|
||||
"<!-- prettier-ignore -->\\n(`{3,})\\w*\\n[\\s\\S]+?\\1",
|
||||
"\\[@\\w+?\\]",
|
||||
"\\[`\\w+`\\]",
|
||||
"ve+r+y+(long\\w+)?"
|
||||
"ve{2,}r{2,}y",
|
||||
"ve+r+y+long\\w*"
|
||||
]
|
||||
}
|
||||
+1
-1
@@ -49,7 +49,7 @@ prettier.resolveConfig(filePath).then(options => {
|
||||
});
|
||||
```
|
||||
|
||||
If `options.editorconfig` is `true` and an [`.editorconfig` file](http://editorconfig.org/) is in your project, Prettier will parse it and convert its properties to the corresponding prettier configuration. This configuration will be overridden by `.prettierrc`, etc. Currently, the following EditorConfig properties are supported:
|
||||
If `options.editorconfig` is `true` and an [`.editorconfig` file](https://editorconfig.org/) is in your project, Prettier will parse it and convert its properties to the corresponding prettier configuration. This configuration will be overridden by `.prettierrc`, etc. Currently, the following EditorConfig properties are supported:
|
||||
|
||||
- `end_of_line`
|
||||
- `indent_style`
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ In practice, this may look something like:
|
||||
prettier --single-quote --trailing-comma es5 --write "{app,__{tests,mocks}__}/**/*.js"
|
||||
```
|
||||
|
||||
Don't forget the quotes around the globs! The quotes make sure that Prettier expands the globs rather than your shell, for cross-platform usage. The [glob syntax from the `fast-glob` module](https://github.com/mrmlnc/fast-glob/blob/master/README.md#pattern-syntax) is used.
|
||||
Don't forget the quotes around the globs! The quotes make sure that Prettier expands the globs rather than your shell, for cross-platform usage. The [glob syntax from the glob module](https://github.com/isaacs/node-glob/blob/master/README.md#glob-primer) is used.
|
||||
|
||||
Prettier CLI will ignore files located in `node_modules` directory. To opt-out from this behavior use `--with-node-modules` flag.
|
||||
|
||||
|
||||
+2
-2
@@ -7,10 +7,10 @@ title: Prettier vs. Linters
|
||||
|
||||
Linters have two categories of rules:
|
||||
|
||||
**Formatting rules**: eg: [max-len](http://eslint.org/docs/rules/max-len), [no-mixed-spaces-and-tabs](http://eslint.org/docs/rules/no-mixed-spaces-and-tabs), [keyword-spacing](http://eslint.org/docs/rules/keyword-spacing), [comma-style](http://eslint.org/docs/rules/comma-style)...
|
||||
**Formatting rules**: eg: [max-len](https://eslint.org/docs/rules/max-len), [no-mixed-spaces-and-tabs](https://eslint.org/docs/rules/no-mixed-spaces-and-tabs), [keyword-spacing](https://eslint.org/docs/rules/keyword-spacing), [comma-style](https://eslint.org/docs/rules/comma-style)...
|
||||
|
||||
Prettier alleviates the need for this whole category of rules! Prettier is going to reprint the entire program from scratch in a consistent way, so it's not possible for the programmer to make a mistake there anymore :)
|
||||
|
||||
**Code-quality rules**: eg [no-unused-vars](http://eslint.org/docs/rules/no-unused-vars), [no-extra-bind](http://eslint.org/docs/rules/no-extra-bind), [no-implicit-globals](http://eslint.org/docs/rules/no-implicit-globals), [prefer-promise-reject-errors](http://eslint.org/docs/rules/prefer-promise-reject-errors)...
|
||||
**Code-quality rules**: eg [no-unused-vars](https://eslint.org/docs/rules/no-unused-vars), [no-extra-bind](https://eslint.org/docs/rules/no-extra-bind), [no-implicit-globals](https://eslint.org/docs/rules/no-implicit-globals), [prefer-promise-reject-errors](https://eslint.org/docs/rules/prefer-promise-reject-errors)...
|
||||
|
||||
Prettier does nothing to help with those kind of rules. They are also the most important ones provided by linters as they are likely to catch real bugs with your code!
|
||||
@@ -63,7 +63,7 @@ singleQuote = true
|
||||
|
||||
Overrides let you have different configuration for certain file extensions, folders and specific files.
|
||||
|
||||
Prettier borrows ESLint’s [override format](http://eslint.org/docs/user-guide/configuring#example-configuration).
|
||||
Prettier borrows ESLint’s [override format](https://eslint.org/docs/user-guide/configuring#example-configuration).
|
||||
|
||||
JSON:
|
||||
|
||||
|
||||
+5
-5
@@ -11,14 +11,14 @@ Prettier is an opinionated code formatter with support for:
|
||||
- [Vue](https://vuejs.org/)
|
||||
- [Flow](https://flow.org/)
|
||||
- [TypeScript](https://www.typescriptlang.org/)
|
||||
- CSS, [Less](http://lesscss.org/), and [SCSS](http://sass-lang.com)
|
||||
- CSS, [Less](http://lesscss.org/), and [SCSS](https://sass-lang.com)
|
||||
- [HTML](https://en.wikipedia.org/wiki/HTML)
|
||||
- [JSON](http://json.org/)
|
||||
- [GraphQL](http://graphql.org/)
|
||||
- [Markdown](http://commonmark.org/), including [GFM](https://github.github.com/gfm/) and [MDX](https://mdxjs.com/)
|
||||
- [YAML](http://yaml.org/)
|
||||
- [GraphQL](https://graphql.org/)
|
||||
- [Markdown](https://commonmark.org/), including [GFM](https://github.github.com/gfm/) and [MDX](https://mdxjs.com/)
|
||||
- [YAML](https://yaml.org/)
|
||||
|
||||
It removes all original styling[\*](#footnotes) and ensures that all outputted code conforms to a consistent style. (See this [blog post](http://jlongster.com/A-Prettier-Formatter))
|
||||
It removes all original styling[\*](#footnotes) and ensures that all outputted code conforms to a consistent style. (See this [blog post](https://jlongster.com/A-Prettier-Formatter))
|
||||
|
||||
Prettier takes your code and reprints it from scratch by taking the line length into account.
|
||||
|
||||
|
||||
+24
-21
@@ -228,28 +228,31 @@ defaultOptions: {
|
||||
|
||||
A `util` module from Prettier core is considered a private API and is not meant to be consumed by plugins. Instead, the `util-shared` module provides the following limited set of utility functions for plugins:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```ts
|
||||
getMaxContinuousCount(str: string, target: string): number;
|
||||
getStringWidth(text: string): number;
|
||||
getAlignmentSize(value: string, tabWidth: number, startIndex: number): number;
|
||||
getIndentSize(value: string, tabWidth: number): number;
|
||||
skip(chars: string|RegExp): number;
|
||||
skipWhitespace(text: string, index: number, options: object): number;
|
||||
skipSpaces(text: string, index: number, options: object): number;
|
||||
skipToLineEnd(text: string, index: number, options: object): number;
|
||||
skipEverythingButNewLine(text: string, index: number, options: object): number;
|
||||
skipInlineComment(text: string, index: number): number;
|
||||
skipTrailingComment(text: string, index: number): number;
|
||||
skipNewline(text: string, index: number, options: object): number;
|
||||
hasNewline(text: string, index: number, options: object): boolean;
|
||||
hasNewlineInRange(text: string, start: number, start: number): boolean;
|
||||
hasSpaces(text: string, index: number, options: object): number;
|
||||
makeString(rawContent: string, enclosingQuote: string, unescapeUnnecessaryEscapes: boolean): string;
|
||||
getNextNonSpaceNonCommentCharacterIndex(text: string, node: object, options: object): number;
|
||||
isNextLineEmptyAfterIndex(text: string, index: number): boolean;
|
||||
isNextLineEmpty(text: string, node: object, options: object): boolean;
|
||||
isPreviousLineEmpty(text: string, node: object, options: object): boolean;
|
||||
mapDoc(doc: object, callback: function): void;
|
||||
type Quote = '"' | "'";
|
||||
type SkipOptions = { backwards?: boolean };
|
||||
function getMaxContinuousCount(str: string, target: string): number;
|
||||
function getStringWidth(text: string): number;
|
||||
function getAlignmentSize(value: string, tabWidth: number, startIndex?: number): number;
|
||||
function getIndentSize(value: string, tabWidth: number): number;
|
||||
function skip(chars: string | RegExp): (text: string, index: number | false, opts?: SkipOptions) => number | false;
|
||||
function skipWhitespace(text: string, index: number | false, opts?: SkipOptions): number | false;
|
||||
function skipSpaces(text: string, index: number | false, opts?: SkipOptions): number | false;
|
||||
function skipToLineEnd(text: string, index: number | false, opts?: SkipOptions): number | false;
|
||||
function skipEverythingButNewLine(text: string, index: number | false, opts?: SkipOptions): number | false;
|
||||
function skipInlineComment(text: string, index: number | false): number | false;
|
||||
function skipTrailingComment(text: string, index: number | false): number | false;
|
||||
function skipNewline(text: string, index: number | false, opts?: SkipOptions): number | false;
|
||||
function hasNewline(text: string, index: number, opts?: SkipOptions): boolean;
|
||||
function hasNewlineInRange(text: string, start: number, end: number): boolean;
|
||||
function hasSpaces(text: string, index: number, opts?: SkipOptions): boolean;
|
||||
function makeString(rawContent: string, enclosingQuote: Quote, unescapeUnnecessaryEscapes?: boolean): string;
|
||||
function getNextNonSpaceNonCommentCharacterIndex<N>(text: string, node: N, locEnd: (node: N) => number): number | false;
|
||||
function isNextLineEmptyAfterIndex(text: string, index: number): boolean;
|
||||
function isNextLineEmpty<N>(text: string, node: N, locEnd: (node: N) => number): boolean;
|
||||
function isPreviousLineEmpty<N>(text: string, node: N, locStart: (node: N) => number): boolean;
|
||||
function mapDoc(doc: object, callback: function): void;
|
||||
```
|
||||
|
||||
### Tutorials
|
||||
|
||||
@@ -3,7 +3,7 @@ id: technical-details
|
||||
title: Technical Details
|
||||
---
|
||||
|
||||
This printer is a fork of [recast](https://github.com/benjamn/recast)'s printer with its algorithm replaced by the one described by Wadler in "[A prettier printer](http://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf)". There still may be leftover code from recast that needs to be cleaned up.
|
||||
This printer is a fork of [recast](https://github.com/benjamn/recast)'s printer with its algorithm replaced by the one described by Wadler in "[A prettier printer](https://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf)". There still may be leftover code from recast that needs to be cleaned up.
|
||||
|
||||
The basic idea is that the printer takes an AST and returns an intermediate representation of the output, and the printer uses that to generate a string. The advantage is that the printer can "measure" the IR and see if the output is going to fit on a line, and break if not.
|
||||
|
||||
|
||||
+17
-15
@@ -14,14 +14,14 @@
|
||||
"node": ">=8"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/compiler": "8.2.7",
|
||||
"@angular/compiler": "8.2.13",
|
||||
"@babel/code-frame": "7.5.5",
|
||||
"@babel/parser": "7.6.4",
|
||||
"@babel/parser": "7.7.2",
|
||||
"@glimmer/syntax": "0.41.0",
|
||||
"@iarna/toml": "2.2.3",
|
||||
"@typescript-eslint/typescript-estree": "2.6.0",
|
||||
"@typescript-eslint/typescript-estree": "2.6.1",
|
||||
"angular-estree-parser": "1.1.5",
|
||||
"angular-html-parser": "1.2.0",
|
||||
"angular-html-parser": "1.3.0",
|
||||
"camelcase": "5.3.1",
|
||||
"chalk": "2.4.2",
|
||||
"cjk-regex": "2.0.0",
|
||||
@@ -35,7 +35,7 @@
|
||||
"esutils": "2.0.3",
|
||||
"find-parent-dir": "0.3.0",
|
||||
"find-project-root": "1.1.1",
|
||||
"flow-parser": "0.89.0",
|
||||
"flow-parser": "0.111.1",
|
||||
"get-stream": "5.1.0",
|
||||
"globby": "6.1.0",
|
||||
"graphql": "14.5.8",
|
||||
@@ -56,7 +56,7 @@
|
||||
"n-readlines": "1.0.0",
|
||||
"normalize-path": "3.0.0",
|
||||
"parse-srcset": "ikatyang/parse-srcset#54eb9c1cb21db5c62b4d0e275d7249516df6f0ee",
|
||||
"postcss-less": "1.1.5",
|
||||
"postcss-less": "2.0.0",
|
||||
"postcss-media-query-parser": "0.2.3",
|
||||
"postcss-scss": "2.0.0",
|
||||
"postcss-selector-parser": "2.2.3",
|
||||
@@ -66,16 +66,16 @@
|
||||
"remark-parse": "5.0.0",
|
||||
"resolve": "1.12.0",
|
||||
"semver": "6.3.0",
|
||||
"string-width": "3.1.0",
|
||||
"typescript": "3.7.1-rc",
|
||||
"string-width": "4.1.0",
|
||||
"typescript": "3.7.2",
|
||||
"unicode-regex": "3.0.0",
|
||||
"unified": "8.4.1",
|
||||
"vnopts": "1.0.2",
|
||||
"yaml-unist-parser": "1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.6.3",
|
||||
"@babel/preset-env": "7.6.3",
|
||||
"@babel/core": "7.7.0",
|
||||
"@babel/preset-env": "7.7.1",
|
||||
"@rollup/plugin-alias": "2.2.0",
|
||||
"@rollup/plugin-replace": "2.2.0",
|
||||
"babel-loader": "8.0.6",
|
||||
@@ -83,12 +83,12 @@
|
||||
"builtin-modules": "3.1.0",
|
||||
"codecov": "codecov/codecov-node#e427d900309adb50746a39a50aa7d80071a5ddd0",
|
||||
"cross-env": "6.0.3",
|
||||
"eslint": "6.5.1",
|
||||
"eslint": "6.6.0",
|
||||
"eslint-config-prettier": "6.5.0",
|
||||
"eslint-formatter-friendly": "7.0.0",
|
||||
"eslint-plugin-import": "2.18.2",
|
||||
"eslint-plugin-prettier": "3.1.1",
|
||||
"eslint-plugin-react": "7.14.3",
|
||||
"eslint-plugin-react": "7.16.0",
|
||||
"execa": "3.2.0",
|
||||
"jest": "23.3.0",
|
||||
"jest-junit": "9.0.0",
|
||||
@@ -99,7 +99,7 @@
|
||||
"prettier": "1.18.2",
|
||||
"prettylint": "1.0.0",
|
||||
"rimraf": "3.0.0",
|
||||
"rollup": "1.26.0",
|
||||
"rollup": "1.26.3",
|
||||
"rollup-plugin-babel": "4.3.3",
|
||||
"rollup-plugin-commonjs": "10.1.0",
|
||||
"rollup-plugin-json": "4.0.0",
|
||||
@@ -109,8 +109,9 @@
|
||||
"shelljs": "0.8.3",
|
||||
"snapshot-diff": "0.4.0",
|
||||
"strip-ansi": "5.2.0",
|
||||
"synchronous-promise": "2.0.10",
|
||||
"tempy": "0.2.1",
|
||||
"terser-webpack-plugin": "2.1.3",
|
||||
"terser-webpack-plugin": "2.2.1",
|
||||
"webpack": "4.41.2"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -122,12 +123,13 @@
|
||||
"perf-repeat": "yarn && yarn build && cross-env NODE_ENV=production node ./dist/bin-prettier.js --debug-repeat ${PERF_REPEAT:-1000} --loglevel debug ${PERF_FILE:-./index.js} > /dev/null",
|
||||
"perf-repeat-inspect": "yarn && yarn build && cross-env NODE_ENV=production node --inspect-brk ./dist/bin-prettier.js --debug-repeat ${PERF_REPEAT:-1000} --loglevel debug ${PERF_FILE:-./index.js} > /dev/null",
|
||||
"perf-benchmark": "yarn && yarn build && cross-env NODE_ENV=production node ./dist/bin-prettier.js --debug-benchmark --loglevel debug ${PERF_FILE:-./index.js} > /dev/null",
|
||||
"check-types": "tsc",
|
||||
"lint": "cross-env EFF_NO_LINK_RULES=true eslint . --format friendly",
|
||||
"lint-docs": "prettylint {.,docs,website,website/blog}/*.md",
|
||||
"lint-dist": "eslint --no-eslintrc --no-ignore --env=browser \"dist/!(bin-prettier|index|third-party).js\"",
|
||||
"build": "node --max-old-space-size=3072 ./scripts/build/build.js",
|
||||
"build-docs": "node ./scripts/build-docs.js",
|
||||
"check-deps": "node ./scripts/check-deps.js",
|
||||
"spellcheck": "npx cspell -p cspell@4.0.31 {bin,scripts,src}/**/*.js {docs,website/blog}/**/*.md CHANGELOG.unreleased.md"
|
||||
"spellcheck": "npx -p cspell@4.0.31 cspell {bin,scripts,src}/**/*.js {docs,website/blog}/**/*.md CHANGELOG.unreleased.md"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export function extname(path) {
|
||||
const dotIndex = path.lastIndexOf(".");
|
||||
if (dotIndex === -1) return "";
|
||||
return path.slice(dotIndex);
|
||||
}
|
||||
+20
-20
@@ -72,23 +72,21 @@ function handleError(context, filename, error) {
|
||||
}
|
||||
|
||||
const isParseError = Boolean(error && error.loc);
|
||||
const isValidationError = /Validation Error/.test(error && error.message);
|
||||
const isValidationError = /^Invalid \S+ value\./.test(error && error.message);
|
||||
|
||||
// For parse errors and validation errors, we only want to show the error
|
||||
// message formatted in a nice way. `String(error)` takes care of that. Other
|
||||
// (unexpected) errors are passed as-is as a separate argument to
|
||||
// `console.error`. That includes the stack trace (if any), and shows a nice
|
||||
// `util.inspect` of throws things that aren't `Error` objects. (The Flow
|
||||
// parser has mistakenly thrown arrays sometimes.)
|
||||
if (isParseError) {
|
||||
// `invalid.js: SyntaxError: Unexpected token (1:1)`.
|
||||
context.logger.error(`${filename}: ${String(error)}`);
|
||||
} else if (isValidationError || error instanceof errors.ConfigError) {
|
||||
context.logger.error(String(error));
|
||||
// `Invalid printWidth value. Expected an integer, but received 0.5.`
|
||||
context.logger.error(error.message);
|
||||
// If validation fails for one file, it will fail for all of them.
|
||||
process.exit(1);
|
||||
} else if (error instanceof errors.DebugError) {
|
||||
// `invalid.js: Some debug error message`
|
||||
context.logger.error(`${filename}: ${error.message}`);
|
||||
} else {
|
||||
// `invalid.js: Error: Some unexpected error\n[stack trace]`
|
||||
context.logger.error(filename + ": " + (error.stack || error));
|
||||
}
|
||||
|
||||
@@ -286,7 +284,9 @@ function getOptionsOrDie(context, filePath) {
|
||||
context.logger.debug("loaded options `" + JSON.stringify(options) + "`");
|
||||
return options;
|
||||
} catch (error) {
|
||||
context.logger.error("Invalid configuration file: " + error.message);
|
||||
context.logger.error(
|
||||
`Invalid configuration file \`${filePath}\`: ` + error.message
|
||||
);
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
@@ -368,24 +368,25 @@ function formatStdin(context) {
|
||||
const ignorer = createIgnorerFromContextOrDie(context);
|
||||
const relativeFilepath = path.relative(process.cwd(), filepath);
|
||||
|
||||
thirdParty.getStream(process.stdin).then(input => {
|
||||
if (relativeFilepath && ignorer.filter([relativeFilepath]).length === 0) {
|
||||
writeOutput(context, { formatted: input });
|
||||
return;
|
||||
}
|
||||
thirdParty
|
||||
.getStream(process.stdin)
|
||||
.then(input => {
|
||||
if (relativeFilepath && ignorer.filter([relativeFilepath]).length === 0) {
|
||||
writeOutput(context, { formatted: input });
|
||||
return;
|
||||
}
|
||||
|
||||
const options = getOptionsForFile(context, filepath);
|
||||
const options = getOptionsForFile(context, filepath);
|
||||
|
||||
try {
|
||||
if (listDifferent(context, input, options, "(stdin)")) {
|
||||
return;
|
||||
}
|
||||
|
||||
writeOutput(context, format(context, input, options), options);
|
||||
} catch (error) {
|
||||
})
|
||||
.catch(error => {
|
||||
handleError(context, relativeFilepath || "stdin", error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function createIgnorerFromContextOrDie(context) {
|
||||
@@ -458,7 +459,6 @@ function formatFiles(context) {
|
||||
});
|
||||
|
||||
if (isTTY()) {
|
||||
// Don't use `console.log` here since we need to replace this line.
|
||||
context.logger.log(filename, { newline: false });
|
||||
}
|
||||
|
||||
|
||||
+153
-8
@@ -38,6 +38,14 @@ function getPenultimate(arr) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {{backwards?: boolean}} SkipOptions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string | RegExp} chars
|
||||
* @returns {(text: string, index: number | false, opts?: SkipOptions) => number | false}
|
||||
*/
|
||||
function skip(chars) {
|
||||
return (text, index, opts) => {
|
||||
const backwards = opts && opts.backwards;
|
||||
@@ -74,11 +82,28 @@ function skip(chars) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {(text: string, index: number | false, opts?: SkipOptions) => number | false}
|
||||
*/
|
||||
const skipWhitespace = skip(/\s/);
|
||||
/**
|
||||
* @type {(text: string, index: number | false, opts?: SkipOptions) => number | false}
|
||||
*/
|
||||
const skipSpaces = skip(" \t");
|
||||
/**
|
||||
* @type {(text: string, index: number | false, opts?: SkipOptions) => number | false}
|
||||
*/
|
||||
const skipToLineEnd = skip(",; \t");
|
||||
/**
|
||||
* @type {(text: string, index: number | false, opts?: SkipOptions) => number | false}
|
||||
*/
|
||||
const skipEverythingButNewLine = skip(/[^\r\n]/);
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {number | false} index
|
||||
* @returns {number | false}
|
||||
*/
|
||||
function skipInlineComment(text, index) {
|
||||
if (index === false) {
|
||||
return false;
|
||||
@@ -94,6 +119,11 @@ function skipInlineComment(text, index) {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {number | false} index
|
||||
* @returns {number | false}
|
||||
*/
|
||||
function skipTrailingComment(text, index) {
|
||||
if (index === false) {
|
||||
return false;
|
||||
@@ -108,6 +138,12 @@ function skipTrailingComment(text, index) {
|
||||
// This one doesn't use the above helper function because it wants to
|
||||
// test \r\n in order and `skip` doesn't support ordering and we only
|
||||
// want to skip one newline. It's simple to implement.
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {number | false} index
|
||||
* @param {SkipOptions=} opts
|
||||
* @returns {number | false}
|
||||
*/
|
||||
function skipNewline(text, index, opts) {
|
||||
const backwards = opts && opts.backwards;
|
||||
if (index === false) {
|
||||
@@ -144,6 +180,12 @@ function skipNewline(text, index, opts) {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {number} index
|
||||
* @param {SkipOptions=} opts
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasNewline(text, index, opts) {
|
||||
opts = opts || {};
|
||||
const idx = skipSpaces(text, opts.backwards ? index - 1 : index, opts);
|
||||
@@ -151,6 +193,12 @@ function hasNewline(text, index, opts) {
|
||||
return idx !== idx2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {number} start
|
||||
* @param {number} end
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasNewlineInRange(text, start, end) {
|
||||
for (let i = start; i < end; ++i) {
|
||||
if (text.charAt(i) === "\n") {
|
||||
@@ -161,7 +209,14 @@ function hasNewlineInRange(text, start, end) {
|
||||
}
|
||||
|
||||
// Note: this function doesn't ignore leading comments unlike isNextLineEmpty
|
||||
/**
|
||||
* @template N
|
||||
* @param {string} text
|
||||
* @param {N} node
|
||||
* @param {(node: N) => number} locStart
|
||||
*/
|
||||
function isPreviousLineEmpty(text, node, locStart) {
|
||||
/** @type {number | false} */
|
||||
let idx = locStart(node) - 1;
|
||||
idx = skipSpaces(text, idx, { backwards: true });
|
||||
idx = skipNewline(text, idx, { backwards: true });
|
||||
@@ -170,8 +225,15 @@ function isPreviousLineEmpty(text, node, locStart) {
|
||||
return idx !== idx2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {number} index
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isNextLineEmptyAfterIndex(text, index) {
|
||||
/** @type {number | false} */
|
||||
let oldIdx = null;
|
||||
/** @type {number | false} */
|
||||
let idx = index;
|
||||
while (idx !== oldIdx) {
|
||||
// We need to skip all the potential trailing inline comments
|
||||
@@ -182,25 +244,47 @@ function isNextLineEmptyAfterIndex(text, index) {
|
||||
}
|
||||
idx = skipTrailingComment(text, idx);
|
||||
idx = skipNewline(text, idx);
|
||||
return hasNewline(text, idx);
|
||||
return idx !== false && hasNewline(text, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @template N
|
||||
* @param {string} text
|
||||
* @param {N} node
|
||||
* @param {(node: N) => number} locEnd
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isNextLineEmpty(text, node, locEnd) {
|
||||
return isNextLineEmptyAfterIndex(text, locEnd(node));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {number} idx
|
||||
* @returns {number | false}
|
||||
*/
|
||||
function getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, idx) {
|
||||
/** @type {number | false} */
|
||||
let oldIdx = null;
|
||||
while (idx !== oldIdx) {
|
||||
oldIdx = idx;
|
||||
idx = skipSpaces(text, idx);
|
||||
idx = skipInlineComment(text, idx);
|
||||
idx = skipTrailingComment(text, idx);
|
||||
idx = skipNewline(text, idx);
|
||||
/** @type {number | false} */
|
||||
let nextIdx = idx;
|
||||
while (nextIdx !== oldIdx) {
|
||||
oldIdx = nextIdx;
|
||||
nextIdx = skipSpaces(text, nextIdx);
|
||||
nextIdx = skipInlineComment(text, nextIdx);
|
||||
nextIdx = skipTrailingComment(text, nextIdx);
|
||||
nextIdx = skipNewline(text, nextIdx);
|
||||
}
|
||||
return idx;
|
||||
return nextIdx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template N
|
||||
* @param {string} text
|
||||
* @param {N} node
|
||||
* @param {(node: N) => number} locEnd
|
||||
* @returns {number | false}
|
||||
*/
|
||||
function getNextNonSpaceNonCommentCharacterIndex(text, node, locEnd) {
|
||||
return getNextNonSpaceNonCommentCharacterIndexWithStartIndex(
|
||||
text,
|
||||
@@ -208,18 +292,36 @@ function getNextNonSpaceNonCommentCharacterIndex(text, node, locEnd) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @template N
|
||||
* @param {string} text
|
||||
* @param {N} node
|
||||
* @param {(node: N) => number} locEnd
|
||||
* @returns {string}
|
||||
*/
|
||||
function getNextNonSpaceNonCommentCharacter(text, node, locEnd) {
|
||||
return text.charAt(
|
||||
// @ts-ignore => TBD: can return false, should we define a fallback?
|
||||
getNextNonSpaceNonCommentCharacterIndex(text, node, locEnd)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {number} index
|
||||
* @param {SkipOptions=} opts
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasSpaces(text, index, opts) {
|
||||
opts = opts || {};
|
||||
const idx = skipSpaces(text, opts.backwards ? index - 1 : index, opts);
|
||||
return idx !== index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{range?: [number, number], start?: number}} node
|
||||
* @param {number} index
|
||||
*/
|
||||
function setLocStart(node, index) {
|
||||
if (node.range) {
|
||||
node.range[0] = index;
|
||||
@@ -228,6 +330,10 @@ function setLocStart(node, index) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{range?: [number, number], end?: number}} node
|
||||
* @param {number} index
|
||||
*/
|
||||
function setLocEnd(node, index) {
|
||||
if (node.range) {
|
||||
node.range[1] = index;
|
||||
@@ -400,6 +506,12 @@ function getLeftMost(node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @param {number} tabWidth
|
||||
* @param {number=} startIndex
|
||||
* @returns {number}
|
||||
*/
|
||||
function getAlignmentSize(value, tabWidth, startIndex) {
|
||||
startIndex = startIndex || 0;
|
||||
|
||||
@@ -419,6 +531,11 @@ function getAlignmentSize(value, tabWidth, startIndex) {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @param {number} tabWidth
|
||||
* @returns {number}
|
||||
*/
|
||||
function getIndentSize(value, tabWidth) {
|
||||
const lastNewlineIndex = value.lastIndexOf("\n");
|
||||
if (lastNewlineIndex === -1) {
|
||||
@@ -432,12 +549,24 @@ function getIndentSize(value, tabWidth) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {'"' | "'"} Quote
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} raw
|
||||
* @param {Quote} preferredQuote
|
||||
* @returns {Quote}
|
||||
*/
|
||||
function getPreferredQuote(raw, preferredQuote) {
|
||||
// `rawContent` is the string exactly like it appeared in the input source
|
||||
// code, without its enclosing quotes.
|
||||
const rawContent = raw.slice(1, -1);
|
||||
|
||||
/** @type {{ quote: '"', regex: RegExp }} */
|
||||
const double = { quote: '"', regex: /"/g };
|
||||
/** @type {{ quote: "'", regex: RegExp }} */
|
||||
const single = { quote: "'", regex: /'/g };
|
||||
|
||||
const preferred = preferredQuote === "'" ? single : double;
|
||||
@@ -474,6 +603,7 @@ function printString(raw, options, isDirectiveLiteral) {
|
||||
const canChangeDirectiveQuotes =
|
||||
!rawContent.includes('"') && !rawContent.includes("'");
|
||||
|
||||
/** @type {Quote} */
|
||||
const enclosingQuote =
|
||||
options.parser === "json"
|
||||
? '"'
|
||||
@@ -508,6 +638,12 @@ function printString(raw, options, isDirectiveLiteral) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} rawContent
|
||||
* @param {Quote} enclosingQuote
|
||||
* @param {boolean=} unescapeUnnecessaryEscapes
|
||||
* @returns {string}
|
||||
*/
|
||||
function makeString(rawContent, enclosingQuote, unescapeUnnecessaryEscapes) {
|
||||
const otherQuote = enclosingQuote === '"' ? "'" : '"';
|
||||
|
||||
@@ -563,6 +699,11 @@ function printNumber(rawNumber) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @param {string} target
|
||||
* @returns {number}
|
||||
*/
|
||||
function getMaxContinuousCount(str, target) {
|
||||
const results = str.match(
|
||||
new RegExp(`(${escapeStringRegexp(target)})+`, "g")
|
||||
@@ -607,6 +748,10 @@ function getMinNotPresentContinuousCount(str, target) {
|
||||
return max + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @returns {number}
|
||||
*/
|
||||
function getStringWidth(text) {
|
||||
if (!text) {
|
||||
return 0;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const editorconfig = require("editorconfig");
|
||||
@@ -8,7 +9,16 @@ const editorConfigToPrettier = require("editorconfig-to-prettier");
|
||||
const findProjectRoot = require("find-project-root");
|
||||
|
||||
const maybeParse = (filePath, config, parse) => {
|
||||
const root = findProjectRoot(path.dirname(path.resolve(filePath)));
|
||||
// findProjectRoot will throw an error if we pass a nonexistent directory to
|
||||
// it, which is possible, for example, when the path is given via
|
||||
// --stdin-filepath. So, first, traverse up until we find an existing
|
||||
// directory.
|
||||
let dirPath = path.dirname(path.resolve(filePath));
|
||||
const fsRoot = path.parse(dirPath).root;
|
||||
while (dirPath !== fsRoot && !fs.existsSync(dirPath)) {
|
||||
dirPath = path.dirname(dirPath);
|
||||
}
|
||||
const root = findProjectRoot(dirPath);
|
||||
return filePath && parse(filePath, { root });
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* TBD properly tagged union for Doc object type is needed here.
|
||||
*
|
||||
* @typedef {object} DocObject
|
||||
* @property {string} type
|
||||
* @property {boolean} [hard]
|
||||
* @property {boolean} [literal]
|
||||
*
|
||||
* @typedef {string | DocObject} Doc
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Doc} val
|
||||
*/
|
||||
function assertDoc(val) {
|
||||
/* istanbul ignore if */
|
||||
if (
|
||||
@@ -11,6 +25,10 @@ function assertDoc(val) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Doc[]} parts
|
||||
* @returns Doc
|
||||
*/
|
||||
function concat(parts) {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
parts.forEach(assertDoc);
|
||||
@@ -25,6 +43,10 @@ function concat(parts) {
|
||||
return { type: "concat", parts };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Doc} contents
|
||||
* @returns Doc
|
||||
*/
|
||||
function indent(contents) {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
assertDoc(contents);
|
||||
@@ -33,6 +55,11 @@ function indent(contents) {
|
||||
return { type: "indent", contents };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} n
|
||||
* @param {Doc} contents
|
||||
* @returns Doc
|
||||
*/
|
||||
function align(n, contents) {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
assertDoc(contents);
|
||||
@@ -41,6 +68,11 @@ function align(n, contents) {
|
||||
return { type: "align", contents, n };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Doc} contents
|
||||
* @param {object} [opts] - TBD ???
|
||||
* @returns Doc
|
||||
*/
|
||||
function group(contents, opts) {
|
||||
opts = opts || {};
|
||||
|
||||
@@ -57,18 +89,36 @@ function group(contents, opts) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Doc} contents
|
||||
* @returns Doc
|
||||
*/
|
||||
function dedentToRoot(contents) {
|
||||
return align(-Infinity, contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Doc} contents
|
||||
* @returns Doc
|
||||
*/
|
||||
function markAsRoot(contents) {
|
||||
// @ts-ignore - TBD ???:
|
||||
return align({ type: "root" }, contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Doc} contents
|
||||
* @returns Doc
|
||||
*/
|
||||
function dedent(contents) {
|
||||
return align(-1, contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Doc[]} states
|
||||
* @param {object} [opts] - TBD ???
|
||||
* @returns Doc
|
||||
*/
|
||||
function conditionalGroup(states, opts) {
|
||||
return group(
|
||||
states[0],
|
||||
@@ -76,6 +126,10 @@ function conditionalGroup(states, opts) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Doc[]} parts
|
||||
* @returns Doc
|
||||
*/
|
||||
function fill(parts) {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
parts.forEach(assertDoc);
|
||||
@@ -84,6 +138,12 @@ function fill(parts) {
|
||||
return { type: "fill", parts };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Doc} [breakContents]
|
||||
* @param {Doc} [flatContents]
|
||||
* @param {object} [opts] - TBD ???
|
||||
* @returns Doc
|
||||
*/
|
||||
function ifBreak(breakContents, flatContents, opts) {
|
||||
opts = opts || {};
|
||||
|
||||
@@ -104,6 +164,10 @@ function ifBreak(breakContents, flatContents, opts) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Doc} contents
|
||||
* @returns Doc
|
||||
*/
|
||||
function lineSuffix(contents) {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
assertDoc(contents);
|
||||
@@ -123,6 +187,11 @@ const literalline = concat([
|
||||
]);
|
||||
const cursor = { type: "cursor", placeholder: Symbol("cursor") };
|
||||
|
||||
/**
|
||||
* @param {Doc} sep
|
||||
* @param {Doc[]} arr
|
||||
* @returns Doc
|
||||
*/
|
||||
function join(sep, arr) {
|
||||
const res = [];
|
||||
|
||||
@@ -137,6 +206,11 @@ function join(sep, arr) {
|
||||
return concat(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Doc} doc
|
||||
* @param {number} size
|
||||
* @param {number} tabWidth
|
||||
*/
|
||||
function addAlignmentToDoc(doc, size, tabWidth) {
|
||||
let aligned = doc;
|
||||
if (size > 0) {
|
||||
|
||||
@@ -4,7 +4,7 @@ const { getStringWidth } = require("../common/util");
|
||||
const { convertEndOfLineToChars } = require("../common/end-of-line");
|
||||
const { concat, fill, cursor } = require("./doc-builders");
|
||||
|
||||
/** @type {{[groupId: PropertyKey]: MODE}} */
|
||||
/** @type {Record<symbol, typeof MODE_BREAK | typeof MODE_FLAT>} */
|
||||
let groupModeMap;
|
||||
|
||||
const MODE_BREAK = 1;
|
||||
|
||||
@@ -256,12 +256,12 @@ function parseMediaQuery(params) {
|
||||
const DEFAULT_SCSS_DIRECTIVE = /(\s*?)(!default).*$/;
|
||||
const GLOBAL_SCSS_DIRECTIVE = /(\s*?)(!global).*$/;
|
||||
|
||||
function parseNestedCSS(node) {
|
||||
function parseNestedCSS(node, options) {
|
||||
if (node && typeof node === "object") {
|
||||
delete node.parent;
|
||||
|
||||
for (const key in node) {
|
||||
parseNestedCSS(node[key]);
|
||||
parseNestedCSS(node[key], options);
|
||||
}
|
||||
|
||||
if (!node.type) {
|
||||
@@ -288,6 +288,16 @@ function parseNestedCSS(node) {
|
||||
node.raws.selector = selector;
|
||||
}
|
||||
|
||||
// postcss-less@2.0.0 parse `custom-selector` as `css-decl`
|
||||
if (
|
||||
options.parser === "css" &&
|
||||
node.type === "css-decl" &&
|
||||
node.prop === "@custom-selector"
|
||||
) {
|
||||
selector = node.value;
|
||||
node.raws.value = selector;
|
||||
}
|
||||
|
||||
let value = "";
|
||||
|
||||
if (typeof node.value === "string") {
|
||||
@@ -478,7 +488,7 @@ function parseNestedCSS(node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
function parseWithParser(parser, text) {
|
||||
function parseWithParser(parser, text, options) {
|
||||
const parsed = parseFrontMatter(text);
|
||||
const { frontMatter } = parsed;
|
||||
text = parsed.content;
|
||||
@@ -494,7 +504,7 @@ function parseWithParser(parser, text) {
|
||||
throw createError("(postcss) " + e.name + " " + e.reason, { start: e });
|
||||
}
|
||||
|
||||
result = parseNestedCSS(addTypePrefix(result, "css-"));
|
||||
result = parseNestedCSS(addTypePrefix(result, "css-"), options);
|
||||
|
||||
if (frontMatter) {
|
||||
result.nodes.unshift(frontMatter);
|
||||
@@ -521,20 +531,20 @@ function requireParser(isSCSSParser) {
|
||||
return require("postcss-less");
|
||||
}
|
||||
|
||||
function parse(text, parsers, opts) {
|
||||
function parse(text, parsers, options) {
|
||||
const hasExplicitParserChoice =
|
||||
opts.parser === "less" || opts.parser === "scss";
|
||||
const isSCSSParser = isSCSS(opts.parser, text);
|
||||
options.parser === "less" || options.parser === "scss";
|
||||
const isSCSSParser = isSCSS(options.parser, text);
|
||||
|
||||
try {
|
||||
return parseWithParser(requireParser(isSCSSParser), text);
|
||||
return parseWithParser(requireParser(isSCSSParser), text, options);
|
||||
} catch (originalError) {
|
||||
if (hasExplicitParserChoice) {
|
||||
throw originalError;
|
||||
}
|
||||
|
||||
try {
|
||||
return parseWithParser(requireParser(!isSCSSParser), text);
|
||||
return parseWithParser(requireParser(!isSCSSParser), text, options);
|
||||
} catch (_secondError) {
|
||||
throw originalError;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ function clean(ast, newObj, parent) {
|
||||
"extra",
|
||||
"start",
|
||||
"end",
|
||||
"flags"
|
||||
"flags",
|
||||
"errors"
|
||||
].forEach(name => {
|
||||
delete newObj[name];
|
||||
});
|
||||
|
||||
@@ -10,7 +10,7 @@ const languages = [
|
||||
Object.assign(data, {
|
||||
since: "0.0.0",
|
||||
parsers: ["babel", "flow"],
|
||||
vscodeLanguageIds: ["javascript"],
|
||||
vscodeLanguageIds: ["javascript", "mongo"],
|
||||
interpreters: data.interpreters.concat(["nodejs"])
|
||||
})
|
||||
),
|
||||
|
||||
@@ -7,7 +7,8 @@ const comments = require("./comments");
|
||||
const {
|
||||
getLeftSidePathName,
|
||||
hasFlowShorthandAnnotationComment,
|
||||
hasNakedLeftSide
|
||||
hasNakedLeftSide,
|
||||
hasNode
|
||||
} = require("./utils");
|
||||
|
||||
function hasClosureCompilerTypeCastComment(text, path) {
|
||||
@@ -353,7 +354,14 @@ function needsParens(path, options) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((po === "||" || po === "??") && no === "&&") {
|
||||
if (
|
||||
(po === "??" && (no === "||" || no === "&&")) ||
|
||||
(no === "??" && (po === "||" || po === "&&"))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (po === "||" && no === "&&") {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -758,6 +766,12 @@ function needsParens(path, options) {
|
||||
parent.type !== "TypeCastExpression" &&
|
||||
parent.type !== "VariableDeclarator")
|
||||
);
|
||||
case "TypeAnnotation":
|
||||
return (
|
||||
name === "returnType" &&
|
||||
parent.type === "ArrowFunctionExpression" &&
|
||||
includesFunctionTypeInObjectType(node)
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -783,6 +797,7 @@ function isStatement(node) {
|
||||
node.type === "DeclareModuleExports" ||
|
||||
node.type === "DeclareVariable" ||
|
||||
node.type === "DoWhileStatement" ||
|
||||
node.type === "EnumDeclaration" ||
|
||||
node.type === "ExportAllDeclaration" ||
|
||||
node.type === "ExportDefaultDeclaration" ||
|
||||
node.type === "ExportNamedDeclaration" ||
|
||||
@@ -814,6 +829,16 @@ function isStatement(node) {
|
||||
);
|
||||
}
|
||||
|
||||
function includesFunctionTypeInObjectType(node) {
|
||||
return hasNode(
|
||||
node,
|
||||
n1 =>
|
||||
(n1.type === "ObjectTypeAnnotation" &&
|
||||
hasNode(n1, n2 => n2.type === "FunctionTypeAnnotation" || undefined)) ||
|
||||
undefined
|
||||
);
|
||||
}
|
||||
|
||||
function endsWithRightBracket(node) {
|
||||
switch (node.type) {
|
||||
case "ObjectExpression":
|
||||
|
||||
@@ -17,6 +17,7 @@ function babelOptions(extraOptions, extraPlugins) {
|
||||
allowReturnOutsideFunction: true,
|
||||
allowSuperOutsideMethod: true,
|
||||
allowUndeclaredExports: true,
|
||||
errorRecovery: true,
|
||||
plugins: [
|
||||
"jsx",
|
||||
"doExpressions",
|
||||
@@ -93,7 +94,7 @@ function createParse(parseMethod, extraPlugins) {
|
||||
}
|
||||
|
||||
const parse = createParse("parse", ["flow"]);
|
||||
const parseFlow = createParse("parse", [["flow", { all: true }]]);
|
||||
const parseFlow = createParse("parse", [["flow", { all: true, enums: true }]]);
|
||||
const parseExpression = createParse("parseExpression");
|
||||
|
||||
function tryCombinations(fn, combinations) {
|
||||
|
||||
@@ -13,6 +13,7 @@ function parse(text, parsers, opts) {
|
||||
const flowParser = require("flow-parser");
|
||||
|
||||
const ast = flowParser.parse(text, {
|
||||
enums: true,
|
||||
esproposal_class_instance_fields: true,
|
||||
esproposal_class_static_fields: true,
|
||||
esproposal_export_star_as: true,
|
||||
|
||||
@@ -27,6 +27,22 @@ function postprocess(ast, options) {
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "EnumDeclaration":
|
||||
// A workaround for what looks like a bug in Flow.
|
||||
// Flow assigns the same range to enum nodes and enum body nodes.
|
||||
if (
|
||||
options.parser === "flow" &&
|
||||
node.body.range[0] === node.range[0] &&
|
||||
node.body.range[1] === node.range[1]
|
||||
) {
|
||||
node.body.range = [node.id.range[1], node.range[1] - 1];
|
||||
}
|
||||
// Babel does strange things as well. E.g. node.body.start > node.body.end can be true.
|
||||
if (options.parser === "babel-flow") {
|
||||
node.body.start = node.id.end;
|
||||
node.body.end = node.end - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ function clean(node, newNode /*, parent*/) {
|
||||
delete newNode.extra;
|
||||
delete newNode.loc;
|
||||
delete newNode.comments;
|
||||
delete newNode.errors;
|
||||
|
||||
if (node.type === "Identifier") {
|
||||
return { type: "StringLiteral", value: node.name };
|
||||
|
||||
@@ -908,8 +908,23 @@ function printPathNoParens(path, options, print, args) {
|
||||
}
|
||||
|
||||
return concat(parts);
|
||||
case "AwaitExpression":
|
||||
return concat(["await ", path.call(print, "argument")]);
|
||||
case "AwaitExpression": {
|
||||
parts.push("await ", path.call(print, "argument"));
|
||||
const parent = path.getParentNode();
|
||||
if (
|
||||
((parent.type === "CallExpression" ||
|
||||
parent.type === "OptionalCallExpression") &&
|
||||
parent.callee === n) ||
|
||||
((parent.type === "MemberExpression" ||
|
||||
parent.type === "OptionalMemberExpression") &&
|
||||
parent.object === n)
|
||||
) {
|
||||
return group(
|
||||
concat([indent(concat([softline, concat(parts)])), softline])
|
||||
);
|
||||
}
|
||||
return concat(parts);
|
||||
}
|
||||
case "ImportSpecifier":
|
||||
if (n.importKind) {
|
||||
parts.push(path.call(print, "importKind"), " ");
|
||||
@@ -1610,15 +1625,8 @@ function printPathNoParens(path, options, print, args) {
|
||||
case "NumericLiteral": // Babel 6 Literal split
|
||||
return printNumber(n.extra.raw);
|
||||
case "BigIntLiteral":
|
||||
return concat([
|
||||
printNumber(
|
||||
n.extra
|
||||
? n.extra.rawValue
|
||||
: // TypeScript
|
||||
n.value
|
||||
),
|
||||
"n"
|
||||
]);
|
||||
// babel: n.extra.raw, typescript: n.raw
|
||||
return (n.extra ? n.extra.raw : n.raw).toLowerCase();
|
||||
case "BooleanLiteral": // Babel 6 Literal split
|
||||
case "StringLiteral": // Babel 6 Literal split
|
||||
case "Literal": {
|
||||
@@ -2613,6 +2621,82 @@ function printPathNoParens(path, options, print, args) {
|
||||
return concat(parts);
|
||||
}
|
||||
|
||||
case "EnumDeclaration":
|
||||
return concat([
|
||||
"enum ",
|
||||
path.call(print, "id"),
|
||||
" ",
|
||||
path.call(print, "body")
|
||||
]);
|
||||
case "EnumBooleanBody":
|
||||
case "EnumNumberBody":
|
||||
case "EnumStringBody":
|
||||
case "EnumSymbolBody": {
|
||||
if (n.type === "EnumSymbolBody" || n.explicitType) {
|
||||
let type = null;
|
||||
switch (n.type) {
|
||||
case "EnumBooleanBody":
|
||||
type = "boolean";
|
||||
break;
|
||||
case "EnumNumberBody":
|
||||
type = "number";
|
||||
break;
|
||||
case "EnumStringBody":
|
||||
type = "string";
|
||||
break;
|
||||
case "EnumSymbolBody":
|
||||
type = "symbol";
|
||||
break;
|
||||
}
|
||||
parts.push("of ", type, " ");
|
||||
}
|
||||
if (n.members.length === 0) {
|
||||
parts.push(
|
||||
group(
|
||||
concat([
|
||||
"{",
|
||||
comments.printDanglingComments(path, options),
|
||||
softline,
|
||||
"}"
|
||||
])
|
||||
)
|
||||
);
|
||||
} else {
|
||||
parts.push(
|
||||
group(
|
||||
concat([
|
||||
"{",
|
||||
indent(
|
||||
concat([
|
||||
hardline,
|
||||
printArrayItems(path, options, "members", print),
|
||||
shouldPrintComma(options) ? "," : ""
|
||||
])
|
||||
),
|
||||
comments.printDanglingComments(
|
||||
path,
|
||||
options,
|
||||
/* sameIndent */ true
|
||||
),
|
||||
hardline,
|
||||
"}"
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
return concat(parts);
|
||||
}
|
||||
case "EnumBooleanMember":
|
||||
case "EnumNumberMember":
|
||||
case "EnumStringMember":
|
||||
return concat([
|
||||
path.call(print, "id"),
|
||||
" = ",
|
||||
typeof n.init === "object" ? path.call(print, "init") : String(n.init)
|
||||
]);
|
||||
case "EnumDefaultedMember":
|
||||
return path.call(print, "id");
|
||||
|
||||
case "FunctionTypeAnnotation":
|
||||
case "TSFunctionType": {
|
||||
// FunctionTypeAnnotation is ambiguous:
|
||||
@@ -4024,7 +4108,9 @@ function printArgumentsList(path, options, print) {
|
||||
somePrintedArgumentsWillBreak ? breakParent : "",
|
||||
conditionalGroup(
|
||||
[
|
||||
!somePrintedArgumentsWillBreak
|
||||
!somePrintedArgumentsWillBreak &&
|
||||
!node.typeArguments &&
|
||||
!node.typeParameters
|
||||
? simpleConcat
|
||||
: ifBreak(allArgsBrokenOut(), simpleConcat),
|
||||
shouldGroupFirst
|
||||
|
||||
@@ -912,6 +912,7 @@ module.exports = {
|
||||
hasNakedLeftSide,
|
||||
hasNewlineBetweenOrAfterDecorators,
|
||||
hasNgSideEffect,
|
||||
hasNode,
|
||||
hasPrettierIgnore,
|
||||
hasTrailingComment,
|
||||
identity,
|
||||
|
||||
@@ -510,7 +510,8 @@ function printComments(path, print, options, needsSemi) {
|
||||
leadingParts.push(contents);
|
||||
|
||||
const text = options.originalText;
|
||||
if (hasNewline(text, skipNewline(text, options.locEnd(comment)))) {
|
||||
const index = skipNewline(text, options.locEnd(comment));
|
||||
if (index !== false && hasNewline(text, index)) {
|
||||
leadingParts.push(hardline);
|
||||
}
|
||||
} else if (trailing) {
|
||||
|
||||
@@ -118,6 +118,9 @@ function optionInfoToSchema(optionInfo, { isCLI, optionInfos }) {
|
||||
parameters.preprocess = value => Number(value);
|
||||
}
|
||||
break;
|
||||
case "string":
|
||||
SchemaConstructor = vnopts.StringSchema;
|
||||
break;
|
||||
case "choice":
|
||||
SchemaConstructor = vnopts.ChoiceSchema;
|
||||
parameters.choices = optionInfo.choices.map(choiceInfo =>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
exports[`multiple.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "typescript"]
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
|
||||
@@ -1 +1 @@
|
||||
run_spec(__dirname, ["flow", "typescript"]);
|
||||
run_spec(__dirname, ["babel", "flow", "typescript"]);
|
||||
@@ -113,6 +113,30 @@ async function f2() {
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`inline_await.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
async function f() {
|
||||
const admins = (await(db.select('*').from('admins').leftJoin('bla').where('id', 'in', [1,2,3,4]))).map(({id, name})=>({id, name}))
|
||||
}
|
||||
|
||||
=====================================output=====================================
|
||||
async function f() {
|
||||
const admins = (
|
||||
await db
|
||||
.select("*")
|
||||
.from("admins")
|
||||
.leftJoin("bla")
|
||||
.where("id", "in", [1, 2, 3, 4])
|
||||
).map(({ id, name }) => ({ id, name }));
|
||||
}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`parens.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "typescript"]
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
async function f() {
|
||||
const admins = (await(db.select('*').from('admins').leftJoin('bla').where('id', 'in', [1,2,3,4]))).map(({id, name})=>({id, name}))
|
||||
}
|
||||
@@ -14,6 +14,9 @@ printWidth: 80
|
||||
0XFFF123n
|
||||
0b101011101n
|
||||
0B101011101n
|
||||
200_000n
|
||||
0x0000_000An
|
||||
0b0111_1111n
|
||||
|
||||
=====================================output=====================================
|
||||
100n;
|
||||
@@ -24,6 +27,9 @@ printWidth: 80
|
||||
0xfff123n;
|
||||
0b101011101n;
|
||||
0b101011101n;
|
||||
200_000n;
|
||||
0x0000_000an;
|
||||
0b0111_1111n;
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
@@ -6,3 +6,6 @@
|
||||
0XFFF123n
|
||||
0b101011101n
|
||||
0B101011101n
|
||||
200_000n
|
||||
0x0000_000An
|
||||
0b0111_1111n
|
||||
@@ -231,3 +231,23 @@ function MyComponent(props) {
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`type_args.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
const response = something.$http.get<ThingamabobService.DetailsData>(
|
||||
\`api/foo.ashx/foo-details/\${myId}\`,
|
||||
{ cache: quux.httpCache, timeout }
|
||||
);
|
||||
|
||||
=====================================output=====================================
|
||||
const response = something.$http.get<ThingamabobService.DetailsData>(
|
||||
\`api/foo.ashx/foo-details/\${myId}\`,
|
||||
{ cache: quux.httpCache, timeout }
|
||||
);
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
@@ -0,0 +1,4 @@
|
||||
const response = something.$http.get<ThingamabobService.DetailsData>(
|
||||
`api/foo.ashx/foo-details/${myId}`,
|
||||
{ cache: quux.httpCache, timeout }
|
||||
);
|
||||
@@ -1125,6 +1125,69 @@ foo(
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`jsdoc.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
/** @type {any} */
|
||||
const x = (
|
||||
<div>
|
||||
<div />
|
||||
</div>
|
||||
);
|
||||
|
||||
/**
|
||||
* @type {object}
|
||||
*/
|
||||
() => (
|
||||
<div>
|
||||
sajdfpoiasdjfpoiasdjfpoiasdjfpoiadsjfpaoisdjfapsdiofjapioisadfaskfaspiofjp
|
||||
</div>
|
||||
);
|
||||
|
||||
/**
|
||||
* @type {object}
|
||||
*/
|
||||
function HelloWorld() {
|
||||
return (
|
||||
<div>
|
||||
<span>Test</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
=====================================output=====================================
|
||||
/** @type {any} */
|
||||
const x = (
|
||||
<div>
|
||||
<div />
|
||||
</div>
|
||||
);
|
||||
|
||||
/**
|
||||
* @type {object}
|
||||
*/
|
||||
() => (
|
||||
<div>
|
||||
sajdfpoiasdjfpoiasdjfpoiasdjfpoiadsjfpaoisdjfapsdiofjapioisadfaskfaspiofjp
|
||||
</div>
|
||||
);
|
||||
|
||||
/**
|
||||
* @type {object}
|
||||
*/
|
||||
function HelloWorld() {
|
||||
return (
|
||||
<div>
|
||||
<span>Test</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`jsx.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel"]
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/** @type {any} */
|
||||
const x = (
|
||||
<div>
|
||||
<div />
|
||||
</div>
|
||||
);
|
||||
|
||||
/**
|
||||
* @type {object}
|
||||
*/
|
||||
() => (
|
||||
<div>
|
||||
sajdfpoiasdjfpoiasdjfpoiasdjfpoiadsjfpaoisdjfapsdiofjapioisadfaskfaspiofjp
|
||||
</div>
|
||||
);
|
||||
|
||||
/**
|
||||
* @type {object}
|
||||
*/
|
||||
function HelloWorld() {
|
||||
return (
|
||||
<div>
|
||||
<span>Test</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1677,6 +1677,12 @@ label {
|
||||
.margin-bottom-1\\/3;
|
||||
}
|
||||
|
||||
// whitespace between variable and colon, #2925 #4090
|
||||
@FoO : bar;
|
||||
|
||||
// should not parse as custom-selector
|
||||
@custom-selector :--icon #id;
|
||||
|
||||
=====================================output=====================================
|
||||
@nice-blue: #5b83ad;
|
||||
@light-blue: @nice-blue + #111;
|
||||
@@ -3281,5 +3287,11 @@ label {
|
||||
.margin-bottom-1\\/3;
|
||||
}
|
||||
|
||||
// whitespace between variable and colon, #2925 #4090
|
||||
@FoO: bar;
|
||||
|
||||
// should not parse as custom-selector
|
||||
@custom-selector: --icon #id;
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
@@ -1668,3 +1668,9 @@ li + li {
|
||||
label {
|
||||
.margin-bottom-1\/3;
|
||||
}
|
||||
|
||||
// whitespace between variable and colon, #2925 #4090
|
||||
@FoO : bar;
|
||||
|
||||
// should not parse as custom-selector
|
||||
@custom-selector :--icon #id;
|
||||
@@ -2,21 +2,7 @@
|
||||
|
||||
exports[`export_default_arrow_expression.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
export default () => {};
|
||||
|
||||
=====================================output=====================================
|
||||
export default () => {};
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`export_default_arrow_expression.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "typescript"]
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
@@ -30,21 +16,7 @@ export default () => {};
|
||||
|
||||
exports[`export_default_call_expression.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
export default foo()
|
||||
|
||||
=====================================output=====================================
|
||||
export default foo();
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`export_default_call_expression.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "typescript"]
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
@@ -58,21 +30,7 @@ export default foo();
|
||||
|
||||
exports[`export_default_class_declaration.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
export default class Foo {}
|
||||
|
||||
=====================================output=====================================
|
||||
export default class Foo {}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`export_default_class_declaration.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "typescript"]
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
@@ -86,21 +44,7 @@ export default class Foo {}
|
||||
|
||||
exports[`export_default_class_expression.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
export default (class foobar {})
|
||||
|
||||
=====================================output=====================================
|
||||
export default (class foobar {});
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`export_default_class_expression.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "typescript"]
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
@@ -114,21 +58,7 @@ export default (class foobar {});
|
||||
|
||||
exports[`export_default_function_declaration.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
export default function() {}
|
||||
|
||||
=====================================output=====================================
|
||||
export default function() {}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`export_default_function_declaration.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "typescript"]
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
@@ -142,21 +72,7 @@ export default function() {}
|
||||
|
||||
exports[`export_default_function_declaration_async.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
export default async function foo() {}
|
||||
|
||||
=====================================output=====================================
|
||||
export default async function foo() {}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`export_default_function_declaration_async.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "typescript"]
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
@@ -170,21 +86,7 @@ export default async function foo() {}
|
||||
|
||||
exports[`export_default_function_declaration_named.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
export default function f(){}
|
||||
|
||||
=====================================output=====================================
|
||||
export default function f() {}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`export_default_function_declaration_named.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "typescript"]
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
@@ -198,21 +100,7 @@ export default function f() {}
|
||||
|
||||
exports[`export_default_function_expression.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
export default (function() {});
|
||||
|
||||
=====================================output=====================================
|
||||
export default (function() {});
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`export_default_function_expression.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "typescript"]
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
@@ -226,21 +114,7 @@ export default (function() {});
|
||||
|
||||
exports[`export_default_function_expression_named.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
export default (function f(){})
|
||||
|
||||
=====================================output=====================================
|
||||
export default (function f() {});
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`export_default_function_expression_named.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "typescript"]
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
@@ -254,21 +128,7 @@ export default (function f() {});
|
||||
|
||||
exports[`export_default_new_expression.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
export default new Foo();
|
||||
|
||||
=====================================output=====================================
|
||||
export default new Foo();
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`export_default_new_expression.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "typescript"]
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
run_spec(__dirname, ["flow"]);
|
||||
// FIXME export_default_function_declaration_async.js flow != babel output
|
||||
run_spec(__dirname, ["babel", "typescript"]);
|
||||
run_spec(__dirname, ["babel", "flow", "typescript"]);
|
||||
@@ -0,0 +1,377 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`enum-boolean-explicit.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
// @flow
|
||||
|
||||
enum E of boolean {
|
||||
A = true,
|
||||
B = false,
|
||||
}
|
||||
|
||||
=====================================output=====================================
|
||||
// @flow
|
||||
|
||||
enum E of boolean {
|
||||
A = true,
|
||||
B = false,
|
||||
}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`enum-boolean-implicit.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A = true,
|
||||
B = false,
|
||||
}
|
||||
|
||||
=====================================output=====================================
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A = true,
|
||||
B = false,
|
||||
}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`enum-comments.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
enum E1 {
|
||||
A = 0,
|
||||
// B = 1,
|
||||
C = 2
|
||||
}
|
||||
|
||||
enum E2 of number {
|
||||
// AA = -1,
|
||||
A = 0,
|
||||
// B = 1,
|
||||
C = 2
|
||||
// D = 100
|
||||
}
|
||||
|
||||
enum E3 {/*Q*/}
|
||||
|
||||
enum E4 of /*Q*/ string {
|
||||
Foo = "foo"
|
||||
}
|
||||
|
||||
enum E5 of string { // Q
|
||||
Bar = "bar"
|
||||
}
|
||||
|
||||
enum /*Q*/ E6 of string {}
|
||||
|
||||
=====================================output=====================================
|
||||
enum E1 {
|
||||
A = 0,
|
||||
// B = 1,
|
||||
C = 2,
|
||||
}
|
||||
|
||||
enum E2 of number {
|
||||
// AA = -1,
|
||||
A = 0,
|
||||
// B = 1,
|
||||
C = 2,
|
||||
// D = 100
|
||||
}
|
||||
|
||||
enum E3 {
|
||||
/*Q*/
|
||||
}
|
||||
|
||||
enum E4 of string {
|
||||
/*Q*/ Foo = "foo",
|
||||
}
|
||||
|
||||
enum E5 of string {
|
||||
// Q
|
||||
Bar = "bar",
|
||||
}
|
||||
|
||||
enum /*Q*/ E6 of string {}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`enum-empty.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
// @flow
|
||||
|
||||
enum E { }
|
||||
|
||||
=====================================output=====================================
|
||||
// @flow
|
||||
|
||||
enum E {}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`enum-export.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
// @flow
|
||||
|
||||
export enum A {}
|
||||
|
||||
export default enum B {}
|
||||
|
||||
=====================================output=====================================
|
||||
// @flow
|
||||
|
||||
export enum A {}
|
||||
|
||||
export default enum B {};
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`enum-name.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
// @flow
|
||||
|
||||
enum type {
|
||||
}
|
||||
|
||||
=====================================output=====================================
|
||||
// @flow
|
||||
|
||||
enum type {}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`enum-no-trailing-comma.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A
|
||||
}
|
||||
|
||||
=====================================output=====================================
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A,
|
||||
}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`enum-number-explicit.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
// @flow
|
||||
|
||||
enum E of number {
|
||||
A = 1,
|
||||
B = 2,
|
||||
}
|
||||
|
||||
=====================================output=====================================
|
||||
// @flow
|
||||
|
||||
enum E of number {
|
||||
A = 1,
|
||||
B = 2,
|
||||
}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`enum-number-implicit.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A = 0,
|
||||
B = 1,
|
||||
}
|
||||
|
||||
=====================================output=====================================
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A = 0,
|
||||
B = 1,
|
||||
}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`enum-string-explicit-defaulted.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
// @flow
|
||||
|
||||
enum E of string {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
=====================================output=====================================
|
||||
// @flow
|
||||
|
||||
enum E of string {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`enum-string-explicit-initialized.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
// @flow
|
||||
|
||||
enum E of string {
|
||||
A = "a",
|
||||
B = "b",
|
||||
}
|
||||
|
||||
=====================================output=====================================
|
||||
// @flow
|
||||
|
||||
enum E of string {
|
||||
A = "a",
|
||||
B = "b",
|
||||
}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`enum-string-implicit-defaulted.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
=====================================output=====================================
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`enum-string-implicit-initialized.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A = "a",
|
||||
B = "b",
|
||||
}
|
||||
|
||||
=====================================output=====================================
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A = "a",
|
||||
B = "b",
|
||||
}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`enum-symbol.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow", "babel-flow"]
|
||||
printWidth: 80
|
||||
trailingComma: "all"
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
// @flow
|
||||
|
||||
enum E of symbol {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
=====================================output=====================================
|
||||
// @flow
|
||||
|
||||
enum E of symbol {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
@@ -0,0 +1,6 @@
|
||||
// @flow
|
||||
|
||||
enum E of boolean {
|
||||
A = true,
|
||||
B = false,
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A = true,
|
||||
B = false,
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
enum E1 {
|
||||
A = 0,
|
||||
// B = 1,
|
||||
C = 2
|
||||
}
|
||||
|
||||
enum E2 of number {
|
||||
// AA = -1,
|
||||
A = 0,
|
||||
// B = 1,
|
||||
C = 2
|
||||
// D = 100
|
||||
}
|
||||
|
||||
enum E3 {/*Q*/}
|
||||
|
||||
enum E4 of /*Q*/ string {
|
||||
Foo = "foo"
|
||||
}
|
||||
|
||||
enum E5 of string { // Q
|
||||
Bar = "bar"
|
||||
}
|
||||
|
||||
enum /*Q*/ E6 of string {}
|
||||
@@ -0,0 +1,3 @@
|
||||
// @flow
|
||||
|
||||
enum E { }
|
||||
@@ -0,0 +1,5 @@
|
||||
// @flow
|
||||
|
||||
export enum A {}
|
||||
|
||||
export default enum B {}
|
||||
@@ -0,0 +1,4 @@
|
||||
// @flow
|
||||
|
||||
enum type {
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @flow
|
||||
|
||||
enum E of number {
|
||||
A = 1,
|
||||
B = 2,
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A = 0,
|
||||
B = 1,
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @flow
|
||||
|
||||
enum E of string {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @flow
|
||||
|
||||
enum E of string {
|
||||
A = "a",
|
||||
B = "b",
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @flow
|
||||
|
||||
enum E {
|
||||
A = "a",
|
||||
B = "b",
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @flow
|
||||
|
||||
enum E of symbol {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
run_spec(__dirname, ["flow", "babel-flow"], { trailingComma: "all" });
|
||||
@@ -1,5 +1,73 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`in_object_type.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
const example1 = (): ({ p: string => string }) => (0: any);
|
||||
const example2 = (): ({ p: { p: string => string } }) => (0: any);
|
||||
const example3 = (): ({ p: { p: { p: string => string } } }) => (0: any);
|
||||
const example4 = (): ({ p: { p: ?{ p: string => string } } }) => (0: any);
|
||||
const example5 = (): ({ p: { p: { p: string => string } | string } }) =>
|
||||
(0: any);
|
||||
const example6 = (): ({ p: { p: { p: string => string } & string } }) =>
|
||||
(0: any);
|
||||
const example7 = (): ({ p: { p: { p: [(string) => string, string] } } }) =>
|
||||
(0: any);
|
||||
function example8(): { p: string => string } {
|
||||
return (0: any);
|
||||
}
|
||||
function example9(): { p: { p: string => string } } {
|
||||
return (0: any);
|
||||
}
|
||||
function example10(): { p: { p: { p: string => string } } } {
|
||||
return (0: any);
|
||||
}
|
||||
const example11 = (): ({ p: string => string } & string) => (0: any);
|
||||
const example12 = (): ({ p: string => string } | string) => (0: any);
|
||||
const example13 = (): ([{ p: string => string }, string]) => (0: any);
|
||||
const example14 = (): ({ p: string => string }[]) => (0: any);
|
||||
const example15 = (): ({ p: { p: { p: (string => string) & string } } }) =>
|
||||
(0: any);
|
||||
const example16 = (): ({ p: { p: { p: (string => string) | string } } }) =>
|
||||
(0: any);
|
||||
const example17 = (): (?{ p: string => string }) => (0: any);
|
||||
|
||||
=====================================output=====================================
|
||||
const example1 = (): ({ p: string => string }) => (0: any);
|
||||
const example2 = (): ({ p: { p: string => string } }) => (0: any);
|
||||
const example3 = (): ({ p: { p: { p: string => string } } }) => (0: any);
|
||||
const example4 = (): ({ p: { p: ?{ p: string => string } } }) => (0: any);
|
||||
const example5 = (): ({ p: { p: { p: string => string } | string } }) =>
|
||||
(0: any);
|
||||
const example6 = (): ({ p: { p: { p: string => string } & string } }) =>
|
||||
(0: any);
|
||||
const example7 = (): ({ p: { p: { p: [(string) => string, string] } } }) =>
|
||||
(0: any);
|
||||
function example8(): { p: string => string } {
|
||||
return (0: any);
|
||||
}
|
||||
function example9(): { p: { p: string => string } } {
|
||||
return (0: any);
|
||||
}
|
||||
function example10(): { p: { p: { p: string => string } } } {
|
||||
return (0: any);
|
||||
}
|
||||
const example11 = (): ({ p: string => string } & string) => (0: any);
|
||||
const example12 = (): ({ p: string => string } | string) => (0: any);
|
||||
const example13 = (): ([{ p: string => string }, string]) => (0: any);
|
||||
const example14 = (): ({ p: string => string }[]) => (0: any);
|
||||
const example15 = (): ({ p: { p: { p: (string => string) & string } } }) =>
|
||||
(0: any);
|
||||
const example16 = (): ({ p: { p: { p: (string => string) | string } } }) =>
|
||||
(0: any);
|
||||
const example17 = (): (?{ p: string => string }) => (0: any);
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`issue-1249.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
@@ -60,16 +128,18 @@ parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
const f = (): (string => string) => {};
|
||||
const f = (): (a | string => string) => {};
|
||||
const f = (): (a & string => string) => {};
|
||||
function f(): string => string {}
|
||||
const f1 = (): (string => string) => {};
|
||||
const f2 = (): ?(y => {a: b => c}) => (0: any);
|
||||
const f3 = (): (a | string => string) => {};
|
||||
const f4 = (): (a & string => string) => {};
|
||||
function f5(): string => string {}
|
||||
|
||||
=====================================output=====================================
|
||||
const f = (): (string => string) => {};
|
||||
const f = (): a | (string => string) => {};
|
||||
const f = (): a & (string => string) => {};
|
||||
function f(): string => string {}
|
||||
const f1 = (): (string => string) => {};
|
||||
const f2 = (): (?(y) => { a: b => c }) => (0: any);
|
||||
const f3 = (): a | (string => string) => {};
|
||||
const f4 = (): a & (string => string) => {};
|
||||
function f5(): string => string {}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
@@ -0,0 +1,28 @@
|
||||
const example1 = (): ({ p: string => string }) => (0: any);
|
||||
const example2 = (): ({ p: { p: string => string } }) => (0: any);
|
||||
const example3 = (): ({ p: { p: { p: string => string } } }) => (0: any);
|
||||
const example4 = (): ({ p: { p: ?{ p: string => string } } }) => (0: any);
|
||||
const example5 = (): ({ p: { p: { p: string => string } | string } }) =>
|
||||
(0: any);
|
||||
const example6 = (): ({ p: { p: { p: string => string } & string } }) =>
|
||||
(0: any);
|
||||
const example7 = (): ({ p: { p: { p: [(string) => string, string] } } }) =>
|
||||
(0: any);
|
||||
function example8(): { p: string => string } {
|
||||
return (0: any);
|
||||
}
|
||||
function example9(): { p: { p: string => string } } {
|
||||
return (0: any);
|
||||
}
|
||||
function example10(): { p: { p: { p: string => string } } } {
|
||||
return (0: any);
|
||||
}
|
||||
const example11 = (): ({ p: string => string } & string) => (0: any);
|
||||
const example12 = (): ({ p: string => string } | string) => (0: any);
|
||||
const example13 = (): ([{ p: string => string }, string]) => (0: any);
|
||||
const example14 = (): ({ p: string => string }[]) => (0: any);
|
||||
const example15 = (): ({ p: { p: { p: (string => string) & string } } }) =>
|
||||
(0: any);
|
||||
const example16 = (): ({ p: { p: { p: (string => string) | string } } }) =>
|
||||
(0: any);
|
||||
const example17 = (): (?{ p: string => string }) => (0: any);
|
||||
@@ -1,4 +1,5 @@
|
||||
const f = (): (string => string) => {};
|
||||
const f = (): (a | string => string) => {};
|
||||
const f = (): (a & string => string) => {};
|
||||
function f(): string => string {}
|
||||
const f1 = (): (string => string) => {};
|
||||
const f2 = (): ?(y => {a: b => c}) => (0: any);
|
||||
const f3 = (): (a | string => string) => {};
|
||||
const f4 = (): (a & string => string) => {};
|
||||
function f5(): string => string {}
|
||||
@@ -7,11 +7,13 @@ printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
<p>I will display €</p>
|
||||
<p>I will display !</p>
|
||||
<p>I will display €</p>
|
||||
<p>I will display €</p>
|
||||
|
||||
=====================================output=====================================
|
||||
<p>I will display €</p>
|
||||
<p>I will display !</p>
|
||||
<p>I will display €</p>
|
||||
<p>I will display €</p>
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<p>I will display €</p>
|
||||
<p>I will display !</p>
|
||||
<p>I will display €</p>
|
||||
<p>I will display €</p>
|
||||
@@ -0,0 +1,16 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`duplicate_bindings.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
class A{} class A{}
|
||||
|
||||
=====================================output=====================================
|
||||
class A {}
|
||||
class A {}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
@@ -0,0 +1 @@
|
||||
class A{} class A{}
|
||||
@@ -0,0 +1 @@
|
||||
run_spec(__dirname, ["babel"]);
|
||||
@@ -2,21 +2,7 @@
|
||||
|
||||
exports[`escape.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
<div><</div>
|
||||
|
||||
=====================================output=====================================
|
||||
<div><</div>;
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`escape.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel"]
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
@@ -30,41 +16,7 @@ printWidth: 80
|
||||
|
||||
exports[`nbsp.js 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
many_nbsp = <div> </div>
|
||||
single_nbsp = <div> </div>
|
||||
nbsp_with_newline =
|
||||
<div>
|
||||
|
||||
</div>
|
||||
|
||||
many_raw_nbsp = <div> </div>
|
||||
many_raw_spaces = <div> </div>
|
||||
|
||||
|
||||
amp = <span>foo & bar</span>
|
||||
raw_amp = <span>foo & bar</span>
|
||||
|
||||
=====================================output=====================================
|
||||
many_nbsp = <div> </div>;
|
||||
single_nbsp = <div> </div>;
|
||||
nbsp_with_newline = <div> </div>;
|
||||
|
||||
many_raw_nbsp = <div> </div>;
|
||||
many_raw_spaces = <div> </div>;
|
||||
|
||||
amp = <span>foo & bar</span>;
|
||||
raw_amp = <span>foo & bar</span>;
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`nbsp.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel"]
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
run_spec(__dirname, ["flow"]);
|
||||
// FIXME nbsp.js flow != babel output, waiting for: https://github.com/babel/babylon/pull/344
|
||||
run_spec(__dirname, ["babel"]);
|
||||
run_spec(__dirname, ["babel", "flow", "typescript"]);
|
||||
@@ -36,42 +36,7 @@ x;
|
||||
|
||||
exports[`comments.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
semi: false
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
let error = new Error(response.statusText);
|
||||
// comment
|
||||
(error: any).response = response
|
||||
|
||||
x;
|
||||
|
||||
/* comment */ (error: any).response = response
|
||||
|
||||
x;
|
||||
|
||||
(error: any).response = response; /* comment */
|
||||
|
||||
=====================================output=====================================
|
||||
let error = new Error(response.statusText)
|
||||
// comment
|
||||
;(error: any).response = response
|
||||
|
||||
x
|
||||
|
||||
/* comment */ ;(error: any).response = response
|
||||
|
||||
x
|
||||
|
||||
;(error: any).response = response /* comment */
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`comments.js 3`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel"]
|
||||
parsers: ["babel", "flow"]
|
||||
printWidth: 80
|
||||
semi: false
|
||||
| printWidth
|
||||
@@ -191,93 +156,7 @@ interface E {
|
||||
|
||||
exports[`flow-interfaces.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
semi: false
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
declare class A {
|
||||
one: boolean;
|
||||
two: { three: string }
|
||||
| number;
|
||||
}
|
||||
|
||||
// NOTE: Flow and Babel both fail to apply ASI here
|
||||
// declare class B {
|
||||
// one: boolean
|
||||
// two: { three: string }
|
||||
// | number
|
||||
// }
|
||||
|
||||
declare interface C {
|
||||
one: boolean;
|
||||
two: { three: string }
|
||||
| number;
|
||||
}
|
||||
|
||||
// NOTE: Flow and Babel both fail to apply ASI here
|
||||
// declare interface D {
|
||||
// one: boolean
|
||||
// two: { three: string }
|
||||
// | number
|
||||
// }
|
||||
|
||||
interface E {
|
||||
one: boolean;
|
||||
two: { three: string }
|
||||
| number;
|
||||
}
|
||||
|
||||
// NOTE: Flow and Babel both fail to apply ASI here
|
||||
// interface F {
|
||||
// one: boolean
|
||||
// two: { three: string }
|
||||
// | number
|
||||
// }
|
||||
|
||||
=====================================output=====================================
|
||||
declare class A {
|
||||
one: boolean;
|
||||
two: { three: string } | number;
|
||||
}
|
||||
|
||||
// NOTE: Flow and Babel both fail to apply ASI here
|
||||
// declare class B {
|
||||
// one: boolean
|
||||
// two: { three: string }
|
||||
// | number
|
||||
// }
|
||||
|
||||
declare interface C {
|
||||
one: boolean;
|
||||
two: { three: string } | number;
|
||||
}
|
||||
|
||||
// NOTE: Flow and Babel both fail to apply ASI here
|
||||
// declare interface D {
|
||||
// one: boolean
|
||||
// two: { three: string }
|
||||
// | number
|
||||
// }
|
||||
|
||||
interface E {
|
||||
one: boolean;
|
||||
two: { three: string } | number;
|
||||
}
|
||||
|
||||
// NOTE: Flow and Babel both fail to apply ASI here
|
||||
// interface F {
|
||||
// one: boolean
|
||||
// two: { three: string }
|
||||
// | number
|
||||
// }
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`flow-interfaces.js 3`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel"]
|
||||
parsers: ["babel", "flow"]
|
||||
printWidth: 80
|
||||
semi: false
|
||||
| printWidth
|
||||
@@ -391,36 +270,7 @@ var c = a.e;
|
||||
|
||||
exports[`issue2006.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
semi: false
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
switch (n) {
|
||||
case 11:
|
||||
var c = a.e;
|
||||
(i.a += Ga(c.e)), F(i, c.i, 0);
|
||||
}
|
||||
|
||||
var c = a.e;
|
||||
(i.a += Ga(c.e)), F(i, c.i, 0);
|
||||
|
||||
=====================================output=====================================
|
||||
switch (n) {
|
||||
case 11:
|
||||
var c = a.e
|
||||
;(i.a += Ga(c.e)), F(i, c.i, 0)
|
||||
}
|
||||
|
||||
var c = a.e
|
||||
;(i.a += Ga(c.e)), F(i, c.i, 0)
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`issue2006.js 3`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel"]
|
||||
parsers: ["babel", "flow"]
|
||||
printWidth: 80
|
||||
semi: false
|
||||
| printWidth
|
||||
@@ -799,358 +649,7 @@ aReallyLongLine012345678901234567890123456789012345678901234567890123456789 *
|
||||
|
||||
exports[`no-semi.js 2`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
semi: false
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
|
||||
// with preexisting semi
|
||||
|
||||
x; [1, 2, 3].forEach(fn)
|
||||
x; [a, b, ...c] = [1, 2]
|
||||
x; /r/i.test('r')
|
||||
x; +1
|
||||
x; - 1
|
||||
x; ('h' + 'i').repeat(10)
|
||||
x; (1, 2)
|
||||
x; (() => {})()
|
||||
x; ({ a: 1 }).entries()
|
||||
x; ({ a: 1 }).entries()
|
||||
x; <Hello />
|
||||
x; \`string\`
|
||||
x; (x, y) => x
|
||||
|
||||
// doesn't have to be preceded by a semicolon
|
||||
|
||||
class X {} [1, 2, 3].forEach(fn)
|
||||
|
||||
// TODO: upgrade parser
|
||||
// class A {
|
||||
// async; // The semicolon is *not* necessary
|
||||
// x(){}
|
||||
// }
|
||||
// class B {
|
||||
// static; // The semicolon *is* necessary
|
||||
// x(){}
|
||||
// }
|
||||
|
||||
class C1 {
|
||||
get; // The semicolon *is* necessary
|
||||
x(){}
|
||||
}
|
||||
class C2 {
|
||||
get = () => {}; // The semicolon is *not* necessary
|
||||
x(){}
|
||||
}
|
||||
class C3 {
|
||||
set; // The semicolon *is* necessary
|
||||
x(){}
|
||||
}
|
||||
class C4 {
|
||||
set = () => {}; // The semicolon is *not* necessary
|
||||
x(){}
|
||||
}
|
||||
|
||||
|
||||
// don't semicolon if it doesn't start statement
|
||||
|
||||
if (true) (() => {})()
|
||||
|
||||
class A {
|
||||
a = 0;
|
||||
[b](){}
|
||||
|
||||
c = 0;
|
||||
*d(){}
|
||||
|
||||
e = 0;
|
||||
[f] = 0
|
||||
|
||||
// none of the semicolons above this comment can be omitted.
|
||||
// none of the semicolons below this comment are necessary.
|
||||
|
||||
q() {};
|
||||
[h](){}
|
||||
|
||||
p() {};
|
||||
*i(){}
|
||||
|
||||
a = 1;
|
||||
get ['y']() {}
|
||||
|
||||
a = 1;
|
||||
static ['y']() {}
|
||||
|
||||
a = 1;
|
||||
set ['z'](z) {}
|
||||
|
||||
a = 1;
|
||||
async ['a']() {}
|
||||
|
||||
a = 1;
|
||||
async *g() {}
|
||||
|
||||
a = 0;
|
||||
b = 1;
|
||||
}
|
||||
|
||||
// being first/last shouldn't break things
|
||||
class G1 {
|
||||
x = 1
|
||||
}
|
||||
class G2 {
|
||||
x() {}
|
||||
}
|
||||
class G3 {
|
||||
*x() {}
|
||||
}
|
||||
class G4 {
|
||||
[x] = 1
|
||||
}
|
||||
|
||||
// check indentation
|
||||
|
||||
if (true) {
|
||||
x; (() => {})()
|
||||
}
|
||||
|
||||
// flow
|
||||
|
||||
(x: void);
|
||||
(y: void)
|
||||
|
||||
// check statement clauses
|
||||
|
||||
do break; while (false)
|
||||
if (true) do break; while (false)
|
||||
|
||||
if (true) 1; else 2
|
||||
for (;;) ;
|
||||
for (x of y) ;
|
||||
|
||||
debugger
|
||||
|
||||
// check that it doesn't break non-ASI
|
||||
|
||||
1
|
||||
- 1
|
||||
|
||||
1
|
||||
+ 1
|
||||
|
||||
1
|
||||
/ 1
|
||||
|
||||
arr
|
||||
[0]
|
||||
|
||||
fn
|
||||
(x)
|
||||
|
||||
!1
|
||||
|
||||
1
|
||||
< 1
|
||||
|
||||
tag
|
||||
\`string\`
|
||||
|
||||
x; x => x
|
||||
|
||||
x; (a || b).c++
|
||||
|
||||
x; ++(a || b).c
|
||||
|
||||
while (false)
|
||||
(function(){}())
|
||||
|
||||
aReallyLongLine012345678901234567890123456789012345678901234567890123456789 *
|
||||
(b + c)
|
||||
|
||||
=====================================output=====================================
|
||||
// with preexisting semi
|
||||
|
||||
x
|
||||
;[1, 2, 3].forEach(fn)
|
||||
x
|
||||
;[a, b, ...c] = [1, 2]
|
||||
x
|
||||
;/r/i.test("r")
|
||||
x
|
||||
;+1
|
||||
x
|
||||
;-1
|
||||
x
|
||||
;("h" + "i").repeat(10)
|
||||
x
|
||||
1, 2
|
||||
x
|
||||
;(() => {})()
|
||||
x
|
||||
;({ a: 1 }.entries())
|
||||
x
|
||||
;({ a: 1 }.entries())
|
||||
x
|
||||
;<Hello />
|
||||
x
|
||||
;\`string\`
|
||||
x
|
||||
;(x, y) => x
|
||||
|
||||
// doesn't have to be preceded by a semicolon
|
||||
|
||||
class X {}
|
||||
;[1, 2, 3].forEach(fn)
|
||||
|
||||
// TODO: upgrade parser
|
||||
// class A {
|
||||
// async; // The semicolon is *not* necessary
|
||||
// x(){}
|
||||
// }
|
||||
// class B {
|
||||
// static; // The semicolon *is* necessary
|
||||
// x(){}
|
||||
// }
|
||||
|
||||
class C1 {
|
||||
get; // The semicolon *is* necessary
|
||||
x() {}
|
||||
}
|
||||
class C2 {
|
||||
get = () => {} // The semicolon is *not* necessary
|
||||
x() {}
|
||||
}
|
||||
class C3 {
|
||||
set; // The semicolon *is* necessary
|
||||
x() {}
|
||||
}
|
||||
class C4 {
|
||||
set = () => {} // The semicolon is *not* necessary
|
||||
x() {}
|
||||
}
|
||||
|
||||
// don't semicolon if it doesn't start statement
|
||||
|
||||
if (true) (() => {})()
|
||||
|
||||
class A {
|
||||
a = 0;
|
||||
[b]() {}
|
||||
|
||||
c = 0;
|
||||
*d() {}
|
||||
|
||||
e = 0;
|
||||
[f] = 0
|
||||
|
||||
// none of the semicolons above this comment can be omitted.
|
||||
// none of the semicolons below this comment are necessary.
|
||||
|
||||
q() {}
|
||||
[h]() {}
|
||||
|
||||
p() {}
|
||||
*i() {}
|
||||
|
||||
a = 1
|
||||
get ["y"]() {}
|
||||
|
||||
a = 1
|
||||
static ["y"]() {}
|
||||
|
||||
a = 1
|
||||
set ["z"](z) {}
|
||||
|
||||
a = 1
|
||||
async ["a"]() {}
|
||||
|
||||
a = 1
|
||||
async *g() {}
|
||||
|
||||
a = 0
|
||||
b = 1
|
||||
}
|
||||
|
||||
// being first/last shouldn't break things
|
||||
class G1 {
|
||||
x = 1
|
||||
}
|
||||
class G2 {
|
||||
x() {}
|
||||
}
|
||||
class G3 {
|
||||
*x() {}
|
||||
}
|
||||
class G4 {
|
||||
[x] = 1
|
||||
}
|
||||
|
||||
// check indentation
|
||||
|
||||
if (true) {
|
||||
x
|
||||
;(() => {})()
|
||||
}
|
||||
|
||||
// flow
|
||||
|
||||
;(x: void)
|
||||
;(y: void)
|
||||
|
||||
// check statement clauses
|
||||
|
||||
do break
|
||||
while (false)
|
||||
if (true)
|
||||
do break
|
||||
while (false)
|
||||
|
||||
if (true) 1
|
||||
else 2
|
||||
for (;;);
|
||||
for (x of y);
|
||||
|
||||
debugger
|
||||
|
||||
// check that it doesn't break non-ASI
|
||||
|
||||
1 - 1
|
||||
|
||||
1 + 1
|
||||
|
||||
1 / 1
|
||||
|
||||
arr[0]
|
||||
|
||||
fn(x)
|
||||
|
||||
!1
|
||||
|
||||
1 < 1
|
||||
|
||||
tag\`string\`
|
||||
|
||||
x
|
||||
x => x
|
||||
|
||||
x
|
||||
;(a || b).c++
|
||||
|
||||
x
|
||||
++(a || b).c
|
||||
|
||||
while (false) (function() {})()
|
||||
|
||||
aReallyLongLine012345678901234567890123456789012345678901234567890123456789 *
|
||||
(b + c)
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`no-semi.js 3`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel"]
|
||||
parsers: ["babel", "flow"]
|
||||
printWidth: 80
|
||||
semi: false
|
||||
| printWidth
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
run_spec(__dirname, ["flow"]);
|
||||
run_spec(__dirname, ["flow"], { semi: false });
|
||||
run_spec(__dirname, ["babel"], { semi: false });
|
||||
run_spec(__dirname, ["babel", "flow"], { semi: false });
|
||||
@@ -13,8 +13,18 @@ const x = (foo, bar = foo ?? bar) => {};
|
||||
foo ? bar ?? foo : baz;
|
||||
|
||||
foo ?? (bar ?? baz);
|
||||
(foo ?? bar) ?? baz;
|
||||
|
||||
// Mixing ?? and (&& or ||) requires parens
|
||||
// It's a syntax error without it.
|
||||
(foo ?? baz) || baz;
|
||||
foo ?? (baz || baz);
|
||||
|
||||
(foo ?? baz) && baz;
|
||||
foo ?? (baz && baz);
|
||||
|
||||
(foo || baz) ?? baz;
|
||||
foo || (baz ?? baz);
|
||||
|
||||
(foo && baz) ?? baz;
|
||||
foo && (baz ?? baz);
|
||||
@@ -27,8 +37,18 @@ const x = (foo, bar = foo ?? bar) => {};
|
||||
foo ? bar ?? foo : baz;
|
||||
|
||||
foo ?? (bar ?? baz);
|
||||
foo ?? bar ?? baz;
|
||||
|
||||
// Mixing ?? and (&& or ||) requires parens
|
||||
// It's a syntax error without it.
|
||||
(foo ?? baz) || baz;
|
||||
foo ?? (baz || baz);
|
||||
|
||||
(foo ?? baz) && baz;
|
||||
foo ?? (baz && baz);
|
||||
|
||||
(foo || baz) ?? baz;
|
||||
foo || (baz ?? baz);
|
||||
|
||||
(foo && baz) ?? baz;
|
||||
foo && (baz ?? baz);
|
||||
|
||||
@@ -5,8 +5,18 @@ const x = (foo, bar = foo ?? bar) => {};
|
||||
foo ? bar ?? foo : baz;
|
||||
|
||||
foo ?? (bar ?? baz);
|
||||
(foo ?? bar) ?? baz;
|
||||
|
||||
// Mixing ?? and (&& or ||) requires parens
|
||||
// It's a syntax error without it.
|
||||
(foo ?? baz) || baz;
|
||||
foo ?? (baz || baz);
|
||||
|
||||
(foo ?? baz) && baz;
|
||||
foo ?? (baz && baz);
|
||||
|
||||
(foo || baz) ?? baz;
|
||||
foo || (baz ?? baz);
|
||||
|
||||
(foo && baz) ?? baz;
|
||||
foo && (baz ?? baz);
|
||||
@@ -219,15 +219,19 @@ printWidth: 80
|
||||
|
||||
// Emoji.
|
||||
("🐶");
|
||||
|
||||
// Empty string.
|
||||
("");
|
||||
("");
|
||||
|
||||
// Single double quote.
|
||||
('"');
|
||||
('"');
|
||||
|
||||
// Single single quote.
|
||||
("'");
|
||||
("'");
|
||||
|
||||
// Unnecessary escapes.
|
||||
("'");
|
||||
('"');
|
||||
@@ -246,6 +250,7 @@ printWidth: 80
|
||||
("aa"); // consecutive unnecessarily escaped characters
|
||||
("aa"); // consecutive unnecessarily escaped characters
|
||||
("escaped \\u2030 ‰ (should not stay escaped)");
|
||||
|
||||
// Meaningful escapes
|
||||
("octal escapes \\0 \\1 \\2 \\3 \\4 \\5 \\6 \\7");
|
||||
("octal escapes \\0 \\1 \\2 \\3 \\4 \\5 \\6 \\7");
|
||||
@@ -257,30 +262,39 @@ printWidth: 80
|
||||
");
|
||||
("escaped \\u2028 \\
");
|
||||
("escaped \\u2029 \\
");
|
||||
|
||||
// One of each.
|
||||
("\\"'");
|
||||
("\\"'");
|
||||
|
||||
// One of each with unnecessary escapes.
|
||||
("\\"'");
|
||||
("\\"'");
|
||||
|
||||
// More double quotes than single quotes.
|
||||
('"\\'"');
|
||||
('"\\'"');
|
||||
|
||||
// More single quotes than double quotes.
|
||||
("\\"''");
|
||||
("\\"''");
|
||||
|
||||
// Two of each.
|
||||
("\\"\\"''");
|
||||
("\\"\\"''");
|
||||
|
||||
// Single backslash.
|
||||
("\\\\");
|
||||
("\\\\");
|
||||
|
||||
// Backslases.
|
||||
("\\"\\\\\\"\\\\\\\\\\" ''\\\\'\\\\'\\\\\\\\'");
|
||||
('\\'\\\\\\'\\\\\\\\\\' ""\\\\"\\\\"\\\\\\\\"');
|
||||
|
||||
// Somewhat more real-word example.
|
||||
("He's sayin': \\"How's it goin'?\\" Don't ask me why.");
|
||||
("He's sayin': \\"How's it goin'?\\" Don't ask me why.");
|
||||
|
||||
// Somewhat more real-word example 2.
|
||||
('var backslash = "\\\\", doubleQuote = \\'"\\';');
|
||||
('var backslash = "\\\\", doubleQuote = \\'"\\';');
|
||||
@@ -418,15 +432,19 @@ singleQuote: true
|
||||
|
||||
// Emoji.
|
||||
('🐶');
|
||||
|
||||
// Empty string.
|
||||
('');
|
||||
('');
|
||||
|
||||
// Single double quote.
|
||||
('"');
|
||||
('"');
|
||||
|
||||
// Single single quote.
|
||||
("'");
|
||||
("'");
|
||||
|
||||
// Unnecessary escapes.
|
||||
("'");
|
||||
('"');
|
||||
@@ -445,6 +463,7 @@ singleQuote: true
|
||||
('aa'); // consecutive unnecessarily escaped characters
|
||||
('aa'); // consecutive unnecessarily escaped characters
|
||||
('escaped \\u2030 ‰ (should not stay escaped)');
|
||||
|
||||
// Meaningful escapes
|
||||
('octal escapes \\0 \\1 \\2 \\3 \\4 \\5 \\6 \\7');
|
||||
('octal escapes \\0 \\1 \\2 \\3 \\4 \\5 \\6 \\7');
|
||||
@@ -456,30 +475,39 @@ singleQuote: true
|
||||
');
|
||||
('escaped \\u2028 \\
');
|
||||
('escaped \\u2029 \\
');
|
||||
|
||||
// One of each.
|
||||
('"\\'');
|
||||
('"\\'');
|
||||
|
||||
// One of each with unnecessary escapes.
|
||||
('"\\'');
|
||||
('"\\'');
|
||||
|
||||
// More double quotes than single quotes.
|
||||
('"\\'"');
|
||||
('"\\'"');
|
||||
|
||||
// More single quotes than double quotes.
|
||||
("\\"''");
|
||||
("\\"''");
|
||||
|
||||
// Two of each.
|
||||
('""\\'\\'');
|
||||
('""\\'\\'');
|
||||
|
||||
// Single backslash.
|
||||
('\\\\');
|
||||
('\\\\');
|
||||
|
||||
// Backslases.
|
||||
("\\"\\\\\\"\\\\\\\\\\" ''\\\\'\\\\'\\\\\\\\'");
|
||||
('\\'\\\\\\'\\\\\\\\\\' ""\\\\"\\\\"\\\\\\\\"');
|
||||
|
||||
// Somewhat more real-word example.
|
||||
("He's sayin': \\"How's it goin'?\\" Don't ask me why.");
|
||||
("He's sayin': \\"How's it goin'?\\" Don't ask me why.");
|
||||
|
||||
// Somewhat more real-word example 2.
|
||||
('var backslash = "\\\\", doubleQuote = \\'"\\';');
|
||||
('var backslash = "\\\\", doubleQuote = \\'"\\';');
|
||||
|
||||
@@ -55,6 +55,7 @@ printWidth: 80
|
||||
|
||||
"\\0",
|
||||
"🐶",
|
||||
|
||||
"\\uD801\\uDC28"
|
||||
];
|
||||
|
||||
@@ -117,6 +118,7 @@ trailingComma: "all"
|
||||
|
||||
"\\0",
|
||||
"🐶",
|
||||
|
||||
"\\uD801\\uDC28",
|
||||
];
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ exports[`show warning with unknown option (stdout) 1`] = `""`;
|
||||
exports[`show warning with unknown option (write) 1`] = `Array []`;
|
||||
|
||||
exports[`throw error for unsupported extension (stderr) 1`] = `
|
||||
"[error] Invalid configuration file: No sync loader specified for extension \\".unsupported\\"
|
||||
"[error] Invalid configuration file \`<cwd>/tests_integration/cli/config/invalid\`: No sync loader specified for extension \\".unsupported\\"
|
||||
"
|
||||
`;
|
||||
|
||||
@@ -28,7 +28,7 @@ exports[`throw error for unsupported extension (stdout) 1`] = `""`;
|
||||
exports[`throw error for unsupported extension (write) 1`] = `Array []`;
|
||||
|
||||
exports[`throw error with invalid config format (stderr) 1`] = `
|
||||
"[error] Invalid configuration file: Cannot find module '--invalid--' from '<cwd>/tests_integration/cli/config/invalid/file'
|
||||
"[error] Invalid configuration file \`<cwd>/tests_integration/cli/config/invalid\`: Cannot find module '--invalid--' from '<cwd>/tests_integration/cli/config/invalid/file'
|
||||
"
|
||||
`;
|
||||
|
||||
@@ -64,7 +64,7 @@ exports[`throw error with invalid config precedence option (configPrecedence) (s
|
||||
exports[`throw error with invalid config precedence option (configPrecedence) (write) 1`] = `Array []`;
|
||||
|
||||
exports[`throw error with invalid config target (directory) (stderr) 1`] = `
|
||||
"[error] Invalid configuration file: EISDIR: illegal operation on a directory, read
|
||||
"[error] Invalid configuration file \`<cwd>/tests_integration/cli/config/invalid\`: EISDIR: illegal operation on a directory, read
|
||||
"
|
||||
`;
|
||||
|
||||
|
||||
File renamed without changes.
@@ -0,0 +1,34 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[` 1`] = `
|
||||
"Snapshot Diff:
|
||||
- First value
|
||||
+ Second value
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
Defaults to avoid.
|
||||
--no-bracket-spacing Do not print spaces between brackets.
|
||||
--end-of-line <auto|lf|crlf|cr>
|
||||
Which end of line characters to apply.
|
||||
Defaults to auto.
|
||||
+ --foo-string <string> foo description
|
||||
+ Defaults to bar.
|
||||
--html-whitespace-sensitivity <css|strict|ignore>
|
||||
How to handle whitespaces in HTML.
|
||||
Defaults to css.
|
||||
--jsx-bracket-same-line Put > on the last line instead of at a new line.
|
||||
Defaults to false."
|
||||
`;
|
||||
|
||||
exports[`show detailed external option with \`--help foo-string\` (stderr) 1`] = `""`;
|
||||
|
||||
exports[`show detailed external option with \`--help foo-string\` (stdout) 1`] = `
|
||||
"--foo-string <string>
|
||||
|
||||
foo description
|
||||
|
||||
Default: bar
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`show detailed external option with \`--help foo-string\` (write) 1`] = `Array []`;
|
||||
@@ -1,5 +1,38 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`apply editorconfig for stdin-filepath with nonexistent directory (stderr) 1`] = `""`;
|
||||
|
||||
exports[`apply editorconfig for stdin-filepath with nonexistent directory (stdout) 1`] = `
|
||||
"function f() {
|
||||
console.log(\\"should be indented with a tab\\")
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`apply editorconfig for stdin-filepath with nonexistent directory (write) 1`] = `Array []`;
|
||||
|
||||
exports[`apply editorconfig for stdin-filepath with nonexistent file (stderr) 1`] = `""`;
|
||||
|
||||
exports[`apply editorconfig for stdin-filepath with nonexistent file (stdout) 1`] = `
|
||||
"function f() {
|
||||
console.log(\\"should be indented with a tab\\")
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`apply editorconfig for stdin-filepath with nonexistent file (write) 1`] = `Array []`;
|
||||
|
||||
exports[`don’t apply editorconfig outside project for stdin-filepath with nonexistent directory (stderr) 1`] = `""`;
|
||||
|
||||
exports[`don’t apply editorconfig outside project for stdin-filepath with nonexistent directory (stdout) 1`] = `
|
||||
"function f() {
|
||||
console.log(\\"should be indented with 2 spaces\\")
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`don’t apply editorconfig outside project for stdin-filepath with nonexistent directory (write) 1`] = `Array []`;
|
||||
|
||||
exports[`format correctly if stdin content compatible with stdin-filepath (stderr) 1`] = `""`;
|
||||
|
||||
exports[`format correctly if stdin content compatible with stdin-filepath (stdout) 1`] = `
|
||||
@@ -11,6 +44,17 @@ exports[`format correctly if stdin content compatible with stdin-filepath (stdou
|
||||
|
||||
exports[`format correctly if stdin content compatible with stdin-filepath (write) 1`] = `Array []`;
|
||||
|
||||
exports[`gracefully handle stdin-filepath with nonexistent directory (stderr) 1`] = `""`;
|
||||
|
||||
exports[`gracefully handle stdin-filepath with nonexistent directory (stdout) 1`] = `
|
||||
".name {
|
||||
display: none;
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`gracefully handle stdin-filepath with nonexistent directory (write) 1`] = `Array []`;
|
||||
|
||||
exports[`output file as-is if stdin-filepath matched patterns in ignore-path (stderr) 1`] = `""`;
|
||||
|
||||
exports[`output file as-is if stdin-filepath matched patterns in ignore-path (write) 1`] = `Array []`;
|
||||
|
||||
@@ -698,7 +698,7 @@ exports[`CLI --support-info (stdout) 1`] = `
|
||||
\\"since\\": \\"0.0.0\\",
|
||||
\\"tmScope\\": \\"source.js\\",
|
||||
\\"type\\": \\"programming\\",
|
||||
\\"vscodeLanguageIds\\": [\\"javascript\\"]
|
||||
\\"vscodeLanguageIds\\": [\\"javascript\\", \\"mongo\\"]
|
||||
},
|
||||
{
|
||||
\\"aceMode\\": \\"javascript\\",
|
||||
|
||||
+10
-16
@@ -5,7 +5,7 @@ const runPrettier = require("../runPrettier");
|
||||
expect.addSnapshotSerializer(require("../path-serializer"));
|
||||
|
||||
describe("multiple patterns", () => {
|
||||
runPrettier("cli/multiple-patterns", [
|
||||
runPrettier("cli/patterns", [
|
||||
"directory/**/*.js",
|
||||
"other-directory/**/*.js",
|
||||
"-l"
|
||||
@@ -15,7 +15,7 @@ describe("multiple patterns", () => {
|
||||
});
|
||||
|
||||
describe("multiple patterns with non exists pattern", () => {
|
||||
runPrettier("cli/multiple-patterns", [
|
||||
runPrettier("cli/patterns", [
|
||||
"directory/**/*.js",
|
||||
"non-existent.js",
|
||||
"-l"
|
||||
@@ -25,7 +25,7 @@ describe("multiple patterns with non exists pattern", () => {
|
||||
});
|
||||
|
||||
describe("multiple patterns with ignore nested directories pattern", () => {
|
||||
runPrettier("cli/multiple-patterns", [
|
||||
runPrettier("cli/patterns", [
|
||||
"**/*.js",
|
||||
"!**/nested-directory/**",
|
||||
"-l"
|
||||
@@ -35,25 +35,19 @@ describe("multiple patterns with ignore nested directories pattern", () => {
|
||||
});
|
||||
|
||||
describe("multiple patterns by with ignore pattern, ignores node_modules by default", () => {
|
||||
runPrettier("cli/multiple-patterns", ["**/*.js", "!directory/**", "-l"]).test(
|
||||
{
|
||||
status: 1
|
||||
}
|
||||
);
|
||||
runPrettier("cli/patterns", ["**/*.js", "!directory/**", "-l"]).test({
|
||||
status: 1
|
||||
});
|
||||
});
|
||||
|
||||
describe("multiple patterns by with ignore pattern, ignores node_modules by with ./**/*.js", () => {
|
||||
runPrettier("cli/multiple-patterns", [
|
||||
"./**/*.js",
|
||||
"!./directory/**",
|
||||
"-l"
|
||||
]).test({
|
||||
runPrettier("cli/patterns", ["./**/*.js", "!./directory/**", "-l"]).test({
|
||||
status: 1
|
||||
});
|
||||
});
|
||||
|
||||
describe("multiple patterns by with ignore pattern, doesn't ignore node_modules with --with-node-modules flag", () => {
|
||||
runPrettier("cli/multiple-patterns", [
|
||||
runPrettier("cli/patterns", [
|
||||
"**/*.js",
|
||||
"!directory/**",
|
||||
"-l",
|
||||
@@ -65,13 +59,13 @@ describe("multiple patterns by with ignore pattern, doesn't ignore node_modules
|
||||
|
||||
describe("no errors on empty patterns", () => {
|
||||
// --parser is mandatory if no filepath is passed
|
||||
runPrettier("cli/multiple-patterns", ["--parser", "babel"]).test({
|
||||
runPrettier("cli/patterns", ["--parser", "babel"]).test({
|
||||
status: 0
|
||||
});
|
||||
});
|
||||
|
||||
describe("multiple patterns, throw error and exit with non zero code on non existing files", () => {
|
||||
runPrettier("cli/multiple-patterns", [
|
||||
runPrettier("cli/patterns", [
|
||||
"non-existent.js",
|
||||
"other-non-existent.js",
|
||||
"-l"
|
||||
@@ -0,0 +1,56 @@
|
||||
"use strict";
|
||||
|
||||
const runPrettier = require("../runPrettier");
|
||||
const snapshotDiff = require("snapshot-diff");
|
||||
|
||||
describe("show external options with `--help`", () => {
|
||||
const originalStdout = runPrettier("plugins/options-string", ["--help"])
|
||||
.stdout;
|
||||
const pluggedStdout = runPrettier("plugins/options-string", [
|
||||
"--help",
|
||||
"--plugin=./plugin"
|
||||
]).stdout;
|
||||
expect(snapshotDiff(originalStdout, pluggedStdout)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe("show detailed external option with `--help foo-string`", () => {
|
||||
runPrettier("plugins/options-string", [
|
||||
"--plugin=./plugin",
|
||||
"--help",
|
||||
"foo-string"
|
||||
]).test({
|
||||
status: 0
|
||||
});
|
||||
});
|
||||
|
||||
describe("external options from CLI should work", () => {
|
||||
runPrettier(
|
||||
"plugins/options-string",
|
||||
[
|
||||
"--plugin=./plugin",
|
||||
"--stdin-filepath",
|
||||
"example.foo",
|
||||
"--foo-string",
|
||||
"baz"
|
||||
],
|
||||
{ input: "hello-world" }
|
||||
).test({
|
||||
stdout: "foo:baz",
|
||||
stderr: "",
|
||||
status: 0,
|
||||
write: []
|
||||
});
|
||||
});
|
||||
|
||||
describe("external options from config file should work", () => {
|
||||
runPrettier(
|
||||
"plugins/options-string",
|
||||
["--config=./config.json", "--stdin-filepath", "example.foo"],
|
||||
{ input: "hello-world" }
|
||||
).test({
|
||||
stdout: "foo:baz",
|
||||
stderr: "",
|
||||
status: 0,
|
||||
write: []
|
||||
});
|
||||
});
|
||||
@@ -22,6 +22,67 @@ describe("throw error if stdin content incompatible with stdin-filepath", () =>
|
||||
});
|
||||
});
|
||||
|
||||
describe("gracefully handle stdin-filepath with nonexistent directory", () => {
|
||||
runPrettier(
|
||||
"cli",
|
||||
["--stdin-filepath", "definitely/nonexistent/path.css"],
|
||||
{ input: ".name { display: none; }" } // css
|
||||
).test({
|
||||
status: 0
|
||||
});
|
||||
});
|
||||
|
||||
describe("apply editorconfig for stdin-filepath with nonexistent file", () => {
|
||||
runPrettier(
|
||||
"cli",
|
||||
["--stdin-filepath", "config/editorconfig/nonexistent.js"],
|
||||
{
|
||||
input: `
|
||||
function f() {
|
||||
console.log("should be indented with a tab");
|
||||
}
|
||||
`.trim() // js
|
||||
}
|
||||
).test({
|
||||
status: 0
|
||||
});
|
||||
});
|
||||
|
||||
describe("apply editorconfig for stdin-filepath with nonexistent directory", () => {
|
||||
runPrettier(
|
||||
"cli",
|
||||
["--stdin-filepath", "config/editorconfig/nonexistent/one/two/three.js"],
|
||||
{
|
||||
input: `
|
||||
function f() {
|
||||
console.log("should be indented with a tab");
|
||||
}
|
||||
`.trim() // js
|
||||
}
|
||||
).test({
|
||||
status: 0
|
||||
});
|
||||
});
|
||||
|
||||
describe("don’t apply editorconfig outside project for stdin-filepath with nonexistent directory", () => {
|
||||
runPrettier(
|
||||
"cli",
|
||||
[
|
||||
"--stdin-filepath",
|
||||
"config/editorconfig/repo-root/nonexistent/one/two/three.js"
|
||||
],
|
||||
{
|
||||
input: `
|
||||
function f() {
|
||||
console.log("should be indented with 2 spaces");
|
||||
}
|
||||
`.trim() // js
|
||||
}
|
||||
).test({
|
||||
status: 0
|
||||
});
|
||||
});
|
||||
|
||||
describe("output file as-is if stdin-filepath matched patterns in ignore-path", () => {
|
||||
runPrettier("cli/stdin-ignore", ["--stdin-filepath", "ignore/example.js"], {
|
||||
input: "hello_world( );"
|
||||
|
||||
File renamed without changes.
File renamed without changes.
Generated
Vendored
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,9 +1,18 @@
|
||||
"use strict";
|
||||
|
||||
const replaceCWD = text => {
|
||||
const cwd = process.cwd();
|
||||
while (text.indexOf(cwd) !== -1) {
|
||||
text = text.replace(cwd, "<cwd>");
|
||||
}
|
||||
|
||||
return text;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
test: value =>
|
||||
typeof value === "string" &&
|
||||
(value.indexOf("\\") > -1 || value.indexOf(process.cwd()) > -1),
|
||||
print: (value, serializer) =>
|
||||
serializer(value.replace(process.cwd(), "<cwd>").replace(/\\/g, "/"))
|
||||
serializer(replaceCWD(value).replace(/\\/g, "/"))
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"plugins": ["./plugin"],
|
||||
"fooString": "baz"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
languages: [
|
||||
{
|
||||
name: "foo",
|
||||
parsers: ["foo-parser"],
|
||||
extensions: [".foo"],
|
||||
since: "1.0.0"
|
||||
}
|
||||
],
|
||||
options: {
|
||||
fooString: {
|
||||
type: "string",
|
||||
default: "bar",
|
||||
description: "foo description"
|
||||
}
|
||||
},
|
||||
parsers: {
|
||||
"foo-parser": {
|
||||
parse: text => ({ text }),
|
||||
astFormat: "foo-ast"
|
||||
}
|
||||
},
|
||||
printers: {
|
||||
"foo-ast": {
|
||||
print: (path, options) =>
|
||||
options.fooString ? `foo:${options.fooString}` : path.getValue().text
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -3,6 +3,7 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const stripAnsi = require("strip-ansi");
|
||||
const SynchronousPromise = require("synchronous-promise").SynchronousPromise;
|
||||
|
||||
const isProduction = process.env.NODE_ENV === "production";
|
||||
const prettierRootDir = isProduction ? process.env.PRETTIER_DIR : "../";
|
||||
@@ -82,9 +83,9 @@ function runPrettier(dir, args, options) {
|
||||
// We cannot use `jest.setMock("get-stream", impl)` here, because in the
|
||||
// production build everything is bundled into one file so there is no
|
||||
// "get-stream" module to mock.
|
||||
jest.spyOn(require(thirdParty), "getStream").mockImplementation(() => ({
|
||||
then: handler => handler(options.input || "")
|
||||
}));
|
||||
jest
|
||||
.spyOn(require(thirdParty), "getStream")
|
||||
.mockImplementation(() => SynchronousPromise.resolve(options.input || ""));
|
||||
jest
|
||||
.spyOn(require(thirdParty), "isCI")
|
||||
.mockImplementation(() => process.env.CI);
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"noEmit": true,
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"resolveJsonModule": true,
|
||||
// TBD it is desired to enabled strict type checking at some point:
|
||||
"strict": false
|
||||
},
|
||||
"exclude": [
|
||||
// [TBD] JavaScript sources *not* affected by src/language-*:
|
||||
"src/main/ast-to-doc.js",
|
||||
"src/main/core.js",
|
||||
"src/common/create-ignorer.js",
|
||||
"src/common/parser-create-error.js",
|
||||
"src/config/resolve-config.js",
|
||||
"src/main/options-normalizer.js",
|
||||
"src/common/get-file-info.js",
|
||||
"src/main/multiparser.js",
|
||||
"src/main/options.js",
|
||||
// [TBD] src/language-* source directory trees with known JSDoc type issues:
|
||||
"src/language-css",
|
||||
"src/language-graphql",
|
||||
"src/language-handlebars",
|
||||
"src/language-html",
|
||||
"src/language-js",
|
||||
"src/language-markdown",
|
||||
"src/language-yaml",
|
||||
// [TBD] JavaScript sources affected by JSDoc issues in src/language-*:
|
||||
"src/common/internal-plugins.js",
|
||||
"src/common/load-plugins.js",
|
||||
"src/cli/index.js",
|
||||
"src/cli/util.js",
|
||||
// [TBD] top-level JavaScript sources affected by JSDoc issues
|
||||
// in other sources:
|
||||
"src/index.js",
|
||||
"src/standalone.js",
|
||||
"index.js",
|
||||
"standalone.js",
|
||||
"bin/",
|
||||
"dist/",
|
||||
"docs/",
|
||||
"scripts/",
|
||||
"tests/",
|
||||
"tests_config/",
|
||||
"tests_integration/",
|
||||
"website/"
|
||||
]
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
- image: "/images/editors/editor_emacs.svg"
|
||||
name: Emacs
|
||||
content: |
|
||||
[`prettier-emacs`](https://github.com/prettier/prettier-emacs)
|
||||
[`prettier-js`](https://github.com/prettier/prettier-emacs)
|
||||
- image: /images/editors/editor_espresso.svg
|
||||
name: Espresso
|
||||
content: |
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "7.6.3",
|
||||
"@babel/preset-react": "7.6.3",
|
||||
"@babel/preset-react": "7.7.0",
|
||||
"@sandhose/prettier-animated-logo": "1.0.3",
|
||||
"babel-loader": "8.0.6",
|
||||
"concurrently": "5.0.0",
|
||||
@@ -28,6 +28,6 @@
|
||||
"js-yaml": "3.13.1",
|
||||
"svgo": "1.3.2",
|
||||
"webpack": "4.41.2",
|
||||
"webpack-cli": "3.3.9"
|
||||
"webpack-cli": "3.3.10"
|
||||
}
|
||||
}
|
||||
@@ -12,12 +12,12 @@ Prettier is an opinionated code formatter with support for:
|
||||
- [Vue](https://vuejs.org/)
|
||||
- [Flow](https://flow.org/)
|
||||
- [TypeScript](https://www.typescriptlang.org/)
|
||||
- CSS, [Less](http://lesscss.org/), and [SCSS](http://sass-lang.com)
|
||||
- CSS, [Less](http://lesscss.org/), and [SCSS](https://sass-lang.com)
|
||||
- [HTML](https://en.wikipedia.org/wiki/HTML)
|
||||
- [JSON](http://json.org/)
|
||||
- [GraphQL](http://graphql.org/)
|
||||
- [Markdown](http://commonmark.org/), including [GFM](https://github.github.com/gfm/) and [MDX](https://mdxjs.com/)
|
||||
- [YAML](http://yaml.org/)
|
||||
- [GraphQL](https://graphql.org/)
|
||||
- [Markdown](https://commonmark.org/), including [GFM](https://github.github.com/gfm/) and [MDX](https://mdxjs.com/)
|
||||
- [YAML](https://yaml.org/)
|
||||
|
||||
It removes all original styling[\*](#footnotes) and ensures that all outputted code conforms to a consistent style. (See this [blog post](http://jlongster.com/A-Prettier-Formatter))
|
||||
|
||||
|
||||
@@ -228,28 +228,31 @@ defaultOptions: {
|
||||
|
||||
A `util` module from Prettier core is considered a private API and is not meant to be consumed by plugins. Instead, the `util-shared` module provides the following limited set of utility functions for plugins:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```ts
|
||||
getMaxContinuousCount(str: string, target: string): number;
|
||||
getStringWidth(text: string): number;
|
||||
getAlignmentSize(value: string, tabWidth: number, startIndex: number): number;
|
||||
getIndentSize(value: string, tabWidth: number): number;
|
||||
skip(chars: string|RegExp): number;
|
||||
skipWhitespace(text: string, index: number, options: object): number;
|
||||
skipSpaces(text: string, index: number, options: object): number;
|
||||
skipToLineEnd(text: string, index: number, options: object): number;
|
||||
skipEverythingButNewLine(text: string, index: number, options: object): number;
|
||||
skipInlineComment(text: string, index: number): number;
|
||||
skipTrailingComment(text: string, index: number): number;
|
||||
skipNewline(text: string, index: number, options: object): number;
|
||||
hasNewline(text: string, index: number, options: object): boolean;
|
||||
hasNewlineInRange(text: string, start: number, start: number): boolean;
|
||||
hasSpaces(text: string, index: number, options: object): number;
|
||||
makeString(rawContent: string, enclosingQuote: string, unescapeUnnecessarEscapes: boolean): string;
|
||||
getNextNonSpaceNonCommentCharacterIndex(text: string, node: object, options: object): number;
|
||||
isNextLineEmptyAfterIndex(text: string, index: number): boolean;
|
||||
isNextLineEmpty(text: string, node: object, options: object): boolean;
|
||||
isPreviousLineEmpty(text: string, node: object, options: object): boolean;
|
||||
mapDoc(doc: object, callback: function): void;
|
||||
type Quote = '"' | "'";
|
||||
type SkipOptions = { backwards?: boolean };
|
||||
function getMaxContinuousCount(str: string, target: string): number;
|
||||
function getStringWidth(text: string): number;
|
||||
function getAlignmentSize(value: string, tabWidth: number, startIndex?: number): number;
|
||||
function getIndentSize(value: string, tabWidth: number): number;
|
||||
function skip(chars: string | RegExp): (text: string, index: number | false, opts?: SkipOptions) => number | false;
|
||||
function skipWhitespace(text: string, index: number | false, opts?: SkipOptions): number | false;
|
||||
function skipSpaces(text: string, index: number | false, opts?: SkipOptions): number | false;
|
||||
function skipToLineEnd(text: string, index: number | false, opts?: SkipOptions): number | false;
|
||||
function skipEverythingButNewLine(text: string, index: number | false, opts?: SkipOptions): number | false;
|
||||
function skipInlineComment(text: string, index: number | false): number | false;
|
||||
function skipTrailingComment(text: string, index: number | false): number | false;
|
||||
function skipNewline(text: string, index: number | false, opts?: SkipOptions): number | false;
|
||||
function hasNewline(text: string, index: number, opts?: SkipOptions): boolean;
|
||||
function hasNewlineInRange(text: string, start: number, end: number): boolean;
|
||||
function hasSpaces(text: string, index: number, opts?: SkipOptions): boolean;
|
||||
function makeString(rawContent: string, enclosingQuote: Quote, unescapeUnnecessaryEscapes?: boolean): string;
|
||||
function getNextNonSpaceNonCommentCharacterIndex<N>(text: string, node: N, locEnd: (node: N) => number): number | false;
|
||||
function isNextLineEmptyAfterIndex(text: string, index: number): boolean;
|
||||
function isNextLineEmpty<N>(text: string, node: N, locEnd: (node: N) => number): boolean;
|
||||
function isPreviousLineEmpty<N>(text: string, node: N, locStart: (node: N) => number): boolean;
|
||||
function mapDoc(doc: object, callback: function): void;
|
||||
```
|
||||
|
||||
### Tutorials
|
||||
|
||||
Loaded 100 of 102 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user