From 88e56f39569196bafa55cddebd884dc256ef582b Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 31 Oct 2017 11:49:52 -0700 Subject: [PATCH] Assert arrays passed to relativeComplement are sorted --- src/compiler/core.ts | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index e2e8a0096f5..3907231a525 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -789,15 +789,37 @@ namespace ts { export function relativeComplement(arrayA: T[] | undefined, arrayB: T[] | undefined, comparer: Comparer): T[] | undefined { if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0) return arrayB; const result: T[] = []; - outer: for (let offsetA = 0, offsetB = 0; offsetB < arrayB.length; offsetB++) { - inner: for (; offsetA < arrayA.length; offsetA++) { + loopB: for (let offsetA = 0, offsetB = 0; offsetB < arrayB.length; offsetB++) { + if (offsetB > 0) { + // Ensure `arrayB` is properly sorted. + Debug.assertGreaterThanOrEqual(comparer(arrayB[offsetB], arrayB[offsetB - 1]), Comparison.EqualTo); + } + + loopA: for (const startA = offsetA; offsetA < arrayA.length; offsetA++) { + if (offsetA > startA) { + // Ensure `arrayA` is properly sorted. We only need to perform this check if + // `offsetA` has changed since we entered the loop. + Debug.assertGreaterThanOrEqual(comparer(arrayA[offsetA], arrayA[offsetA - 1]), Comparison.EqualTo); + } + switch (comparer(arrayB[offsetB], arrayA[offsetA])) { - case Comparison.LessThan: break inner; - case Comparison.EqualTo: continue outer; - case Comparison.GreaterThan: continue inner; + case Comparison.LessThan: + // If B is less than A, B does not exist in arrayA. Add B to the result and + // move to the next element in arrayB without changing the current position + // in arrayA. + result.push(arrayB[offsetB]); + continue loopB; + case Comparison.EqualTo: + // If B is equal to A, B exists in arrayA. Move to the next element in + // arrayB without adding B to the result or changing the current position + // in arrayA. + continue loopB; + case Comparison.GreaterThan: + // If B is greater than A, we need to keep looking for B in arrayA. Move to + // the next element in arrayA and recheck. + continue loopA; } } - result.push(arrayB[offsetB]); } return result; }