Skip to content
This repository was archived by the owner on May 31, 2026. It is now read-only.

Commit 9bcc825

Browse files
committed
feat: 完善代码生成,解决编译错误
1 parent b3f08a6 commit 9bcc825

5 files changed

Lines changed: 58 additions & 42 deletions

File tree

src/binding.ts

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,10 @@ function compileObjectInitializer(obj: ObjectBinding) {
262262
}
263263
switch (init.kind) {
264264
case SyntaxKind.StringLiteral:
265-
return `strdup(${init.text})`;
265+
if (init.text === 'NULL') {
266+
return 'NULL';
267+
}
268+
return `strdup2(${init.text})`;
266269
case SyntaxKind.NumericLiteral:
267270
return init.text;
268271
case SyntaxKind.NewExpression:
@@ -401,52 +404,48 @@ function compileComponentEventHandlers(ctx: ComponentContext) {
401404
].join("\n\n");
402405
}
403406

404-
function compileComponentMethods(ctx: ComponentContext) {
405-
return [
406-
`static void ${ctx.name}_react_init(ui_widget_t *w)`,
407-
"{",
408-
` ${ctx.name}_react_t *_that = ui_widget_get_data(w, ${ctx.name}_proto);`,
409-
` ${ctx.name}_load_template(w, &_that->refs);`,
410-
` ${ctx.name}_react_init_state(w);`,
411-
` ${ctx.name}_react_init_events(w);`,
412-
` ${ctx.name}_react_update(w);`,
413-
"}\n",
414-
`static void ${ctx.name}_react_destroy(ui_widget_t *w)`,
415-
"{",
416-
` ${ctx.name}_react_destroy_state(w);`,
417-
"}\n",
418-
compileComponentMethod({ ctx, name: "react_update" }),
419-
].join("\n");
420-
}
421-
422407
function compileTypes(ctx: ComponentContext) {
423408
return [
424-
"typedef struct {",
409+
`typedef struct ${ctx.name}_react_state {`,
425410
...ctx.state.map(
426411
(item) =>
427412
` ${getObjectTypeName(item.initializer)} ${item.identifier};`
428413
),
429414
`} ${ctx.name}_react_state_t;`,
430-
'',
431-
'typedef struct {',
415+
"",
416+
`typedef struct ${ctx.name}_react {`,
432417
` ${ctx.name}_react_state_t state;`,
433418
` ${ctx.name}_refs_t refs;`,
434-
`} ${ctx.name}_react_t;`
435-
].join('\n');
419+
`} ${ctx.name}_react_t;`,
420+
].join("\n");
436421
}
437422

438423
function compileComponent(ctx: ComponentContext) {
439424
return [
440-
compiler.compileComponentState(ctx),
441-
compiler.compileComponentEventHandlers(ctx),
442-
compiler.compileComponentMethods(ctx),
425+
compileComponentState(ctx),
426+
compileComponentMethod({ ctx, name: "react_update" }),
427+
compileComponentEventHandlers(ctx),
428+
[
429+
`static void ${ctx.name}_react_init(ui_widget_t *w)`,
430+
"{",
431+
` ${ctx.name}_react_t *_that = ui_widget_get_data(w, ${ctx.name}_proto);`,
432+
` ${ctx.name}_load_template(w, &_that->refs);`,
433+
` ${ctx.name}_react_init_state(w);`,
434+
` ${ctx.name}_react_init_events(w);`,
435+
` ${ctx.name}_react_update(w);`,
436+
"}\n",
437+
`static void ${ctx.name}_react_destroy(ui_widget_t *w)`,
438+
"{",
439+
` ${ctx.name}_react_destroy_state(w);`,
440+
"}",
441+
].join("\n"),
443442
].join("\n\n");
444443
}
445444

446445
let contextList: FunctionContext[] = [];
447446

