Why in plugin mode, the virtual code is offset by the size of the original file? #188
-
Hi! I have a use case, where my generated code (the code after import { Component, Directive, Input, Pipe, TemplateRef, ViewContainerRef } from '@angular/core';
import { NgClass, NgIf, NgIfContext } from '@angular/common';
import { RouterOutlet } from '@angular/router';
import {TcbCheckComponent} from "./tcb-check/tcb-check.component";
import {FormsModule} from "@angular/forms";
@Directive({
standalone: true,
selector: "ng-template[ngIf]"
})
export class TestIf<T> {
constructor(_viewContainer: ViewContainerRef, templateRef: TemplateRef<NgIfContext<T>>) {
}
@Input()
set ngIf(condition: T) {
}
@Input()
set ngIfThen(templateRef: TemplateRef<NgIfContext<T>> | null) {
}
static ngTemplateGuard_ngIf: 'binding';
static ngTemplateContextGuard<T>(dir: NgIf<T>, ctx: any): ctx is NgIfContext<number> {
return true
}
}
@Directive({
standalone: true,
selector: "[foo]"
})
export class TestFoo<T extends number> {
@Input()
set foo(condition: T) {
}
@Input()
set foo2(condition: T) {
}
}
@Pipe({
standalone: true,
name: "thePipe"
})
export class MyPipe {
transform(i: number): string {
return ""
}
}
type mytype = string
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, TestIf, NgClass, TestFoo, MyPipe, TcbCheckComponent, FormsModule],
templateUrl: "template.html",
})
export class AppComponent<T extends mytype> {
title = 'My Awesome Signal Store';
minutes!: number;
protected check(arg: T) {
}
}
/*tcb1*/
import * as _i0 from '@angular/forms';
function _tcb_1123<T extends mytype>(this: AppComponent<T>) { if (true) {
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 /*T:DIR*/ /*0,53*/ = _ctor1({ "ngIf": ((((this).title /*13,18*/) /*13,18*/) != ("foo" /*22,27*/) /*13,27*/) /*7,28*/, "ngIfThen": null as any }) /*D:ignore*/;
_t1.ngIf /*7,11*/ = ((((this).title /*13,18*/) /*13,18*/) != ("foo" /*22,27*/) /*13,27*/) /*7,28*/;
var _t2: any = null!;
if (TestIf.ngTemplateContextGuard(_t1, _t2) /*0,221*/ && (((this).title /*13,18*/) /*13,18*/) != ("foo" /*22,27*/) /*13,27*/ /*D:ignore*/) {
var _t3 /*31,34*/ = (_t2.ngIf /*7,11*/) /*7,34*/;
var _t5: RouterOutlet /*T:DIR*/ /*159,188*/ = null!;
var _t4 /*175,178*/ = _t5 /*174,187*/;
var _t6 /*T:DIR*/ /*0,53*/ = _ctor2({ "foo": ({
"a": _t4 /*47,50*/
} /*43,51*/) /*36,52*/, "foo2": null as any }) /*D:ignore*/;
_t6.foo /*37,40*/ = ({
"a": _t4 /*47,50*/
} /*43,51*/) /*36,52*/;
var _t7 /*T:DIR*/ /*56,154*/ = _ctor2({ "foo": ({
"a": _t4 /*72,75*/
} /*68,76*/) /*61,77*/, "foo2": (_pipe1.transform /*91,98*/(12 /*86,88*/, 123 /*101,104*/, 234 /*107,110*/) /*86,110*/) /*78,111*/ }) /*D:ignore*/;
_t7.foo /*62,65*/ = ({
"a": _t4 /*72,75*/
} /*68,76*/) /*61,77*/;
_t7.foo2 /*79,83*/ = (_pipe1.transform /*91,98*/(12 /*86,88*/, 123 /*101,104*/, 234 /*107,110*/) /*86,110*/) /*78,111*/;
var _t8: _i0.NgModel /*T:DIR*/ /*56,154*/ = null!;
_t8.model /*136,143*/ = (((this).title /*147,152*/) /*147,152*/) /*134,153*/;
_t8["update"] /*136,143*/.subscribe(($event /*T:EP*/): any => { if (TestIf.ngTemplateContextGuard(_t1, _t2) /*0,221*/ && (((this).title /*13,18*/) /*13,18*/) != ("foo" /*22,27*/) /*13,27*/ /*D:ignore*/)
(((this).title /*147,152*/) /*147,160*/ = ($event /*154,160*/)) /*147,160*/; }) /*134,153*/;
var _t9 = document.createElement("div") /*56,154*/;
_t9.addEventListener /*113,118*/("abort", ($event /*T:EP*/): any => { if (TestIf.ngTemplateContextGuard(_t1, _t2) /*0,221*/ && (((this).title /*13,18*/) /*13,18*/) != ("foo" /*22,27*/) /*13,27*/ /*D:ignore*/)
(((this).title /*121,126*/) /*121,126*/).at /*127,129*/(1 /*130,131*/) /*121,132*/; }) /*112,133*/;
}
"" + (((this).minutes /*243,250*/) /*243,250*/);
"" + (((this).minutes /*303,310*/) /*303,310*/);
} } All of the code in |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Due to the fact that the TS LanguageService API returns offsets instead of line/column positions, tsserver needs to convert the offsets to line/column positions. The purpose of adding offsets is to allow tsserver to correctly convert offsets to line/column positions. Consider the following source code and virtual code. Source code: <script setup>
// @ts-expect-error
let foo: string = 1;
// ^^^ 39~42
</script> Virtual code without offset: export default defineComponent(() => {
// @ts-expect-error
let foo: string = 1;
// ^^^ 64~67
}) Virtual code with offset:
export default defineComponent(() => {
// @ts-expect-error
let foo: string = 1;
// ^^^ 103~106
}) The range reported by ts-expect-error should be 39~42. For the "virtual code without offset", For the "virtual code with offset", because the offset aligns with the source code, the line/column can be correctly calculated as |
Beta Was this translation helpful? Give feedback.
Due to the fact that the TS LanguageService API returns offsets instead of line/column positions, tsserver needs to convert the offsets to line/column positions. The purpose of adding offsets is to allow tsserver to correctly convert offsets to line/column positions.
Consider the following source code and virtual code.
Source code:
Virtual code without offset:
Virtual code with offset: