Signatur
Beschreibung
Die Eigenschaft linePos einer GPUCompilationMessage gibt an, an welcher Stelle innerhalb einer Zeile des WGSL-Shader-Codes eine Fehlermeldung, Warnung oder ein Hinweis beginnt. Zusammen mit lineNum ergibt sich so eine Position im Stil „Zeile:Spalte“, wie man sie aus Compiler-Ausgaben und Code-Editoren kennt.
Der Wert ist 1-basiert und wird in UTF-16-Codeeinheiten gezählt – also genauso wie JavaScript-String-Indizes, nur um eins verschoben. Bezieht sich eine Meldung nicht auf eine bestimmte Stelle (etwa auf den gesamten Shader), ist linePos 0.
Man erhält GPUCompilationMessage-Objekte über GPUShaderModule.getCompilationInfo(), das ein GPUCompilationInfo-Objekt mit dem Array messages liefert. Typische Anwendungen sind eigene Fehlerausgaben mit Markierung unter der fehlerhaften Stelle (Caret) oder das Setzen von Markierungen in Online-Shader-Editoren.
Rückgabewert
lineNum; 0, wenn die Meldung keiner bestimmten Position zugeordnet ist.Beispiele
Compiler-Meldungen mit Zeile und Spalte ausgeben
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const code = `@vertex
fn main() -> @builtin(position) vec4f {
return vec4f(0.0, 0.0, 0.0, 1.0)
}`; // fehlendes Semikolon
const module = device.createShaderModule({ code });
const info = await module.getCompilationInfo();
for (const msg of info.messages) {
console.log(`${msg.type} [${msg.lineNum}:${msg.linePos}] ${msg.message}`);
}
Fehlerstelle mit Caret (^) markieren
const formatMessage = (source, msg) => {
if (msg.lineNum === 0) return `${msg.type}: ${msg.message}`;
const line = source.split('\n')[msg.lineNum - 1] ?? '';
// linePos ist 1-basiert, daher -1 für die Einrückung
const caretPos = Math.max(msg.linePos - 1, 0);
const marker = ' '.repeat(caretPos) + '^'.repeat(Math.max(msg.length, 1));
return `${msg.lineNum}:${msg.linePos} ${msg.type}: ${msg.message}\n${line}\n${marker}`;
};
const info = await module.getCompilationInfo();
info.messages.forEach((m) => console.warn(formatMessage(code, m)));
Markierungen für einen Code-Editor erzeugen
const toEditorMarkers = (messages) =>
messages
.filter((m) => m.lineNum > 0)
.map((m) => ({
severity: m.type, // 'error' | 'warning' | 'info'
startLineNumber: m.lineNum,
startColumn: m.linePos,
endLineNumber: m.lineNum,
endColumn: m.linePos + Math.max(m.length, 1),
message: m.message,
}));
const { messages } = await module.getCompilationInfo();
console.log(toEditorMarkers(messages));
// Wichtig · Fallstricke
- 1-basiert: Für String-Operationen wie
slice()odersubstring()muss manlinePos - 1verwenden. Ein Wert von0bedeutet „keine konkrete Position“ und sollte nicht als Spalte 0 interpretiert werden. - UTF-16-Codeeinheiten: Stehen Zeichen außerhalb der BMP (z. B. Emojis in Kommentaren) vor der Fehlerstelle, zählen diese doppelt. Das passt zu JavaScript-Strings, aber nicht zur Anzahl sichtbarer Zeichen oder zu UTF-8-Byte-Offsets.
- Die Eigenschaft ist schreibgeschützt; Zuweisungen werden ignoriert (im Strict Mode
TypeError). - Inhalt und genaue Position der Meldungen hängen von der Implementierung ab (Chrome nutzt Tint, Firefox Naga) – nicht auf exakte Werte in Tests verlassen.
- WebGPU ist nur in sicheren Kontexten (HTTPS) verfügbar und noch nicht auf allen Plattformen aktiviert; vorher per
if (!navigator.gpu)prüfen.