448447
export function getFunctionContext() {
449-
if (contextList.length < 2) {
448+
if (contextList.length < 1) {
450449
throw new SyntaxError("FunctionContext is missing");
451450
}
452451
return contextList[contextList.length - 1];
@@ -662,10 +661,9 @@ export const compiler = {
662661
compileObjectDestroyer,
663662
compileFunction,
664663
compileComponentState,
665-
compileComponentMethods,
666664
compileComponentEventHandlers,
667665
compileComponentMethod,
668-
compileComponent
666+
compileComponent,
669667
};
670668

671669
export const factory = {

src/compile.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { ReactElement, ReactNode } from "react";
1+
import React, { ReactElement, ReactNode, isValidElement } from "react";
22
import {
33
call,
44
ComponentContext,
@@ -9,6 +9,7 @@ import {
99
compiler,
1010
} from "./binding.js";
1111
import fmt from "./fmt.js";
12+
import { JSXObjectBinding } from "./jsx-runtime.js";
1213

1314
type ComponentFunction<T = {}> = {
1415
displayName?: string;
@@ -63,7 +64,7 @@ function transformNodeStyle(node: Node, style: Record<string, any>) {
6364

6465
function transformNodeChildren(node: Node, rawChildren: ReactNode[]) {
6566
let isPureText = true;
66-
let needFormat = false;
67+
let needFormat = true;
6768
const children = [];
6869

6970
React.Children.forEach(rawChildren, (child) => {
@@ -73,16 +74,16 @@ function transformNodeChildren(node: Node, rawChildren: ReactNode[]) {
7374
children.push(`${child}`);
7475
break;
7576
case "object":
76-
if (child) {
77-
if (isObjectBinding(child)) {
78-
needFormat = true;
79-
children.push(child);
80-
} else if (React.isValidElement(child)) {
81-
isPureText = false;
77+
if (isValidElement(child)) {
78+
isPureText = false;
79+
if (child.type === JSXObjectBinding) {
80+
children.push(child.props.value);
81+
} else {
82+
needFormat = false;
8283
children.push(child);
8384
}
84-
break;
8585
}
86+
break;
8687
default:
8788
break;
8889
}
@@ -276,13 +277,21 @@ void ${ctx.name}_update(ui_widget_t *w);
276277
277278
static void ${ctx.name}_init(ui_widget_t *w)
278279
{
279-
ui_widget_add_data(${ctx.name}_proto, sizeof(${ctx.name}_t));
280+
ui_widget_add_data(w, ${ctx.name}_proto, sizeof(${ctx.name}_t));
280281
${ctx.name}_react_init(w);
281282
// Write the initialization code for your component here
282283
// such as state initialization, event binding, etc
283284
// ...
284285
}
285286
287+
static void ${ctx.name}_destroy(ui_widget_t *w)
288+
{
289+
// Write code here to destroy the relevant resources of the component
290+
// ...
291+
292+
${ctx.name}_react_destroy(w);
293+
}
294+
286295
void ${ctx.name}_update(ui_widget_t *w)
287296
{
288297
${ctx.name}_react_update(w);

src/fmt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default function fmt(...args: Value[]) {
1414
8,
1515
CType.Size
1616
);
17-
const list = args.map((value) => stringifyValue(value));
17+
const list = args.map((value) => stringifyValue(value).__meta__.name);
1818

1919
ctx.body.push(...list.map((id) => `${len.__meta__.name} += strlen(${id})`));
2020
ctx.body.push(

src/jsx.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
declare namespace JSX {
2+
interface IntrinsicElements {
3+
a: LinkProps;
4+
text: WidgetBaseProps;
5+
textinput: TextInputProps;
6+
widget: WidgetProps;
7+
div: WidgetProps;
8+
}
9+
}

src/useState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export default function useState(initialValue: Value) {
6262
const ctx = getComponentContext();
6363
const stateName =
6464
ctx.stateNames[ctx.state.length] || `unnamed_state_${ctx.state.length}`;
65-
const stateCName = `_that->${stateName}`;
65+
const stateCName = `_that->state.${stateName}`;
6666

6767
if (isObjectBinding(initialValue)) {
6868
value = initialValue;

0 commit comments

Comments
 (0)