Skip to content

Fix diagnostics #9385

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

Merged
merged 4 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 5 additions & 23 deletions sites/svelte-5-preview/src/lib/CodeMirror.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
import Message from './Message.svelte';
import { svelteTheme } from './theme.js';

/** @type {import('./types').StartOrEnd | null} */
export let errorLoc = null;

/** @type {import('@codemirror/lint').LintSource | undefined} */
export let diagnostics = undefined;

Expand Down Expand Up @@ -171,37 +168,22 @@

let marked = false;

/** @type {number | null}*/
let error_line = null;

let updating_externally = false;

/** @type {import('@codemirror/state').Extension[]} */
let extensions = [];

let cursor_pos = 0;

$: {
if ($cmInstance.view) {
fulfil_module_editor_ready();
}
$: if ($cmInstance.view) {
fulfil_module_editor_ready();
}

$: if ($cmInstance.view && w && h) resize();

$: {
if (marked) {
unmarkText();
marked = false;
}

if (errorLoc) {
markText({ from: errorLoc.character, to: errorLoc.character + 1, className: 'error-loc' });

error_line = errorLoc.line;
} else {
error_line = null;
}
$: if (marked) {
unmarkText();
marked = false;
}

const watcher = EditorView.updateListener.of((viewUpdate) => {
Expand Down
75 changes: 30 additions & 45 deletions sites/svelte-5-preview/src/lib/Input/ModuleEditor.svelte
Original file line number Diff line number Diff line change
@@ -1,66 +1,51 @@
<script>
import { get_repl_context } from '$lib/context.js';
import { get_full_filename } from '$lib/utils.js';
import CodeMirror from '../CodeMirror.svelte';

/** @type {import('$lib/types').StartOrEnd | null} */
export let errorLoc = null;

/** @type {boolean} */
export let autocomplete;

/** @type {any} */ // TODO
export let error;

/** @type {any[]} */ // TODO
export let warnings;

export function focus() {
$module_editor?.focus();
}

const { bundle, handle_change, module_editor, selected, bundling } = get_repl_context();

async function diagnostics() {
/** @type {import('@codemirror/lint').Diagnostic[]} */
const diagnostics = [];

if (!$selected || !$bundle) return diagnostics;

await $bundling;

const filename = get_full_filename($selected);

if (
$bundle.error &&
$bundle.error.filename === filename &&
$bundle.error.start &&
$bundle.error.end
) {
diagnostics.push({
from: $bundle.error.start.character,
to: $bundle.error.end.character,
severity: 'error',
message: $bundle.error.message
});
}

for (const warning of $bundle.warnings) {
if (warning.filename === filename) {
diagnostics.push({
from: warning.start.character,
to: warning.end.character,
severity: 'warning',
message: warning.message
});
}
}

return diagnostics;
}
const { handle_change, module_editor } = get_repl_context();
</script>

<div class="editor-wrapper">
<div class="editor notranslate" translate="no">
<CodeMirror
bind:this={$module_editor}
{errorLoc}
{autocomplete}
diagnostics={$selected && $bundle ? diagnostics : () => []}
diagnostics={() => {
if (error) {
return [
{
severity: 'error',
from: error.position[0],
to: error.position[1],
message: error.message
}
];
}

if (warnings) {
return warnings.map((warning) => ({
severity: 'warning',
from: warning.start.character,
to: warning.end.character,
message: warning.message
}));
}

return [];
}}
on:change={handle_change}
/>
</div>
Expand Down
4 changes: 2 additions & 2 deletions sites/svelte-5-preview/src/lib/Output/Compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ export default class Compiler {

/**
* @param {import('$lib/types').File} file
* @param {import('svelte/types/compiler').CompileOptions} options
* @param {import('svelte/compiler').CompileOptions} options
* @param {boolean} return_ast
* @returns
* @returns {Promise<import('$lib/workers/workers').CompileMessageData>}
*/
compile(file, options, return_ast) {
return new Promise((fulfil) => {
Expand Down
89 changes: 22 additions & 67 deletions sites/svelte-5-preview/src/lib/Output/Output.svelte
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
<script>
import { get_repl_context } from '$lib/context.js';
import { BROWSER } from 'esm-env';
import { marked } from 'marked';
import CodeMirror from '../CodeMirror.svelte';
import AstView from './AstView.svelte';
import Compiler from './Compiler.js';
import CompilerOptions from './CompilerOptions.svelte';
import PaneWithPanel from './PaneWithPanel.svelte';
import Viewer from './Viewer.svelte';

export let svelteUrl;

/** @type {string | null} */
export let status;

/** @type {import('$lib/types').StartOrEnd | null} */
export let sourceErrorLoc = null;

/** @type {import('$lib/types').MessageDetails | null} */
export let runtimeError = null;

Expand All @@ -35,62 +28,25 @@
/** @type {'light' | 'dark'} */
export let previewTheme;

/**
* @param {import('$lib/types').File} file
* @param {import('svelte/compiler').CompileOptions} options
*/
export async function set(file, options) {
selected_type = file.type;
/** @type {import('../types').File | null} */
export let selected;

if (file.type === 'json') {
/** @type {import('../workers/workers').CompileMessageData | null} */
export let compiled;

$: if (selected) {
if (selected.type === 'json') {
js_editor.set({ code: `/* Select a component to see its compiled code */`, lang: 'js' });
css_editor.set({ code: `/* Select a component to see its compiled code */`, lang: 'css' });
return;
}

if (file.type === 'md') {
markdown = marked(file.source);
return;
}

if (!compiler) return console.error('Compiler not initialized.');

const compiled = await compiler.compile(file, options, showAst);
if (!js_editor) return; // unmounted

js_editor.set({
code: compiled.js,
lang: 'js'
});
css_editor.set({ code: compiled.css, lang: 'css' });
ast = compiled.ast;
}

/**
* @param {import('$lib/types').File} selected
* @param {import('svelte/compiler').CompileOptions} options
*/
export async function update(selected, options) {
if (selected.type === 'json') return;

if (selected.type === 'md') {
} else if (selected.type === 'md') {
markdown = marked(selected.source);
return;
} else if (compiled) {
js_editor.set({ code: compiled.result.js, lang: 'js' });
css_editor.set({ code: compiled.result.css, lang: 'css' });
}

if (!compiler) return console.error('Compiler not initialized.');

const { result, metadata } = await compiler.compile(selected, options, showAst);

js_editor.update({ code: result.js, lang: 'js' });
css_editor.update({ code: result.css, lang: 'css' });
$runes_mode = metadata?.runes;
ast = result.ast;
}

const { module_editor, runes_mode } = get_repl_context();

const compiler = BROWSER ? new Compiler(svelteUrl) : null;
const { module_editor } = get_repl_context();

/** @type {CodeMirror} */
let js_editor;
Expand All @@ -100,15 +56,14 @@

/** @type {'result' | 'js' | 'css' | 'ast'} */
let view = 'result';
let selected_type = '';
let markdown = '';

/** @type {import('svelte/types/compiler/interfaces').Ast} */
let ast;
</script>

<div class="view-toggle">
{#if selected_type === 'md'}
{#if selected?.type === 'md'}
<button class="active">Markdown</button>
{:else}
<button class:active={view === 'result'} on:click={() => (view = 'result')}>Result</button>
Expand All @@ -121,7 +76,7 @@
</div>

<!-- component viewer -->
<div class="tab-content" class:visible={selected_type !== 'md' && view === 'result'}>
<div class="tab-content" class:visible={selected?.type !== 'md' && view === 'result'}>
<Viewer
bind:error={runtimeError}
{status}
Expand All @@ -133,13 +88,13 @@
</div>

<!-- js output -->
<div class="tab-content" class:visible={selected_type !== 'md' && view === 'js'}>
<div class="tab-content" class:visible={selected?.type !== 'md' && view === 'js'}>
{#if embedded}
<CodeMirror bind:this={js_editor} errorLoc={sourceErrorLoc} readonly />
<CodeMirror bind:this={js_editor} readonly />
{:else}
<PaneWithPanel pos="50%" panel="Compiler options">
<div slot="main">
<CodeMirror bind:this={js_editor} errorLoc={sourceErrorLoc} readonly />
<CodeMirror bind:this={js_editor} readonly />
</div>

<div slot="panel-body">
Expand All @@ -150,22 +105,22 @@
</div>

<!-- css output -->
<div class="tab-content" class:visible={selected_type !== 'md' && view === 'css'}>
<CodeMirror bind:this={css_editor} errorLoc={sourceErrorLoc} readonly />
<div class="tab-content" class:visible={selected?.type !== 'md' && view === 'css'}>
<CodeMirror bind:this={css_editor} readonly />
</div>

<!-- ast output -->
{#if showAst}
<div class="tab-content" class:visible={selected_type !== 'md' && view === 'ast'}>
<div class="tab-content" class:visible={selected?.type !== 'md' && view === 'ast'}>
<!-- ast view interacts with the module editor, wait for it first -->
{#if $module_editor}
<AstView {ast} autoscroll={selected_type !== 'md' && view === 'ast'} />
<AstView {ast} autoscroll={selected?.type !== 'md' && view === 'ast'} />
{/if}
</div>
{/if}

<!-- markdown output -->
<div class="tab-content" class:visible={selected_type === 'md'}>
<div class="tab-content" class:visible={selected?.type === 'md'}>
<iframe title="Markdown" srcdoc={markdown} />
</div>

Expand Down
Loading