From cadd7679a2e3bf819f58e575a650fcf6118a9c96 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 19 Jan 2018 13:08:22 -0800 Subject: [PATCH 1/2] DT runner:Fix $ExpectError handling Indices into lines of the file are zero-based, but the errors reporting by Typescript are one-based. Also, the regex ignored $ExpectError in tsx files. --- src/harness/externalCompileRunner.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/harness/externalCompileRunner.ts b/src/harness/externalCompileRunner.ts index c829a6490bb..1f945cfcc9c 100644 --- a/src/harness/externalCompileRunner.ts +++ b/src/harness/externalCompileRunner.ts @@ -131,13 +131,13 @@ function removeExpectedErrors(errors: string, cwd: string): string { function isUnexpectedError(cwd: string) { return (error: string[]) => { ts.Debug.assertGreaterThanOrEqual(error.length, 1); - const match = error[0].match(/(.+\.ts)\((\d+),\d+\): error TS/); + const match = error[0].match(/(.+\.tsx?)\((\d+),\d+\): error TS/); if (!match) { return true; } const [, errorFile, lineNumberString] = match; const lines = fs.readFileSync(path.join(cwd, errorFile), { encoding: "utf8" }).split("\n"); - const lineNumber = parseInt(lineNumberString); + const lineNumber = parseInt(lineNumberString) - 1; ts.Debug.assertGreaterThanOrEqual(lineNumber, 0); ts.Debug.assertLessThan(lineNumber, lines.length); const previousLine = lineNumber - 1 > 0 ? lines[lineNumber - 1] : ""; From 588716926dcaa063aecb4d64232e2f3cfd8e23b2 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 22 Jan 2018 10:15:57 -0800 Subject: [PATCH 2/2] Fix bug: result of createUnionOrIntersectionProperty may be undefined (#21332) --- src/compiler/checker.ts | 6 ++++-- tests/cases/fourslash/completionsUnion.ts | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 405fd11f138..14631fa69cb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5995,7 +5995,9 @@ namespace ts { for (const memberType of types) { for (const { escapedName } of getAugmentedPropertiesOfType(memberType)) { if (!props.has(escapedName)) { - props.set(escapedName, createUnionOrIntersectionProperty(unionType as UnionType, escapedName)); + const prop = createUnionOrIntersectionProperty(unionType as UnionType, escapedName); + // May be undefined if the property is private + if (prop) props.set(escapedName, prop); } } } @@ -6177,7 +6179,7 @@ namespace ts { t; } - function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol { + function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol | undefined { let props: Symbol[]; const isUnion = containingType.flags & TypeFlags.Union; const excludeModifiers = isUnion ? ModifierFlags.NonPublicAccessibilityModifier : 0; diff --git a/tests/cases/fourslash/completionsUnion.ts b/tests/cases/fourslash/completionsUnion.ts index ed449936680..d9d1d3c792f 100644 --- a/tests/cases/fourslash/completionsUnion.ts +++ b/tests/cases/fourslash/completionsUnion.ts @@ -2,7 +2,9 @@ ////interface I { x: number; } ////interface Many extends ReadonlyArray { extra: number; } -////const x: I | I[] | Many = { /**/ }; +////class C { private priv: number; } +////const x: I | I[] | Many | C = { /**/ }; // We specifically filter out any array-like types. +// Private members will be excluded by `createUnionOrIntersectionProperty`. verify.completionsAt("", ["x"]);