Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80713 views
1
import {isArray} from "../utils";
2
3
try {
4
var SourceMap = require('source-map'),
5
SourceNode = SourceMap.SourceNode;
6
} catch (err) {
7
/* istanbul ignore next: tested but not covered in istanbul due to dist build */
8
SourceNode = function(line, column, srcFile, chunks) {
9
this.src = '';
10
if (chunks) {
11
this.add(chunks);
12
}
13
};
14
/* istanbul ignore next */
15
SourceNode.prototype = {
16
add: function(chunks) {
17
if (isArray(chunks)) {
18
chunks = chunks.join('');
19
}
20
this.src += chunks;
21
},
22
prepend: function(chunks) {
23
if (isArray(chunks)) {
24
chunks = chunks.join('');
25
}
26
this.src = chunks + this.src;
27
},
28
toStringWithSourceMap: function() {
29
return {code: this.toString()};
30
},
31
toString: function() {
32
return this.src;
33
}
34
};
35
}
36
37
38
function castChunk(chunk, codeGen, loc) {
39
if (isArray(chunk)) {
40
var ret = [];
41
42
for (var i = 0, len = chunk.length; i < len; i++) {
43
ret.push(codeGen.wrap(chunk[i], loc));
44
}
45
return ret;
46
} else if (typeof chunk === 'boolean' || typeof chunk === 'number') {
47
// Handle primitives that the SourceNode will throw up on
48
return chunk+'';
49
}
50
return chunk;
51
}
52
53
54
function CodeGen(srcFile) {
55
this.srcFile = srcFile;
56
this.source = [];
57
}
58
59
CodeGen.prototype = {
60
prepend: function(source, loc) {
61
this.source.unshift(this.wrap(source, loc));
62
},
63
push: function(source, loc) {
64
this.source.push(this.wrap(source, loc));
65
},
66
67
merge: function() {
68
var source = this.empty();
69
this.each(function(line) {
70
source.add([' ', line, '\n']);
71
});
72
return source;
73
},
74
75
each: function(iter) {
76
for (var i = 0, len = this.source.length; i < len; i++) {
77
iter(this.source[i]);
78
}
79
},
80
81
empty: function(loc) {
82
loc = loc || this.currentLocation || {start:{}};
83
return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
84
},
85
wrap: function(chunk, loc) {
86
if (chunk instanceof SourceNode) {
87
return chunk;
88
}
89
90
loc = loc || this.currentLocation || {start:{}};
91
chunk = castChunk(chunk, this, loc);
92
93
return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk);
94
},
95
96
functionCall: function(fn, type, params) {
97
params = this.generateList(params);
98
return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']);
99
},
100
101
quotedString: function(str) {
102
return '"' + (str + '')
103
.replace(/\\/g, '\\\\')
104
.replace(/"/g, '\\"')
105
.replace(/\n/g, '\\n')
106
.replace(/\r/g, '\\r')
107
.replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
108
.replace(/\u2029/g, '\\u2029') + '"';
109
},
110
111
objectLiteral: function(obj) {
112
var pairs = [];
113
114
for (var key in obj) {
115
if (obj.hasOwnProperty(key)) {
116
var value = castChunk(obj[key], this);
117
if (value !== 'undefined') {
118
pairs.push([this.quotedString(key), ':', value]);
119
}
120
}
121
}
122
123
var ret = this.generateList(pairs);
124
ret.prepend('{');
125
ret.add('}');
126
return ret;
127
},
128
129
130
generateList: function(entries, loc) {
131
var ret = this.empty(loc);
132
133
for (var i = 0, len = entries.length; i < len; i++) {
134
if (i) {
135
ret.add(',');
136
}
137
138
ret.add(castChunk(entries[i], this, loc));
139
}
140
141
return ret;
142
},
143
144
generateArray: function(entries, loc) {
145
var ret = this.generateList(entries, loc);
146
ret.prepend('[');
147
ret.add(']');
148
149
return ret;
150
}
151
};
152
153
export default CodeGen;
154
155
156