diff --git a/testdata/baselines/reference/compiler/circularControlFlowNarrowingWithCurrentElement01.symbols b/testdata/baselines/reference/compiler/circularControlFlowNarrowingWithCurrentElement01.symbols new file mode 100644 index 0000000000..8b47e8ef22 --- /dev/null +++ b/testdata/baselines/reference/compiler/circularControlFlowNarrowingWithCurrentElement01.symbols @@ -0,0 +1,105 @@ +//// [tests/cases/compiler/circularControlFlowNarrowingWithCurrentElement01.ts] //// + +=== circularControlFlowNarrowingWithCurrentElement01.ts === +class A { +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) + + next: A | null = null; +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) + + constructor(readonly children: (A | null)[]) {} +>children : Symbol(children, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 3, 14)) +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) +} + +function getNodes(): A[] { +>getNodes : Symbol(getNodes, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 4, 1)) +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) + + const out: A[] = []; +>out : Symbol(out, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 7, 7)) +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) + + let current: A | null = new A([]); +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) + + while (current !== null) { +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) + + let firstChild = null; +>firstChild : Symbol(firstChild, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 12, 7)) + + if (out.length) { +>out.length : Symbol(length, Decl(lib.es5.d.ts, --, --)) +>out : Symbol(out, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 7, 7)) +>length : Symbol(length, Decl(lib.es5.d.ts, --, --)) + + current = current.next; +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>current.next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) + + continue; + } + + for (let i = 0; i < current.children.length; i++) { +>i : Symbol(i, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 19, 12)) +>i : Symbol(i, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 19, 12)) +>current.children.length : Symbol(length, Decl(lib.es5.d.ts, --, --)) +>current.children : Symbol(children, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 3, 14)) +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>children : Symbol(children, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 3, 14)) +>length : Symbol(length, Decl(lib.es5.d.ts, --, --)) +>i : Symbol(i, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 19, 12)) + + const child = current.children[i]; +>child : Symbol(child, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 20, 11)) +>current.children : Symbol(children, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 3, 14)) +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>children : Symbol(children, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 3, 14)) +>i : Symbol(i, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 19, 12)) + + if (child) { +>child : Symbol(child, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 20, 11)) + + if (!firstChild) { +>firstChild : Symbol(firstChild, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 12, 7)) + + firstChild = child; +>firstChild : Symbol(firstChild, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 12, 7)) +>child : Symbol(child, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 20, 11)) + + firstChild.next = current.next; +>firstChild.next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>firstChild : Symbol(firstChild, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 12, 7)) +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>current.next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) + } + + child.next = current.next; +>child.next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>child : Symbol(child, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 20, 11)) +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>current.next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) + } + } + + current = firstChild || current.next; +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>firstChild : Symbol(firstChild, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 12, 7)) +>current.next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) + } + + return out; +>out : Symbol(out, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 7, 7)) +} diff --git a/testdata/baselines/reference/compiler/circularControlFlowNarrowingWithCurrentElement01.types b/testdata/baselines/reference/compiler/circularControlFlowNarrowingWithCurrentElement01.types new file mode 100644 index 0000000000..09a5ecd958 --- /dev/null +++ b/testdata/baselines/reference/compiler/circularControlFlowNarrowingWithCurrentElement01.types @@ -0,0 +1,115 @@ +//// [tests/cases/compiler/circularControlFlowNarrowingWithCurrentElement01.ts] //// + +=== circularControlFlowNarrowingWithCurrentElement01.ts === +class A { +>A : A + + next: A | null = null; +>next : A | null + + constructor(readonly children: (A | null)[]) {} +>children : (A | null)[] +} + +function getNodes(): A[] { +>getNodes : () => A[] + + const out: A[] = []; +>out : A[] +>[] : never[] + + let current: A | null = new A([]); +>current : A | null +>new A([]) : A +>A : typeof A +>[] : never[] + + while (current !== null) { +>current !== null : boolean +>current : A | null + + let firstChild = null; +>firstChild : any + + if (out.length) { +>out.length : number +>out : A[] +>length : number + + current = current.next; +>current = current.next : A | null +>current : A | null +>current.next : A | null +>current : A +>next : A | null + + continue; + } + + for (let i = 0; i < current.children.length; i++) { +>i : number +>0 : 0 +>i < current.children.length : boolean +>i : number +>current.children.length : number +>current.children : (A | null)[] +>current : A +>children : (A | null)[] +>length : number +>i++ : number +>i : number + + const child = current.children[i]; +>child : A | null +>current.children[i] : A | null +>current.children : (A | null)[] +>current : A +>children : (A | null)[] +>i : number + + if (child) { +>child : A | null + + if (!firstChild) { +>!firstChild : boolean +>firstChild : A | null + + firstChild = child; +>firstChild = child : A +>firstChild : any +>child : A + + firstChild.next = current.next; +>firstChild.next = current.next : A | null +>firstChild.next : A | null +>firstChild : A +>next : A | null +>current.next : A | null +>current : A +>next : A | null + } + + child.next = current.next; +>child.next = current.next : A | null +>child.next : A | null +>child : A +>next : A | null +>current.next : A | null +>current : A +>next : A | null + } + } + + current = firstChild || current.next; +>current = firstChild || current.next : A | null +>current : A | null +>firstChild || current.next : A | null +>firstChild : A | null +>current.next : A | null +>current : A +>next : A | null + } + + return out; +>out : A[] +} diff --git a/testdata/tests/cases/compiler/circularControlFlowNarrowingWithCurrentElement01.ts b/testdata/tests/cases/compiler/circularControlFlowNarrowingWithCurrentElement01.ts new file mode 100644 index 0000000000..50d2917404 --- /dev/null +++ b/testdata/tests/cases/compiler/circularControlFlowNarrowingWithCurrentElement01.ts @@ -0,0 +1,40 @@ +// @strict: true +// @noEmit: true + +class A { + next: A | null = null; + + constructor(readonly children: (A | null)[]) {} +} + +function getNodes(): A[] { + const out: A[] = []; + + let current: A | null = new A([]); + + while (current !== null) { + let firstChild = null; + + if (out.length) { + current = current.next; + continue; + } + + for (let i = 0; i < current.children.length; i++) { + const child = current.children[i]; + + if (child) { + if (!firstChild) { + firstChild = child; + firstChild.next = current.next; + } + + child.next = current.next; + } + } + + current = firstChild || current.next; + } + + return out; +} \ No newline at end of file