LCOV - code coverage report
Current view: top level - dashql-app/src/session/editor - dashql_script_references.ts Coverage Total Hit
Test: DashQL 915828b Lines: 89.2 % 37 33
Test Date: 2026-11-06 19:30:32

            Line data    Source code
       1              : import * as dashql from '@ankoh/dashql-core';
       2              : 
       3              : import { EditorState, StateEffect, StateField, Transaction } from '@codemirror/state';
       4              : 
       5              : import { DashQLProcessorPlugin } from './dashql_processor.js';
       6              : import type { ScriptReferenceReport } from '../scripts/script_reference_check.js';
       7              : 
       8              : /// Set the checked script references of the script of the editor
       9            1 : export const DashQLScriptReferencesEffect = StateEffect.define<ScriptReferenceReport | null>();
      10              : 
      11              : interface ScriptReferencesState {
      12              :     /// The report of the script, null if there is none
      13              :     report: ScriptReferenceReport | null;
      14              :     /// The analyzed text version the diagnostics were built for, null if the report does not match it
      15              :     textVersion: bigint | null;
      16              :     /// The diagnostics of the analysis that `diagnostics` extends
      17              :     base: dashql.buffers.editor.EditorDiagnosticT[] | null;
      18              :     /// The diagnostics of the analysis and the errors of the script references, in text order
      19              :     diagnostics: dashql.buffers.editor.EditorDiagnosticT[] | null;
      20              : }
      21              : 
      22            1 : function referenceDiagnostics(report: ScriptReferenceReport): dashql.buffers.editor.EditorDiagnosticT[] {
      23            1 :     return report.marks.filter(mark => mark.errors.length > 0).map(mark => new dashql.buffers.editor.EditorDiagnosticT(
      24            0 :         dashql.buffers.editor.EditorDiagnosticSource.ANALYZER,
      25            0 :         dashql.buffers.editor.EditorDiagnosticSeverity.ERROR,
      26            0 :         mark.errors.join('; '),
      27            0 :         new dashql.buffers.editor.EditorTextSpanT(BigInt(mark.from), BigInt(mark.to - mark.from)),
      28            1 :     ));
      29            1 : }
      30              : 
      31            1 : const EMPTY: ScriptReferencesState = { report: null, textVersion: null, base: null, diagnostics: null };
      32              : 
      33              : /// The checked script references of the script of the editor, their errors join the diagnostics of the analysis
      34            1 : const ScriptReferencesField = StateField.define<ScriptReferencesState>({
      35            1 :     create: () => EMPTY,
      36            1 :     update: (prev: ScriptReferencesState, transaction: Transaction) => {
      37            1 :         let report = prev.report;
      38            1 :         for (const effect of transaction.effects) {
      39            1 :             if (effect.is(DashQLScriptReferencesEffect)) report = effect.value;
      40              :         }
      41            1 :         const processor = transaction.state.field(DashQLProcessorPlugin);
      42            1 :         const base = processor.editorUpdate?.diagnostics ?? null;
      43            1 :         const analyzed = processor.editorUpdate?.textVersion ?? null;
      44              :         // The report belongs to the analyzed text, after an edit its errors wait for the next report
      45            1 :         const textVersion = report != null && analyzed != null && report.textVersion === analyzed ? analyzed : null;
      46            1 :         if (report === prev.report && base === prev.base && textVersion === prev.textVersion) {
      47            1 :             return prev;
      48              :         }
      49            1 :         const references = report != null && textVersion != null ? referenceDiagnostics(report) : [];
      50            1 :         const diagnostics = references.length === 0
      51            1 :             ? base
      52            1 :             : [...(base ?? []), ...references].sort((l, r) => Number((l.textSpan?.offset ?? 0n) - (r.textSpan?.offset ?? 0n)));
      53            1 :         return { report, textVersion, base, diagnostics };
      54            1 :     },
      55            1 : });
      56              : 
      57              : /// The diagnostics of the editor: those of the analysis and the errors of the script references. The array keeps
      58              : /// its identity while neither changes.
      59            1 : export function editorDiagnostics(state: EditorState): dashql.buffers.editor.EditorDiagnosticT[] | null {
      60            1 :     const references = state.field(ScriptReferencesField, false);
      61            1 :     return references != null ? references.diagnostics : (state.field(DashQLProcessorPlugin).editorUpdate?.diagnostics ?? null);
      62            1 : }
      63              : 
      64              : /// The checked script references that the editor shows
      65            1 : export function shownScriptReferences(state: EditorState): ScriptReferenceReport | null {
      66            1 :     return state.field(ScriptReferencesField, false)?.report ?? null;
      67            1 : }
      68              : 
      69            1 : export const DashQLScriptReferencesPlugin = [ScriptReferencesField];
        

Generated by: LCOV version 2.0-1