Skip to content
This repository was archived by the owner on Sep 21, 2019. It is now read-only.

Commit 0ef45c4

Browse files
committed
Pretty print using prettier
1 parent 1204fea commit 0ef45c4

File tree

48 files changed

+3459
-463
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3459
-463
lines changed

.vscode/launch.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
"env": {
88
"NODE_ENV": "test"
99
},
10-
"externalConsole": false,
10+
"console": "internalConsole",
1111
"name": "Run Tests",
12-
"outDir": "${workspaceRoot}/dist",
13-
"preLaunchTask": "compile",
12+
"outFiles": ["${workspaceRoot}/dist"],
13+
"preLaunchTask": "tsc",
1414
"program": "${workspaceRoot}/node_modules/.bin/jest",
1515
"request": "launch",
1616
"runtimeArgs": [],

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"transform": {
2323
".ts": "<rootDir>/node_modules/ts-jest/preprocessor.js"
2424
},
25-
"testRegex": "test/runner.ts",
25+
"testRegex": "(/tests/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
2626
"moduleFileExtensions": ["ts", "js"]
2727
},
2828
"lint-staged": {
@@ -34,22 +34,26 @@
3434
"dependencies": {
3535
"chalk": "^1.1.3",
3636
"commander": "^2.10.0",
37+
"detect-indent": "^5.0.0",
3738
"glob": "^7.1.2",
3839
"lodash": "^4.17.4",
40+
"prettier": "^1.10.2",
3941
"typescript": "^2.6.2"
4042
},
4143
"devDependencies": {
4244
"@types/chalk": "^0.4.31",
4345
"@types/commander": "^2.9.1",
46+
"@types/detect-indent": "^5.0.0",
4447
"@types/glob": "^5.0.30",
4548
"@types/jest": "^20.0.2",
4649
"@types/lodash": "^4.14.93",
4750
"@types/node": "^8.0.2",
51+
"@types/prettier": "^1.10.0",
4852
"@types/react": "^15.0.31",
53+
"dedent": "^0.7.0",
4954
"husky": "^0.14.3",
5055
"jest": "^20.0.4",
5156
"lint-staged": "^6.0.1",
52-
"prettier": "^1.10.2",
5357
"ts-jest": "^20.0.6",
5458
"ts-node": "^3.1.0",
5559
"tslint": "^5.2.0"

src/cli.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ import { run } from '.';
99

1010
program
1111
.version('1.0.0')
12+
.option('--arrow-parens <avoid|always>', 'Include parentheses around a sole arrow function parameter.', 'avoid')
13+
.option('--no-bracket-spacing', 'Do not print spaces between brackets.', false)
14+
.option('--jsx-bracket-same-line', 'Put > on the last line instead of at a new line.', false)
15+
.option('--print-width <int>', 'The line length where Prettier will try wrap.', 80)
16+
.option('--prose-wrap <always|never|preserve> How to wrap prose. (markdown)', 'preserve')
17+
.option('--no-semi', 'Do not print semicolons, except at the beginning of lines which may need them', false)
18+
.option('--single-quote', 'Use single quotes instead of double quotes.', false)
19+
.option('--tab-width <int>', 'Number of spaces per indentation level.', 2)
20+
.option('--trailing-comma <none|es5|all>', 'Print trailing commas wherever possible when multi-line.', 'none')
21+
.option('--use-tabs', 'Indent with tabs instead of spaces.', false)
1222
.usage('[options] <filename or glob>')
1323
.command('* <glob>')
1424
.action(globPattern => {

src/compiler.ts

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1+
import * as os from 'os';
2+
import * as fs from 'fs';
13
import * as ts from 'typescript';
24
import * as chalk from 'chalk';
5+
import * as _ from 'lodash';
6+
import * as prettier from 'prettier';
7+
import * as detectIndent from 'detect-indent';
38

49
import { TransformFactoryFactory } from '.';
510

611
/**
712
* Compile and return result TypeScript
813
* @param filePath Path to file to compile
914
*/
10-
export function compile(filePath: string, factoryFactories: TransformFactoryFactory[]) {
15+
export function compile(
16+
filePath: string,
17+
factoryFactories: TransformFactoryFactory[],
18+
incomingPrettierOptions: prettier.Options = {},
19+
) {
1120
const compilerOptions: ts.CompilerOptions = {
1221
target: ts.ScriptTarget.ES2017,
1322
module: ts.ModuleKind.ES2015,
@@ -42,5 +51,69 @@ export function compile(filePath: string, factoryFactories: TransformFactoryFact
4251
const printer = ts.createPrinter();
4352

4453
// TODO: fix the index 0 access... What if program have multiple source files?
45-
return printer.printNode(ts.EmitHint.SourceFile, result.transformed[0], sourceFiles[0]);
54+
const printed = printer.printNode(ts.EmitHint.SourceFile, result.transformed[0], sourceFiles[0]);
55+
56+
const inputSource = fs.readFileSync(filePath, 'utf-8');
57+
const prettierOptions = getPrettierOptions(filePath, inputSource, incomingPrettierOptions);
58+
59+
return prettier.format(printed, incomingPrettierOptions);
60+
}
61+
62+
/**
63+
* Get Prettier options based on style of a JavaScript
64+
* @param filePath Path to source file
65+
* @param source Body of a JavaScript
66+
* @param options Existing prettier option
67+
*/
68+
export function getPrettierOptions(filePath: string, source: string, options: prettier.Options): prettier.Options {
69+
const resolvedOptions = prettier.resolveConfig.sync(filePath);
70+
if (resolvedOptions) {
71+
return resolvedOptions;
72+
}
73+
const { amount: indentAmount, type: indentType } = detectIndent(source);
74+
const sourceWidth = getCodeWidth(source, 80);
75+
const semi = getUseOfSemi(source);
76+
const quotations = getQuotation(source);
77+
78+
_.defaults(options, {
79+
tabWidth: indentAmount,
80+
useTabs: indentType && indentType === 'tab',
81+
printWidth: sourceWidth,
82+
semi,
83+
singleQuote: quotations === 'single',
84+
});
85+
86+
return options;
87+
}
88+
89+
/**
90+
* Given body of a source file, return its code width
91+
* @param source
92+
*/
93+
function getCodeWidth(source: string, defaultWidth: number): number {
94+
return source.split(os.EOL).reduce((result, line) => Math.max(result, line.length), defaultWidth);
95+
}
96+
97+
/**
98+
* Detect if a source file is using semicolon
99+
* @todo: use an actual parser. This is not a proper implementation
100+
* @param source
101+
* @return true if code is using semicolons
102+
*/
103+
function getUseOfSemi(source: string): boolean {
104+
return source.indexOf(';') !== -1;
105+
}
106+
107+
/**
108+
* Detect if a source file is using single quotes or double quotes
109+
* @todo use an actual parser. This is not a proper implementation
110+
* @param source
111+
*/
112+
function getQuotation(source: string): 'single' | 'double' {
113+
const numberOfSingleQuotes = (source.match(/\'/g) || []).length;
114+
const numberOfDoubleQuotes = (source.match(/\"/g) || []).length;
115+
if (numberOfSingleQuotes > numberOfDoubleQuotes) {
116+
return 'single';
117+
}
118+
return 'double';
46119
}

src/untyped-modules.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
declare module 'dedent';
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
type Foo = {
2-
foo: string;
3-
stuff: boolean;
4-
other: () => void;
5-
bar: number;
6-
[key: string]: number;
2+
foo: string,
3+
stuff: boolean,
4+
other: () => void,
5+
bar: number,
6+
[key: string]: number
77
};
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
type Foo = {
2-
};
1+
type Foo = {};
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
type Foo = {
2-
foo: string;
3-
bar: number;
2+
foo: string,
3+
bar: number
44
};
55
type Bar = {
6-
foo: number;
7-
bar: string;
6+
foo: number,
7+
bar: string
88
};
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
type Foo = {
2-
foo: string;
3-
bar: number;
2+
foo: string,
3+
bar: number
44
};

test/end-to-end/basic/output.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import * as React from 'react';
2-
export default class MyComponent extends React.Component<{
3-
}, {
4-
}> {
5-
render() {
6-
return <div />;
7-
}
1+
import * as React from "react";
2+
export default class MyComponent extends React.Component<{}, {}> {
3+
render() {
4+
return <div />;
5+
}
86
}
Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
import * as React from 'react';
1+
import * as React from "react";
22
type MyComponentProps = {
3-
baz: string;
3+
baz: string
44
};
55
type MyComponentState = {
6-
dynamicState: number;
7-
foo: number;
8-
bar: string;
6+
dynamicState: number,
7+
foo: number,
8+
bar: string
99
};
10-
export default class MyComponent extends React.Component<MyComponentProps, MyComponentState> {
11-
state = { foo: 1, bar: 'str' };
12-
render() {
13-
return <div />;
14-
}
15-
otherFn() {
16-
this.setState({ dynamicState: 42 });
17-
}
10+
export default class MyComponent extends React.Component<
11+
MyComponentProps,
12+
MyComponentState
13+
> {
14+
state = { foo: 1, bar: "str" };
15+
render() {
16+
return <div />;
17+
}
18+
otherFn() {
19+
this.setState({ dynamicState: 42 });
20+
}
1821
}
Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
import * as React from 'react';
1+
import * as React from "react";
22
type MyComponentProps = {
3-
baz: string;
3+
baz: string
44
};
55
type MyComponentState = {
6-
foo: number;
7-
bar: string;
6+
foo: number,
7+
bar: string
88
};
9-
export default class MyComponent extends React.Component<MyComponentProps, MyComponentState> {
10-
state = { foo: 1, bar: 'str' };
11-
render() {
12-
return <div />;
13-
}
9+
export default class MyComponent extends React.Component<
10+
MyComponentProps,
11+
MyComponentState
12+
> {
13+
state = { foo: 1, bar: "str" };
14+
render() {
15+
return <div />;
16+
}
1417
}
Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,35 @@
11
type HelloProps = {
2-
message?: string;
2+
message?: string
33
};
44
const Hello: React.SFC<HelloProps> = ({ message }) => {
5-
return <div>hello {message}</div>;
5+
return <div>hello {message}</div>;
66
};
77
type HeyProps = {
8-
message?: string;
8+
message?: string
99
};
1010
const Hey: React.SFC<HeyProps> = ({ name }) => {
11-
return <div>hey, {name}</div>;
11+
return <div>hey, {name}</div>;
1212
};
1313
type MyComponentState = {
14-
foo: number;
15-
bar: number;
14+
foo: number,
15+
bar: number
1616
};
17-
export default class MyComponent extends React.Component<{
18-
}, MyComponentState> {
19-
render() {
20-
return <button onClick={this.onclick.bind(this)}/>;
21-
}
22-
onclick() {
23-
this.setState({ foo: 1, bar: 2 });
24-
}
17+
export default class MyComponent extends React.Component<{}, MyComponentState> {
18+
render() {
19+
return <button onClick={this.onclick.bind(this)} />;
20+
}
21+
onclick() {
22+
this.setState({ foo: 1, bar: 2 });
23+
}
2524
}
2625
type AnotherComponentProps = {
27-
foo: string;
26+
foo: string
2827
};
29-
export class AnotherComponent extends React.Component<AnotherComponentProps, {
30-
}> {
31-
render() {
32-
return <div />;
33-
}
28+
export class AnotherComponent extends React.Component<
29+
AnotherComponentProps,
30+
{}
31+
> {
32+
render() {
33+
return <div />;
34+
}
3435
}

test/end-to-end/non-react/output.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
class Foo {
2-
render() {
3-
return '100';
4-
}
2+
render() {
3+
return "100";
4+
}
55
}
66
class Bar extends Foo {
7-
baz() {
8-
}
7+
baz() {}
98
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
type HelloProps = {
2-
message?: string;
2+
message?: string
33
};
44
const Hello: React.SFC<HelloProps> = ({ message }) => {
5-
return <div>hello {message}</div>;
5+
return <div>hello {message}</div>;
66
};
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
type HelloProps = {
2-
message?: string;
2+
message?: string
33
};
44
export const Hello: React.SFC<HelloProps> = ({ message }) => {
5-
return <div>hello {message}</div>;
5+
return <div>hello {message}</div>;
66
};

0 commit comments

Comments
 (0)