@bablr/boot 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,21 +8,45 @@ const isNull = require('iter-tools/methods/is-null');
8
8
  const isString = require('iter-tools/methods/is-string');
9
9
  const concat = require('iter-tools/methods/concat');
10
10
  const { createMacro } = require('babel-plugin-macros');
11
- const { TemplateParser, set, getAgASTValue } = require('./lib/index.js');
11
+ const { TemplateParser, add, getAgASTValue } = require('./lib/index.js');
12
12
  const i = require('./lib/languages/instruction.js');
13
13
  const re = require('./lib/languages/regex.js');
14
14
  const spam = require('./lib/languages/spamex.js');
15
15
  const cstml = require('./lib/languages/cstml.js');
16
16
  const { addNamespace, addNamed } = require('@babel/helper-module-imports');
17
- const { PathResolver } = require('@bablr/boot-helpers/path');
18
17
  const { printPrettyCSTML } = require('./lib/print.js');
18
+ const sym = require('@bablr/boot-helpers/symbols');
19
+ const {
20
+ OpenNodeTag,
21
+ CloseNodeTag,
22
+ ReferenceTag,
23
+ GapTag,
24
+ ArrayTag,
25
+ LiteralTag,
26
+ EmbeddedNode,
27
+ } = require('@bablr/boot-helpers/symbols');
28
+ const btree = require('@bablr/boot-helpers/btree');
19
29
 
20
30
  const { isArray } = Array;
31
+ const { hasOwn } = Object;
21
32
  const isNumber = (v) => typeof v === 'number';
22
33
  const isBoolean = (v) => typeof v === 'boolean';
23
34
  const isPlainObject = (v) => isObject(v) && !isArray(v);
24
35
  const printRef = (ref) => (ref.isArray ? `${ref.name}[]` : ref.name);
25
36
 
