-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
116 lines (99 loc) · 2.68 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
const prettier = require('prettier')
const has = require('has')
const SourceMapGenerator = require('source-map').SourceMapGenerator
const optionKeys = [
'printWidth',
'tabWidth',
'useTabs',
'semi',
'singleQuote',
'quoteProps',
'jsxSingleQuote',
'trailingComma',
'bracketSpacing',
'jsxBracketSameLine',
'arrowParens',
'requirePragma',
'insertPragma',
'endOfLine'
]
function print (parse, ast, opts, input) {
const formatOpts = {
// By using a custom parser we can use the already parsed AST.
// This is better than using __debug.formatAST, because this way prettier still handles comments;
// comments would be lost when using the formatAST API.
parser: function () {
return ast
}
}
const filename = opts.sourceFileName
for (let i = 0; i < optionKeys.length; i++) {
if (has(opts, optionKeys[i])) {
formatOpts[optionKeys[i]] = opts[optionKeys[i]]
}
}
const result = prettier.format(input, formatOpts)
let map = null
if (opts.sourceMaps) {
const parsed = parse(result)
map = generateSourceMap(ast, parsed, {
file: filename,
source: input
})
}
return {
code: result,
map: map
}
}
module.exports = function generatorPrettier (api) {
api.assertVersion(7)
let parseOptions = {}
function parse (code) {
return api.parseSync(code, parseOptions.parserOpts)
}
return {
manipulateOptions: function (opts) {
parseOptions = opts
},
generatorOverride: print.bind(null, parse)
}
}
function isNode (node) {
return typeof node === 'object' && node && typeof node.type === 'string'
}
function generateSourceMap (left, right, opts) {
const generator = new SourceMapGenerator({ file: opts.file })
generator.setSourceContent(opts.file, opts.input)
walk(left, right, function (sourceNode, formattedNode) {
generator.addMapping({
source: opts.file,
original: sourceNode.loc.start,
generated: formattedNode.loc.start
})
generator.addMapping({
source: opts.file,
original: sourceNode.loc.end,
generated: formattedNode.loc.end
})
})
return generator.toJSON()
function walk (left, right, visit) {
const cont = visit(left, right)
if (cont === false) return
for (const k in left) {
if (has(left, k)) {
if (isNode(left[k]) && isNode(right[k])) {
walk(left[k], right[k], visit)
} else if (Array.isArray(left[k]) && Array.isArray(right[k])) {
walkArray(left[k], right[k], visit)
}
}
}
}
function walkArray (left, right, visit) {
for (let i = 0; i < left.length; i++) {
if (isNode(left[i]) && isNode(right[i])) walk(left[i], right[i], visit)
}
}
}