diff --git a/src/resolver.ts b/src/resolver.ts index db485a0973..e1d7989805 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -996,6 +996,9 @@ export class Resolver extends DiagnosticEmitter { return null; } + /** resolving expressions */ + private resolvingExpressions: Set = new Set(); + /** Resolves an expression to its static type. */ resolveExpression( /** The expression to resolve. */ @@ -1006,6 +1009,21 @@ export class Resolver extends DiagnosticEmitter { ctxType: Type = Type.auto, /** How to proceed with eventual diagnostics. */ reportMode: ReportMode = ReportMode.REPORT + ): Type | null { + const resolvingExpressions = this.resolvingExpressions; + if (resolvingExpressions.has(node)) return null; + resolvingExpressions.add(node); + const resolved = this.doResolveExpression(node, ctxFlow, ctxType, reportMode); + resolvingExpressions.delete(node); + return resolved; + } + + /** Resolves an expression to its static type. (may cause stack overflow) */ + private doResolveExpression( + node: Expression, + ctxFlow: Flow, + ctxType: Type = Type.auto, + reportMode: ReportMode = ReportMode.REPORT ): Type | null { while (node.kind == NodeKind.PARENTHESIZED) { // skip node = (node).expression; diff --git a/tests/compiler/avoid-resolve-loop.json b/tests/compiler/avoid-resolve-loop.json new file mode 100644 index 0000000000..9499b5939d --- /dev/null +++ b/tests/compiler/avoid-resolve-loop.json @@ -0,0 +1,10 @@ +{ + "asc_flags": [ + ], + "stderr": [ + "AS225: Expression cannot be represented by a type.", + "TS2448: Variable 'avoid-resolve-loop/e' used before its declaration.", + "TS2322: Type 'void' is not assignable to type ''.", + "AS225: Expression cannot be represented by a type." + ] +} \ No newline at end of file diff --git a/tests/compiler/avoid-resolve-loop.ts b/tests/compiler/avoid-resolve-loop.ts new file mode 100644 index 0000000000..1c0d726068 --- /dev/null +++ b/tests/compiler/avoid-resolve-loop.ts @@ -0,0 +1,4 @@ +let a = a[0]; + +let e = e; +typeof [e]; \ No newline at end of file