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

feat(source-map): add API to support generated code with different length than original code #183

Merged
merged 1 commit into from
May 23, 2024

Conversation

piotrtomiak
Copy link
Contributor

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 on Mapping interface and adds support for it across the codebase.

There is also a fix for findOverlapCodeRange present. mappedEnd was incorrectly calculated.

@johnsoncodehk
Copy link
Member

johnsoncodehk commented May 23, 2024

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.

CC8u6Lp8BOSnpuZp.mp4

Before merging the PR, I want to confirm whether you have considered the above method.

@piotrtomiak
Copy link
Contributor Author

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.

@johnsoncodehk
Copy link
Member

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.

@johnsoncodehk johnsoncodehk merged commit cc05562 into volarjs:master May 23, 2024
3 checks passed
@piotrtomiak
Copy link
Contributor Author

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants