Closed piotrtomiak closed 3 months ago
Thank you for your contribution. This method has been deprecated in Volar v2, as we found a more reliable way is to split the code with varying lengths into multiple segments.
For example, the v-load
directive in the Vue template is generated into vLoad
of different length, and the mapping input is:
{
sourceOffsets: [0 /* v */, 2 /* load */],
generatedOffsets: [0 /* v */, 1 /* Load */],
lengths: [1, 4],
}
This helps to align each character.
https://github.com/volarjs/volar.js/assets/16279759/7ee7f9ab-c935-40aa-bd52-03bf959076dd
Before merging the PR, I want to confirm whether you have considered the above method.
That's a good point. I wanted to do something like that, but the problem I am facing is as follows:
This is the template:
<main *ngIf="title != 'foo' as bar" [foo]="{a: outletRef}">
<div [foo]="{a: outletRef}" [foo2]="12 | thePipe">
<router-outlet #outletRef="outlet"></router-outlet>
</div>
</main>
<span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago}}</span>
and this is the generated code:
function _tcb_0<T extends mytype>(this: AppComponent<T>) {
var _pipe1: MyPipe = null!;
const _ctor1: <T = any>(init: Pick<TestIf<T>, "ngIf" | "ngIfThen">) => TestIf<T> = null!;
const _ctor2: <T extends number = any>(init: Pick<TestFoo<T>, "foo" | "foo2">) => TestFoo<T> = null!;
var _t1 = _ctor1({ "ngIf": this.title != 'foo', "ngIfThen": null as any });
_t1.ngIf = this.title != 'foo';
var _t2: any = null!;
if (TestIf.ngTemplateContextGuard(_t1, _t2) && this.title != 'foo') {
var _t3 = _t2.ngIf;
var _t5: RouterOutlet = null!;
var _t4 = _t5;
var _t6 = _ctor2({ "foo": {
"a": _t4
}, "foo2": null as any });
_t6.foo = {
"a": _t4
};
var _t7 = _ctor2({ "foo": {
"a": _t4
}, "foo2": _pipe1.transform(12) });
_t7.foo = ({
"a": _t4
});
_t7.foo2 = _pipe1.transform(12);
}
"" + this.minutes;
"" + this.minutes;
}
A good example here is pipe call: 12 | thePipe
, which is translated to _pipe1.transform(12)
in the output. The thePipe
needs to map to transform
.
Another one is {a: outletRef}
, which is translated to {"a": _t4}
. Here outletRef
variable is replaced with generated name _t4
, so all of the references are replaced as well.
The transpilation code comes from Agnular compiler, and I cannot change the output.
Thanks for the explanation, I can see this being a problem that cannot be solved without replacing/changing the Angular compiler.
Not sure if that helps you, in https://github.com/volarjs/angular-language-tools (based on a rather outdated version of Volar) we avoid this by replacing the Angular compiler with @angular-eslint/bundled-angular-compiler
and implementing template code transpilation ourselves.
I'll merge it so it doesn't block your implementation, but if one day you solve this problem and no longer need generatedLengths
please let me know.
Thank you!
I am working on support for type checking of Angular templates in WebStorm using Volar in plug-in mode. In the Angular template transpilation logic some variables in expressions are renamed in the output, so the generated range length does not always match the source range length. This PR adds support for an optional
generatedLength
property onMapping
interface and adds support for it across the codebase.There is also a fix for
findOverlapCodeRange
present.mappedEnd
was incorrectly calculated.