diff --git a/src/Spec.ts b/src/Spec.ts
index 13d04f89..1b93813b 100644
--- a/src/Spec.ts
+++ b/src/Spec.ts
@@ -474,7 +474,7 @@ export default class Spec {
this.autolink();
- this.log('Propagating can-call-user-code annotations...');
+ this.log('Propagating effect annotations...');
this.propagateEffects();
this.log('Linking xrefs...');
this._xrefs.forEach(xref => xref.build());
diff --git a/src/Xref.ts b/src/Xref.ts
index 21dc6fae..32233742 100644
--- a/src/Xref.ts
+++ b/src/Xref.ts
@@ -89,8 +89,22 @@ export default class Xref extends Builder {
canHaveEffect(effectName: string) {
if (!this.isInvocation) return false;
- if (this.clause && !this.clause.canHaveEffect(effectName)) {
- return false;
+ if (this.clause) {
+ // Xrefs nested inside Abstract Closures should not propagate the
+ // user-code effect, since those are effectively nested functions.
+ //
+ // Calls to Abstract Closures that can call user code must be explicitly
+ // marked as such with
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:
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:
+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:
+