Skip to content

Commit d1f675d

Browse files
committed
Merge branch 'master' into feature/10178
2 parents e5c1731 + 2c9f7e6 commit d1f675d

16 files changed

+518
-260
lines changed

scripts/open-user-pr.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ function padNum(number: number) {
1818
}
1919

2020
const userName = process.env.GH_USERNAME;
21-
const reviewers = ["weswigham", "sandersn", "RyanCavanaugh"]
21+
const reviewers = process.env.requesting_user ? [process.env.requesting_user] : ["weswigham", "sandersn", "RyanCavanaugh"];
2222
const now = new Date();
23-
const branchName = `user-update-${now.getFullYear()}${padNum(now.getMonth())}${padNum(now.getDay())}`;
23+
const branchName = `user-update-${process.env.TARGET_FORK}-${now.getFullYear()}${padNum(now.getMonth())}${padNum(now.getDay())}${process.env.TARGET_BRANCH ? "-" + process.env.TARGET_BRANCH : ""}`;
2424
const remoteUrl = `https://${process.argv[2]}@github.com/${userName}/TypeScript.git`;
2525
runSequence([
2626
["git", ["checkout", "."]], // reset any changes
@@ -41,23 +41,33 @@ gh.pulls.create({
4141
owner: process.env.TARGET_FORK,
4242
repo: "TypeScript",
4343
maintainer_can_modify: true,
44-
title: `🤖 User test baselines have changed`,
44+
title: `🤖 User test baselines have changed` + (process.env.TARGET_BRANCH ? ` for ${process.env.TARGET_BRANCH}` : ""),
4545
head: `${userName}:${branchName}`,
46-
base: "master",
46+
base: process.env.TARGET_BRANCH || "master",
4747
body:
48-
`Please review the diff and merge if no changes are unexpected.
48+
`${process.env.source_issue ? `This test run was triggerd by a request on https://github.com/Microsoft/TypeScript/pull/${process.env.source_issue} `+"\n" : ""}Please review the diff and merge if no changes are unexpected.
4949
You can view the build log [here](https://typescript.visualstudio.com/TypeScript/_build/index?buildId=${process.env.BUILD_BUILDID}&_a=summary).
5050
5151
cc ${reviewers.map(r => "@" + r).join(" ")}`,
52-
}).then(r => {
52+
}).then(async r => {
5353
const num = r.data.number;
5454
console.log(`Pull request ${num} created.`);
55-
return gh.pulls.createReviewRequest({
56-
owner: process.env.TARGET_FORK,
57-
repo: "TypeScript",
58-
number: num,
59-
reviewers,
60-
});
55+
if (!process.env.source_issue) {
56+
await gh.pulls.createReviewRequest({
57+
owner: process.env.TARGET_FORK,
58+
repo: "TypeScript",
59+
number: num,
60+
reviewers,
61+
});
62+
}
63+
else {
64+
await gh.issues.createComment({
65+
number: +process.env.source_issue,
66+
owner: "Microsoft",
67+
repo: "TypeScript",
68+
body: `The user suite test run you requested has finished and _failed_. I've opened a [PR with the baseline diff from master](${r.data.html_url}).`
69+
});
70+
}
6171
}).then(() => {
6272
console.log(`Reviewers requested, done.`);
6373
}).catch(e => {

src/compiler/checker.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ namespace ts {
392392
const literalTypes = createMap<LiteralType>();
393393
const indexedAccessTypes = createMap<IndexedAccessType>();
394394
const conditionalTypes = createMap<Type>();
395+
const substitutionTypes = createMap<SubstitutionType>();
395396
const evolvingArrayTypes: EvolvingArrayType[] = [];
396397
const undefinedProperties = createMap<Symbol>() as UnderscoreEscapedMap<Symbol>;
397398

@@ -8914,9 +8915,15 @@ namespace ts {
89148915
if (substitute.flags & TypeFlags.AnyOrUnknown) {
89158916
return typeVariable;
89168917
}
8918+
const id = `${getTypeId(typeVariable)}>${getTypeId(substitute)}`;
8919+
const cached = substitutionTypes.get(id);
8920+
if (cached) {
8921+
return cached;
8922+
}
89178923
const result = <SubstitutionType>createType(TypeFlags.Substitution);
89188924
result.typeVariable = typeVariable;
89198925
result.substitute = substitute;
8926+
substitutionTypes.set(id, result);
89208927
return result;
89218928
}
89228929

@@ -14763,17 +14770,25 @@ namespace ts {
1476314770
inferFromTypes(source, (<ConditionalType>target).falseType);
1476414771
}
1476514772
else if (target.flags & TypeFlags.UnionOrIntersection) {
14773+
// We infer from types that are not naked type variables first so that inferences we
14774+
// make from nested naked type variables and given slightly higher priority by virtue
14775+
// of being first in the candidates array.
14776+
for (const t of (<UnionOrIntersectionType>target).types) {
14777+
if (!getInferenceInfoForType(t)) {
14778+
inferFromTypes(source, t);
14779+
}
14780+
}
14781+
// Inferences directly to naked type variables are given lower priority as they are
14782+
// less specific. For example, when inferring from Promise<string> to T | Promise<T>,
14783+
// we want to infer string for T, not Promise<string> | string.
14784+
const savePriority = priority;
14785+
priority |= InferencePriority.NakedTypeVariable;
1476614786
for (const t of (<UnionOrIntersectionType>target).types) {
14767-
const savePriority = priority;
14768-
// Inferences directly to naked type variables are given lower priority as they are
14769-
// less specific. For example, when inferring from Promise<string> to T | Promise<T>,
14770-
// we want to infer string for T, not Promise<string> | string.
1477114787
if (getInferenceInfoForType(t)) {
14772-
priority |= InferencePriority.NakedTypeVariable;
14788+
inferFromTypes(source, t);
1477314789
}
14774-
inferFromTypes(source, t);
14775-
priority = savePriority;
1477614790
}
14791+
priority = savePriority;
1477714792
}
1477814793
else if (source.flags & TypeFlags.Union) {
1477914794
// Source is a union or intersection type, infer from each constituent type

src/compiler/program.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1134,7 +1134,7 @@ namespace ts {
11341134
function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName: string): boolean {
11351135
const resolutionToFile = getResolvedModule(oldSourceFile!, moduleName);
11361136
const resolvedFile = resolutionToFile && oldProgram!.getSourceFile(resolutionToFile.resolvedFileName);
1137-
if (resolutionToFile && resolvedFile && !resolvedFile.externalModuleIndicator) {
1137+
if (resolutionToFile && resolvedFile) {
11381138
// In the old program, we resolved to an ambient module that was in the same
11391139
// place as we expected to find an actual module file.
11401140
// We actually need to return 'false' here even though this seems like a 'true' case

src/server/project.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,9 @@ namespace ts.server {
958958
);
959959
const elapsed = timestamp() - start;
960960
this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} Version: ${this.getProjectVersion()} structureChanged: ${hasNewProgram} Elapsed: ${elapsed}ms`);
961+
if (this.program !== oldProgram) {
962+
this.print();
963+
}
961964
return hasNewProgram;
962965
}
963966

src/testRunner/unittests/tsserver/projectErrors.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,90 @@ namespace ts.projectSystem {
479479
session.clearMessages();
480480
}
481481
});
482+
483+
it("Correct errors when resolution resolves to file that has same ambient module and is also module", () => {
484+
const projectRootPath = "/users/username/projects/myproject";
485+
const aFile: File = {
486+
path: `${projectRootPath}/src/a.ts`,
487+
content: `import * as myModule from "@custom/plugin";
488+
function foo() {
489+
// hello
490+
}`
491+
};
492+
const config: File = {
493+
path: `${projectRootPath}/tsconfig.json`,
494+
content: JSON.stringify({ include: ["src"] })
495+
};
496+
const plugin: File = {
497+
path: `${projectRootPath}/node_modules/@custom/plugin/index.d.ts`,
498+
content: `import './proposed';
499+
declare module '@custom/plugin' {
500+
export const version: string;
501+
}`
502+
};
503+
const pluginProposed: File = {
504+
path: `${projectRootPath}/node_modules/@custom/plugin/proposed.d.ts`,
505+
content: `declare module '@custom/plugin' {
506+
export const bar = 10;
507+
}`
508+
};
509+
const files = [libFile, aFile, config, plugin, pluginProposed];
510+
const host = createServerHost(files);
511+
const session = createSession(host, { canUseEvents: true });
512+
const service = session.getProjectService();
513+
openFilesForSession([aFile], session);
514+
515+
checkNumberOfProjects(service, { configuredProjects: 1 });
516+
session.clearMessages();
517+
checkErrors();
518+
519+
session.executeCommandSeq<protocol.ChangeRequest>({
520+
command: protocol.CommandTypes.Change,
521+
arguments: {
522+
file: aFile.path,
523+
line: 3,
524+
offset: 8,
525+
endLine: 3,
526+
endOffset: 8,
527+
insertString: "o"
528+
}
529+
});
530+
checkErrors();
531+
532+
function checkErrors() {
533+
host.checkTimeoutQueueLength(0);
534+
const expectedSequenceId = session.getNextSeq();
535+
session.executeCommandSeq<protocol.GeterrRequest>({
536+
command: server.CommandNames.Geterr,
537+
arguments: {
538+
delay: 0,
539+
files: [aFile.path],
540+
}
541+
});
542+
543+
host.checkTimeoutQueueLengthAndRun(1);
544+
545+
checkErrorMessage(session, "syntaxDiag", { file: aFile.path, diagnostics: [] }, /*isMostRecent*/ true);
546+
session.clearMessages();
547+
548+
host.runQueuedImmediateCallbacks(1);
549+
550+
checkErrorMessage(session, "semanticDiag", { file: aFile.path, diagnostics: [] });
551+
session.clearMessages();
552+
553+
host.runQueuedImmediateCallbacks(1);
554+
555+
checkErrorMessage(session, "suggestionDiag", {
556+
file: aFile.path,
557+
diagnostics: [
558+
createDiagnostic({ line: 1, offset: 1 }, { line: 1, offset: 44 }, Diagnostics._0_is_declared_but_its_value_is_never_read, ["myModule"], "suggestion", /*reportsUnnecessary*/ true),
559+
createDiagnostic({ line: 2, offset: 10 }, { line: 2, offset: 13 }, Diagnostics._0_is_declared_but_its_value_is_never_read, ["foo"], "suggestion", /*reportsUnnecessary*/ true)
560+
],
561+
});
562+
checkCompleteEvent(session, 2, expectedSequenceId);
563+
session.clearMessages();
564+
}
565+
});
482566
});
483567

484568
describe("unittests:: tsserver:: Project Errors for Configure file diagnostics events", () => {

tests/baselines/reference/inlinedAliasAssignableToConstraintSameAsAlias.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class A {
3131
>z : A[]
3232

3333
whereRelated< // Works // Type is same as A1, but is not assignable to type A
34-
>whereRelated : <RF extends RelationFields = RelationFields, N extends "x" | "y" | "z" = "x" | "y" | "z", A1 extends A = RF[N] extends A[] ? RF[N][0] : never, A2 extends A = ShouldA<RF, N>>() => number
34+
>whereRelated : <RF extends RelationFields = RelationFields, N extends "x" | "y" | "z" = "x" | "y" | "z", A1 extends A = RF[N] extends A[] ? RF[N][0] : never, A2 extends A = RF[N] extends A[] ? RF[N][0] : never>() => number
3535

3636
RF extends RelationFields = RelationFields,
3737
N extends Name = Name,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//// [unionAndIntersectionInference3.ts]
2+
// Repro from #30720
3+
4+
type Maybe<T> = T | undefined;
5+
declare function concatMaybe<T>(...args: (Maybe<T> | Maybe<T>[])[]): T[];
6+
concatMaybe([1, 2, 3], 4);
7+
8+
9+
//// [unionAndIntersectionInference3.js]
10+
"use strict";
11+
// Repro from #30720
12+
concatMaybe([1, 2, 3], 4);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
=== tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts ===
2+
// Repro from #30720
3+
4+
type Maybe<T> = T | undefined;
5+
>Maybe : Symbol(Maybe, Decl(unionAndIntersectionInference3.ts, 0, 0))
6+
>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 2, 11))
7+
>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 2, 11))
8+
9+
declare function concatMaybe<T>(...args: (Maybe<T> | Maybe<T>[])[]): T[];
10+
>concatMaybe : Symbol(concatMaybe, Decl(unionAndIntersectionInference3.ts, 2, 30))
11+
>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 3, 29))
12+
>args : Symbol(args, Decl(unionAndIntersectionInference3.ts, 3, 32))
13+
>Maybe : Symbol(Maybe, Decl(unionAndIntersectionInference3.ts, 0, 0))
14+
>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 3, 29))
15+
>Maybe : Symbol(Maybe, Decl(unionAndIntersectionInference3.ts, 0, 0))
16+
>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 3, 29))
17+
>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 3, 29))
18+
19+
concatMaybe([1, 2, 3], 4);
20+
>concatMaybe : Symbol(concatMaybe, Decl(unionAndIntersectionInference3.ts, 2, 30))
21+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
=== tests/cases/conformance/types/typeRelationships/typeInference/unionAndIntersectionInference3.ts ===
2+
// Repro from #30720
3+
4+
type Maybe<T> = T | undefined;
5+
>Maybe : Maybe<T>
6+
7+
declare function concatMaybe<T>(...args: (Maybe<T> | Maybe<T>[])[]): T[];
8+
>concatMaybe : <T>(...args: (T | Maybe<T>[] | undefined)[]) => T[]
9+
>args : (T | Maybe<T>[] | undefined)[]
10+
11+
concatMaybe([1, 2, 3], 4);
12+
>concatMaybe([1, 2, 3], 4) : number[]
13+
>concatMaybe : <T>(...args: (T | Maybe<T>[] | undefined)[]) => T[]
14+
>[1, 2, 3] : number[]
15+
>1 : 1
16+
>2 : 2
17+
>3 : 3
18+
>4 : 4
19+

0 commit comments

Comments
 (0)