diff --git a/src/lib/ErrorOutput.svelte b/src/lib/ErrorOutput.svelte
new file mode 100644
index 0000000..66b18cb
--- /dev/null
+++ b/src/lib/ErrorOutput.svelte
@@ -0,0 +1,95 @@
+
+
+{#if msg.stack}
+ {#each msg.stack as entry, i}
+ {#if i === 0 || entry.location.filename !== msg.stack[i - 1].location.filename || entry.location.firstLine !== msg.stack[i - 1].location.firstLine}
+
+
+
+
+ dispatch('goto', {
+ location: entry.location,
+ })}>{displayLocation(entry.location)}
+
+ {/if}
+ {#if entry.isCompIter}
+ with
+ {:else}
+ in
+ {/if}
+ {entry.description}
+
+ {/each}
+{:else if msg.location}
+
+
+
+
+ dispatch('goto', {
+ location: msg.location,
+ })}>{displayLocation(msg.location)}:
+
+{/if}
+{#if msg.includedFrom}
+ {#each msg.includedFrom as include}
+ (included from {include})
+
+ {/each}
+{/if}
+{#if msg.type === 'error'}
+ MiniZinc:
+{:else}
+ Warning:
+{/if}
+{msg.what}: {msg.message}
+{#if msg.cycle}
+ {#each msg.cycle as it}
+ {it}
+
+ {/each}
+{/if}
+
+
+
diff --git a/src/lib/Output.svelte b/src/lib/Output.svelte
index a46d42a..3ff5f1d 100644
--- a/src/lib/Output.svelte
+++ b/src/lib/Output.svelte
@@ -2,6 +2,7 @@
import { createEventDispatcher, tick } from 'svelte';
import Fa from 'svelte-fa/src/fa.svelte';
import { faEraser, faTrash } from '@fortawesome/free-solid-svg-icons';
+ import ErrorOutput from './ErrorOutput.svelte';
const dispatch = createEventDispatcher();
export let output;
@@ -29,10 +30,22 @@
run.output.some((m) => m.type === 'time')
);
$: hasWarnings = output.some((run) =>
- run.output.some((m) => m.type === 'warning')
+ run.output.some(
+ (m) =>
+ m.type === 'warning' ||
+ (m.type === 'checker' &&
+ m.messages &&
+ m.messages.some((m) => m.type === 'warning'))
+ )
);
$: hasErrors = output.some((run) =>
- run.output.some((m) => m.type === 'error')
+ run.output.some(
+ (m) =>
+ m.type === 'error' ||
+ (m.type === 'checker' &&
+ m.messages &&
+ m.messages.some((m) => m.type === 'error'))
+ )
);
function getUserSections(output) {
@@ -116,23 +129,64 @@
return elapsed.trimEnd();
}
- function prependLines(prefix, s) {
- return `${prefix}${s.split('\n').join(`\n${prefix}`)}`;
- }
-
- function displayLocation(loc) {
- if (loc.firstLine == loc.lastLine) {
- if (loc.firstColumn == loc.lastColumn) {
- return `${loc.filename}:${loc.firstLine}.${loc.firstColumn}`;
+ function processCheckerMessage(msg, hiddenSections) {
+ const parts = [];
+ let buffer = [];
+ const flush = () => {
+ if (buffer.length > 0) {
+ const split = buffer.join('').split('\n');
+ if (split[split.length - 1] === '') {
+ split.splice(split.length - 1, 1);
+ }
+ parts.push({
+ type: 'text',
+ message: split.map((x) => `% ${x}`).join('\n'),
+ });
+ buffer = [];
+ }
+ };
+ if (msg.messages) {
+ for (const message of msg.messages) {
+ if (message.type === 'solution') {
+ for (const section of message.sections) {
+ if (
+ hiddenSections.indexOf(section) === -1 &&
+ section !== 'raw'
+ ) {
+ buffer.push(msg.output[section]);
+ }
+ }
+ } else if (message.type === 'trace') {
+ if (
+ hiddenSections.indexOf(message.section) === -1 &&
+ message.section !== 'raw'
+ ) {
+ buffer.push(message.message);
+ }
+ } else {
+ flush();
+ parts.push(message);
+ }
+ }
+ flush();
+ } else {
+ for (const section of msg.sections) {
+ if (hiddenSections.indexOf(section) === -1) {
+ buffer.push(msg.output[section]);
+ }
}
- return `${loc.filename}:${loc.firstLine}.${loc.firstColumn}-${loc.lastColumn}`;
+ flush();
}
- return `${loc.filename}:${loc.firstLine}.${loc.firstColumn}-${loc.lastLine}.${loc.lastColumn}`;
+ return parts;
}
-
-
+
+
{#if showSectionToggles}