diff --git a/src/Algorithm.ts b/src/Algorithm.ts
index 71580cbb..205edd9e 100644
--- a/src/Algorithm.ts
+++ b/src/Algorithm.ts
@@ -87,13 +87,12 @@ export default class Algorithm extends Builder {
continue;
}
const completionyThing = part.contents.match(
- /\b(ReturnIfAbrupt|throw|Return (Normal|Throw)?Completion|the result of evaluating)\b|(?<=[\s(])\?\s/i
+ /\b(ReturnIfAbrupt\b|(^|(?<=, ))[tT]hrow (a\b|the\b|$)|[rR]eturn (Normal|Throw|Return)?Completion\(|[rR]eturn( a| a new| the)? Completion Record\b|the result of evaluating\b)|(?<=[\s(])\?\s/
);
if (completionyThing != null) {
if (returnType?.kind === 'completion') {
containsAnyCompletionyThings = true;
- } else if (clause.aoid !== 'GeneratorStart') {
- // TODO: remove above exception when the spec is more coherent (https://github.com/tc39/ecma262/pull/2429)
+ } else {
spec.warn({
type: 'contents',
ruleId: 'completiony-thing-in-non-completion-algorithm',
diff --git a/test/typecheck.js b/test/typecheck.js
index c2d2a7fe..5833605e 100644
--- a/test/typecheck.js
+++ b/test/typecheck.js
@@ -254,7 +254,50 @@ describe('typechecking completions', () => {
- 1. ${M}Throw a new TypeError.
+ 1. ${M}Throw a *TypeError* exception.
+
+
+ `,
+ {
+ ruleId: 'completiony-thing-in-non-completion-algorithm',
+ nodeType: 'emu-alg',
+ message:
+ 'this would return a Completion Record, but the containing AO is declared not to return a Completion Record',
+ }
+ );
+
+ await assertLint(
+ positioned`
+
+
+ ExampleAlg (): a Number
+
+
+
+ 1. If some condition is met, ${M}throw a *TypeError* exception.
+
+
+ `,
+ {
+ ruleId: 'completiony-thing-in-non-completion-algorithm',
+ nodeType: 'emu-alg',
+ message:
+ 'this would return a Completion Record, but the containing AO is declared not to return a Completion Record',
+ }
+ );
+
+ await assertLint(
+ positioned`
+
+
+ ExampleAlg (): a Number
+
+
+
+ 1. Let _foo_ be a thing.
+ 1. ${M}Throw _foo_.
`,
@@ -290,6 +333,28 @@ describe('typechecking completions', () => {
extraBiblios: [biblio],
}
);
+
+ await assertLint(
+ positioned`
+
+
+ ExampleAlg (): a Number
+
+
+
+ 1. Let _x_ be 0.
+ 1. ${M}Return Completion Record { [[Type]]: ~return~, [[Value]]: _x_, [[Target]]: ~empty~ }.
+
+
+ `,
+ {
+ ruleId: 'completiony-thing-in-non-completion-algorithm',
+ nodeType: 'emu-alg',
+ message:
+ 'this would return a Completion Record, but the containing AO is declared not to return a Completion Record',
+ }
+ );
});
it('negative', async () => {
@@ -314,6 +379,26 @@ describe('typechecking completions', () => {
extraBiblios: [biblio],
}
);
+
+ await assertLintFree(
+ `
+
+
+ ExampleAlg (): a Number
+
+
+
+ 1. Do something with Completion(0).
+ 1. NOTE: This will not throw a *TypeError* exception.
+ 1. Consider whether something is a return completion.
+
+
+ `,
+ {
+ extraBiblios: [biblio],
+ }
+ );
});
});
@@ -507,7 +592,7 @@ describe('typechecking completions', () => {
- 1. Throw something.
+ 1. Throw a *TypeError* exception.