ripple 0.2.183 → 0.2.185
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 +2 -2
- package/src/compiler/phases/2-analyze/index.js +7 -2
- package/src/compiler/phases/3-transform/client/index.js +181 -131
- package/src/compiler/phases/3-transform/segments.js +93 -49
- package/src/compiler/phases/3-transform/server/index.js +135 -45
- package/src/compiler/scope.js +11 -16
- package/src/compiler/types/index.d.ts +333 -90
- package/src/compiler/types/parse.d.ts +127 -9
- package/src/runtime/index-server.js +10 -27
- package/src/runtime/internal/client/operations.js +1 -1
- package/src/runtime/internal/client/runtime.js +8 -8
- package/src/runtime/internal/client/types.d.ts +5 -5
- package/src/runtime/internal/server/index.js +268 -17
- package/src/runtime/internal/server/types.d.ts +19 -11
- package/tests/client/switch.test.ripple +73 -23
- package/tests/server/basic.test.ripple +119 -0
- package/tests/server/composite.test.ripple +1 -1
- package/tests/server/context.test.ripple +31 -0
- package/tests/server/switch.test.ripple +21 -0
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Ripple is an elegant TypeScript UI framework",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Dominic Gannaway",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.185",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"module": "src/runtime/index-client.js",
|
|
9
9
|
"main": "src/runtime/index-client.js",
|
|
@@ -86,6 +86,6 @@
|
|
|
86
86
|
"vscode-languageserver-types": "^3.17.5"
|
|
87
87
|
},
|
|
88
88
|
"peerDependencies": {
|
|
89
|
-
"ripple": "0.2.
|
|
89
|
+
"ripple": "0.2.185"
|
|
90
90
|
}
|
|
91
91
|
}
|
|
@@ -423,6 +423,11 @@ const visitors = {
|
|
|
423
423
|
context.visit(node.discriminant, context.state);
|
|
424
424
|
|
|
425
425
|
for (const switch_case of node.cases) {
|
|
426
|
+
// Fallthrough
|
|
427
|
+
if (switch_case.consequent.length === 0) {
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
|
|
426
431
|
// Validate that each cases ends in a break statement, except for the last case
|
|
427
432
|
const last = switch_case.consequent?.[switch_case.consequent.length - 1];
|
|
428
433
|
|
|
@@ -728,9 +733,9 @@ const visitors = {
|
|
|
728
733
|
}
|
|
729
734
|
if (state.inside_head) {
|
|
730
735
|
if (node.id.name === 'title') {
|
|
731
|
-
const
|
|
736
|
+
const children = normalize_children(node.children, context);
|
|
732
737
|
|
|
733
|
-
if (
|
|
738
|
+
if (children.length !== 1 || children[0].type !== 'Text') {
|
|
734
739
|
error(
|
|
735
740
|
'<title> must have only contain text nodes',
|
|
736
741
|
state.analysis.module.filename,
|
|
@@ -61,17 +61,6 @@ import {
|
|
|
61
61
|
} from '../../../../utils/events.js';
|
|
62
62
|
import { createHash } from 'node:crypto';
|
|
63
63
|
|
|
64
|
-
/**
|
|
65
|
-
* @param {TransformClientContext} context
|
|
66
|
-
*/
|
|
67
|
-
function add_ripple_internal_import(context) {
|
|
68
|
-
if (!context.state.to_ts) {
|
|
69
|
-
if (!context.state.imports.has(`import * as _$_ from 'ripple/internal/client'`)) {
|
|
70
|
-
context.state.imports.add(`import * as _$_ from 'ripple/internal/client'`);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
64
|
/**
|
|
76
65
|
*
|
|
77
66
|
* @param {AST.FunctionDeclaration | AST.FunctionExpression | AST.ArrowFunctionExpression} node
|
|
@@ -112,7 +101,6 @@ function visit_function(node, context) {
|
|
|
112
101
|
const new_body = [];
|
|
113
102
|
|
|
114
103
|
if (!is_inside_component(context, true) && is_component_level_function(context)) {
|
|
115
|
-
add_ripple_internal_import(context);
|
|
116
104
|
new_body.push(b.var('__block', b.call('_$_.scope')));
|
|
117
105
|
}
|
|
118
106
|
if (body.type === 'BlockStatement') {
|
|
@@ -397,11 +385,9 @@ const visitors = {
|
|
|
397
385
|
context.state.metadata.tracking = true;
|
|
398
386
|
}
|
|
399
387
|
if (node.tracked) {
|
|
400
|
-
add_ripple_internal_import(context);
|
|
401
388
|
return b.call('_$_.get', build_getter(node, context));
|
|
402
389
|
}
|
|
403
390
|
}
|
|
404
|
-
add_ripple_internal_import(context);
|
|
405
391
|
return build_getter(node, context);
|
|
406
392
|
}
|
|
407
393
|
}
|
|
@@ -663,8 +649,6 @@ const visitors = {
|
|
|
663
649
|
|
|
664
650
|
if (node.tracked || (node.property.type === 'Identifier' && node.property.tracked)) {
|
|
665
651
|
// In TypeScript mode, skip the transformation and let transform_ts_child handle it
|
|
666
|
-
add_ripple_internal_import(context);
|
|
667
|
-
|
|
668
652
|
if (!context.state.to_ts) {
|
|
669
653
|
return b.call(
|
|
670
654
|
'_$_.get_property',
|
|
@@ -1595,9 +1579,6 @@ const visitors = {
|
|
|
1595
1579
|
|
|
1596
1580
|
Component(node, context) {
|
|
1597
1581
|
let prop_statements;
|
|
1598
|
-
|
|
1599
|
-
add_ripple_internal_import(context);
|
|
1600
|
-
|
|
1601
1582
|
const metadata = { await: false };
|
|
1602
1583
|
|
|
1603
1584
|
if (context.state.to_ts) {
|
|
@@ -1683,7 +1664,6 @@ const visitors = {
|
|
|
1683
1664
|
left.type === 'MemberExpression' &&
|
|
1684
1665
|
(left.tracked || (left.property.type === 'Identifier' && left.property.tracked))
|
|
1685
1666
|
) {
|
|
1686
|
-
add_ripple_internal_import(context);
|
|
1687
1667
|
const operator = node.operator;
|
|
1688
1668
|
const right = node.right;
|
|
1689
1669
|
|
|
@@ -1710,7 +1690,6 @@ const visitors = {
|
|
|
1710
1690
|
}
|
|
1711
1691
|
|
|
1712
1692
|
if (left.type === 'Identifier' && left.tracked) {
|
|
1713
|
-
add_ripple_internal_import(context);
|
|
1714
1693
|
const operator = node.operator;
|
|
1715
1694
|
const right = node.right;
|
|
1716
1695
|
|
|
@@ -1744,7 +1723,6 @@ const visitors = {
|
|
|
1744
1723
|
argument.type === 'MemberExpression' &&
|
|
1745
1724
|
(argument.tracked || (argument.property.type === 'Identifier' && argument.property.tracked))
|
|
1746
1725
|
) {
|
|
1747
|
-
add_ripple_internal_import(context);
|
|
1748
1726
|
if (context.state.metadata?.tracking === false) {
|
|
1749
1727
|
context.state.metadata.tracking = true;
|
|
1750
1728
|
}
|
|
@@ -1854,27 +1832,34 @@ const visitors = {
|
|
|
1854
1832
|
let i = 1;
|
|
1855
1833
|
|
|
1856
1834
|
for (const switch_case of node.cases) {
|
|
1857
|
-
const
|
|
1858
|
-
context.state.scopes.get(switch_case.consequent) || context.state.scope;
|
|
1859
|
-
const consequent_id = context.state.scope.generate(
|
|
1860
|
-
'switch_case_' + (switch_case.test == null ? 'default' : i),
|
|
1861
|
-
);
|
|
1862
|
-
const consequent = b.block(
|
|
1863
|
-
transform_body(switch_case.consequent, {
|
|
1864
|
-
...context,
|
|
1865
|
-
state: { ...context.state, scope: consequent_scope },
|
|
1866
|
-
}),
|
|
1867
|
-
);
|
|
1835
|
+
const case_body = [];
|
|
1868
1836
|
|
|
1869
|
-
|
|
1837
|
+
if (switch_case.consequent.length !== 0) {
|
|
1838
|
+
const consequent_scope =
|
|
1839
|
+
context.state.scopes.get(switch_case.consequent) || context.state.scope;
|
|
1840
|
+
const consequent_id = context.state.scope.generate(
|
|
1841
|
+
'switch_case_' + (switch_case.test == null ? 'default' : i),
|
|
1842
|
+
);
|
|
1843
|
+
const consequent = b.block(
|
|
1844
|
+
transform_body(switch_case.consequent, {
|
|
1845
|
+
...context,
|
|
1846
|
+
state: { ...context.state, scope: consequent_scope },
|
|
1847
|
+
}),
|
|
1848
|
+
);
|
|
1849
|
+
|
|
1850
|
+
statements.push(b.var(b.id(consequent_id), b.arrow([b.id('__anchor')], consequent)));
|
|
1851
|
+
|
|
1852
|
+
case_body.push(b.return(b.id(consequent_id)));
|
|
1853
|
+
|
|
1854
|
+
i++;
|
|
1855
|
+
}
|
|
1870
1856
|
|
|
1871
1857
|
cases.push(
|
|
1872
1858
|
b.switch_case(
|
|
1873
1859
|
switch_case.test ? /** @type {AST.Expression} */ (context.visit(switch_case.test)) : null,
|
|
1874
|
-
|
|
1860
|
+
case_body,
|
|
1875
1861
|
),
|
|
1876
1862
|
);
|
|
1877
|
-
i++;
|
|
1878
1863
|
}
|
|
1879
1864
|
|
|
1880
1865
|
statements.push(
|
|
@@ -2911,10 +2896,10 @@ function transform_body(body, { visit, state }) {
|
|
|
2911
2896
|
|
|
2912
2897
|
/**
|
|
2913
2898
|
* Create a TSX language handler with enhanced TypeScript support
|
|
2914
|
-
* @returns {
|
|
2899
|
+
* @returns {Visitors<AST.Node, TransformClientState>} TSX language handler with TypeScript return type support
|
|
2915
2900
|
*/
|
|
2916
2901
|
function create_tsx_with_typescript_support() {
|
|
2917
|
-
const base_tsx = /** @type {
|
|
2902
|
+
const base_tsx = /** @type {Visitors<AST.Node, TransformClientState>} */ (tsx());
|
|
2918
2903
|
|
|
2919
2904
|
// Add custom TypeScript node handlers that aren't in tsx
|
|
2920
2905
|
|
|
@@ -2922,7 +2907,7 @@ function create_tsx_with_typescript_support() {
|
|
|
2922
2907
|
* Shared handler for function-like nodes to support component->function mapping
|
|
2923
2908
|
* Creates source maps for 'function' keyword by passing node to context.write()
|
|
2924
2909
|
* @param {AST.Function} node
|
|
2925
|
-
* @param {
|
|
2910
|
+
* @param {TransformClientContext} context
|
|
2926
2911
|
*/
|
|
2927
2912
|
const handle_function = (node, context) => {
|
|
2928
2913
|
if (node.async) {
|
|
@@ -2963,16 +2948,8 @@ function create_tsx_with_typescript_support() {
|
|
|
2963
2948
|
}
|
|
2964
2949
|
};
|
|
2965
2950
|
|
|
2966
|
-
return {
|
|
2951
|
+
return /** @type {Visitors<AST.Node, TransformClientState>} */ ({
|
|
2967
2952
|
...base_tsx,
|
|
2968
|
-
/**
|
|
2969
|
-
* Custom handler for Property nodes to prevent method shorthand for components
|
|
2970
|
-
* When a component is transformed to a FunctionExpression, we want to preserve
|
|
2971
|
-
* the explicit syntax (key: function name() {}) instead of method shorthand (key() {})
|
|
2972
|
-
* This ensures proper source mapping for the 'function'/'component' keyword
|
|
2973
|
-
* @param {AST.Property} node
|
|
2974
|
-
* @param {ESRap.Context} context
|
|
2975
|
-
*/
|
|
2976
2953
|
Property(node, context) {
|
|
2977
2954
|
// Check if the value is a function that was originally a component
|
|
2978
2955
|
const isComponent =
|
|
@@ -3019,18 +2996,13 @@ function create_tsx_with_typescript_support() {
|
|
|
3019
2996
|
context.write(node.computed ? ']: ' : ': ');
|
|
3020
2997
|
context.visit(node.value);
|
|
3021
2998
|
} else {
|
|
3022
|
-
base_tsx.Property?.(node, context);
|
|
2999
|
+
base_tsx.Property?.(node, /** @type {ESRap.} */ (context));
|
|
3023
3000
|
}
|
|
3024
3001
|
} else {
|
|
3025
3002
|
// Use default handler for non-component properties
|
|
3026
3003
|
base_tsx.Property?.(node, context);
|
|
3027
3004
|
}
|
|
3028
3005
|
},
|
|
3029
|
-
/**
|
|
3030
|
-
* Custom handler for JSXClosingElement to ensure closing tag brackets have source mappings
|
|
3031
|
-
* @param {ESTreeJSX.JSXClosingElement} node
|
|
3032
|
-
* @param {ESRap.Context} context
|
|
3033
|
-
*/
|
|
3034
3006
|
JSXClosingElement(node, context) {
|
|
3035
3007
|
// Set location for '<' then write '</'
|
|
3036
3008
|
if (node.loc) {
|
|
@@ -3050,12 +3022,99 @@ function create_tsx_with_typescript_support() {
|
|
|
3050
3022
|
context.write('>');
|
|
3051
3023
|
}
|
|
3052
3024
|
},
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3025
|
+
MethodDefinition(node, context) {
|
|
3026
|
+
// Check if there are type parameters to handle
|
|
3027
|
+
// @ts-ignore - typeParameters may exist on node
|
|
3028
|
+
const hasTypeParams = node.typeParameters || node.value?.typeParameters;
|
|
3029
|
+
|
|
3030
|
+
if (!hasTypeParams) {
|
|
3031
|
+
// No type parameters, use default handler
|
|
3032
|
+
return base_tsx.MethodDefinition?.(node, context);
|
|
3033
|
+
}
|
|
3034
|
+
|
|
3035
|
+
// Has type parameters - we need to manually handle to ensure they're visited
|
|
3036
|
+
// Write modifiers (static, async, etc.)
|
|
3037
|
+
if (node.static) {
|
|
3038
|
+
context.write('static ');
|
|
3039
|
+
}
|
|
3040
|
+
|
|
3041
|
+
// Handle getters/setters
|
|
3042
|
+
if (node.kind === 'get') {
|
|
3043
|
+
context.write('get ');
|
|
3044
|
+
} else if (node.kind === 'set') {
|
|
3045
|
+
context.write('set ');
|
|
3046
|
+
}
|
|
3047
|
+
|
|
3048
|
+
// Write * for generator methods
|
|
3049
|
+
if (node.value?.generator) {
|
|
3050
|
+
context.write('*');
|
|
3051
|
+
}
|
|
3052
|
+
|
|
3053
|
+
// Write async keyword
|
|
3054
|
+
if (node.value?.async) {
|
|
3055
|
+
context.write('async ');
|
|
3056
|
+
}
|
|
3057
|
+
|
|
3058
|
+
// Write the method key
|
|
3059
|
+
if (node.computed) {
|
|
3060
|
+
context.write('[');
|
|
3061
|
+
context.visit(node.key);
|
|
3062
|
+
context.write(']');
|
|
3063
|
+
} else {
|
|
3064
|
+
context.visit(node.key);
|
|
3065
|
+
}
|
|
3066
|
+
|
|
3067
|
+
// Visit typeParameters if present (THIS IS THE FIX)
|
|
3068
|
+
// TypeParameters can be on either the MethodDefinition or its value (FunctionExpression)
|
|
3069
|
+
if (node.typeParameters) {
|
|
3070
|
+
context.visit(node.typeParameters);
|
|
3071
|
+
} else if (node.value?.typeParameters) {
|
|
3072
|
+
context.visit(node.value.typeParameters);
|
|
3073
|
+
}
|
|
3074
|
+
|
|
3075
|
+
// Write parameters - set location for opening '('
|
|
3076
|
+
if (node.value?.loc) {
|
|
3077
|
+
context.location(node.value.loc.start.line, node.value.loc.start.column);
|
|
3078
|
+
}
|
|
3079
|
+
context.write('(');
|
|
3080
|
+
if (node.value?.params) {
|
|
3081
|
+
for (let i = 0; i < node.value.params.length; i++) {
|
|
3082
|
+
if (i > 0) context.write(', ');
|
|
3083
|
+
context.visit(node.value.params[i]);
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
context.write(')');
|
|
3087
|
+
|
|
3088
|
+
// Write return type if present
|
|
3089
|
+
if (node.value?.returnType) {
|
|
3090
|
+
context.visit(node.value.returnType);
|
|
3091
|
+
}
|
|
3092
|
+
|
|
3093
|
+
// Write method body
|
|
3094
|
+
if (node.value?.body) {
|
|
3095
|
+
context.write(' ');
|
|
3096
|
+
context.visit(node.value.body);
|
|
3097
|
+
}
|
|
3098
|
+
},
|
|
3099
|
+
TSTypeParameter(node, context) {
|
|
3100
|
+
// Set location for the type parameter name
|
|
3101
|
+
if (node.loc) {
|
|
3102
|
+
context.location(node.loc.start.line, node.loc.start.column);
|
|
3103
|
+
}
|
|
3104
|
+
if (typeof node.name === 'string') {
|
|
3105
|
+
context.write(node.name);
|
|
3106
|
+
} else if (node.name && node.name.name) {
|
|
3107
|
+
context.write(node.name.name);
|
|
3108
|
+
}
|
|
3109
|
+
if (node.constraint) {
|
|
3110
|
+
context.write(' extends ');
|
|
3111
|
+
context.visit(node.constraint);
|
|
3112
|
+
}
|
|
3113
|
+
if (node.default) {
|
|
3114
|
+
context.write(' = ');
|
|
3115
|
+
context.visit(node.default);
|
|
3116
|
+
}
|
|
3117
|
+
},
|
|
3059
3118
|
ArrayPattern(node, context) {
|
|
3060
3119
|
context.write('[');
|
|
3061
3120
|
for (let i = 0; i < node.elements.length; i++) {
|
|
@@ -3070,31 +3129,12 @@ function create_tsx_with_typescript_support() {
|
|
|
3070
3129
|
context.visit(node.typeAnnotation);
|
|
3071
3130
|
}
|
|
3072
3131
|
},
|
|
3073
|
-
/**
|
|
3074
|
-
* Custom handler for FunctionDeclaration to support component->function mapping
|
|
3075
|
-
* Needed for volar mappings and intellisense on function or component keyword
|
|
3076
|
-
* @param {AST.FunctionDeclaration} node
|
|
3077
|
-
* @param {ESRap.Context} context
|
|
3078
|
-
*/
|
|
3079
3132
|
FunctionDeclaration(node, context) {
|
|
3080
3133
|
handle_function(node, context);
|
|
3081
3134
|
},
|
|
3082
|
-
/**
|
|
3083
|
-
* Custom handler for FunctionExpression to support component->function mapping
|
|
3084
|
-
* This is used for components transformed by the Component visitor
|
|
3085
|
-
* @param {AST.FunctionExpression} node
|
|
3086
|
-
* @param {ESRap.Context} context
|
|
3087
|
-
*/
|
|
3088
3135
|
FunctionExpression(node, context) {
|
|
3089
3136
|
handle_function(node, context);
|
|
3090
3137
|
},
|
|
3091
|
-
/**
|
|
3092
|
-
* Custom handler for ImportDeclaration to ensure 'import' keyword has source mapping
|
|
3093
|
-
* This creates a source map entry at the start of the import statement
|
|
3094
|
-
* Esrap's default handler writes 'import' without passing the node, so no source map entry
|
|
3095
|
-
* @param {AST.ImportDeclaration} node
|
|
3096
|
-
* @param {ESRap.Context} context
|
|
3097
|
-
*/
|
|
3098
3138
|
ImportDeclaration(node, context) {
|
|
3099
3139
|
// Write 'import' keyword with node location for source mapping
|
|
3100
3140
|
context.write('import', node);
|
|
@@ -3148,13 +3188,6 @@ function create_tsx_with_typescript_support() {
|
|
|
3148
3188
|
// Write source
|
|
3149
3189
|
context.visit(node.source);
|
|
3150
3190
|
},
|
|
3151
|
-
/**
|
|
3152
|
-
* Custom handler for JSXOpeningElement to ensure '<' and '>' have source mappings
|
|
3153
|
-
* Esrap's default handler only maps the tag name, not the brackets
|
|
3154
|
-
* This creates mappings for the brackets so auto-close can find the cursor position
|
|
3155
|
-
* @param {ESTreeJSX.JSXOpeningElement} node
|
|
3156
|
-
* @param {ESRap.Context} context
|
|
3157
|
-
*/
|
|
3158
3191
|
JSXOpeningElement(node, context) {
|
|
3159
3192
|
// Set location for '<'
|
|
3160
3193
|
if (node.loc) {
|
|
@@ -3182,21 +3215,11 @@ function create_tsx_with_typescript_support() {
|
|
|
3182
3215
|
context.write('>');
|
|
3183
3216
|
}
|
|
3184
3217
|
},
|
|
3185
|
-
/**
|
|
3186
|
-
* Custom handler for TSParenthesizedType: (Type)
|
|
3187
|
-
* @param {AST.TSParenthesizedType} node
|
|
3188
|
-
* @param {ESRap.Context} context
|
|
3189
|
-
*/
|
|
3190
3218
|
TSParenthesizedType(node, context) {
|
|
3191
3219
|
context.write('(');
|
|
3192
3220
|
context.visit(/** @type {AST.TSTypeAnnotation} */ (node.typeAnnotation));
|
|
3193
3221
|
context.write(')');
|
|
3194
3222
|
},
|
|
3195
|
-
/**
|
|
3196
|
-
* Custom handler for TSMappedType: { [K in keyof T]: T[K] }
|
|
3197
|
-
* @param {AST.TSMappedType} node
|
|
3198
|
-
* @param {ESRap.Context} context
|
|
3199
|
-
*/
|
|
3200
3223
|
TSMappedType(node, context) {
|
|
3201
3224
|
context.write('{ ');
|
|
3202
3225
|
if (node.readonly) {
|
|
@@ -3228,34 +3251,6 @@ function create_tsx_with_typescript_support() {
|
|
|
3228
3251
|
}
|
|
3229
3252
|
context.write(' }');
|
|
3230
3253
|
},
|
|
3231
|
-
/**
|
|
3232
|
-
* Custom handler for TSTypeParameter: K in T (for mapped types)
|
|
3233
|
-
* acorn-ts has a bug where `in` is printed as `extends`, so we override it here
|
|
3234
|
-
* @param {AST.TSTypeParameter} node
|
|
3235
|
-
* @param {ESRap.Context} context
|
|
3236
|
-
*/
|
|
3237
|
-
TSTypeParameter(node, context) {
|
|
3238
|
-
// For mapped types, the name is just a string, not an Identifier node
|
|
3239
|
-
// Pass the node as second parameter to context.write() to create source map entry
|
|
3240
|
-
if (typeof node.name === 'string') {
|
|
3241
|
-
context.write(node.name, node);
|
|
3242
|
-
} else if (node.name && node.name.name) {
|
|
3243
|
-
context.write(node.name.name, node.name);
|
|
3244
|
-
}
|
|
3245
|
-
if (node.constraint) {
|
|
3246
|
-
context.write(' in ');
|
|
3247
|
-
context.visit(node.constraint);
|
|
3248
|
-
}
|
|
3249
|
-
if (node.default) {
|
|
3250
|
-
context.write(' = ');
|
|
3251
|
-
context.visit(node.default);
|
|
3252
|
-
}
|
|
3253
|
-
},
|
|
3254
|
-
/**
|
|
3255
|
-
* Override the ArrowFunctionExpression handler to support TypeScript return types
|
|
3256
|
-
* @param {AST.ArrowFunctionExpression} node
|
|
3257
|
-
* @param {ESRap.Context} context
|
|
3258
|
-
*/
|
|
3259
3254
|
ArrowFunctionExpression(node, context) {
|
|
3260
3255
|
if (node.async) context.write('async ');
|
|
3261
3256
|
|
|
@@ -3287,11 +3282,57 @@ function create_tsx_with_typescript_support() {
|
|
|
3287
3282
|
context.visit(node.body);
|
|
3288
3283
|
}
|
|
3289
3284
|
},
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3285
|
+
ClassDeclaration(node, context) {
|
|
3286
|
+
context.write('class ');
|
|
3287
|
+
if (node.id) {
|
|
3288
|
+
context.visit(node.id);
|
|
3289
|
+
}
|
|
3290
|
+
if (node.typeParameters) {
|
|
3291
|
+
context.visit(node.typeParameters);
|
|
3292
|
+
}
|
|
3293
|
+
if (node.superClass) {
|
|
3294
|
+
context.write(' extends ');
|
|
3295
|
+
context.visit(node.superClass);
|
|
3296
|
+
if (node.superTypeArguments) {
|
|
3297
|
+
context.visit(node.superTypeArguments);
|
|
3298
|
+
}
|
|
3299
|
+
}
|
|
3300
|
+
if (node.implements && node.implements.length > 0) {
|
|
3301
|
+
context.write(' implements ');
|
|
3302
|
+
for (let i = 0; i < node.implements.length; i++) {
|
|
3303
|
+
if (i > 0) context.write(', ');
|
|
3304
|
+
context.visit(node.implements[i]);
|
|
3305
|
+
}
|
|
3306
|
+
}
|
|
3307
|
+
context.write(' ');
|
|
3308
|
+
context.visit(node.body);
|
|
3309
|
+
},
|
|
3310
|
+
ClassExpression(node, context) {
|
|
3311
|
+
context.write('class');
|
|
3312
|
+
if (node.id) {
|
|
3313
|
+
context.write(' ');
|
|
3314
|
+
context.visit(node.id);
|
|
3315
|
+
}
|
|
3316
|
+
if (node.typeParameters) {
|
|
3317
|
+
context.visit(node.typeParameters);
|
|
3318
|
+
}
|
|
3319
|
+
if (node.superClass) {
|
|
3320
|
+
context.write(' extends ');
|
|
3321
|
+
context.visit(node.superClass);
|
|
3322
|
+
if (node.superTypeArguments) {
|
|
3323
|
+
context.visit(node.superTypeArguments);
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
if (node.implements && node.implements.length > 0) {
|
|
3327
|
+
context.write(' implements ');
|
|
3328
|
+
for (let i = 0; i < node.implements.length; i++) {
|
|
3329
|
+
if (i > 0) context.write(', ');
|
|
3330
|
+
context.visit(node.implements[i]);
|
|
3331
|
+
}
|
|
3332
|
+
}
|
|
3333
|
+
context.write(' ');
|
|
3334
|
+
context.visit(node.body);
|
|
3335
|
+
},
|
|
3295
3336
|
TryStatement(node, context) {
|
|
3296
3337
|
context.write('try ');
|
|
3297
3338
|
context.visit(node.block);
|
|
@@ -3325,7 +3366,7 @@ function create_tsx_with_typescript_support() {
|
|
|
3325
3366
|
context.visit(node.finalizer);
|
|
3326
3367
|
}
|
|
3327
3368
|
},
|
|
3328
|
-
};
|
|
3369
|
+
});
|
|
3329
3370
|
}
|
|
3330
3371
|
|
|
3331
3372
|
/**
|
|
@@ -3389,6 +3430,13 @@ export function transform_client(filename, source, analysis, to_ts, minify_css)
|
|
|
3389
3430
|
metadata: {},
|
|
3390
3431
|
};
|
|
3391
3432
|
|
|
3433
|
+
// Add ripple internal import once for the entire module
|
|
3434
|
+
// Whatever is unused will be tree-shaken later, including a rare case
|
|
3435
|
+
// where nothing from ripple/internal/client is used
|
|
3436
|
+
if (!to_ts) {
|
|
3437
|
+
state.imports.add(`import * as _$_ from 'ripple/internal/client'`);
|
|
3438
|
+
}
|
|
3439
|
+
|
|
3392
3440
|
const program = /** @type {AST.Program} */ (walk(analysis.ast, { ...state }, visitors));
|
|
3393
3441
|
|
|
3394
3442
|
for (const hoisted of state.hoisted) {
|
|
@@ -3407,7 +3455,9 @@ export function transform_client(filename, source, analysis, to_ts, minify_css)
|
|
|
3407
3455
|
);
|
|
3408
3456
|
}
|
|
3409
3457
|
|
|
3410
|
-
const language_handler = to_ts
|
|
3458
|
+
const language_handler = to_ts
|
|
3459
|
+
? create_tsx_with_typescript_support()
|
|
3460
|
+
: /** @type {Visitors<AST.Node, TransformClientState>} */ (tsx());
|
|
3411
3461
|
|
|
3412
3462
|
const js =
|
|
3413
3463
|
/** @type {ReturnType<typeof print> & { post_processing_changes?: PostProcessingChanges, line_offsets?: number[] }} */ (
|