rip-lang 3.13.80 → 3.13.81
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/README.md +1 -1
- package/bin/rip +3 -9
- package/package.json +1 -1
- package/src/compiler.js +20 -63
- package/src/components.js +40 -73
- package/src/typecheck.js +12 -11
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
|
-
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.13.
|
|
12
|
+
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.13.81-blue.svg" alt="Version"></a>
|
|
13
13
|
<a href="#zero-dependencies"><img src="https://img.shields.io/badge/dependencies-ZERO-brightgreen.svg" alt="Dependencies"></a>
|
|
14
14
|
<a href="#"><img src="https://img.shields.io/badge/tests-1%2C436%2F1%2C436-brightgreen.svg" alt="Tests"></a>
|
|
15
15
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
|
package/bin/rip
CHANGED
|
@@ -32,7 +32,6 @@ Usage:
|
|
|
32
32
|
Options:
|
|
33
33
|
-c, --compile Show compiled JavaScript output
|
|
34
34
|
-d, --dts Show type declarations
|
|
35
|
-
-l, --lsp Show LSP TypeScript output (DTS + typed code for IntelliSense)
|
|
36
35
|
-m, --map Embed inline source map in compiled output
|
|
37
36
|
-h, --help Show this help message
|
|
38
37
|
-o, --output <file> Write JavaScript to file
|
|
@@ -162,7 +161,6 @@ async function main() {
|
|
|
162
161
|
const showSExpr = ripOptions.includes('-s') || ripOptions.includes('--sexpr');
|
|
163
162
|
const showCompiled = ripOptions.includes('-c') || ripOptions.includes('--compile');
|
|
164
163
|
const generateDts = ripOptions.includes('-d') || ripOptions.includes('--dts');
|
|
165
|
-
const showLsp = ripOptions.includes('-l') || ripOptions.includes('--lsp');
|
|
166
164
|
const generateMap = ripOptions.includes('-m') || ripOptions.includes('--map');
|
|
167
165
|
const quiet = ripOptions.includes('-q') || ripOptions.includes('--quiet');
|
|
168
166
|
|
|
@@ -176,7 +174,7 @@ async function main() {
|
|
|
176
174
|
}
|
|
177
175
|
|
|
178
176
|
// Stdin handling — read into memory; only write temp file for the execute path
|
|
179
|
-
const hasCompileFlag = showCompiled || showTokens || showSExpr || generateDts ||
|
|
177
|
+
const hasCompileFlag = showCompiled || showTokens || showSExpr || generateDts || generateMap || outputFile;
|
|
180
178
|
let source;
|
|
181
179
|
|
|
182
180
|
if (!inputFile) {
|
|
@@ -257,24 +255,20 @@ async function main() {
|
|
|
257
255
|
|
|
258
256
|
try {
|
|
259
257
|
const compiler = new Compiler({ showTokens, showSExpr, quiet,
|
|
260
|
-
types:
|
|
258
|
+
types: generateDts ? 'emit' : undefined,
|
|
261
259
|
sourceMap: generateMap ? 'inline' : undefined,
|
|
262
|
-
mode: showLsp ? 'lsp' : undefined,
|
|
263
260
|
});
|
|
264
261
|
const result = compiler.compile(source);
|
|
265
262
|
|
|
266
263
|
if (outputFile) {
|
|
267
264
|
writeFileSync(outputFile, result.code, 'utf-8');
|
|
268
265
|
if (!quiet) console.log(`Compiled to ${outputFile}`);
|
|
269
|
-
} else if (showLsp) {
|
|
270
|
-
if (!quiet) console.log(`// == LSP TypeScript output by Rip ${VERSION} == //\n`);
|
|
271
|
-
console.log(result.code);
|
|
272
266
|
} else if (showCompiled) {
|
|
273
267
|
if (!quiet) console.log(`// == JavaScript output by Rip ${VERSION} == //\n`);
|
|
274
268
|
console.log(result.code);
|
|
275
269
|
}
|
|
276
270
|
|
|
277
|
-
if (generateDts &&
|
|
271
|
+
if (generateDts && result.dts) {
|
|
278
272
|
if (!quiet) console.log(`// == Type declarations == //\n`);
|
|
279
273
|
console.log(result.dts);
|
|
280
274
|
}
|
package/package.json
CHANGED
package/src/compiler.js
CHANGED
|
@@ -297,11 +297,6 @@ export class CodeGenerator {
|
|
|
297
297
|
if (entry.loc) {
|
|
298
298
|
this.sourceMap.addMapping(lineOffset, 0, entry.loc.r, entry.loc.c);
|
|
299
299
|
}
|
|
300
|
-
if (entry.subLocs) {
|
|
301
|
-
for (const { lineOffset: lo, loc } of entry.subLocs) {
|
|
302
|
-
if (loc) this.sourceMap.addMapping(lineOffset + lo, 0, loc.r, loc.c);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
300
|
lineOffset += entry.code.split('\n').length;
|
|
306
301
|
}
|
|
307
302
|
}
|
|
@@ -624,12 +619,7 @@ export class CodeGenerator {
|
|
|
624
619
|
if (!blockStmts.includes(h) || !generated.endsWith('}')) generated += ';';
|
|
625
620
|
}
|
|
626
621
|
let loc = Array.isArray(stmt) ? stmt.loc : null;
|
|
627
|
-
|
|
628
|
-
if (this._pendingComponentLineLocs) {
|
|
629
|
-
entry.subLocs = this._pendingComponentLineLocs;
|
|
630
|
-
this._pendingComponentLineLocs = null;
|
|
631
|
-
}
|
|
632
|
-
return entry;
|
|
622
|
+
return { code: generated, loc };
|
|
633
623
|
});
|
|
634
624
|
let statementsCode = stmtEntries.map(e => e.code).join('\n');
|
|
635
625
|
|
|
@@ -681,32 +671,26 @@ export class CodeGenerator {
|
|
|
681
671
|
}
|
|
682
672
|
}
|
|
683
673
|
|
|
684
|
-
if (this.
|
|
685
|
-
if (
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
code += 'var { __state, __computed, __effect, __batch, __readonly, __setErrorHandler, __handleError, __catchErrors } = globalThis.__rip;\n';
|
|
692
|
-
} else if (typeof globalThis !== 'undefined' && globalThis.__rip) {
|
|
693
|
-
code += 'const { __state, __computed, __effect, __batch, __readonly, __setErrorHandler, __handleError, __catchErrors } = globalThis.__rip;\n';
|
|
694
|
-
} else {
|
|
695
|
-
code += this.getReactiveRuntime();
|
|
696
|
-
}
|
|
697
|
-
needsBlank = true;
|
|
674
|
+
if (this.usesReactivity && !skip) {
|
|
675
|
+
if (skipRT) {
|
|
676
|
+
code += 'var { __state, __computed, __effect, __batch, __readonly, __setErrorHandler, __handleError, __catchErrors } = globalThis.__rip;\n';
|
|
677
|
+
} else if (typeof globalThis !== 'undefined' && globalThis.__rip) {
|
|
678
|
+
code += 'const { __state, __computed, __effect, __batch, __readonly, __setErrorHandler, __handleError, __catchErrors } = globalThis.__rip;\n';
|
|
679
|
+
} else {
|
|
680
|
+
code += this.getReactiveRuntime();
|
|
698
681
|
}
|
|
682
|
+
needsBlank = true;
|
|
683
|
+
}
|
|
699
684
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
}
|
|
708
|
-
needsBlank = true;
|
|
685
|
+
if (this.usesTemplates && !skip) {
|
|
686
|
+
if (skipRT) {
|
|
687
|
+
code += 'var { __pushComponent, __popComponent, setContext, getContext, hasContext, __clsx, __lis, __reconcile, __transition, __handleComponentError, __Component } = globalThis.__ripComponent;\n';
|
|
688
|
+
} else if (typeof globalThis !== 'undefined' && globalThis.__ripComponent) {
|
|
689
|
+
code += 'const { __pushComponent, __popComponent, setContext, getContext, hasContext, __clsx, __lis, __reconcile, __transition, __handleComponentError, __Component } = globalThis.__ripComponent;\n';
|
|
690
|
+
} else {
|
|
691
|
+
code += this.getComponentRuntime();
|
|
709
692
|
}
|
|
693
|
+
needsBlank = true;
|
|
710
694
|
}
|
|
711
695
|
|
|
712
696
|
if (this.dataSection !== null && this.dataSection !== undefined && !skip) {
|
|
@@ -3305,15 +3289,13 @@ export class Compiler {
|
|
|
3305
3289
|
sourceMap = new SourceMapGenerator(file, sourceFile, source);
|
|
3306
3290
|
}
|
|
3307
3291
|
|
|
3308
|
-
let lspMode = this.options.mode === 'lsp';
|
|
3309
|
-
|
|
3310
3292
|
let generator = new CodeGenerator({
|
|
3311
3293
|
dataSection,
|
|
3312
|
-
skipPreamble:
|
|
3294
|
+
skipPreamble: this.options.skipPreamble,
|
|
3313
3295
|
skipRuntimes: this.options.skipRuntimes,
|
|
3314
3296
|
skipExports: this.options.skipExports,
|
|
3297
|
+
stubComponents: this.options.stubComponents,
|
|
3315
3298
|
reactiveVars: this.options.reactiveVars,
|
|
3316
|
-
lspMode,
|
|
3317
3299
|
sourceMap,
|
|
3318
3300
|
});
|
|
3319
3301
|
let code = generator.compile(sexpr);
|
|
@@ -3332,11 +3314,6 @@ export class Compiler {
|
|
|
3332
3314
|
dts = emitTypes(typeTokens, sexpr);
|
|
3333
3315
|
}
|
|
3334
3316
|
|
|
3335
|
-
// LSP mode: prepend DTS to code for a single combined output
|
|
3336
|
-
if (lspMode && dts) {
|
|
3337
|
-
code = dts.trimEnd() + '\n\n' + code;
|
|
3338
|
-
}
|
|
3339
|
-
|
|
3340
3317
|
return { tokens, sexpr, code, dts, map, reverseMap, data: dataSection, reactiveVars: generator.reactiveVars };
|
|
3341
3318
|
}
|
|
3342
3319
|
|
|
@@ -3398,24 +3375,4 @@ export function getComponentRuntime() {
|
|
|
3398
3375
|
return new CodeGenerator({}).getComponentRuntime();
|
|
3399
3376
|
}
|
|
3400
3377
|
|
|
3401
|
-
export function getLspRuntimeDeclarations() {
|
|
3402
|
-
return `\
|
|
3403
|
-
interface Signal<T> { value: T; read(): T; }
|
|
3404
|
-
interface Computed<T> { readonly value: T; read(): T; }
|
|
3405
|
-
declare function __state<T>(v: T): Signal<T>;
|
|
3406
|
-
declare function __computed<T>(fn: () => T): Computed<T>;
|
|
3407
|
-
declare function __effect(fn: () => void | (() => void)): () => void;
|
|
3408
|
-
declare function __batch<T>(fn: () => T): T;
|
|
3409
|
-
declare function __readonly<T>(v: T): Readonly<{ value: T }>;
|
|
3410
|
-
declare function __pushComponent(component: any): any;
|
|
3411
|
-
declare function __popComponent(prev: any): void;
|
|
3412
|
-
declare function __handleComponentError(error: any, component: any): void;
|
|
3413
|
-
declare function __clsx(...args: any[]): string;
|
|
3414
|
-
declare function setContext(key: string, value: any): void;
|
|
3415
|
-
declare function getContext(key: string): any;
|
|
3416
|
-
declare function hasContext(key: string): boolean;
|
|
3417
|
-
declare class __Component { constructor(props?: any); _create?(): any; _setup?(): void; _root?: any; _children?: any[]; [key: string]: any; }
|
|
3418
|
-
`;
|
|
3419
|
-
}
|
|
3420
|
-
|
|
3421
3378
|
export { formatSExpr };
|
package/src/components.js
CHANGED
|
@@ -669,6 +669,8 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
669
669
|
* Pattern: ["component", null, ["block", ...statements]]
|
|
670
670
|
*/
|
|
671
671
|
proto.generateComponent = function(head, rest, context, sexpr) {
|
|
672
|
+
if (this.options.stubComponents) return 'class {}';
|
|
673
|
+
|
|
672
674
|
const [, body] = rest;
|
|
673
675
|
|
|
674
676
|
this.usesTemplates = true;
|
|
@@ -713,35 +715,35 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
713
715
|
} else if (op === 'state') {
|
|
714
716
|
const varName = getMemberName(stmt[1]);
|
|
715
717
|
if (varName) {
|
|
716
|
-
stateVars.push({ name: varName, value: stmt[2], isPublic: isPublicProp(stmt[1]), type: getMemberType(stmt[1])
|
|
718
|
+
stateVars.push({ name: varName, value: stmt[2], isPublic: isPublicProp(stmt[1]), type: getMemberType(stmt[1]) });
|
|
717
719
|
memberNames.add(varName);
|
|
718
720
|
reactiveMembers.add(varName);
|
|
719
721
|
}
|
|
720
722
|
} else if (op === 'computed') {
|
|
721
723
|
const varName = getMemberName(stmt[1]);
|
|
722
724
|
if (varName) {
|
|
723
|
-
derivedVars.push({ name: varName, expr: stmt[2]
|
|
725
|
+
derivedVars.push({ name: varName, expr: stmt[2] });
|
|
724
726
|
memberNames.add(varName);
|
|
725
727
|
reactiveMembers.add(varName);
|
|
726
728
|
}
|
|
727
729
|
} else if (op === 'readonly') {
|
|
728
730
|
const varName = getMemberName(stmt[1]);
|
|
729
731
|
if (varName) {
|
|
730
|
-
readonlyVars.push({ name: varName, value: stmt[2], isPublic: isPublicProp(stmt[1]), type: getMemberType(stmt[1])
|
|
732
|
+
readonlyVars.push({ name: varName, value: stmt[2], isPublic: isPublicProp(stmt[1]), type: getMemberType(stmt[1]) });
|
|
731
733
|
memberNames.add(varName);
|
|
732
734
|
}
|
|
733
735
|
} else if (op === '=') {
|
|
734
736
|
const varName = getMemberName(stmt[1]);
|
|
735
737
|
if (varName) {
|
|
736
738
|
if (LIFECYCLE_HOOKS.has(varName)) {
|
|
737
|
-
lifecycleHooks.push({ name: varName, value: stmt[2]
|
|
739
|
+
lifecycleHooks.push({ name: varName, value: stmt[2] });
|
|
738
740
|
} else {
|
|
739
741
|
const val = stmt[2];
|
|
740
742
|
if (Array.isArray(val) && (val[0] === '->' || val[0] === '=>')) {
|
|
741
|
-
methods.push({ name: varName, func: val
|
|
743
|
+
methods.push({ name: varName, func: val });
|
|
742
744
|
memberNames.add(varName);
|
|
743
745
|
} else {
|
|
744
|
-
stateVars.push({ name: varName, value: val, isPublic: isPublicProp(stmt[1])
|
|
746
|
+
stateVars.push({ name: varName, value: val, isPublic: isPublicProp(stmt[1]) });
|
|
745
747
|
memberNames.add(varName);
|
|
746
748
|
reactiveMembers.add(varName);
|
|
747
749
|
}
|
|
@@ -757,9 +759,9 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
757
759
|
if (!Array.isArray(pair)) continue;
|
|
758
760
|
const [methodName, funcDef] = pair;
|
|
759
761
|
if (typeof methodName === 'string' && LIFECYCLE_HOOKS.has(methodName)) {
|
|
760
|
-
lifecycleHooks.push({ name: methodName, value: funcDef
|
|
762
|
+
lifecycleHooks.push({ name: methodName, value: funcDef });
|
|
761
763
|
} else if (typeof methodName === 'string') {
|
|
762
|
-
methods.push({ name: methodName, func: funcDef
|
|
764
|
+
methods.push({ name: methodName, func: funcDef });
|
|
763
765
|
memberNames.add(methodName);
|
|
764
766
|
}
|
|
765
767
|
}
|
|
@@ -783,76 +785,49 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
783
785
|
this._autoEventHandlers = autoEventHandlers.size > 0 ? autoEventHandlers : null;
|
|
784
786
|
|
|
785
787
|
const lines = [];
|
|
786
|
-
const lineLocs = [];
|
|
787
788
|
let blockFactoriesCode = '';
|
|
788
789
|
|
|
789
|
-
|
|
790
|
-
const pushLine = (line, loc) => {
|
|
791
|
-
if (loc) lineLocs.push({ lineOffset: totalLines, loc });
|
|
792
|
-
lines.push(line);
|
|
793
|
-
totalLines += line.split('\n').length;
|
|
794
|
-
};
|
|
795
|
-
const pushPlain = (line) => {
|
|
796
|
-
lines.push(line);
|
|
797
|
-
totalLines += line.split('\n').length;
|
|
798
|
-
};
|
|
799
|
-
|
|
800
|
-
pushPlain('class extends __Component {');
|
|
790
|
+
lines.push('class extends __Component {');
|
|
801
791
|
|
|
802
792
|
// --- Init (called by __Component constructor) ---
|
|
803
|
-
|
|
804
|
-
const typedProps = [];
|
|
805
|
-
for (const v of [...readonlyVars, ...stateVars]) {
|
|
806
|
-
if (v.isPublic) {
|
|
807
|
-
const t = v.type || 'any';
|
|
808
|
-
typedProps.push(`${v.name}?: ${t}`);
|
|
809
|
-
typedProps.push(`__bind_${v.name}__?: ${t}`);
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
const propsType = typedProps.length > 0
|
|
813
|
-
? `{ ${typedProps.join(', ')}, [key: string]: any }`
|
|
814
|
-
: 'any';
|
|
815
|
-
pushPlain(` _init(props: ${propsType}) {`);
|
|
816
|
-
} else {
|
|
817
|
-
pushPlain(' _init(props) {');
|
|
818
|
-
}
|
|
793
|
+
lines.push(' _init(props) {');
|
|
819
794
|
|
|
820
795
|
// Constants (readonly)
|
|
821
|
-
for (const { name, value, isPublic
|
|
796
|
+
for (const { name, value, isPublic } of readonlyVars) {
|
|
822
797
|
const val = this.generateInComponent(value, 'value');
|
|
823
|
-
|
|
798
|
+
lines.push(isPublic
|
|
824
799
|
? ` this.${name} = props.${name} ?? ${val};`
|
|
825
|
-
: ` this.${name} = ${val}
|
|
800
|
+
: ` this.${name} = ${val};`);
|
|
826
801
|
}
|
|
827
802
|
|
|
828
803
|
// Accepted vars (from ancestor context via getContext)
|
|
829
804
|
for (const name of acceptedVars) {
|
|
830
|
-
|
|
805
|
+
lines.push(` this.${name} = getContext('${name}');`);
|
|
831
806
|
}
|
|
832
807
|
|
|
833
808
|
// State variables (__state handles signal passthrough)
|
|
834
|
-
for (const { name, value, isPublic
|
|
809
|
+
for (const { name, value, isPublic } of stateVars) {
|
|
835
810
|
const val = this.generateInComponent(value, 'value');
|
|
836
|
-
|
|
811
|
+
lines.push(isPublic
|
|
837
812
|
? ` this.${name} = __state(props.__bind_${name}__ ?? props.${name} ?? ${val});`
|
|
838
|
-
: ` this.${name} = __state(${val})
|
|
813
|
+
: ` this.${name} = __state(${val});`);
|
|
839
814
|
}
|
|
840
815
|
|
|
841
816
|
// Computed (derived)
|
|
842
|
-
for (const { name, expr
|
|
817
|
+
for (const { name, expr } of derivedVars) {
|
|
843
818
|
if (this.is(expr, 'block')) {
|
|
844
819
|
const transformed = this.transformComponentMembers(expr);
|
|
845
820
|
const body = this.generateFunctionBody(transformed);
|
|
846
|
-
|
|
821
|
+
lines.push(` this.${name} = __computed(() => ${body});`);
|
|
847
822
|
} else {
|
|
848
823
|
const val = this.generateInComponent(expr, 'value');
|
|
849
|
-
|
|
824
|
+
lines.push(` this.${name} = __computed(() => ${val});`);
|
|
850
825
|
}
|
|
851
826
|
}
|
|
852
827
|
|
|
853
828
|
// Offered vars (share with descendants via setContext — after all members are initialized)
|
|
854
829
|
for (const name of offeredVars) {
|
|
855
|
-
|
|
830
|
+
lines.push(` setContext('${name}', this.${name});`);
|
|
856
831
|
}
|
|
857
832
|
|
|
858
833
|
// Effects
|
|
@@ -862,36 +837,36 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
862
837
|
if (this.is(effectBody, 'block')) {
|
|
863
838
|
const transformed = this.transformComponentMembers(effectBody);
|
|
864
839
|
const body = this.generateFunctionBody(transformed, [], true);
|
|
865
|
-
|
|
840
|
+
lines.push(` __effect(${isAsync}() => ${body});`);
|
|
866
841
|
} else {
|
|
867
842
|
const effectCode = this.generateInComponent(effectBody, 'value');
|
|
868
|
-
|
|
843
|
+
lines.push(` __effect(${isAsync}() => { ${effectCode}; });`);
|
|
869
844
|
}
|
|
870
845
|
}
|
|
871
846
|
|
|
872
|
-
|
|
847
|
+
lines.push(' }');
|
|
873
848
|
|
|
874
849
|
// --- Methods ---
|
|
875
|
-
for (const { name, func
|
|
850
|
+
for (const { name, func } of methods) {
|
|
876
851
|
if (Array.isArray(func) && (func[0] === '->' || func[0] === '=>')) {
|
|
877
852
|
const [, params, methodBody] = func;
|
|
878
853
|
const paramStr = Array.isArray(params) ? params.map(p => this.formatParam(p)).join(', ') : '';
|
|
879
854
|
const transformed = this.reactiveMembers ? this.transformComponentMembers(methodBody) : methodBody;
|
|
880
855
|
const isAsync = this.containsAwait(methodBody);
|
|
881
856
|
const bodyCode = this.generateFunctionBody(transformed, params || []);
|
|
882
|
-
|
|
857
|
+
lines.push(` ${isAsync ? 'async ' : ''}${name}(${paramStr}) ${bodyCode}`);
|
|
883
858
|
}
|
|
884
859
|
}
|
|
885
860
|
|
|
886
861
|
// --- Lifecycle hooks ---
|
|
887
|
-
for (const { name, value
|
|
862
|
+
for (const { name, value } of lifecycleHooks) {
|
|
888
863
|
if (Array.isArray(value) && (value[0] === '->' || value[0] === '=>')) {
|
|
889
864
|
const [, params, hookBody] = value;
|
|
890
865
|
const paramStr = Array.isArray(params) ? params.map(p => this.formatParam(p)).join(', ') : '';
|
|
891
866
|
const transformed = this.reactiveMembers ? this.transformComponentMembers(hookBody) : hookBody;
|
|
892
867
|
const isAsync = this.containsAwait(hookBody);
|
|
893
868
|
const bodyCode = this.generateFunctionBody(transformed, params || []);
|
|
894
|
-
|
|
869
|
+
lines.push(` ${isAsync ? 'async ' : ''}${name}(${paramStr}) ${bodyCode}`);
|
|
895
870
|
}
|
|
896
871
|
}
|
|
897
872
|
|
|
@@ -900,43 +875,35 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
900
875
|
const renderBody = renderBlock[1];
|
|
901
876
|
const result = this.buildRender(renderBody);
|
|
902
877
|
|
|
903
|
-
if (
|
|
878
|
+
if (result.blockFactories.length > 0) {
|
|
904
879
|
blockFactoriesCode = result.blockFactories.join('\n\n') + '\n\n';
|
|
905
880
|
}
|
|
906
881
|
|
|
907
|
-
|
|
882
|
+
lines.push(' _create() {');
|
|
908
883
|
for (const line of result.createLines) {
|
|
909
|
-
|
|
884
|
+
lines.push(` ${line}`);
|
|
910
885
|
}
|
|
911
|
-
|
|
912
|
-
|
|
886
|
+
lines.push(` return ${result.rootVar};`);
|
|
887
|
+
lines.push(' }');
|
|
913
888
|
|
|
914
|
-
if (
|
|
915
|
-
|
|
889
|
+
if (result.setupLines.length > 0) {
|
|
890
|
+
lines.push(' _setup() {');
|
|
916
891
|
for (const line of result.setupLines) {
|
|
917
|
-
|
|
892
|
+
lines.push(` ${line}`);
|
|
918
893
|
}
|
|
919
|
-
|
|
894
|
+
lines.push(' }');
|
|
920
895
|
}
|
|
921
896
|
}
|
|
922
897
|
|
|
923
|
-
|
|
898
|
+
lines.push('}');
|
|
924
899
|
|
|
925
900
|
// Restore context
|
|
926
901
|
this.componentMembers = prevComponentMembers;
|
|
927
902
|
this.reactiveMembers = prevReactiveMembers;
|
|
928
903
|
this._autoEventHandlers = prevAutoEventHandlers;
|
|
929
904
|
|
|
930
|
-
// Store line-level source mappings for the parent statement entry
|
|
931
|
-
if (lineLocs.length > 0) {
|
|
932
|
-
this._pendingComponentLineLocs = lineLocs;
|
|
933
|
-
}
|
|
934
|
-
|
|
935
905
|
// If block factories exist, wrap in IIFE so they're in scope
|
|
936
906
|
if (blockFactoriesCode) {
|
|
937
|
-
// Adjust lineOffsets for the IIFE wrapper + block factories prefix
|
|
938
|
-
const prefixLines = blockFactoriesCode.split('\n').length;
|
|
939
|
-
for (const entry of lineLocs) entry.lineOffset += prefixLines;
|
|
940
907
|
return `(() => {\n${blockFactoriesCode}return ${lines.join('\n')};\n})()`;
|
|
941
908
|
}
|
|
942
909
|
|
package/src/typecheck.js
CHANGED
|
@@ -41,11 +41,12 @@ export const SKIP_CODES = new Set([
|
|
|
41
41
|
2307, // Cannot find module
|
|
42
42
|
2393, // Duplicate function implementation
|
|
43
43
|
2451, // Cannot redeclare block-scoped variable
|
|
44
|
-
2554, // Expected N arguments but got M (generated event handler wrappers pass event arg)
|
|
45
|
-
7006, // Parameter implicitly has 'any' type (generated event callback params)
|
|
46
44
|
1064, // Return type of async function must be Promise
|
|
47
45
|
2582, // Cannot find name 'test' (test runner globals)
|
|
48
46
|
2593, // Cannot find name 'describe' (test runner globals)
|
|
47
|
+
7005, // Variable implicitly has an 'any' type (compiler-generated locals)
|
|
48
|
+
7006, // Parameter implicitly has an 'any' type (compiler-generated params)
|
|
49
|
+
7034, // Variable implicitly has type 'any' in some locations (compiler-generated)
|
|
49
50
|
]);
|
|
50
51
|
|
|
51
52
|
// Base TypeScript compiler settings for type-checking. Callers can
|
|
@@ -66,12 +67,13 @@ export function createTypeCheckSettings(ts, overrides = {}) {
|
|
|
66
67
|
|
|
67
68
|
// ── Shared compilation pipeline ────────────────────────────────────
|
|
68
69
|
|
|
69
|
-
// Compile a .rip file for type-checking.
|
|
70
|
-
//
|
|
71
|
-
//
|
|
70
|
+
// Compile a .rip file for type-checking. Prepends DTS declarations to
|
|
71
|
+
// compiled JS, detects type annotations, and builds bidirectional
|
|
72
|
+
// source maps. Returns everything both the CLI and LSP need.
|
|
72
73
|
export function compileForCheck(filePath, source, compiler) {
|
|
73
|
-
const result = compiler.compile(source, { sourceMap: true, types: 'emit',
|
|
74
|
+
const result = compiler.compile(source, { sourceMap: true, types: 'emit', skipPreamble: true, stubComponents: true });
|
|
74
75
|
let code = result.code || '';
|
|
76
|
+
const dts = result.dts ? result.dts.trimEnd() + '\n' : '';
|
|
75
77
|
|
|
76
78
|
// Determine if this file should be type-checked
|
|
77
79
|
const hasOwnTypes = hasTypeAnnotations(source);
|
|
@@ -92,9 +94,8 @@ export function compileForCheck(filePath, source, compiler) {
|
|
|
92
94
|
// Ensure every file is treated as a module (not a global script)
|
|
93
95
|
if (!/\bexport\b/.test(code) && !/\bimport\b/.test(code)) code += '\nexport {};\n';
|
|
94
96
|
|
|
95
|
-
const
|
|
96
|
-
const
|
|
97
|
-
const headerLines = hasTypes && dts ? countLines(dts + '\n') : 1;
|
|
97
|
+
const tsContent = (hasTypes ? dts + '\n' : '') + code;
|
|
98
|
+
const headerLines = hasTypes ? countLines(dts + '\n') : 1;
|
|
98
99
|
|
|
99
100
|
// Build bidirectional line maps
|
|
100
101
|
const { srcToGen, genToSrc } = buildLineMap(result.reverseMap, result.map, headerLines);
|
|
@@ -143,7 +144,7 @@ export function compileForCheck(filePath, source, compiler) {
|
|
|
143
144
|
}
|
|
144
145
|
}
|
|
145
146
|
|
|
146
|
-
return { tsContent, headerLines, hasTypes, srcToGen, genToSrc, source };
|
|
147
|
+
return { tsContent, headerLines, hasTypes, srcToGen, genToSrc, source, dts };
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
// ── Source mapping helpers ──────────────────────────────────────────
|
|
@@ -246,7 +247,7 @@ export async function runCheck(targetDir, opts = {}) {
|
|
|
246
247
|
}
|
|
247
248
|
|
|
248
249
|
// Create TypeScript language service
|
|
249
|
-
const settings = createTypeCheckSettings(ts
|
|
250
|
+
const settings = createTypeCheckSettings(ts);
|
|
250
251
|
|
|
251
252
|
const host = {
|
|
252
253
|
getScriptFileNames: () => [...compiled.keys()].map(toVirtual),
|