Skip to content

Commit ce4a276

Browse files
authored
Fix header parser (#403)
1 parent 74db0e9 commit ce4a276

File tree

7 files changed

+59
-32
lines changed

7 files changed

+59
-32
lines changed

src/Clause.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ import type { Context } from './Context';
77
import Builder from './Builder';
88
import { formatPreamble, parseStructuredHeaderDl, parseAndFormatH1 } from './header-parser';
99

10+
export function extractStructuredHeader(header: Element): Element | null {
11+
const dl = header.nextElementSibling;
12+
if (dl == null || dl.tagName !== 'DL' || !dl.classList.contains('header')) {
13+
return null;
14+
}
15+
return dl;
16+
}
17+
1018
/*@internal*/
1119
export default class Clause extends Builder {
1220
id: string;
@@ -93,8 +101,8 @@ export default class Clause extends Builder {
93101
}
94102

95103
buildStructuredHeader(header: Element) {
96-
const dl = header.nextElementSibling;
97-
if (dl == null || dl.tagName !== 'DL' || !dl.classList.contains('header')) {
104+
const dl = extractStructuredHeader(header);
105+
if (dl === null) {
98106
return;
99107
}
100108
// if we find such a DL, treat this as a structured header

src/header-parser.ts

+7-13
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,6 @@ export function parseAndFormatH1(
306306
}
307307

308308
const {
309-
type,
310309
wrappingTag,
311310
prefix,
312311
name,
@@ -338,19 +337,14 @@ export function parseAndFormatH1(
338337
}
339338
}
340339

341-
let formattedHeader;
342-
if (type === 'single-line') {
343-
formattedHeader = header.innerHTML;
344-
} else {
345-
formattedHeader =
346-
(prefix == null ? '' : prefix + ' ') +
347-
name +
348-
' ' +
349-
printSimpleParamList(params, optionalParams);
340+
let formattedHeader =
341+
(prefix == null ? '' : prefix + ' ') +
342+
name +
343+
' ' +
344+
printSimpleParamList(params, optionalParams);
350345

351-
if (wrappingTag !== null) {
352-
formattedHeader = `<${wrappingTag}>${formattedHeader}</${wrappingTag}>`;
353-
}
346+
if (wrappingTag !== null) {
347+
formattedHeader = `<${wrappingTag}>${formattedHeader}</${wrappingTag}>`;
354348
}
355349

356350
return { name, formattedHeader, formattedParams, formattedReturnType: returnType };

src/lint/collect-header-diagnostics.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { extractStructuredHeader } from '../Clause';
12
import type { Warning } from '../Spec';
23

34
import { offsetToLineAndColumn } from '../utils';
@@ -9,6 +10,10 @@ export function collectHeaderDiagnostics(
910
headers: { element: Element; contents: string }[]
1011
) {
1112
for (const { element, contents } of headers) {
13+
if (extractStructuredHeader(element) !== null) {
14+
// these will be handled by header-parser.ts
15+
continue;
16+
}
1217
if (!/\(.*\)$/.test(contents) || / Operator \( `[^`]+` \)$/.test(contents)) {
1318
continue;
1419
}

test/baselines/generated-reference/effect-user-code.html

+17-17
Original file line numberDiff line numberDiff line change
@@ -27,61 +27,61 @@ <h1><span class="secnum">3</span> Nop ( )</h1>
2727
</emu-clause>
2828

2929
<emu-clause id="sec-direct-call" type="abstract operation" aoid="DirectCall">
30-
<h1><span class="secnum">4</span> DirectCall()</h1>
30+
<h1><span class="secnum">4</span> DirectCall ( )</h1>
3131
<p>The abstract operation DirectCall takes no arguments. Calling AOs that can call user code should insert <code>e-user-code</code> as a class into the AO link. It performs the following steps when called:</p>
3232
<emu-alg><ol><li><emu-xref aoid="UserCode" id="_ref_0"><a href="#sec-user-code" class="e-user-code">UserCode</a></emu-xref>().</li><li><emu-xref aoid="UserCode2" id="_ref_1"><a href="#sec-user-code-2" class="e-user-code">UserCode2</a></emu-xref>().</li></ol></emu-alg>
3333
</emu-clause>
3434

3535
<emu-clause id="sec-transitive-call" type="abstract operation" aoid="TransitiveCall">
36-
<h1><span class="secnum">5</span> TransitiveCall()</h1>
36+
<h1><span class="secnum">5</span> TransitiveCall ( )</h1>
3737
<p>The abstract operation TransitiveCall takes no arguments. Calling AOs that can transitively call user code should insert <code>e-user-code</code> as a class into the AO link. It performs the following steps when called:</p>
3838
<emu-alg><ol><li><emu-xref aoid="DirectCall" id="_ref_2"><a href="#sec-direct-call" class="e-user-code">DirectCall</a></emu-xref>().</li></ol></emu-alg>
3939
</emu-clause>
4040

4141
<emu-clause id="sec-suppressed-direct-call" type="abstract operation" aoid="SuppressedDirectCall">
42-
<h1><span class="secnum">6</span> SuppressedDirectCall()</h1>
42+
<h1><span class="secnum">6</span> SuppressedDirectCall ( )</h1>
4343
<p>The abstract operation SuppressedDirectCall takes no arguments. Can-call-user-code callsites that are suppressed do not get <code>e-user-code</code> as a class in the AO link. It performs the following steps when called:</p>
4444
<emu-alg><ol><li><emu-xref aoid="TransitiveCall" id="_ref_3"><a href="#sec-transitive-call">TransitiveCall</a></emu-xref>().</li></ol></emu-alg>
4545
</emu-clause>
4646

4747
<emu-clause id="sec-suppressed-transitive-call" type="abstract operation" aoid="SuppressedTransitiveCall">
48-
<h1><span class="secnum">7</span> SuppressedTransitiveCall()</h1>
48+
<h1><span class="secnum">7</span> SuppressedTransitiveCall ( )</h1>
4949
<p>The abstract operation SuppressedTransitiveCall takes no arguments. Can-call-user-code callsites that are suppressed do not propagate the effect It performs the following steps when called:</p>
5050
<emu-alg><ol><li><emu-xref aoid="SuppressedDirectCall" id="_ref_4"><a href="#sec-suppressed-direct-call">SuppressedDirectCall</a></emu-xref>().</li></ol></emu-alg>
5151
</emu-clause>
5252

5353
<emu-clause id="sec-added-direct-call" type="abstract operation" aoid="AddedDirectCall">
54-
<h1><span class="secnum">8</span> AddedDirectCall()</h1>
54+
<h1><span class="secnum">8</span> AddedDirectCall ( )</h1>
5555
<p>The abstract operation AddedDirectCall takes no arguments. AOs can have manually added user-code effect at a callsite that propagates. It performs the following steps when called:</p>
5656
<emu-alg><ol><li><emu-xref aoid="Nop" id="_ref_5"><a href="#sec-nop" class="e-user-code">Nop</a></emu-xref>().</li></ol></emu-alg>
5757
</emu-clause>
5858

5959
<emu-clause id="sec-added-transitive-call" type="abstract operation" aoid="AddedTransitiveCall">
60-
<h1><span class="secnum">9</span> AddedTransitiveCall()</h1>
60+
<h1><span class="secnum">9</span> AddedTransitiveCall ( )</h1>
6161
<p>The abstract operation AddedTransitiveCall takes no arguments. AOs can have manually added user-code effect at a callsite that propagates. It performs the following steps when called:</p>
6262
<emu-alg><ol><li><emu-xref aoid="AddedDirectCall" id="_ref_6"><a href="#sec-added-direct-call" class="e-user-code">AddedDirectCall</a></emu-xref>().</li></ol></emu-alg>
6363
</emu-clause>
6464

6565
<emu-clause id="sec-sdo-invocation" type="abstract operation" aoid="SDOInvocations">
66-
<h1><span class="secnum">10</span> SDOInvocations()</h1>
66+
<h1><span class="secnum">10</span> SDOInvocations ( )</h1>
6767
<p>The abstract operation SDOInvocations takes no arguments. SDO-style invocations of AOs that can call user code also have the <code>e-user-code</code> class in the link. It performs the following steps when called:</p>
6868
<emu-alg><ol><li><emu-xref aoid="UserCode" id="_ref_7"><a href="#sec-user-code" class="e-user-code">UserCode</a></emu-xref> of Bar.</li></ol></emu-alg>
6969
</emu-clause>
7070

7171
<emu-clause id="sec-non-invocations" type="abstract operation" aoid="NonInvocations">
72-
<h1><span class="secnum">11</span> NonInvocations()</h1>
72+
<h1><span class="secnum">11</span> NonInvocations ( )</h1>
7373
<p>The abstract operation NonInvocations takes no arguments. Non-invocations (i.e. not followed by () or " of") do not have <code>e-user-code</code> as a class in the AO link. It performs the following steps when called:</p>
7474
<emu-alg><ol><li><emu-xref aoid="UserCode" id="_ref_8"><a href="#sec-user-code">UserCode</a></emu-xref> is an abstract operation.</li></ol></emu-alg>
7575
</emu-clause>
7676

7777
<emu-clause id="sec-non-abrupt" type="abstract operation" aoid="NonAbrupt">
78-
<h1><span class="secnum">12</span> NonAbrupt()</h1>
78+
<h1><span class="secnum">12</span> NonAbrupt ( )</h1>
7979
<p>The abstract operation NonAbrupt takes no arguments. Invocations that cannot result in abrupt completions suppress the user-code effect by default. It performs the following steps when called:</p>
8080
<emu-alg><ol><li>Let <var>res</var> be !&nbsp;<emu-xref aoid="UserCode" id="_ref_9"><a href="#sec-user-code">UserCode</a></emu-xref>().</li></ol></emu-alg>
8181
</emu-clause>
8282

8383
<emu-clause id="sec-non-abrupt-override" type="abstract operation" aoid="NonAbruptOverride">
84-
<h1><span class="secnum">13</span> NonAbruptOverride()</h1>
84+
<h1><span class="secnum">13</span> NonAbruptOverride ( )</h1>
8585
<p>The abstract operation NonAbruptOverride takes no arguments. Invocations that cannot result in abrupt completions suppress the user-code effect by default but can still be overridden. It performs the following steps when called:</p>
8686
<emu-alg><ol><li>Let <var>res</var> be !&nbsp;<emu-xref aoid="UserCode" id="_ref_10"><a href="#sec-user-code" class="e-user-code e-user-code">UserCode</a></emu-xref>().</li></ol></emu-alg>
8787
</emu-clause>
@@ -99,43 +99,43 @@ <h1><span class="secnum">15</span> Static Semantics: StaticTransitiveCall</h1>
9999
</emu-clause>
100100

101101
<emu-clause id="sec-rendered-meta" type="abstract operation" aoid="RenderedMeta">
102-
<h1><span class="secnum">16</span> RenderedMeta()</h1>
102+
<h1><span class="secnum">16</span> RenderedMeta ( )</h1>
103103
<p>The abstract operation RenderedMeta takes no arguments. emu-meta tags with the effects attribute that aren't surrounding what ecmarkup recognizes as invocations are changed into span tags to be rendered. The effects list is prefixed with e- and changed into class names. It performs the following steps when called:</p>
104104
<emu-alg><ol><li>Perform ?&nbsp;<span class="e-user-code"><var>O</var>.[[Call]]()</span>.</li></ol></emu-alg>
105105
</emu-clause>
106106

107107
<emu-clause id="sec-make-abstract-closure" type="abstract operation" aoid="MakeAbstractClosure">
108-
<h1><span class="secnum">17</span> MakeAbstractClosure()</h1>
108+
<h1><span class="secnum">17</span> MakeAbstractClosure ( )</h1>
109109
<p>The abstract operation MakeAbstractClosure takes no arguments. The user-code effect doesn't propagate through Abstract Closure boundaries by recognizing the "be a new Abstract Closure" substring. It performs the following steps when called:</p>
110110
<emu-alg><ol><li>Let <var>closure</var> be a new Abstract Closure that captures nothing and performs the following steps when called:<ol><li><emu-xref aoid="UserCode" id="_ref_13"><a href="#sec-user-code" class="e-user-code">UserCode</a></emu-xref>().</li></ol></li><li>Return <var>closure</var>.</li></ol></emu-alg>
111111
</emu-clause>
112112

113113
<emu-clause id="sec-call-make-abstract-closure" type="abstract operation" aoid="CallMakeAbstractClosure">
114-
<h1><span class="secnum">18</span> CallMakeAbstractClosure()</h1>
114+
<h1><span class="secnum">18</span> CallMakeAbstractClosure ( )</h1>
115115
<p>The abstract operation CallMakeAbstractClosure takes no arguments. The user-code effect doesn't propagate through Abstract Closure boundaries by recognizing the "be a new Abstract Closure" substring. It performs the following steps when called:</p>
116116
<emu-alg><ol><li><emu-xref aoid="MakeAbstractClosure" id="_ref_14"><a href="#sec-make-abstract-closure">MakeAbstractClosure</a></emu-xref>().</li></ol></emu-alg>
117117
</emu-clause>
118118

119119
<emu-clause id="sec-xref-not-first-child-of-emu-meta" type="abstract operation" aoid="XrefNotFirstChildOfEmuMeta">
120-
<h1><span class="secnum">19</span> XrefNotFirstChildOfEmuMeta()</h1>
120+
<h1><span class="secnum">19</span> XrefNotFirstChildOfEmuMeta ( )</h1>
121121
<p>The abstract operation XrefNotFirstChildOfEmuMeta takes no arguments. Effect additions and suppressions via emu-meta only affect xrefs that are the first child of the emu-meta. Below, <emu-xref aoid="UserCode" id="_ref_15"><a href="#sec-user-code" class="e-user-code">UserCode</a></emu-xref>() gets autolinked and get an xref. Its parent element is an emu-meta, but since the xref is not the first child, it should not be interpreted to override the effects of the <emu-xref aoid="UserCode" id="_ref_16"><a href="#sec-user-code" class="e-user-code">UserCode</a></emu-xref>() call. It performs the following steps when called:</p>
122122
<emu-alg><ol><li>Perform <span class="e-user-code"><var>map</var>.[[DefineOwnProperty]](! <emu-xref aoid="UserCode" id="_ref_17"><a href="#sec-user-code">UserCode</a></emu-xref>())</span>.</li></ol></emu-alg>
123123
</emu-clause>
124124

125125
<emu-clause id="sec-result-of-evaluating" type="abstract operation" aoid="ResultOfEvaluating">
126-
<h1><span class="secnum">20</span> ResultOfEvaluating()</h1>
126+
<h1><span class="secnum">20</span> ResultOfEvaluating ( )</h1>
127127
<p>The abstract operation ResultOfEvaluating takes no arguments. The phrase "the result of evaluating Foo" is automatically considered as can call user code. It performs the following steps when called:</p>
128128
<emu-alg><ol><li>Let <var>res</var> be the result of <span class="e-user-code">evaluating <emu-nt>Foo</emu-nt></span>.</li></ol></emu-alg>
129129
</emu-clause>
130130

131131
<emu-clause id="sec-fenced-effects" type="abstract operation" aoid="FencedEffects">
132-
<h1><span class="secnum">21</span> FencedEffects()</h1>
132+
<h1><span class="secnum">21</span> FencedEffects ( )</h1>
133133
<p>The abstract operation FencedEffects takes no arguments. Effects don't propagate past fences in parent steps. A fence must be at the beginning of a step. It performs the following steps when called:</p>
134134
<emu-alg><ol><li fence-effects="user-code">Fence.<ol><li><emu-xref aoid="UserCode" id="_ref_18"><a href="#sec-user-code" class="e-user-code">UserCode</a></emu-xref>().</li><li>Let <var>foo</var> be the result of <span class="e-user-code">evaluating <var>someUserCode</var></span>.</li></ol></li></ol></emu-alg>
135135
</emu-clause>
136136

137137
<emu-clause id="sec-call-fenced-effects" type="abstract operation" aoid="CallFencedEffects">
138-
<h1><span class="secnum">22</span> CallFencedEffects()</h1>
138+
<h1><span class="secnum">22</span> CallFencedEffects ( )</h1>
139139
<p>The abstract operation CallFencedEffects takes no arguments. Effects don't propagate past fences in parent steps. It performs the following steps when called:</p>
140140
<emu-alg><ol><li><emu-xref aoid="FencedEffects" id="_ref_19"><a href="#sec-fenced-effects">FencedEffects</a></emu-xref>().</li></ol></emu-alg>
141141
</emu-clause>

test/baselines/generated-reference/structured-headers.html

+6
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,10 @@ <h1><span class="secnum">5</span> ExampleAO3 ( param )</h1>
7171
<p>The abstract operation <emu-xref aoid="ExampleAO3" id="_ref_0"><a href="#sec-example-return-type">ExampleAO3</a></emu-xref> takes argument param (an <emu-xref href="#integer"><a href="https://tc39.es/ecma262/#integer">integer</a></emu-xref>) and returns the return type. It performs the following steps when called:</p>
7272
<emu-alg><ol><li>Algorithm steps go here.</li></ol></emu-alg>
7373
</emu-clause>
74+
75+
<emu-clause id="sec-example-single-line-return-type" type="abstract operation" aoid="ExampleA4">
76+
<h1><span class="secnum">6</span> ExampleA4 ( )</h1>
77+
<p>The abstract operation ExampleA4 takes no arguments and returns <emu-val>false</emu-val>. It performs the following steps when called:</p>
78+
<emu-alg><ol><li>Return <emu-val>false</emu-val>.</li></ol></emu-alg>
79+
</emu-clause>
7480
</div></body>

test/baselines/sources/structured-headers.html

+9
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,12 @@ <h1>
102102
1. Algorithm steps go here.
103103
</emu-alg>
104104
</emu-clause>
105+
106+
<emu-clause id="sec-example-single-line-return-type" type="abstract operation">
107+
<h1>ExampleA4 ( ): *false*</h1>
108+
<dl class='header'>
109+
</dl>
110+
<emu-alg>
111+
1. Return *false*.
112+
</emu-alg>
113+
</emu-clause>

test/lint.js

+5
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,11 @@ describe('linting whole program', () => {
253253
<emu-clause id="i10">
254254
<h1>Example ( _a_ <del>[ , _b_ ] </del>)</h1>
255255
</emu-clause>
256+
<emu-clause id="i11" type="abstract operation">
257+
<h1>Example ( ): a thing (which has a parenthetical)</h1>
258+
<dl class="header">
259+
</dl>
260+
</emu-clause>
256261
`);
257262
});
258263
});

0 commit comments

Comments
 (0)