37
+ const getBtreeASTValue = (tree, exprs, bindings) => {
38
+ if (!isArray(tree)) return tree;
39
+
40
+ if (btree.isLeafNode(tree)) {
41
+ return t.arrayExpression(tree);
42
+ } else {
43
+ return t.arrayExpression([
44
+ t.numericLiteral(tree[0]),
45
+ t.arrayExpression(tree[1].map((v) => getBtreeASTValue(v, exprs, bindings))),
46
+ ]);
47
+ }
48
+ };
49
+
26
50
  const getBabelASTValue = (v, exprs, bindings) => {
27
51
  return isNull(v)
28
52
  ? t.nullLiteral()
@@ -46,30 +70,38 @@ const getBabelASTValue = (v, exprs, bindings) => {
46
70
  };
47
71
 
48
72
  const generateBabelNodeChild = (child, exprs, bindings) => {
49
- if (child.type === 'Reference') {
73
+ if (child.type === ReferenceTag) {
50
74
  return expression(`%%t%%.ref\`${printRef(child.value)}\``)({ t: bindings.t });
51
- } else if (child.type === 'Literal') {
75
+ } else if (child.type === LiteralTag) {
52
76
  return expression(`%%t%%.lit(%%value%%)`)({
53
77
  t: bindings.t,
54
78
  value: getBabelASTValue(child.value, exprs, bindings),
55
79
  });
56
- } else if (child.type === 'EmbeddedNode') {
80
+ } else if (child.type === EmbeddedNode) {
57
81
  return expression(`%%t%%.embedded(%%value%%)`)({
58
82
  t: bindings.t,
59
83
  value: generateBabelNode(child.value, exprs, bindings),
60
84
  });
85
+ } else if (child.type === ArrayTag) {
86
+ return expression(`%%t%%.arr()`)({
87
+ t: bindings.t,
88
+ });
89
+ } else if (child.type === GapTag) {
90
+ return expression(`%%t%%.gap()`)({
91
+ t: bindings.t,
92
+ });
61
93
  } else {
62
94
  throw new Error(`Unknown child type ${child.type}`);
63
95
  }
64
96
  };
65
97
 
66
98
  const getAgastNodeType = (flags) => {
67
- if (flags.intrinsic && flags.token) {
68
- return 's_i_node';
69
- } else if (flags.token && flags.trivia) {
99
+ if (flags.token && flags.trivia) {
70
100
  return 's_t_node';
71
101
  } else if (flags.token && flags.escape) {
72
102
  return 's_e_node';
103
+ } else if (flags.escape) {
104
+ return 'e_node';
73
105
  } else if (flags.token) {
74
106
  return 's_node';
75
107
  } else {
@@ -78,75 +110,81 @@ const getAgastNodeType = (flags) => {
78
110
  };
79
111
 
80
112
  const generateBabelNode = (node, exprs, bindings) => {
81
- const resolver = new PathResolver(node);
82
113
  const { flags = {}, children, type, language, attributes } = node;
83
114
 
84
115
  const properties_ = {};
85
- const children_ = [];
116
+ let children_ = [];
86
117
 
87
118
  if (!children) {
88
119
  throw new Error();
89
120
  }
90
121
 
91
- for (const child of children) {
92
- if (child.type === 'Reference') {
93
- const path = child.value;
94
- const { isArray: pathIsArray } = path;
95
- const resolved = resolver.get(path);
122
+ // resolver.advance({ type: DoctypeTag, value: {} });
96
123
 
97
- if (resolved) {
98
- set(properties_, path, generateBabelNode(resolved, exprs, bindings));
99
- children_.push(generateBabelNodeChild(child, exprs, bindings));
100
- } else {
101
- // gap
102
- const expr = exprs.pop();
103
- const { interpolateArray, interpolateArrayChildren, interpolateString } = bindings;
124
+ for (const child of btree.traverse(children)) {
125
+ if (child.type === ReferenceTag) {
126
+ const path = child.value;
127
+ const { isArray: pathIsArray, name } = path;
128
+ if (!pathIsArray || hasOwn(properties_, name)) {
129
+ let resolved = node.properties[name];
104
130
 
105
131
  if (pathIsArray) {
106
- set(
107
- properties_,
108
- path,
109
- expression('[...%%interpolateArray%%(%%expr%%)]')({
110
- interpolateArray,
111
- expr,
112
- }).elements[0],
113
- );
114
-
115
- children_.push(
116
- t.spreadElement(
117
- expression('%%interpolateArrayChildren%%(%%expr%%, %%ref%%, %%sep%%)')({
118
- interpolateArrayChildren,
132
+ resolved = btree.getAt(btree.getSum(properties_[name]), resolved);
133
+ }
134
+
135
+ if (resolved.type !== sym.gap) {
136
+ add(properties_, path, generateBabelNode(resolved, exprs, bindings));
137
+ children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
138
+ } else {
139
+ // gap
140
+ const expr = exprs.pop();
141
+ const { interpolateArray, interpolateFragmentChildren, interpolateString } = bindings;
142
+
143
+ if (pathIsArray) {
144
+ add(
145
+ properties_,
146
+ path,
147
+ expression('[...%%interpolateArray%%(%%expr%%)]')({
148
+ interpolateArray,
149
+ expr,
150
+ }).elements[0],
151
+ );
152
+
153
+ children_ = btree.push(
154
+ children_,
155
+ t.spreadElement(
156
+ expression('%%interpolateFragmentChildren%%(%%expr%%, %%ref%%)')({
157
+ interpolateFragmentChildren,
158
+ expr,
159
+ ref: expression(`%%t%%.ref\`${printRef(child.value)}\``)({ t: bindings.t }),
160
+ }),
161
+ ),
162
+ );
163
+ } else if (language === cstml.canonicalURL && type === 'String') {
164
+ add(
165
+ properties_,
166
+ path,
167
+ expression('%%interpolateString%%(%%expr%%)')({
168
+ interpolateString,
119
169
  expr,
120
- ref: expression(`%%t%%.ref\`${printRef(child.value)}\``)({ t: bindings.t }),
121
-
122
- // Really really awful unsafe-as-heck hack, to be removed ASAP
123
- // Fixing this requires having interpolation happen during parsing
124
- // That way the grammar can deal with the separators!
125
- sep: expression(
126
- "%%t%%.embedded(%%t%%.t_node(%%l%%.Comment, null, [%%t%%.embedded(%%t%%.t_node('Space', 'Space', [%%t%%.lit(' ')]))]))",
127
- )({ t: bindings.t, l: bindings.l }),
128
170
  }),
129
- ),
130
- );
131
- } else if (language === cstml.canonicalURL && type === 'String') {
132
- set(
133
- properties_,
134
- path,
135
- expression('%%interpolateString%%(%%expr%%)')({
136
- interpolateString,
137
- expr,
138
- }),
139
- );
140
-
141
- children_.push(generateBabelNodeChild(child, exprs, bindings));
142
- } else {
143
- set(properties_, path, expr);
171
+ );
144
172
 
145
- children_.push(generateBabelNodeChild(child, exprs, bindings));
173
+ children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
174
+ } else {
175
+ add(properties_, path, expr);
176
+
177
+ children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
178
+ }
146
179
  }
180
+ } else if (pathIsArray) {
181
+ children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
182
+ properties_[name] = [];
147
183
  }
148
184
  } else {
149
- children_.push(generateBabelNodeChild(child, exprs, bindings));
185
+ if (child.type !== OpenNodeTag && child.type !== CloseNodeTag) {
186
+ children_ = btree.push(children_, generateBabelNodeChild(child, exprs, bindings));
187
+ }
150
188
  }
151
189
  }
152
190
 
@@ -160,10 +198,7 @@ const generateBabelNode = (node, exprs, bindings) => {
160
198
  : {
161
199
  properties: t.objectExpression(
162
200
  Object.entries(properties_).map(([key, value]) =>
163
- t.objectProperty(
164
- t.identifier(key),
165
- isArray(value) ? t.arrayExpression(value) : value,
166
- ),
201
+ t.objectProperty(t.identifier(key), isArray(value) ? getBtreeASTValue(value) : value),
167
202
  ),
168
203
  ),
169
204
  attributes: t.objectExpression(
@@ -173,6 +208,10 @@ const generateBabelNode = (node, exprs, bindings) => {
173
208
  ),
174
209
  };
175
210
 
211
+ if (type === sym.gap) {
212
+ return expression(`%%t%%.g_node()`)({ t: bindings.t });
213
+ }
214
+
176
215
  return expression(`%%t%%.%%nodeType%%(%%l%%.%%language%%, %%type%%, %%children%%${propsAtts})`)({
177
216
  t: bindings.t,
178
217
  l: bindings.l,
@@ -181,8 +220,8 @@ const generateBabelNode = (node, exprs, bindings) => {
181
220
  type: t.stringLiteral(type),
182
221
  children:
183
222
  nodeType === 's_node' || nodeType === 's_i_node'
184
- ? t.stringLiteral(children[0].value)
185
- : t.arrayExpression(children_),
223
+ ? t.stringLiteral(btree.getAt(1, children).value)
224
+ : getBtreeASTValue(children_),
186
225
  ...propsAttsValue,
187
226
  });
188
227
  };
@@ -258,10 +297,10 @@ const shorthandMacro = ({ references }) => {
258
297
  );
259
298
  }
260
299
 
261
- if (!bindings.interpolateArrayChildren) {
262
- bindings.interpolateArrayChildren = addNamed(
300
+ if (!bindings.interpolateFragmentChildren) {
301
+ bindings.interpolateFragmentChildren = addNamed(
263
302
  getTopScope(ref.scope).path,
264
- 'interpolateArrayChildren',
303
+ 'interpolateFragmentChildren',
265
304
  '@bablr/agast-helpers/template',
266
305
  );
267
306
  }
package/lib/symbols.js DELETED
@@ -1,4 +0,0 @@
1
- const node = Symbol.for('@bablr/node');
2
- const fragment = Symbol.for('@bablr/fragment');
3
-
4
- module.exports = { node, fragment };