Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81169 views
1
var assert = require("assert");
2
var types = require("./types");
3
var n = types.namedTypes;
4
var b = types.builders;
5
var isObject = types.builtInTypes.object;
6
var isArray = types.builtInTypes.array;
7
var isFunction = types.builtInTypes.function;
8
var Patcher = require("./patcher").Patcher;
9
var normalizeOptions = require("./options").normalize;
10
var fromString = require("./lines").fromString;
11
var attachComments = require("./comments").attach;
12
13
exports.parse = function parse(source, options) {
14
options = normalizeOptions(options);
15
16
var lines = fromString(source, options);
17
18
var sourceWithoutTabs = lines.toString({
19
tabWidth: options.tabWidth,
20
reuseWhitespace: false,
21
useTabs: false
22
});
23
24
var program = options.esprima.parse(sourceWithoutTabs, {
25
loc: true,
26
range: options.range,
27
comment: true,
28
tolerant: options.tolerant,
29
sourceType: 'module'
30
});
31
32
var comments = program.comments;
33
delete program.comments;
34
35
// In order to ensure we reprint leading and trailing program
36
// comments, wrap the original Program node with a File node.
37
var file = b.file(program);
38
file.loc = {
39
lines: lines,
40
indent: 0,
41
start: lines.firstPos(),
42
end: lines.lastPos()
43
};
44
45
// Return a copy of the original AST so that any changes made may be
46
// compared to the original.
47
var copy = new TreeCopier(lines).copy(file);
48
49
// Attach comments to the copy rather than the original.
50
attachComments(comments, copy, lines);
51
52
return copy;
53
};
54
55
function TreeCopier(lines) {
56
assert.ok(this instanceof TreeCopier);
57
this.lines = lines;
58
this.indent = 0;
59
}
60
61
var TCp = TreeCopier.prototype;
62
63
TCp.copy = function(node) {
64
if (isArray.check(node)) {
65
return node.map(this.copy, this);
66
}
67
68
if (!isObject.check(node)) {
69
return node;
70
}
71
72
if ((n.MethodDefinition && n.MethodDefinition.check(node)) ||
73
(n.Property.check(node) && (node.method || node.shorthand))) {
74
// If the node is a MethodDefinition or a .method or .shorthand
75
// Property, then the location information stored in
76
// node.value.loc is very likely untrustworthy (just the {body}
77
// part of a method, or nothing in the case of shorthand
78
// properties), so we null out that information to prevent
79
// accidental reuse of bogus source code during reprinting.
80
node.value.loc = null;
81
82
if (n.FunctionExpression.check(node.value)) {
83
// FunctionExpression method values should be anonymous,
84
// because their .id fields are ignored anyway.
85
node.value.id = null;
86
}
87
}
88
89
var copy = Object.create(Object.getPrototypeOf(node), {
90
original: { // Provide a link from the copy to the original.
91
value: node,
92
configurable: false,
93
enumerable: false,
94
writable: true
95
}
96
});
97
98
var loc = node.loc;
99
var oldIndent = this.indent;
100
var newIndent = oldIndent;
101
102
if (loc) {
103
if (loc.start.line < 1) {
104
loc.start.line = 1;
105
}
106
107
if (loc.end.line < 1) {
108
loc.end.line = 1;
109
}
110
111
if (this.lines.isPrecededOnlyByWhitespace(loc.start)) {
112
newIndent = this.indent = loc.start.column;
113
}
114
115
loc.lines = this.lines;
116
loc.indent = newIndent;
117
}
118
119
var keys = Object.keys(node);
120
var keyCount = keys.length;
121
for (var i = 0; i < keyCount; ++i) {
122
var key = keys[i];
123
if (key === "loc") {
124
copy[key] = node[key];
125
} else if (key === "comments") {
126
// Handled below.
127
} else {
128
copy[key] = this.copy(node[key]);
129
}
130
}
131
132
this.indent = oldIndent;
133
134
if (node.comments) {
135
Object.defineProperty(copy, "comments", {
136
value: node.comments,
137
enumerable: false
138
});
139
}
140
141
return copy;
142
};
143
144