Skip to content
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
10 changes: 10 additions & 0 deletions css/elements.css
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@

--attributes-tag-foreground-color: #884400;

--ac-body-border-color: #ddd;

--figure-background: #fff;
}

Expand Down Expand Up @@ -157,6 +159,8 @@

--attributes-tag-foreground-color: #e6a96d;

--ac-body-border-color: #555;

--figure-background: #fff;
}
}
Expand Down Expand Up @@ -496,6 +500,12 @@ emu-alg ol.nested-lots ol {
list-style-type: lower-roman;
}

emu-alg ol.ac-body {
border-left: 3px solid var(--ac-body-border-color);
border-radius: 0 0 0 20px;
padding-bottom: 5px;
}

emu-eqn {
display: block;
margin-left: 4em;
Expand Down
12 changes: 11 additions & 1 deletion src/Algorithm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { PartialBiblioEntry, StepBiblioEntry } from './Biblio';

import Builder from './Builder';
import { SPECIAL_KINDS_MAP, SPECIAL_KINDS } from './Clause';
import { warnEmdFailure, wrapEmdFailure } from './utils';
import { isAbstractClosureHeader, ownTextContent, warnEmdFailure, wrapEmdFailure } from './utils';
import { collectNonterminalsFromEmd } from './lint/utils';
import * as emd from 'ecmarkdown';

Expand Down Expand Up @@ -119,6 +119,16 @@ export default class Algorithm extends Builder {
}
}

for (const step of node.querySelectorAll('li')) {
if (isAbstractClosureHeader(ownTextContent(step))) {
for (const ol of step.children) {
if (ol.tagName === 'OL') {
ol.classList.add('ac-body');
}
}
}
}

