UNPKG

2.94 kBJavaScriptView Raw
1class SourceBuffer {
2 constructor () {
3 this.buffer = []
4 this.locationMap = []
5 this.line = 1
6 this.column = 1
7 this.indention = 0
8 this.indentionSize = 2
9 }
10
11 write (str, defaultValue) {
12 if (!str) {
13 if (defaultValue) {
14 this.write(defaultValue)
15 }
16
17 return this
18 }
19
20 if (typeof str === 'object') {
21 str.compile(this)
22 return this
23 }
24
25 const lastIndex = str.lastIndexOf('\n')
26 if (lastIndex === -1) {
27 this.column += str.length
28 } else {
29 this.column = str.length - lastIndex
30 this.line += (str.split('\n').length - 1)
31 }
32
33 this.buffer.push(str)
34 return this
35 }
36
37 writeItem (item) {
38 if (item.leadingComments && item.leadingComments.length) {
39 this.writeComments(item.leadingComments)
40 this.indent()
41 }
42
43 item.compile(this)
44
45 if (item.trailingComments && item.trailingComments.length) {
46 this.indent()
47 this.writeComments(item.trailingComments)
48 }
49 }
50
51 writeComments (comments, joiner) {
52 if (comments && comments.length > 0) {
53 comments.forEach((comment, index) => {
54 if (index) {
55 joiner === undefined ? this.indent() : this.write(joiner)
56 }
57
58 this.write(comment)
59 })
60 }
61 }
62
63 nl (num = 1) {
64 this.line += num
65 this.column = 1
66
67 this.buffer.push('\n'.repeat(num))
68 return this
69 }
70
71 getLocation () {
72 return [ this.line, this.column ]
73 }
74
75 getIndent () {
76 // console.log('INDENT', this.indention, this.indentionSize, `"${' '.repeat(this.indention * this.indentionSize)}"`)
77 return '\n' + ' '.repeat(this.indention * this.indentionSize)
78 }
79
80 indent (size, noWrite) {
81 size = size || 0
82 this.indention += size
83
84 if (!noWrite) {
85 this.write(this.getIndent())
86 }
87 }
88
89 item (node) {
90 node.compile(this)
91 return this
92 }
93
94 loop (arr, joiner = this.getIndent(), fn) {
95 if (arr) {
96 arr.forEach((item, index) => {
97 if (index > 0) {
98 this.write(joiner)
99 }
100
101 this.writeItem(item)
102 })
103 }
104
105 return this
106 }
107
108 registerItem (origLocation, name) {
109 if (origLocation) {
110 const map = [
111 origLocation.line,
112 origLocation.column,
113 this.line,
114 this.column
115 ]
116
117 if (typeof name === 'string') {
118 map.push(name)
119 }
120
121 this.locationMap.push(map)
122 }
123
124 return this
125 }
126
127 toString () {
128 return this.buffer.join('')
129 }
130
131 print () {
132 console.log(this.buffer.slice(-5))
133 }
134
135 createLocationMap () {
136 if (this.locationMap.length === 0) {
137 return
138 }
139
140 this.write('module.exports.__fsLocationMap = [')
141 this.write(this.locationMap.map((item) => {
142 const args = item.slice(0, 4)
143 if (item[4]) {
144 args.push(`'${item[4].replace(/'/g, '\\\'')}'`)
145 }
146
147 return `[${args.join(', ')}]`
148 }).join(', '))
149
150 this.write('];')
151 }
152}
153
154module.exports = SourceBuffer