@glint/ember-tsc 1.8.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cli/run-volar-tsc.d.ts.map +1 -1
- package/lib/cli/run-volar-tsc.js +112 -0
- package/lib/cli/run-volar-tsc.js.map +1 -1
- package/lib/transform/template/rewrite-module.js +35 -8
- package/lib/transform/template/rewrite-module.js.map +1 -1
- package/package.json +4 -4
- package/src/cli/run-volar-tsc.ts +136 -0
- package/src/transform/template/rewrite-module.ts +35 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-volar-tsc.d.ts","sourceRoot":"","sources":["../../src/cli/run-volar-tsc.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-volar-tsc.d.ts","sourceRoot":"","sources":["../../src/cli/run-volar-tsc.ts"],"names":[],"mappings":"AAcA,wBAAgB,GAAG,IAAI,IAAI,CAgC1B"}
|
package/lib/cli/run-volar-tsc.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { runTsc } from '@volar/typescript/lib/quickstart/runTsc.js';
|
|
2
2
|
import { createEmberLanguagePlugin } from '../volar/ember-language-plugin.js';
|
|
3
3
|
import { findConfig } from '../config/index.js';
|
|
4
|
+
import { VirtualGtsCode } from '../volar/gts-virtual-code.js';
|
|
5
|
+
import { getTransformErrorDiagnostics } from '../transform/diagnostics/transform-errors.js';
|
|
4
6
|
import { createRequire } from 'node:module';
|
|
5
7
|
const require = createRequire(import.meta.url);
|
|
6
8
|
// Loaded via CJS require so we can monkey-patch readFileSync; the ESM namespace
|
|
@@ -9,6 +11,7 @@ const require = createRequire(import.meta.url);
|
|
|
9
11
|
const fs = require('node:fs');
|
|
10
12
|
export function run() {
|
|
11
13
|
patchVolarProxyForExtensionlessImports();
|
|
14
|
+
patchVolarDecorateProgramForContentTagErrors();
|
|
12
15
|
let cwd = process.cwd();
|
|
13
16
|
const options = {
|
|
14
17
|
extraSupportedExtensions: ['.gjs', '.gts'],
|
|
@@ -73,4 +76,113 @@ function applyProxyPatches(source) {
|
|
|
73
76
|
}
|
|
74
77
|
return source.replace(literalsPattern, `$1${guard}$2`).replace(namesPattern, `$1${guard}$2`);
|
|
75
78
|
}
|
|
79
|
+
// Volar's `runTsc` does not surface the content-tag parse errors that we attach
|
|
80
|
+
// to `TransformedModule.errors` when content-tag fails to parse a .gts/.gjs
|
|
81
|
+
// file. The transformed source is intentionally blanked to whitespace in that
|
|
82
|
+
// case (see `rewriteModule`) so TypeScript does not emit a flood of misleading
|
|
83
|
+
// errors against the still-unparsed `<template>` tags; the trade-off is that
|
|
84
|
+
// the underlying parse failure is silently dropped.
|
|
85
|
+
//
|
|
86
|
+
// In language-server / tsserver-plugin contexts that silence is fine because
|
|
87
|
+
// the parse error is re-surfaced by separate diagnostic providers. But the
|
|
88
|
+
// `ember-tsc` CLI runs `tsc` via volar's `runTsc` (the Program path), which has
|
|
89
|
+
// no such provider — so `ember-tsc --noEmit` would report no errors at all on
|
|
90
|
+
// a broken template tag.
|
|
91
|
+
//
|
|
92
|
+
// We bridge that gap here by hot-patching `decorateProgram` from
|
|
93
|
+
// `@volar/typescript`: every time volar decorates a freshly created Program,
|
|
94
|
+
// we wrap its diagnostic methods to also include the synthesized content-tag
|
|
95
|
+
// diagnostics for any `.gts`/`.gjs` source files involved.
|
|
96
|
+
function patchVolarDecorateProgramForContentTagErrors() {
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-explicit-any
|
|
98
|
+
const decorateModule = require('@volar/typescript/lib/node/decorateProgram.js');
|
|
99
|
+
const originalDecorateProgram = decorateModule.decorateProgram;
|
|
100
|
+
decorateModule.decorateProgram = (language, program) => {
|
|
101
|
+
originalDecorateProgram(language, program);
|
|
102
|
+
injectContentTagDiagnostics(language, program);
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function injectContentTagDiagnostics(language, program) {
|
|
106
|
+
// Loaded lazily so the runtime `ts` namespace is available without changing
|
|
107
|
+
// the existing `import type ts` style at the top of the file.
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
109
|
+
const tsRuntime = require('typescript');
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
111
|
+
const lang = language;
|
|
112
|
+
// Cache of synthetic SourceFiles built from the original .gts/.gjs text,
|
|
113
|
+
// keyed by file name. We need our own SourceFile here because the one TS
|
|
114
|
+
// gives us via `program.getSourceFile` was built from the *transformed*
|
|
115
|
+
// (whitespace-blanked, on parse failure) text — so `--pretty` rendering
|
|
116
|
+
// would print an empty source line under the diagnostic header (see
|
|
117
|
+
// https://github.com/typed-ember/glint/pull/1149#discussion_r... for the
|
|
118
|
+
// bug report). The original text lives on volar's `sourceScript.snapshot`.
|
|
119
|
+
const originalSourceFiles = new Map();
|
|
120
|
+
const getOriginalSourceFile = (fileName) => {
|
|
121
|
+
const cached = originalSourceFiles.get(fileName);
|
|
122
|
+
if (cached)
|
|
123
|
+
return cached;
|
|
124
|
+
const sourceScript = lang.scripts.get(fileName);
|
|
125
|
+
const snapshot = sourceScript?.snapshot;
|
|
126
|
+
if (!snapshot)
|
|
127
|
+
return undefined;
|
|
128
|
+
const text = snapshot.getText(0, snapshot.getLength());
|
|
129
|
+
const sf = tsRuntime.createSourceFile(fileName, text, tsRuntime.ScriptTarget.Latest,
|
|
130
|
+
/* setParentNodes */ false);
|
|
131
|
+
originalSourceFiles.set(fileName, sf);
|
|
132
|
+
return sf;
|
|
133
|
+
};
|
|
134
|
+
// Returns the synthesized content-tag diagnostics for a given source file (or
|
|
135
|
+
// for every .gts/.gjs source file in the program when `sourceFile` is
|
|
136
|
+
// omitted). Diagnostic offsets are in original .gts/.gjs coordinates, which
|
|
137
|
+
// already match the synthetic SourceFile we attach.
|
|
138
|
+
const collectExtras = (sourceFile) => {
|
|
139
|
+
if (!sourceFile) {
|
|
140
|
+
const extras = [];
|
|
141
|
+
for (const sf of program.getSourceFiles()) {
|
|
142
|
+
extras.push(...collectExtras(sf));
|
|
143
|
+
}
|
|
144
|
+
return extras;
|
|
145
|
+
}
|
|
146
|
+
const sourceScript = lang.scripts.get(sourceFile.fileName);
|
|
147
|
+
const root = sourceScript?.generated?.root;
|
|
148
|
+
if (!(root instanceof VirtualGtsCode)) {
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
const transformedModule = root.transformedModule;
|
|
152
|
+
if (!transformedModule) {
|
|
153
|
+
return [];
|
|
154
|
+
}
|
|
155
|
+
// Render against the original .gts/.gjs text (not the SourceFile TS
|
|
156
|
+
// hands back, which holds the blanked transformed contents) so
|
|
157
|
+
// `tsc --pretty` prints the actual offending source line.
|
|
158
|
+
const originalSourceFile = getOriginalSourceFile(sourceFile.fileName) ?? sourceFile;
|
|
159
|
+
return getTransformErrorDiagnostics(transformedModule, originalSourceFile);
|
|
160
|
+
};
|
|
161
|
+
const wrapPerFileDiagnostics = (key) => {
|
|
162
|
+
// `getBindAndCheckDiagnostics` is the watch-mode counterpart and is also
|
|
163
|
+
// wrapped below via the same helper through a cast.
|
|
164
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
165
|
+
const original = program[key];
|
|
166
|
+
if (typeof original !== 'function') {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
170
|
+
program[key] = (sourceFile, cancellationToken) => {
|
|
171
|
+
const original$ = original.call(program, sourceFile, cancellationToken);
|
|
172
|
+
const extras = collectExtras(sourceFile);
|
|
173
|
+
return extras.length ? [...original$, ...extras] : original$;
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
wrapPerFileDiagnostics('getSyntacticDiagnostics');
|
|
177
|
+
wrapPerFileDiagnostics('getSemanticDiagnostics');
|
|
178
|
+
// `getBindAndCheckDiagnostics` is used by `tsc --noEmit --watch`; it has the
|
|
179
|
+
// same signature as the methods above but is not part of the public types.
|
|
180
|
+
wrapPerFileDiagnostics('getBindAndCheckDiagnostics');
|
|
181
|
+
const originalEmit = program.emit;
|
|
182
|
+
program.emit = (...args) => {
|
|
183
|
+
const result = originalEmit.apply(program, args);
|
|
184
|
+
const extras = collectExtras();
|
|
185
|
+
return extras.length ? { ...result, diagnostics: [...result.diagnostics, ...extras] } : result;
|
|
186
|
+
};
|
|
187
|
+
}
|
|
76
188
|
//# sourceMappingURL=run-volar-tsc.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-volar-tsc.js","sourceRoot":"","sources":["../../src/cli/run-volar-tsc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"run-volar-tsc.js","sourceRoot":"","sources":["../../src/cli/run-volar-tsc.ts"],"names":[],"mappings":"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"}
|
|
@@ -64,16 +64,43 @@ function calculateCorrelatedSpans(ts, script, environment, clientId) {
|
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
else if ('isContentTagError' in error && error.isContentTagError) {
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
// Translate content-tag's 1-based (line, column) into an absolute
|
|
68
|
+
// offset in the original source. We use the line/column verbatim
|
|
69
|
+
// (rather than shifting back a line) so the diagnostic lands exactly
|
|
70
|
+
// where content-tag's own snippet points — including for cases like
|
|
71
|
+
// `Unexpected eof` where the report sits at the end of a broken
|
|
72
|
+
// closing tag. The previous implementation summed the first
|
|
73
|
+
// `error.line` lines' lengths *without* their newlines, which by
|
|
74
|
+
// coincidence landed on the line above for some inputs and pointed
|
|
75
|
+
// at a blank line (or past EOF) for others (e.g. a `.gts` ending in
|
|
76
|
+
// `</templat\n`, which would render an empty source snippet).
|
|
77
|
+
let lines = script.contents.split('\n');
|
|
78
|
+
let lineIdx = Math.max(0, Math.min(error.line - 1, lines.length - 1));
|
|
79
|
+
let lineStart = 0;
|
|
80
|
+
for (let i = 0; i < lineIdx; i++) {
|
|
81
|
+
lineStart += lines[i].length + 1; // +1 for the consumed `\n`
|
|
82
|
+
}
|
|
83
|
+
let lineLength = lines[lineIdx]?.length ?? 0;
|
|
84
|
+
// Clamp the column to the last *character* of the line, not the
|
|
85
|
+
// newline that follows it. Otherwise a 1-char-wide diagnostic at
|
|
86
|
+
// (line N, col past EOL) would span across the `\n` into line N+1
|
|
87
|
+
// and TS would render two source-snippet lines (the second one
|
|
88
|
+
// empty) instead of just the offending one.
|
|
89
|
+
let col = lineLength === 0 ? 0 : Math.max(0, Math.min(error.column - 1, lineLength - 1));
|
|
90
|
+
let start = lineStart + col;
|
|
91
|
+
let end = Math.min(start + 1, script.contents.length);
|
|
72
92
|
errors.push({
|
|
73
93
|
isContentTagError: true,
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
|
|
94
|
+
// Use only `error.message` here. `error.help` is content-tag's pretty-
|
|
95
|
+
// printed source snippet with its own (1-based, post-error-line) line
|
|
96
|
+
// numbers, which conflict with the line/column the surrounding
|
|
97
|
+
// diagnostic surface (tsc, tsserver, LSP) reports for `location`.
|
|
98
|
+
// Including both produced output like
|
|
99
|
+
// src/Foo.gts(6,11): error TS0: Unexpected token ...
|
|
100
|
+
//
|
|
101
|
+
// 7 │ }
|
|
102
|
+
// where the two line numbers disagree and confuse readers.
|
|
103
|
+
message: error.message,
|
|
77
104
|
source: script,
|
|
78
105
|
location: {
|
|
79
106
|
start,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewrite-module.js","sourceRoot":"","sources":["../../../src/transform/template/rewrite-module.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,OAAO,EAAE,MAAM,EAAS,MAAM,YAAY,CAAC;AAG3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,iBAKN,MAAM,yBAAyB,CAAC;AASjC;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAC3B,EAAS,EACT,EAAE,MAAM,EAAgB,EACxB,WAA6B,EAC7B,QAAiB;IAEjB,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,wBAAwB,CACjE,EAAE,EACF,MAAM,EACN,WAAW,EACX,QAAQ,CACT,CAAC;IAEF,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,WAAW,GAAG,uBAAuB,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,0BAA0B,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;IAEhG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACpD,oEAAoE;QACpE,sEAAsE;QACtE,sEAAsE;QACtE,kEAAkE;QAClE,uEAAuE;QACvE,mEAAmE;QACnE,sEAAsE;QACtE,sDAAsD;QACtD,QAAQ,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QAC1C,eAAe,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC/C,GAAG,IAAI;YACP,iBAAiB,EAAE,oBAAoB,CAAC,IAAI,CAAC,iBAAiB,CAAC;SAChE,CAAC,CAAC,CAAC;IACN,CAAC;IAED,OAAO,IAAI,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC/F,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAa;IACzC,qEAAqE;IACrE,yEAAyE;IACzE,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;GAMG;AACH,SAAS,wBAAwB,CAC/B,EAAS,EACT,MAAkB,EAClB,WAA6B,EAC7B,QAAiB;IAEjB,IAAI,UAAU,GAAqB,EAAE,CAAC;IACtC,IAAI,MAAM,GAA0B,EAAE,CAAC;IAEvC,IAAI,YAAY,GAAiC,EAAE,CAAC;IAEpD,IAAI,QAAQ,KAAK,iBAAiB,EAAE,CAAC;QACnC,YAAY,CAAC,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IAExE,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,IAAI,CAAC;gBACV,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;gBACvD,MAAM,EAAE,MAAM;aACf,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,mBAAmB,IAAI,KAAK,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YACnE,
|
|
1
|
+
{"version":3,"file":"rewrite-module.js","sourceRoot":"","sources":["../../../src/transform/template/rewrite-module.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glint/ember-tsc",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.1",
|
|
4
4
|
"repository": "typed-ember/glint",
|
|
5
5
|
"description": "A CLI for performing typechecking on Glimmer templates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"vscode-languageserver-protocol": "^3.17.5",
|
|
83
83
|
"vscode-languageserver-textdocument": "^1.0.12",
|
|
84
84
|
"vscode-uri": "^3.1.0",
|
|
85
|
-
"@glint/template": "1.7.
|
|
85
|
+
"@glint/template": "1.7.8"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
88
|
"@glimmer/component": "^2.0.0",
|
|
@@ -97,8 +97,8 @@
|
|
|
97
97
|
"execa": "^4.0.1",
|
|
98
98
|
"strip-ansi": "^6.0.0",
|
|
99
99
|
"typescript": "^5.9.3",
|
|
100
|
-
"
|
|
101
|
-
"glint-
|
|
100
|
+
"glint-monorepo-test-utils": "0.0.0",
|
|
101
|
+
"@glint/type-test": "2.0.1"
|
|
102
102
|
},
|
|
103
103
|
"publishConfig": {
|
|
104
104
|
"access": "public"
|
package/src/cli/run-volar-tsc.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { runTsc } from '@volar/typescript/lib/quickstart/runTsc.js';
|
|
2
|
+
import type ts from 'typescript';
|
|
2
3
|
import { createEmberLanguagePlugin } from '../volar/ember-language-plugin.js';
|
|
3
4
|
import { findConfig } from '../config/index.js';
|
|
5
|
+
import { VirtualGtsCode } from '../volar/gts-virtual-code.js';
|
|
6
|
+
import { getTransformErrorDiagnostics } from '../transform/diagnostics/transform-errors.js';
|
|
4
7
|
|
|
5
8
|
import { createRequire } from 'node:module';
|
|
6
9
|
const require = createRequire(import.meta.url);
|
|
@@ -11,6 +14,7 @@ const fs = require('node:fs') as typeof import('node:fs');
|
|
|
11
14
|
|
|
12
15
|
export function run(): void {
|
|
13
16
|
patchVolarProxyForExtensionlessImports();
|
|
17
|
+
patchVolarDecorateProgramForContentTagErrors();
|
|
14
18
|
|
|
15
19
|
let cwd = process.cwd();
|
|
16
20
|
|
|
@@ -89,3 +93,135 @@ function applyProxyPatches(source: string): string {
|
|
|
89
93
|
|
|
90
94
|
return source.replace(literalsPattern, `$1${guard}$2`).replace(namesPattern, `$1${guard}$2`);
|
|
91
95
|
}
|
|
96
|
+
|
|
97
|
+
// Volar's `runTsc` does not surface the content-tag parse errors that we attach
|
|
98
|
+
// to `TransformedModule.errors` when content-tag fails to parse a .gts/.gjs
|
|
99
|
+
// file. The transformed source is intentionally blanked to whitespace in that
|
|
100
|
+
// case (see `rewriteModule`) so TypeScript does not emit a flood of misleading
|
|
101
|
+
// errors against the still-unparsed `<template>` tags; the trade-off is that
|
|
102
|
+
// the underlying parse failure is silently dropped.
|
|
103
|
+
//
|
|
104
|
+
// In language-server / tsserver-plugin contexts that silence is fine because
|
|
105
|
+
// the parse error is re-surfaced by separate diagnostic providers. But the
|
|
106
|
+
// `ember-tsc` CLI runs `tsc` via volar's `runTsc` (the Program path), which has
|
|
107
|
+
// no such provider — so `ember-tsc --noEmit` would report no errors at all on
|
|
108
|
+
// a broken template tag.
|
|
109
|
+
//
|
|
110
|
+
// We bridge that gap here by hot-patching `decorateProgram` from
|
|
111
|
+
// `@volar/typescript`: every time volar decorates a freshly created Program,
|
|
112
|
+
// we wrap its diagnostic methods to also include the synthesized content-tag
|
|
113
|
+
// diagnostics for any `.gts`/`.gjs` source files involved.
|
|
114
|
+
function patchVolarDecorateProgramForContentTagErrors(): void {
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-explicit-any
|
|
116
|
+
const decorateModule = require('@volar/typescript/lib/node/decorateProgram.js') as {
|
|
117
|
+
decorateProgram: (language: unknown, program: ts.Program) => void;
|
|
118
|
+
};
|
|
119
|
+
const originalDecorateProgram = decorateModule.decorateProgram;
|
|
120
|
+
|
|
121
|
+
decorateModule.decorateProgram = (language, program) => {
|
|
122
|
+
originalDecorateProgram(language, program);
|
|
123
|
+
injectContentTagDiagnostics(language, program);
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function injectContentTagDiagnostics(language: unknown, program: ts.Program): void {
|
|
128
|
+
// Loaded lazily so the runtime `ts` namespace is available without changing
|
|
129
|
+
// the existing `import type ts` style at the top of the file.
|
|
130
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
131
|
+
const tsRuntime = require('typescript') as typeof ts;
|
|
132
|
+
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
134
|
+
const lang = language as { scripts: { get(id: string): any } };
|
|
135
|
+
|
|
136
|
+
// Cache of synthetic SourceFiles built from the original .gts/.gjs text,
|
|
137
|
+
// keyed by file name. We need our own SourceFile here because the one TS
|
|
138
|
+
// gives us via `program.getSourceFile` was built from the *transformed*
|
|
139
|
+
// (whitespace-blanked, on parse failure) text — so `--pretty` rendering
|
|
140
|
+
// would print an empty source line under the diagnostic header (see
|
|
141
|
+
// https://github.com/typed-ember/glint/pull/1149#discussion_r... for the
|
|
142
|
+
// bug report). The original text lives on volar's `sourceScript.snapshot`.
|
|
143
|
+
const originalSourceFiles = new Map<string, ts.SourceFile>();
|
|
144
|
+
|
|
145
|
+
const getOriginalSourceFile = (fileName: string): ts.SourceFile | undefined => {
|
|
146
|
+
const cached = originalSourceFiles.get(fileName);
|
|
147
|
+
if (cached) return cached;
|
|
148
|
+
const sourceScript = lang.scripts.get(fileName);
|
|
149
|
+
const snapshot = sourceScript?.snapshot as ts.IScriptSnapshot | undefined;
|
|
150
|
+
if (!snapshot) return undefined;
|
|
151
|
+
const text = snapshot.getText(0, snapshot.getLength());
|
|
152
|
+
const sf = tsRuntime.createSourceFile(
|
|
153
|
+
fileName,
|
|
154
|
+
text,
|
|
155
|
+
tsRuntime.ScriptTarget.Latest,
|
|
156
|
+
/* setParentNodes */ false,
|
|
157
|
+
);
|
|
158
|
+
originalSourceFiles.set(fileName, sf);
|
|
159
|
+
return sf;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// Returns the synthesized content-tag diagnostics for a given source file (or
|
|
163
|
+
// for every .gts/.gjs source file in the program when `sourceFile` is
|
|
164
|
+
// omitted). Diagnostic offsets are in original .gts/.gjs coordinates, which
|
|
165
|
+
// already match the synthetic SourceFile we attach.
|
|
166
|
+
const collectExtras = (sourceFile?: ts.SourceFile): ts.Diagnostic[] => {
|
|
167
|
+
if (!sourceFile) {
|
|
168
|
+
const extras: ts.Diagnostic[] = [];
|
|
169
|
+
for (const sf of program.getSourceFiles()) {
|
|
170
|
+
extras.push(...collectExtras(sf));
|
|
171
|
+
}
|
|
172
|
+
return extras;
|
|
173
|
+
}
|
|
174
|
+
const sourceScript = lang.scripts.get(sourceFile.fileName);
|
|
175
|
+
const root = sourceScript?.generated?.root;
|
|
176
|
+
if (!(root instanceof VirtualGtsCode)) {
|
|
177
|
+
return [];
|
|
178
|
+
}
|
|
179
|
+
const transformedModule = root.transformedModule;
|
|
180
|
+
if (!transformedModule) {
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
// Render against the original .gts/.gjs text (not the SourceFile TS
|
|
184
|
+
// hands back, which holds the blanked transformed contents) so
|
|
185
|
+
// `tsc --pretty` prints the actual offending source line.
|
|
186
|
+
const originalSourceFile = getOriginalSourceFile(sourceFile.fileName) ?? sourceFile;
|
|
187
|
+
return getTransformErrorDiagnostics(transformedModule, originalSourceFile);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const wrapPerFileDiagnostics = <K extends 'getSyntacticDiagnostics' | 'getSemanticDiagnostics'>(
|
|
191
|
+
key: K,
|
|
192
|
+
): void => {
|
|
193
|
+
// `getBindAndCheckDiagnostics` is the watch-mode counterpart and is also
|
|
194
|
+
// wrapped below via the same helper through a cast.
|
|
195
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
196
|
+
const original = (program as any)[key];
|
|
197
|
+
if (typeof original !== 'function') {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
201
|
+
(program as any)[key] = (
|
|
202
|
+
sourceFile?: ts.SourceFile,
|
|
203
|
+
cancellationToken?: ts.CancellationToken,
|
|
204
|
+
): readonly ts.Diagnostic[] => {
|
|
205
|
+
const original$ = original.call(
|
|
206
|
+
program,
|
|
207
|
+
sourceFile,
|
|
208
|
+
cancellationToken,
|
|
209
|
+
) as readonly ts.Diagnostic[];
|
|
210
|
+
const extras = collectExtras(sourceFile);
|
|
211
|
+
return extras.length ? [...original$, ...extras] : original$;
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
wrapPerFileDiagnostics('getSyntacticDiagnostics');
|
|
216
|
+
wrapPerFileDiagnostics('getSemanticDiagnostics');
|
|
217
|
+
// `getBindAndCheckDiagnostics` is used by `tsc --noEmit --watch`; it has the
|
|
218
|
+
// same signature as the methods above but is not part of the public types.
|
|
219
|
+
wrapPerFileDiagnostics('getBindAndCheckDiagnostics' as unknown as 'getSyntacticDiagnostics');
|
|
220
|
+
|
|
221
|
+
const originalEmit = program.emit;
|
|
222
|
+
program.emit = (...args) => {
|
|
223
|
+
const result = originalEmit.apply(program, args);
|
|
224
|
+
const extras = collectExtras();
|
|
225
|
+
return extras.length ? { ...result, diagnostics: [...result.diagnostics, ...extras] } : result;
|
|
226
|
+
};
|
|
227
|
+
}
|
|
@@ -106,17 +106,44 @@ function calculateCorrelatedSpans(
|
|
|
106
106
|
source: script,
|
|
107
107
|
});
|
|
108
108
|
} else if ('isContentTagError' in error && error.isContentTagError) {
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
109
|
+
// Translate content-tag's 1-based (line, column) into an absolute
|
|
110
|
+
// offset in the original source. We use the line/column verbatim
|
|
111
|
+
// (rather than shifting back a line) so the diagnostic lands exactly
|
|
112
|
+
// where content-tag's own snippet points — including for cases like
|
|
113
|
+
// `Unexpected eof` where the report sits at the end of a broken
|
|
114
|
+
// closing tag. The previous implementation summed the first
|
|
115
|
+
// `error.line` lines' lengths *without* their newlines, which by
|
|
116
|
+
// coincidence landed on the line above for some inputs and pointed
|
|
117
|
+
// at a blank line (or past EOF) for others (e.g. a `.gts` ending in
|
|
118
|
+
// `</templat\n`, which would render an empty source snippet).
|
|
119
|
+
let lines = script.contents.split('\n');
|
|
120
|
+
let lineIdx = Math.max(0, Math.min(error.line - 1, lines.length - 1));
|
|
121
|
+
let lineStart = 0;
|
|
122
|
+
for (let i = 0; i < lineIdx; i++) {
|
|
123
|
+
lineStart += lines[i].length + 1; // +1 for the consumed `\n`
|
|
124
|
+
}
|
|
125
|
+
let lineLength = lines[lineIdx]?.length ?? 0;
|
|
126
|
+
// Clamp the column to the last *character* of the line, not the
|
|
127
|
+
// newline that follows it. Otherwise a 1-char-wide diagnostic at
|
|
128
|
+
// (line N, col past EOL) would span across the `\n` into line N+1
|
|
129
|
+
// and TS would render two source-snippet lines (the second one
|
|
130
|
+
// empty) instead of just the offending one.
|
|
131
|
+
let col = lineLength === 0 ? 0 : Math.max(0, Math.min(error.column - 1, lineLength - 1));
|
|
132
|
+
let start = lineStart + col;
|
|
133
|
+
let end = Math.min(start + 1, script.contents.length);
|
|
114
134
|
|
|
115
135
|
errors.push({
|
|
116
136
|
isContentTagError: true,
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
|
|
137
|
+
// Use only `error.message` here. `error.help` is content-tag's pretty-
|
|
138
|
+
// printed source snippet with its own (1-based, post-error-line) line
|
|
139
|
+
// numbers, which conflict with the line/column the surrounding
|
|
140
|
+
// diagnostic surface (tsc, tsserver, LSP) reports for `location`.
|
|
141
|
+
// Including both produced output like
|
|
142
|
+
// src/Foo.gts(6,11): error TS0: Unexpected token ...
|
|
143
|
+
//
|
|
144
|
+
// 7 │ }
|
|
145
|
+
// where the two line numbers disagree and confuse readers.
|
|
146
|
+
message: error.message,
|
|
120
147
|
source: script,
|
|
121
148
|
location: {
|
|
122
149
|
start,
|