Skip to content

Commit

Permalink
make malformed early error clauses a soft error (#433)
Browse files Browse the repository at this point in the history
  • Loading branch information
bakkot authored Apr 2, 2022
1 parent 2a8cb92 commit e4fb2ad
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 13 deletions.
53 changes: 40 additions & 13 deletions src/lint/collect-nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,37 +51,64 @@ export function collectNodes(
const title = textContentExcludingDeleted(first);
headers.push({ element: first, contents: title });
if (title.trim() === 'Static Semantics: Early Errors') {
let grammar = null;
let grammar: Element | null = null;
let lists: HTMLUListElement[] = [];
let warned = false;
for (const child of node.children) {
if (child.nodeName === 'EMU-GRAMMAR') {
if (grammar !== null) {
if (lists.length === 0) {
// TODO soft errors
throw new Error(
'unrecognized structure for early errors: grammar without errors'
);
spec.warn({
type: 'node',
node: grammar,
ruleId: 'early-error-shape',
message:
'unrecognized structure for early errors: multiple consecutive <emu-grammar>s without intervening <ul> of errors',
});
warned = true;
break;
}
earlyErrors.push({ grammar, lists });
}
grammar = child;
lists = [];
} else if (child.nodeName === 'UL') {
if (grammar === null) {
throw new Error(
'unrecognized structure for early errors: errors without corresponding grammar'
);
spec.warn({
type: 'node',
node: child,
ruleId: 'early-error-shape',
message:
'unrecognized structure for early errors: <ul> without preceding <emu-grammar>',
});
warned = true;
break;
}
lists.push(child as HTMLUListElement);
}
}

if (grammar === null) {
throw new Error('unrecognized structure for early errors: no grammars');
}
if (lists.length === 0) {
throw new Error('unrecognized structure for early errors: grammar without errors');
if (!warned) {
spec.warn({
type: 'node',
node,
ruleId: 'early-error-shape',
message: 'unrecognized structure for early errors: no <emu-grammar>',
});
}
} else if (lists.length === 0) {
if (!warned) {
spec.warn({
type: 'node',
node,
ruleId: 'early-error-shape',
message: 'unrecognized structure for early errors: no <ul> of errors',
});
}
} else {
earlyErrors.push({ grammar, lists });
}
earlyErrors.push({ grammar, lists });
}
}
} else if (node.nodeName === 'EMU-GRAMMAR' && !node.hasAttribute('example')) {
Expand Down
84 changes: 84 additions & 0 deletions test/lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,90 @@ describe('linting whole program', () => {
});
});

describe('early error shape', () => {
it('missing grammar', async () => {
await assertLint(
positioned`
<emu-grammar type="definition">
Foo : \`a\`
</emu-grammar>
<emu-clause id="example">
<h1>Static Semantics: Early Errors</h1>
${M}<ul>
<li>It is an Early Error sometimes.</li>
</ul>
</emu-clause>
`,
{
ruleId: 'early-error-shape',
nodeType: 'ul',
message: 'unrecognized structure for early errors: <ul> without preceding <emu-grammar>',
}
);
});

it('missing UL', async () => {
await assertLint(
positioned`
<emu-grammar type="definition">
Foo : \`a\`
</emu-grammar>
${M}<emu-clause id="example">
<h1>Static Semantics: Early Errors</h1>
<emu-grammar>Foo : \`a\`</emu-grammar>
<emu-alg>
1. Some logic.
</emu-alg>
</emu-clause>
`,
{
ruleId: 'early-error-shape',
nodeType: 'emu-clause',
message: 'unrecognized structure for early errors: no <ul> of errors',
}
);
});

it('multiple grammars', async () => {
await assertLint(
positioned`
<emu-grammar type="definition">
Foo : \`a\`
</emu-grammar>
<emu-clause id="example">
<h1>Static Semantics: Early Errors</h1>
${M}<emu-grammar>Foo : \`a\`</emu-grammar>
<emu-grammar>Foo : \`a\`</emu-grammar>
</emu-clause>
`,
{
ruleId: 'early-error-shape',
nodeType: 'emu-grammar',
message:
'unrecognized structure for early errors: multiple consecutive <emu-grammar>s without intervening <ul> of errors',
}
);
});

it('missing everything', async () => {
await assertLint(
positioned`
<emu-grammar type="definition">
Foo : \`a\`
</emu-grammar>
${M}<emu-clause id="example">
<h1>Static Semantics: Early Errors</h1>
</emu-clause>
`,
{
ruleId: 'early-error-shape',
nodeType: 'emu-clause',
message: 'unrecognized structure for early errors: no <emu-grammar>',
}
);
});
});

describe('grammar+SDO validity', () => {
it('undefined nonterminals in SDOs', async () => {
await assertLint(
Expand Down

0 comments on commit e4fb2ad

Please sign in to comment.