Skip to content
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
9 changes: 9 additions & 0 deletions .changeset/async-attr-method-shorthand.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@marko/language-server": minor
"@marko/language-tools": minor
"@marko/ts-plugin": minor
"@marko/type-check": minor
"marko-vscode": minor
---

Support the `async` shorthand method modifier, eg `<button async onClick() { await save() }>`, so its body type-checks as an async function.
6 changes: 3 additions & 3 deletions packages/language-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@
},
"dependencies": {
"@luxass/strip-json-comments": "^1.4.0",
"@marko/compiler": "^5.41.7",
"@marko/compiler": "^5.42.0",
"@marko/language-tools": "^2.6.8",
"axe-core": "^4.12.1",
"htmljs-parser": "^5.12.1",
"htmljs-parser": "^5.14.0",
"jsdom": "^29.1.1",
"marko": "^5.39.27",
"marko": "^5.39.33",
"prettier": "^3.8.4",
"prettier-plugin-marko": "^4.0.10",
"relative-import-path": "^1.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,42 @@
5 | };
```

## Diagnostics
### Ln 1, Col 1
```marko
> 1 | <effect() {
| ^^^^^^^^^^^
> 2 | $signal.onabort = () => {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 3 | // ^?
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 4 | console.log('aborted');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 5 | };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 6 | }/>
| ^^^^ The 'effect' tag has been replaced by the 'script' tag.
7 |
```

## Code Actions
### The 'effect' tag has been replaced by the 'script' tag.
```marko
<script >
$signal.onabort = () => {
// ^?
console.log('aborted');
};
</script>
```

### Fix all auto-fixable Marko issues
```marko
<script >
$signal.onabort = () => {
// ^?
console.log('aborted');
};
</script>
```

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div data-marko-node-id="0"></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
export interface Input {
value(v: number): Promise<void>;
}
abstract class Component extends Marko.Component<Input> {}
export { type Component };
(function (this: void) {
const input = Marko._.any as Input;
const component = Marko._.any as Component;
const state = Marko._.state(component);
const out = Marko._.any as Marko.Out;
const $signal = Marko._.any as AbortSignal;
const $global = Marko._.getGlobal(
// @ts-expect-error We expect the compiler to error because we are checking if the MarkoRun.Context is defined.
(Marko._.error, Marko._.any as MarkoRun.Context),
);
Marko._.renderNativeTag("div")()()({});
Marko._.noop({ component, state, out, input, $global, $signal });
return;
})();
const __marko_internal_api = "class";
export { __marko_internal_api as "~api" };
const MyTag = new (class Template extends Marko._.Template<{
render(
input: Marko.TemplateInput<Input>,
stream?: {
write: (chunk: string) => void;
end: (chunk?: string) => void;
},
): Marko.Out<Component>;

render(
input: Marko.TemplateInput<Input>,
cb?: (err: Error | null, result: Marko.RenderResult<Component>) => void,
): Marko.Out<Component>;

renderSync(input: Marko.TemplateInput<Input>): Marko.RenderResult<Component>;

renderToString(input: Marko.TemplateInput<Input>): string;

stream(
input: Marko.TemplateInput<Input>,
): ReadableStream<string> & NodeJS.ReadableStream;

mount(
input: Marko.TemplateInput<Input>,
reference: Node,
position?: "afterbegin" | "afterend" | "beforebegin" | "beforeend",
): Marko.MountedTemplate<typeof input>;

api: typeof __marko_internal_api;
_(): () => <__marko_internal_input extends unknown>(
input: Marko.Directives &
Input &
Marko._.Relate<__marko_internal_input, Marko.Directives & Input>,
) => Marko._.ReturnWithScope<__marko_internal_input, void>;
}> {})();
export default MyTag;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<button data-marko-node-id="1" onClick>increment</button><button data-marko-node-id="2" onClick>generic</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
export interface Input {}
(function (this: void) {
const input = Marko._.any as Input;
const $signal = Marko._.any as AbortSignal;
const $global = Marko._.getGlobal(
// @ts-expect-error We expect the compiler to error because we are checking if the MarkoRun.Context is defined.
(Marko._.error, Marko._.any as MarkoRun.Context),
);
const count = Marko._.hoist(() => __marko_internal_hoist__count);
const __marko_internal_tag_1 = Marko._.resolveTemplate(
import("@marko/runtime-tags/tags/let.d.marko"),
);
{
const count = Marko._.returned(() => __marko_internal_rendered_1);
const __marko_internal_rendered_1 = Marko._.renderTemplate(
__marko_internal_tag_1,
)()()({
value: 0,
});
const __marko_internal_change__count = Marko._.change(
"count",
"value",
__marko_internal_rendered_1.return,
);
Marko._.renderNativeTag("button")()()({
async onClick() {
__marko_internal_change__count.count = await Promise.resolve(1);
},
[Marko._.content]: (() => {
return () => {
return Marko._.voidReturn;
};
})(),
});
Marko._.renderNativeTag("button")()()({
async onClick<T extends PointerEvent>(event: T) {
__marko_internal_change__count.count = await Promise.resolve(
event.detail,
);
},
[Marko._.content]: (() => {
return () => {
return Marko._.voidReturn;
};
})(),
});
const __marko_internal_tag_2 = Marko._.resolveTemplate(
import("./components/my-tag.marko"),
);
Marko._.renderTemplate(__marko_internal_tag_2)()()({
async value(value: number) {
__marko_internal_change__count.count = await Promise.resolve(value);
},
});
var __marko_internal_hoist__count = count;
}
Marko._.noop({ count, input, $global, $signal });
return;
})();
const __marko_internal_api = "tags";
export { __marko_internal_api as "~api" };
export default new (class Template extends Marko._.Template<{
render(
input: Marko.TemplateInput<Input>,
stream?: {
write: (chunk: string) => void;
end: (chunk?: string) => void;
},
): Marko.Out<never>;

render(
input: Marko.TemplateInput<Input>,
cb?: (err: Error | null, result: Marko.RenderResult<never>) => void,
): Marko.Out<never>;

renderSync(input: Marko.TemplateInput<Input>): Marko.RenderResult<never>;

renderToString(input: Marko.TemplateInput<Input>): string;

stream(
input: Marko.TemplateInput<Input>,
): ReadableStream<string> & NodeJS.ReadableStream;

mount(
input: Marko.TemplateInput<Input>,
reference: Node,
position?: "afterbegin" | "afterend" | "beforebegin" | "beforeend",
): Marko.MountedTemplate<typeof input>;

api: typeof __marko_internal_api;
_(): () => <__marko_internal_input extends unknown>(
input: Marko.Directives &
Input &
Marko._.Relate<__marko_internal_input, Marko.Directives & Input>,
) => Marko._.ReturnWithScope<__marko_internal_input, void>;
}> {})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface Input {
value(v: number): Promise<void>;
}

<div/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<let/count=0/>

<button async onClick() {
count = await Promise.resolve(1);
}>increment</button>

<button async onClick<T extends PointerEvent>(event: T) {
count = await Promise.resolve(event.detail);
}>generic</button>

<my-tag async (value: number) {
count = await Promise.resolve(value);
}/>
Loading