diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts
index 4d4cf909fd..0347a28743 100644
--- a/src/compiler/compile/Component.ts
+++ b/src/compiler/compile/Component.ts
@@ -24,7 +24,7 @@ import TemplateScope from './nodes/shared/TemplateScope';
import fuzzymatch from '../utils/fuzzymatch';
import get_object from './utils/get_object';
import Slot from './nodes/Slot';
-import { Node, ImportDeclaration, ExportNamedDeclaration, Identifier, ExpressionStatement, AssignmentExpression, Literal, Property, RestElement, ExportDefaultDeclaration, ExportAllDeclaration } from 'estree';
+import { Node, ImportDeclaration, ExportNamedDeclaration, Identifier, ExpressionStatement, AssignmentExpression, Literal, Property, RestElement, ExportDefaultDeclaration, ExportAllDeclaration, FunctionDeclaration, FunctionExpression } from 'estree';
import add_to_set from './utils/add_to_set';
import check_graph_for_cycles from './utils/check_graph_for_cycles';
import { print, b } from 'code-red';
@@ -766,12 +766,13 @@ export default class Component {
};
let scope_updated = false;
- let generator_count = 0;
+ const current_function_stack = [];
+ let current_function: FunctionDeclaration | FunctionExpression = null;
walk(content, {
enter(node: Node, parent: Node, prop, index) {
- if ((node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') && node.generator === true) {
- generator_count++;
+ if ((node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression')) {
+ current_function_stack.push(current_function = node);
}
if (map.has(node)) {
@@ -800,12 +801,13 @@ export default class Component {
},
leave(node: Node) {
- if ((node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') && node.generator === true) {
- generator_count--;
+ if ((node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression')) {
+ current_function_stack.pop();
+ current_function = current_function_stack[current_function_stack.length - 1];
}
// do it on leave, to prevent infinite loop
- if (component.compile_options.dev && component.compile_options.loopGuardTimeout > 0 && generator_count <= 0) {
+ if (component.compile_options.dev && component.compile_options.loopGuardTimeout > 0 && (!current_function || (!current_function.generator && !current_function.async))) {
const to_replace_for_loop_protect = component.loop_protect(node, scope, component.compile_options.loopGuardTimeout);
if (to_replace_for_loop_protect) {
this.replace(to_replace_for_loop_protect);
diff --git a/test/runtime/samples/loop-protect-async-opt-out/_config.js b/test/runtime/samples/loop-protect-async-opt-out/_config.js
new file mode 100644
index 0000000000..b1855c83eb
--- /dev/null
+++ b/test/runtime/samples/loop-protect-async-opt-out/_config.js
@@ -0,0 +1,9 @@
+export default {
+ compileOptions: {
+ dev: true,
+ loopGuardTimeout: 1
+ },
+ async test({ component }) {
+ await component.run_async_function();
+ }
+};
diff --git a/test/runtime/samples/loop-protect-async-opt-out/main.svelte b/test/runtime/samples/loop-protect-async-opt-out/main.svelte
new file mode 100644
index 0000000000..bc711ac5a3
--- /dev/null
+++ b/test/runtime/samples/loop-protect-async-opt-out/main.svelte
@@ -0,0 +1,12 @@
+
diff --git a/test/runtime/samples/loop-protect-generator-opt-out/_config.js b/test/runtime/samples/loop-protect-generator-opt-out/_config.js
index 0fe83a36db..2680ecfdfb 100644
--- a/test/runtime/samples/loop-protect-generator-opt-out/_config.js
+++ b/test/runtime/samples/loop-protect-generator-opt-out/_config.js
@@ -2,5 +2,8 @@ export default {
compileOptions: {
dev: true,
loopGuardTimeout: 1
+ },
+ async test({ component }) {
+ await component.run_generator();
}
};
diff --git a/test/runtime/samples/loop-protect-generator-opt-out/main.svelte b/test/runtime/samples/loop-protect-generator-opt-out/main.svelte
index a7aa790681..514089435d 100644
--- a/test/runtime/samples/loop-protect-generator-opt-out/main.svelte
+++ b/test/runtime/samples/loop-protect-generator-opt-out/main.svelte
@@ -1,10 +1,12 @@