ripple 0.2.24 → 0.2.26
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.
- package/package.json +1 -1
- package/src/compiler/phases/2-analyze/index.js +49 -22
- package/src/compiler/phases/3-transform/index.js +18 -10
- package/src/compiler/utils.js +2 -0
- package/src/runtime/internal/client/index.js +1 -0
- package/src/runtime/internal/client/runtime.js +4 -0
- package/src/utils/ast.js +4 -0
- package/tests/composite.test.ripple +55 -1
package/package.json
CHANGED
|
@@ -34,7 +34,7 @@ function visit_function(node, context) {
|
|
|
34
34
|
if (binding !== null && is_tracked_name(name)) {
|
|
35
35
|
const id = context.state.scope.generate('arg');
|
|
36
36
|
node.params[i] = b.id(id);
|
|
37
|
-
binding.kind = 'prop';
|
|
37
|
+
binding.kind = path.has_default_value ? 'prop_fallback' : 'prop';
|
|
38
38
|
|
|
39
39
|
binding.transform = {
|
|
40
40
|
read: (_) => b.call('$.get_property', b.id(id), b.literal(name)),
|
|
@@ -315,30 +315,57 @@ const visitors = {
|
|
|
315
315
|
const binding = context.state.scope.get(name);
|
|
316
316
|
|
|
317
317
|
if (binding !== null && is_tracked_name(name)) {
|
|
318
|
-
binding.kind = 'prop';
|
|
318
|
+
binding.kind = path.has_default_value ? 'prop_fallback' : 'prop';
|
|
319
319
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}
|
|
320
|
+
if (path.has_default_value) {
|
|
321
|
+
binding.transform = {
|
|
322
|
+
read: (_) => b.call('$.get_computed', path.node),
|
|
323
|
+
assign: (node, value) => {
|
|
324
|
+
return b.call(
|
|
325
|
+
'$.set',
|
|
326
|
+
path.node,
|
|
327
|
+
value,
|
|
328
|
+
b.id('__block'),
|
|
329
|
+
);
|
|
330
|
+
},
|
|
331
|
+
update: (_) =>
|
|
332
|
+
b.call(
|
|
333
|
+
node.prefix ? '$.update_pre' : '$.update',
|
|
334
|
+
path.node,
|
|
335
|
+
b.id('__block'),
|
|
336
|
+
node.operator === '--' && b.literal(-1),
|
|
337
|
+
),
|
|
338
|
+
};
|
|
339
|
+
} else {
|
|
340
|
+
binding.transform = {
|
|
341
|
+
read: (_) => b.call('$.get_property', b.id('__props'), b.literal(name)),
|
|
342
|
+
assign: (node, value) => {
|
|
343
|
+
return b.call(
|
|
344
|
+
'$.set_property',
|
|
345
|
+
b.id('__props'),
|
|
346
|
+
b.literal(name),
|
|
347
|
+
value,
|
|
348
|
+
b.id('__block'),
|
|
349
|
+
);
|
|
350
|
+
},
|
|
351
|
+
update: (_) =>
|
|
352
|
+
b.call(
|
|
353
|
+
node.prefix ? '$.update_property_pre' : '$.update_property',
|
|
354
|
+
b.id('__props'),
|
|
355
|
+
b.literal(name),
|
|
356
|
+
b.id('__block'),
|
|
357
|
+
node.operator === '--' && b.literal(-1),
|
|
358
|
+
),
|
|
359
|
+
};
|
|
360
|
+
}
|
|
340
361
|
}
|
|
341
362
|
}
|
|
363
|
+
} else if (props.type === 'AssignmentPattern') {
|
|
364
|
+
error(
|
|
365
|
+
'Props are always an object, use destructured props with default values instead',
|
|
366
|
+
context.state.analysis.module.filename,
|
|
367
|
+
props,
|
|
368
|
+
);
|
|
342
369
|
}
|
|
343
370
|
}
|
|
344
371
|
const elements = [];
|
|
@@ -724,13 +724,16 @@ const visitors = {
|
|
|
724
724
|
return b.function(node.id, node.params, b.block(body_statements));
|
|
725
725
|
}
|
|
726
726
|
|
|
727
|
+
let props = b.id('__props');
|
|
728
|
+
|
|
727
729
|
if (node.params.length > 0) {
|
|
728
|
-
let
|
|
730
|
+
let props_param = node.params[0];
|
|
729
731
|
|
|
730
|
-
if (
|
|
731
|
-
delete
|
|
732
|
-
|
|
733
|
-
|
|
732
|
+
if (props_param.type === 'Identifier') {
|
|
733
|
+
delete props_param.typeAnnotation;
|
|
734
|
+
props = props_param;
|
|
735
|
+
} else if (props_param.type === 'ObjectPattern') {
|
|
736
|
+
const paths = extract_paths(props_param);
|
|
734
737
|
|
|
735
738
|
for (const path of paths) {
|
|
736
739
|
const name = path.node.name;
|
|
@@ -742,6 +745,15 @@ const visitors = {
|
|
|
742
745
|
prop_statements = [];
|
|
743
746
|
}
|
|
744
747
|
prop_statements.push(b.var(name, b.member(b.id('__props'), key)));
|
|
748
|
+
} else if (binding !== null && path.has_default_value) {
|
|
749
|
+
if (prop_statements === undefined) {
|
|
750
|
+
prop_statements = [];
|
|
751
|
+
}
|
|
752
|
+
const fallback = path.expression(b.id('__props'));
|
|
753
|
+
|
|
754
|
+
prop_statements.push(
|
|
755
|
+
b.var(name, b.call('$.computed', b.thunk(context.visit(fallback)), b.id('__block'))),
|
|
756
|
+
);
|
|
745
757
|
}
|
|
746
758
|
}
|
|
747
759
|
}
|
|
@@ -763,11 +775,7 @@ const visitors = {
|
|
|
763
775
|
return b.function(
|
|
764
776
|
node.id,
|
|
765
777
|
node.params.length > 0
|
|
766
|
-
? [
|
|
767
|
-
b.id('__anchor'),
|
|
768
|
-
node.params[0].type === 'Identifier' ? node.params[0] : b.id('__props'),
|
|
769
|
-
b.id('__block'),
|
|
770
|
-
]
|
|
778
|
+
? [b.id('__anchor'), props, b.id('__block')]
|
|
771
779
|
: [b.id('__anchor'), b.id('_'), b.id('__block')],
|
|
772
780
|
b.block([
|
|
773
781
|
...(prop_statements ?? []),
|
package/src/compiler/utils.js
CHANGED
|
@@ -291,6 +291,8 @@ function get_hoisted_params(node, context) {
|
|
|
291
291
|
if (binding !== null && !scope.declarations.has(reference) && binding.initial !== node) {
|
|
292
292
|
if (binding.kind === 'prop') {
|
|
293
293
|
push_unique(b.id('__props'));
|
|
294
|
+
} else if (binding.kind === 'prop_fallback') {
|
|
295
|
+
push_unique(b.id(binding.node.name));
|
|
294
296
|
} else if (
|
|
295
297
|
// imports don't need to be hoisted
|
|
296
298
|
binding.declaration_kind !== 'import'
|
package/src/utils/ast.js
CHANGED
|
@@ -201,6 +201,10 @@ function _extract_paths(assignments = [], param, expression, update_expression,
|
|
|
201
201
|
return assignments;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
+
export function build_fallback(expression, fallback) {
|
|
205
|
+
return b.call('$.fallback', expression, fallback);
|
|
206
|
+
}
|
|
207
|
+
|
|
204
208
|
/**
|
|
205
209
|
* @param {ESTree.AssignmentOperator} operator
|
|
206
210
|
* @param {ESTree.Identifier | ESTree.MemberExpression} left
|
|
@@ -241,5 +241,59 @@ describe('composite components', () => {
|
|
|
241
241
|
render(App);
|
|
242
242
|
|
|
243
243
|
expect(container).toMatchSnapshot();
|
|
244
|
-
})
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('correctly handles default prop values', () => {
|
|
247
|
+
component Child({ $foo = 456 }) {
|
|
248
|
+
<div>{$foo}</div>
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
component App(props) {
|
|
252
|
+
let $foo = 123;
|
|
253
|
+
|
|
254
|
+
<Child />
|
|
255
|
+
<Child {$foo} />
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
render(App);
|
|
259
|
+
|
|
260
|
+
expect(container.querySelectorAll('div')[0].textContent).toBe('456');
|
|
261
|
+
expect(container.querySelectorAll('div')[1].textContent).toBe('123');
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it('correctly handles no props', () => {
|
|
265
|
+
component Child(props) {
|
|
266
|
+
<div>{props.$foo}</div>
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
component App(props) {
|
|
270
|
+
let $foo = 123;
|
|
271
|
+
|
|
272
|
+
<Child />
|
|
273
|
+
<Child {$foo} />
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
render(App);
|
|
277
|
+
|
|
278
|
+
expect(container.querySelectorAll('div')[0].textContent).toBe('');
|
|
279
|
+
expect(container.querySelectorAll('div')[1].textContent).toBe('123');
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('correctly handles no props #2', () => {
|
|
283
|
+
component Child({ $foo }) {
|
|
284
|
+
<div>{$foo}</div>
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
component App(props) {
|
|
288
|
+
let $foo = 123;
|
|
289
|
+
|
|
290
|
+
<Child />
|
|
291
|
+
<Child {$foo} />
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
render(App);
|
|
295
|
+
|
|
296
|
+
expect(container.querySelectorAll('div')[0].textContent).toBe('');
|
|
297
|
+
expect(container.querySelectorAll('div')[1].textContent).toBe('123');
|
|
298
|
+
});
|
|
245
299
|
});
|