for (const step of node.querySelectorAll(kindSelector)) {
// prettier-ignore
const attributes = SPECIAL_KINDS
Expand Down
7 changes: 2 additions & 5 deletions src/lint/rules/variable-use-def.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type {
import type { Reporter } from '../algorithm-error-reporter-type';
import type { Seq } from '../../expr-parser';
import { walk as walkExpr } from '../../expr-parser';
import { offsetToLineAndColumn } from '../../utils';
import { isAbstractClosureHeader, offsetToLineAndColumn } from '../../utils';

/*
Ecmaspeak scope rules are a bit weird.
Expand Down Expand Up @@ -244,10 +244,7 @@ function walkAlgorithm(
}

// handle abstract closures
if (
last?.name === 'text' &&
/ performs the following steps (atomically )?when called:$/.test(last.contents)
) {
if (last?.name === 'text' && isAbstractClosureHeader(last.contents)) {
if (first.name === 'text' && first.contents === 'Let ' && isVariable(expr.items[1])) {
const closureName = expr.items[1];
scope.declare(closureName.contents, closureName);
Expand Down
19 changes: 15 additions & 4 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,7 @@ export function doesEffectPropagateToParent(node: Element, effect: string) {
// This is super hacky. It's checking the output of ecmarkdown.
if (parent.tagName !== 'LI') continue;

if (
effect === 'user-code' &&
/be a new (\w+ )*Abstract Closure/.test(parent.textContent ?? '')
) {
if (effect === 'user-code' && isAbstractClosureHeader(ownTextContent(parent))) {
return false;
}

Expand Down Expand Up @@ -343,3 +340,17 @@ export function withOrdinalSuffix(n: number): string {
const suffixes = { one: 'st', two: 'nd', few: 'rd', other: 'th' };
return `${n}${suffixes[rule as keyof typeof suffixes]}`;
}

const acHeaderRe = / performs the following steps (atomically )?when called:$/;
export function isAbstractClosureHeader(text: string): boolean {
return acHeaderRe.test(text);
}

export function ownTextContent(el: Element): string {
let text = '';
for (const child of el.childNodes) {
if (child.nodeType === 1 && (child as Element).tagName === 'OL') continue;
text += child.textContent;
}
return text;
}
Comment on lines +349 to +356
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the record, I have the same complaint about this function as @bakkot raised about my proposed isAbstractClosure—it presumes an HTML structure without any indication of such a requirement (i.e., "own" does not imply anything specific to HTML list items).

If we're going to keep this function implementation (given an element, return the concatenation of all non-<ol> children's textContent), I'd prefer renaming it to something like stepOwnTextContent, or alternatively generalizing the implementation to also filter out <ul> children and renaming it to something like liOwnTextContent.

10 changes: 10 additions & 0 deletions test/baselines/generated-reference/assets-inline.html
Original file line number Diff line number Diff line change
Expand Up @@ -1693,6 +1693,8 @@
--attributes-tag-foreground-color: #884400;
--ac-body-border-color: #ddd;
--figure-background: #fff;
}
Expand Down Expand Up @@ -1775,6 +1777,8 @@
--attributes-tag-foreground-color: #e6a96d;
--ac-body-border-color: #555;
--figure-background: #fff;
}
}
Expand Down Expand Up @@ -2114,6 +2118,12 @@
list-style-type: lower-roman;
}
emu-alg ol.ac-body {
border-left: 3px solid var(--ac-body-border-color);
border-radius: 0 0 0 20px;
padding-bottom: 5px;
}
emu-eqn {
display: block;
margin-left: 4em;
Expand Down
4 changes: 2 additions & 2 deletions test/baselines/generated-reference/effect-user-code.html
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,13 @@ <h1><span class="secnum">16</span> RenderedMeta ( )</h1>
<emu-clause id="sec-make-abstract-closure" type="abstract operation" aoid="MakeAbstractClosure">
<h1><span class="secnum">17</span> MakeAbstractClosure ( )</h1>
<p>The abstract operation MakeAbstractClosure takes no arguments. The user-code effect doesn't propagate through <emu-xref href="#sec-abstract-closure"><a href="https://tc39.es/ecma262/#sec-abstract-closure">Abstract Closure</a></emu-xref> boundaries by recognizing the "be a new <emu-xref href="#sec-abstract-closure"><a href="https://tc39.es/ecma262/#sec-abstract-closure">Abstract Closure</a></emu-xref>" <emu-xref href="#substring"><a href="https://tc39.es/ecma262/#substring">substring</a></emu-xref>. It performs the following steps when called:</p>
<emu-alg><ol><li>Let <var>closure</var> be a new <emu-xref href="#sec-abstract-closure"><a href="https://tc39.es/ecma262/#sec-abstract-closure">Abstract Closure</a></emu-xref> 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>
<emu-alg><ol><li>Let <var>closure</var> be a new <emu-xref href="#sec-abstract-closure"><a href="https://tc39.es/ecma262/#sec-abstract-closure">Abstract Closure</a></emu-xref> that captures nothing and performs the following steps when called:<ol class="ac-body"><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>
</emu-clause>

<emu-clause id="sec-make-special-abstract-closure" type="abstract operation" aoid="MakeJobAbstractClosure">
<h1><span class="secnum">18</span> MakeJobAbstractClosure ( )</h1>
<p>The abstract operation MakeJobAbstractClosure takes no arguments. The user-code effect doesn't propagate through specialized <emu-xref href="#sec-abstract-closure"><a href="https://tc39.es/ecma262/#sec-abstract-closure">Abstract Closure</a></emu-xref> boundaries by recognizing the "be a new Something <emu-xref href="#sec-abstract-closure"><a href="https://tc39.es/ecma262/#sec-abstract-closure">Abstract Closure</a></emu-xref>" <emu-xref href="#substring"><a href="https://tc39.es/ecma262/#substring">substring</a></emu-xref>. It performs the following steps when called:</p>
<emu-alg><ol><li>Let <var>closure</var> be a new <emu-xref href="#job"><a href="https://tc39.es/ecma262/#job">Job</a></emu-xref> <emu-xref href="#sec-abstract-closure"><a href="https://tc39.es/ecma262/#sec-abstract-closure">Abstract Closure</a></emu-xref> that captures nothing and performs the following steps when called:<ol><li><emu-xref aoid="UserCode" id="_ref_14"><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>
<emu-alg><ol><li>Let <var>closure</var> be a new <emu-xref href="#job"><a href="https://tc39.es/ecma262/#job">Job</a></emu-xref> <emu-xref href="#sec-abstract-closure"><a href="https://tc39.es/ecma262/#sec-abstract-closure">Abstract Closure</a></emu-xref> that captures nothing and performs the following steps when called:<ol class="ac-body"><li><emu-xref aoid="UserCode" id="_ref_14"><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>
</emu-clause>

<emu-clause id="sec-call-make-abstract-closure" type="abstract operation" aoid="CallMakeAbstractClosure">
Expand Down