Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80540 views
1
/**
2
* Copyright 2013 Facebook, Inc.
3
*
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
7
*
8
* http://www.apache.org/licenses/LICENSE-2.0
9
*
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
15
*/
16
17
/*jslint node:true*/
18
19
/**
20
* @typechecks
21
*/
22
'use strict';
23
24
var Syntax = require('esprima-fb').Syntax;
25
var utils = require('../src/utils');
26
27
/**
28
* http://people.mozilla.org/~jorendorff/es6-draft.html#sec-12.1.9
29
*/
30
function visitTemplateLiteral(traverse, node, path, state) {
31
var templateElements = node.quasis;
32
33
utils.append('(', state);
34
for (var ii = 0; ii < templateElements.length; ii++) {
35
var templateElement = templateElements[ii];
36
if (templateElement.value.raw !== '') {
37
utils.append(getCookedValue(templateElement), state);
38
if (!templateElement.tail) {
39
// + between element and substitution
40
utils.append(' + ', state);
41
}
42
// maintain line numbers
43
utils.move(templateElement.range[0], state);
44
utils.catchupNewlines(templateElement.range[1], state);
45
} else { // templateElement.value.raw === ''
46
// Concatenat adjacent substitutions, e.g. `${x}${y}`. Empty templates
47
// appear before the first and after the last element - nothing to add in
48
// those cases.
49
if (ii > 0 && !templateElement.tail) {
50
// + between substitution and substitution
51
utils.append(' + ', state);
52
}
53
}
54
55
utils.move(templateElement.range[1], state);
56
if (!templateElement.tail) {
57
var substitution = node.expressions[ii];
58
if (substitution.type === Syntax.Identifier ||
59
substitution.type === Syntax.MemberExpression ||
60
substitution.type === Syntax.CallExpression) {
61
utils.catchup(substitution.range[1], state);
62
} else {
63
utils.append('(', state);
64
traverse(substitution, path, state);
65
utils.catchup(substitution.range[1], state);
66
utils.append(')', state);
67
}
68
// if next templateElement isn't empty...
69
if (templateElements[ii + 1].value.cooked !== '') {
70
utils.append(' + ', state);
71
}
72
}
73
}
74
utils.move(node.range[1], state);
75
utils.append(')', state);
76
return false;
77
}
78
79
visitTemplateLiteral.test = function(node, path, state) {
80
return node.type === Syntax.TemplateLiteral;
81
};
82
83
/**
84
* http://people.mozilla.org/~jorendorff/es6-draft.html#sec-12.2.6
85
*/
86
function visitTaggedTemplateExpression(traverse, node, path, state) {
87
var template = node.quasi;
88
var numQuasis = template.quasis.length;
89
90
// print the tag
91
utils.move(node.tag.range[0], state);
92
traverse(node.tag, path, state);
93
utils.catchup(node.tag.range[1], state);
94
95
// print array of template elements
96
utils.append('(function() { var siteObj = [', state);
97
for (var ii = 0; ii < numQuasis; ii++) {
98
utils.append(getCookedValue(template.quasis[ii]), state);
99
if (ii !== numQuasis - 1) {
100
utils.append(', ', state);
101
}
102
}
103
utils.append(']; siteObj.raw = [', state);
104
for (ii = 0; ii < numQuasis; ii++) {
105
utils.append(getRawValue(template.quasis[ii]), state);
106
if (ii !== numQuasis - 1) {
107
utils.append(', ', state);
108
}
109
}
110
utils.append(
111
']; Object.freeze(siteObj.raw); Object.freeze(siteObj); return siteObj; }()',
112
state
113
);
114
115
// print substitutions
116
if (numQuasis > 1) {
117
for (ii = 0; ii < template.expressions.length; ii++) {
118
var expression = template.expressions[ii];
119
utils.append(', ', state);
120
121
// maintain line numbers by calling catchupWhiteSpace over the whole
122
// previous TemplateElement
123
utils.move(template.quasis[ii].range[0], state);
124
utils.catchupNewlines(template.quasis[ii].range[1], state);
125
126
utils.move(expression.range[0], state);
127
traverse(expression, path, state);
128
utils.catchup(expression.range[1], state);
129
}
130
}
131
132
// print blank lines to push the closing ) down to account for the final
133
// TemplateElement.
134
utils.catchupNewlines(node.range[1], state);
135
136
utils.append(')', state);
137
138
return false;
139
}
140
141
visitTaggedTemplateExpression.test = function(node, path, state) {
142
return node.type === Syntax.TaggedTemplateExpression;
143
};
144
145
function getCookedValue(templateElement) {
146
return JSON.stringify(templateElement.value.cooked);
147
}
148
149
function getRawValue(templateElement) {
150
return JSON.stringify(templateElement.value.raw);
151
}
152
153
exports.visitorList = [
154
visitTemplateLiteral,
155
visitTaggedTemplateExpression
156
];
157
158