Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "fix: improve renderBody codegen" #286

Merged
merged 1 commit into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/pretty-spiders-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@marko/language-server": patch
"@marko/language-tools": patch
"@marko/type-check": patch
"marko-vscode": patch
---

Revert change to renderBody codegen which caused a regression with the `<await>` tag.
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
## Diagnostics
### Ln 2, Col 11
### Ln 3, Col 10
```marko
1 | <test-tag({ value: "hello!" })/>
> 2 | <test-tag("hello!")/>
| ^^^^^^^^ Argument of type 'string' is not assignable to parameter of type 'Directives & Input'.
Type 'string' is not assignable to type 'Input'.
3 | <test-tag("hello!", 1, 2)/>
4 |
```

### Ln 3, Col 21
```marko
1 | <test-tag({ value: "hello!" })/>
2 | <test-tag("hello!")/>
1 | <test-tag("hello!")/>
2 | <test-tag("hello!", 1)/>
> 3 | <test-tag("hello!", 1, 2)/>
| ^^^^ Expected 1 arguments, but got 3.
| ^^^^^^^^^^^^^^^^ Type of computed property's value is '[string, number, number]', which is not assignable to type '[string, (number | undefined)?]'.
Source has 3 element(s) but target allows only 2.
4 |
```

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export interface Input {
value: string
value: [string, number?]
}
<div/>
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<test-tag({ value: "hello!" })/>
<test-tag("hello!")/>
<test-tag("hello!", 1)/>
<test-tag("hello!", 1, 2)/>
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@ export interface Input {
renderBody: Marko.Body<[string]>
}

<${input.renderBody} value=["hi"] />

<${input.renderBody}=["hi"] />

<${input.renderBody}("hi") />

Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ export interface Input {
renderBody: Marko.Body<["a"], { value: "a" | "b" }>
}

<${input.renderBody}("a") />
<${input.renderBody}=["a"] />
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
## Diagnostics
### Ln 7, Col 27
### Ln 7, Col 28
```marko
5 | <${input.renderBody}("a", "b") />
5 | <${input.renderBody}=["a", "b"] />
6 |
> 7 | <${input.renderBody}("a", "c") />
| ^^^ Argument of type '"c"' is not assignable to parameter of type '"b"'.
> 7 | <${input.renderBody}=["a", "c"] />
| ^^^ Type '"c"' is not assignable to type '"b"'.
8 |
9 | <${input.renderBody}("a", "b", "c") />
9 | <${input.renderBody}=["a", "b", "c"] />
10 |
```

### Ln 9, Col 32
### Ln 9, Col 21
```marko
7 | <${input.renderBody}("a", "c") />
7 | <${input.renderBody}=["a", "c"] />
8 |
> 9 | <${input.renderBody}("a", "b", "c") />
| ^^^ Expected 2 arguments, but got 3.
> 9 | <${input.renderBody}=["a", "b", "c"] />
| ^ Type '["a", "b", string]' is not assignable to type '["a", "b"]'.
Source has 3 element(s) but target allows only 2.
10 |
```

Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ export interface Input {
renderBody: Marko.Body<["a", "b"]>
}

<${input.renderBody}("a", "b") />
<${input.renderBody}=["a", "b"] />

<${input.renderBody}("a", "c") />
<${input.renderBody}=["a", "c"] />

<${input.renderBody}("a", "b", "c") />
<${input.renderBody}=["a", "b", "c"] />
35 changes: 23 additions & 12 deletions packages/language-tools/marko.internal.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,14 @@ declare global {
? NativeTagRenderer<Name>
: [Name] extends [AnyMarkoBody]
? BodyRenderer<Name>
: [Name] extends [
{ renderBody?: infer Name extends AnyMarkoBody },
]
? BodyRenderer<Name>
: [Name] extends [{ renderBody?: AnyMarkoBody }]
? [Name["renderBody"]] extends [AnyMarkoBody]
? BodyRenderer<Name["renderBody"]>
: BaseRenderer<
RenderBodyInput<
BodyParameters<Exclude<Name["renderBody"], void>>
>
>
: DefaultRenderer;

export type TemplateRenderer<Template> = Template extends {
Expand Down Expand Up @@ -345,8 +349,12 @@ declare global {
export interface BodyRenderer<Body extends AnyMarkoBody> {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint
(): () => <__marko_internal_input extends unknown>(
...args: BodyParamsWithDefault<Body> &
Relate<__marko_internal_input, BodyParamsWithDefault<Body>>
input: Marko.Directives &
RenderBodyInput<BodyParameters<Body>> &
Relate<
__marko_internal_input,
Marko.Directives & RenderBodyInput<BodyParameters<Body>>
>,
) => ReturnAndScope<
Scopes<__marko_internal_input>,
BodyReturnType<Body>
Expand Down Expand Up @@ -393,12 +401,15 @@ type ReturnAndScope<Scope, Return> = {
scope: Scope;
};

type BodyParamsWithDefault<Body extends AnyMarkoBody> =
Body extends Marko.Body<infer Params, any>
? Params extends []
? [input?: Record<string, never>]
: Params
: never;
type RenderBodyInput<Args extends readonly unknown[]> = Args extends {
length: infer Length;
}
? number extends Length
? { value?: Args }
: 0 extends Length
? { value?: [] }
: { value: Args }
: never;

type Scopes<Input> = [0] extends [1 & Input]
? never
Expand Down
32 changes: 18 additions & 14 deletions packages/language-tools/src/extractors/script/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1197,27 +1197,33 @@ constructor(_?: Return) {}
#writeTagInputObject(tag: Node.ParentTag) {
if (!tag.params) this.#writeComments(tag);

const body = this.#processBody(tag);
let writeInputObj = true;
let hasInput = false;
this.#extractor.write("{\n");

if (tag.args) {
hasInput = true;
this.#extractor.copy(tag.args.value);

if (body || tag.attrs || tag.shorthandId || tag.shorthandClassNames) {
this.#extractor.write(",\n{\n");
} else {
writeInputObj = false;
}
} else {
this.#extractor.write("{\n");
this.#extractor
.write("[")
.copy({
start: tag.args.start,
end: tag.args.start + 1,
})
.write('"value"')
.copy({
start: tag.args.end - 1,
end: tag.args.end,
})
.write(`]: ${varShared("tuple")}(`)
.copy(tag.args.value)
.write(")")
.write(",\n");
}

if (this.#writeAttrs(tag)) {
hasInput = true;
}

const body = this.#processBody(tag);
let hasRenderBody = false;
if (body) {
hasInput = true;
Expand Down Expand Up @@ -1278,9 +1284,7 @@ constructor(_?: Return) {}
this.#writeTagNameComment(tag);
}

if (writeInputObj) {
this.#extractor.write("\n}");
}
this.#extractor.write("\n}");
}

#writeObjectKeys(keys: Iterable<string>) {
Expand Down
Loading