Skip to content

Commit 3dd3ded

Browse files
author
Andy Hanson
committed
Merge branch 'master' into dtsgen
2 parents a74e826 + 6adb9d1 commit 3dd3ded

File tree

110 files changed

+1760
-543
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+1760
-543
lines changed

Diff for: src/compiler/builderState.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ namespace ts.BuilderState {
8888
function getReferencedFileFromImportedModuleSymbol(symbol: Symbol) {
8989
if (symbol.declarations && symbol.declarations[0]) {
9090
const declarationSourceFile = getSourceFileOfNode(symbol.declarations[0]);
91-
return declarationSourceFile && declarationSourceFile.path;
91+
return declarationSourceFile && (declarationSourceFile.resolvedPath || declarationSourceFile.path);
9292
}
9393
}
9494

@@ -100,6 +100,13 @@ namespace ts.BuilderState {
100100
return symbol && getReferencedFileFromImportedModuleSymbol(symbol);
101101
}
102102

103+
/**
104+
* Gets the path to reference file from file name, it could be resolvedPath if present otherwise path
105+
*/
106+
function getReferencedFileFromFileName(program: Program, fileName: string, sourceFileDirectory: Path, getCanonicalFileName: GetCanonicalFileName): Path {
107+
return toPath(program.getProjectReferenceRedirect(fileName) || fileName, sourceFileDirectory, getCanonicalFileName);
108+
}
109+
103110
/**
104111
* Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true
105112
*/
@@ -123,7 +130,7 @@ namespace ts.BuilderState {
123130
// Handle triple slash references
124131
if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) {
125132
for (const referencedFile of sourceFile.referencedFiles) {
126-
const referencedPath = toPath(referencedFile.fileName, sourceFileDirectory, getCanonicalFileName);
133+
const referencedPath = getReferencedFileFromFileName(program, referencedFile.fileName, sourceFileDirectory, getCanonicalFileName);
127134
addReferencedFile(referencedPath);
128135
}
129136
}
@@ -136,7 +143,7 @@ namespace ts.BuilderState {
136143
}
137144

138145
const fileName = resolvedTypeReferenceDirective.resolvedFileName!; // TODO: GH#18217
139-
const typeFilePath = toPath(fileName, sourceFileDirectory, getCanonicalFileName);
146+
const typeFilePath = getReferencedFileFromFileName(program, fileName, sourceFileDirectory, getCanonicalFileName);
140147
addReferencedFile(typeFilePath);
141148
});
142149
}

Diff for: src/compiler/checker.ts

+120-46
Large diffs are not rendered by default.

Diff for: src/compiler/commandLineParser.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -2030,7 +2030,7 @@ namespace ts {
20302030
if (ownConfig.extendedConfigPath) {
20312031
// copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios.
20322032
resolutionStack = resolutionStack.concat([resolvedPath]);
2033-
const extendedConfig = getExtendedConfig(sourceFile!, ownConfig.extendedConfigPath, host, basePath, resolutionStack, errors);
2033+
const extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, resolutionStack, errors);
20342034
if (extendedConfig && isSuccessfulParsedTsconfig(extendedConfig)) {
20352035
const baseRaw = extendedConfig.raw;
20362036
const raw = ownConfig.raw;
@@ -2171,7 +2171,7 @@ namespace ts {
21712171
}
21722172

21732173
function getExtendedConfig(
2174-
sourceFile: TsConfigSourceFile,
2174+
sourceFile: TsConfigSourceFile | undefined,
21752175
extendedConfigPath: string,
21762176
host: ParseConfigHost,
21772177
basePath: string,
@@ -2180,7 +2180,7 @@ namespace ts {
21802180
): ParsedTsconfig | undefined {
21812181
const extendedResult = readJsonConfigFile(extendedConfigPath, path => host.readFile(path));
21822182
if (sourceFile) {
2183-
(sourceFile.extendedSourceFiles || (sourceFile.extendedSourceFiles = [])).push(extendedResult.fileName);
2183+
sourceFile.extendedSourceFiles = [extendedResult.fileName];
21842184
}
21852185
if (extendedResult.parseDiagnostics.length) {
21862186
errors.push(...extendedResult.parseDiagnostics);
@@ -2190,8 +2190,8 @@ namespace ts {
21902190
const extendedDirname = getDirectoryPath(extendedConfigPath);
21912191
const extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname,
21922192
getBaseFileName(extendedConfigPath), resolutionStack, errors);
2193-
if (sourceFile) {
2194-
sourceFile.extendedSourceFiles!.push(...extendedResult.extendedSourceFiles!);
2193+
if (sourceFile && extendedResult.extendedSourceFiles) {
2194+
sourceFile.extendedSourceFiles!.push(...extendedResult.extendedSourceFiles);
21952195
}
21962196

21972197
if (isSuccessfulParsedTsconfig(extendedConfig)) {

Diff for: src/compiler/core.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ namespace ts {
842842
return deduplicateSorted(sort(array, comparer), equalityComparer || comparer);
843843
}
844844

845-
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T> | undefined, array2: ReadonlyArray<T> | undefined, equalityComparer: (a: T, b: T) => boolean = equateValues): boolean {
845+
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T> | undefined, array2: ReadonlyArray<T> | undefined, equalityComparer: (a: T, b: T, index: number) => boolean = equateValues): boolean {
846846
if (!array1 || !array2) {
847847
return array1 === array2;
848848
}
@@ -852,7 +852,7 @@ namespace ts {
852852
}
853853

854854
for (let i = 0; i < array1.length; i++) {
855-
if (!equalityComparer(array1[i], array2[i])) {
855+
if (!equalityComparer(array1[i], array2[i], i)) {
856856
return false;
857857
}
858858
}

Diff for: src/compiler/diagnosticMessages.json

+8
Original file line numberDiff line numberDiff line change
@@ -2112,6 +2112,10 @@
21122112
"category": "Error",
21132113
"code": 2585
21142114
},
2115+
"Enum type '{0}' circularly references itself.": {
2116+
"category": "Error",
2117+
"code": 2586
2118+
},
21152119
"JSX element attributes type '{0}' may not be a union type.": {
21162120
"category": "Error",
21172121
"code": 2600
@@ -3886,6 +3890,10 @@
38863890
"category": "Message",
38873891
"code": 6501
38883892
},
3893+
"The expected type comes from the return type of this signature.": {
3894+
"category": "Message",
3895+
"code": 6502
3896+
},
38893897

38903898
"Variable '{0}' implicitly has an '{1}' type.": {
38913899
"category": "Error",

Diff for: src/compiler/inspectValue.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ namespace ts {
9696

9797
function getPrototypeMembers(fn: AnyFunction, recurser: Recurser): ReadonlyArray<ValueInfo> {
9898
const prototype = fn.prototype as unknown;
99-
return typeof prototype !== "object" || prototype === null ? emptyArray : mapDefined(getEntriesOfObject(prototype), ({ key, value }) =>
99+
// tslint:disable-next-line no-unnecessary-type-assertion (TODO: update LKG and it will really be unnecessary)
100+
return typeof prototype !== "object" || prototype === null ? emptyArray : mapDefined(getEntriesOfObject(prototype as object), ({ key, value }) =>
100101
key === "constructor" ? undefined : getValueInfo(key, value, recurser));
101102
}
102103

Diff for: src/compiler/program.ts

+47-15
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ namespace ts {
455455
}
456456

457457
// If project references dont match
458-
if (!arrayIsEqualTo(program.getProjectReferences(), projectReferences)) {
458+
if (!arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) {
459459
return false;
460460
}
461461

@@ -483,9 +483,27 @@ namespace ts {
483483

484484
return true;
485485

486-
function sourceFileNotUptoDate(sourceFile: SourceFile): boolean {
487-
return sourceFile.version !== getSourceVersion(sourceFile.path) ||
488-
hasInvalidatedResolution(sourceFile.path);
486+
function sourceFileNotUptoDate(sourceFile: SourceFile) {
487+
return !sourceFileVersionUptoDate(sourceFile) ||
488+
hasInvalidatedResolution(sourceFile.resolvedPath || sourceFile.path);
489+
}
490+
491+
function sourceFileVersionUptoDate(sourceFile: SourceFile) {
492+
return sourceFile.version === getSourceVersion(sourceFile.resolvedPath || sourceFile.path);
493+
}
494+
495+
function projectReferenceUptoDate(oldRef: ProjectReference, newRef: ProjectReference, index: number) {
496+
if (!projectReferenceIsEqualTo(oldRef, newRef)) {
497+
return false;
498+
}
499+
const oldResolvedRef = program!.getResolvedProjectReferences()![index];
500+
if (oldResolvedRef) {
501+
// If sourceFile for the oldResolvedRef existed, check the version for uptodate
502+
return sourceFileVersionUptoDate(oldResolvedRef.sourceFile);
503+
}
504+
// In old program, not able to resolve project reference path,
505+
// so if config file doesnt exist, it is uptodate.
506+
return !fileExists(resolveProjectReferencePath(oldRef));
489507
}
490508
}
491509

@@ -658,8 +676,9 @@ namespace ts {
658676
const parsedRef = parseProjectReferenceConfigFile(ref);
659677
resolvedProjectReferences!.push(parsedRef);
660678
if (parsedRef) {
661-
if (parsedRef.commandLine.options.outFile) {
662-
const dtsOutfile = changeExtension(parsedRef.commandLine.options.outFile, ".d.ts");
679+
const out = parsedRef.commandLine.options.outFile || parsedRef.commandLine.options.out;
680+
if (out) {
681+
const dtsOutfile = changeExtension(out, ".d.ts");
663682
processSourceFile(dtsOutfile, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
664683
}
665684
addProjectReferenceRedirects(parsedRef.commandLine, projectReferenceRedirects);
@@ -758,7 +777,8 @@ namespace ts {
758777
getConfigFileParsingDiagnostics,
759778
getResolvedModuleWithFailedLookupLocationsFromCache,
760779
getProjectReferences,
761-
getResolvedProjectReferences
780+
getResolvedProjectReferences,
781+
getProjectReferenceRedirect
762782
};
763783

764784
verifyCompilerOptions();
@@ -1225,6 +1245,13 @@ namespace ts {
12251245
}
12261246
resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives();
12271247
resolvedProjectReferences = oldProgram.getResolvedProjectReferences();
1248+
if (resolvedProjectReferences) {
1249+
resolvedProjectReferences.forEach(ref => {
1250+
if (ref) {
1251+
addProjectReferenceRedirects(ref.commandLine, projectReferenceRedirects);
1252+
}
1253+
});
1254+
}
12281255

12291256
sourceFileToPackageName = oldProgram.sourceFileToPackageName;
12301257
redirectTargetsMap = oldProgram.redirectTargetsMap;
@@ -1280,12 +1307,13 @@ namespace ts {
12801307
const ref = projectReferences[i];
12811308
const resolvedRefOpts = resolvedProjectReferences![i]!.commandLine;
12821309
if (ref.prepend && resolvedRefOpts && resolvedRefOpts.options) {
1310+
const out = resolvedRefOpts.options.outFile || resolvedRefOpts.options.out;
12831311
// Upstream project didn't have outFile set -- skip (error will have been issued earlier)
1284-
if (!resolvedRefOpts.options.outFile) continue;
1312+
if (!out) continue;
12851313

1286-
const dtsFilename = changeExtension(resolvedRefOpts.options.outFile, ".d.ts");
1287-
const js = host.readFile(resolvedRefOpts.options.outFile) || `/* Input file ${resolvedRefOpts.options.outFile} was missing */\r\n`;
1288-
const jsMapPath = resolvedRefOpts.options.outFile + ".map"; // TODO: try to read sourceMappingUrl comment from the file
1314+
const dtsFilename = changeExtension(out, ".d.ts");
1315+
const js = host.readFile(out) || `/* Input file ${out} was missing */\r\n`;
1316+
const jsMapPath = out + ".map"; // TODO: try to read sourceMappingUrl comment from the file
12891317
const jsMap = host.readFile(jsMapPath);
12901318
const dts = host.readFile(dtsFilename) || `/* Input file ${dtsFilename} was missing */\r\n`;
12911319
const dtsMapPath = dtsFilename + ".map";
@@ -2427,9 +2455,10 @@ namespace ts {
24272455
createDiagnosticForReference(i, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
24282456
}
24292457
if (ref.prepend) {
2430-
if (resolvedRefOpts.outFile) {
2431-
if (!host.fileExists(resolvedRefOpts.outFile)) {
2432-
createDiagnosticForReference(i, Diagnostics.Output_file_0_from_project_1_does_not_exist, resolvedRefOpts.outFile, ref.path);
2458+
const out = resolvedRefOpts.outFile || resolvedRefOpts.out;
2459+
if (out) {
2460+
if (!host.fileExists(out)) {
2461+
createDiagnosticForReference(i, Diagnostics.Output_file_0_from_project_1_does_not_exist, out, ref.path);
24332462
}
24342463
}
24352464
else {
@@ -2821,7 +2850,10 @@ namespace ts {
28212850
export function parseConfigHostFromCompilerHost(host: CompilerHost): ParseConfigFileHost {
28222851
return {
28232852
fileExists: f => host.fileExists(f),
2824-
readDirectory: (root, extensions, includes, depth?) => host.readDirectory ? host.readDirectory(root, extensions, includes, depth) : [],
2853+
readDirectory(root, extensions, excludes, includes, depth) {
2854+
Debug.assertDefined(host.readDirectory, "'CompilerHost.readDirectory' must be implemented to correctly process 'projectReferences'");
2855+
return host.readDirectory!(root, extensions, excludes, includes, depth);
2856+
},
28252857
readFile: f => host.readFile(f),
28262858
useCaseSensitiveFileNames: host.useCaseSensitiveFileNames(),
28272859
getCurrentDirectory: () => host.getCurrentDirectory(),

Diff for: src/compiler/tsbuild.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -285,16 +285,17 @@ namespace ts {
285285
}
286286

287287
function getOutFileOutputs(project: ParsedCommandLine): ReadonlyArray<string> {
288-
if (!project.options.outFile) {
288+
const out = project.options.outFile || project.options.out;
289+
if (!out) {
289290
return Debug.fail("outFile must be set");
290291
}
291292
const outputs: string[] = [];
292-
outputs.push(project.options.outFile);
293+
outputs.push(out);
293294
if (project.options.sourceMap) {
294-
outputs.push(`${project.options.outFile}.map`);
295+
outputs.push(`${out}.map`);
295296
}
296297
if (getEmitDeclarations(project.options)) {
297-
const dts = changeExtension(project.options.outFile, Extension.Dts);
298+
const dts = changeExtension(out, Extension.Dts);
298299
outputs.push(dts);
299300
if (project.options.declarationMap) {
300301
outputs.push(`${dts}.map`);
@@ -862,7 +863,7 @@ namespace ts {
862863
if (buildProject) {
863864
buildSingleInvalidatedProject(buildProject.project, buildProject.reloadLevel);
864865
if (hasPendingInvalidatedProjects()) {
865-
if (!timerToBuildInvalidatedProject) {
866+
if (options.watch && !timerToBuildInvalidatedProject) {
866867
scheduleBuildInvalidatedProject();
867868
}
868869
}
@@ -1248,7 +1249,7 @@ namespace ts {
12481249
}
12491250

12501251
export function getAllProjectOutputs(project: ParsedCommandLine): ReadonlyArray<string> {
1251-
if (project.options.outFile) {
1252+
if (project.options.outFile || project.options.out) {
12521253
return getOutFileOutputs(project);
12531254
}
12541255
else {

Diff for: src/compiler/types.ts

+7
Original file line numberDiff line numberDiff line change
@@ -2551,6 +2551,11 @@ namespace ts {
25512551
fileName: string;
25522552
/* @internal */ path: Path;
25532553
text: string;
2554+
/** Resolved path can be different from path property,
2555+
* when file is included through project reference is mapped to its output instead of source
2556+
* in that case resolvedPath = path to output file
2557+
* path = input file's path
2558+
*/
25542559
/* @internal */ resolvedPath: Path;
25552560

25562561
/**
@@ -2819,6 +2824,7 @@ namespace ts {
28192824

28202825
getProjectReferences(): ReadonlyArray<ProjectReference> | undefined;
28212826
getResolvedProjectReferences(): (ResolvedProjectReference | undefined)[] | undefined;
2827+
/*@internal*/ getProjectReferenceRedirect(fileName: string): string | undefined;
28222828
}
28232829

28242830
/* @internal */
@@ -3670,6 +3676,7 @@ namespace ts {
36703676
export interface NodeLinks {
36713677
flags: NodeCheckFlags; // Set of flags specific to Node
36723678
resolvedType?: Type; // Cached type of type node
3679+
resolvedEnumType?: Type; // Cached constraint type from enum jsdoc tag
36733680
resolvedSignature?: Signature; // Cached signature of signature node or call expression
36743681
resolvedSignatures?: Map<Signature[]>; // Cached signatures of jsx node
36753682
resolvedSymbol?: Symbol; // Cached name resolution result

Diff for: src/compiler/watch.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,8 @@ namespace ts {
546546
},
547547
maxNumberOfFilesToIterateForInvalidation: host.maxNumberOfFilesToIterateForInvalidation,
548548
getCurrentProgram,
549-
writeLog
549+
writeLog,
550+
readDirectory: (path, extensions, exclude, include, depth?) => directoryStructureHost.readDirectory!(path, extensions, exclude, include, depth),
550551
};
551552
// Cache for the module resolution
552553
const resolutionCache = createResolutionCache(compilerHost, configFileName ?

Diff for: src/harness/virtualFileSystemWithWatch.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,10 @@ interface Array<T> {}`
187187
}
188188

189189
export function checkArray(caption: string, actual: ReadonlyArray<string>, expected: ReadonlyArray<string>) {
190+
checkMapKeys(caption, arrayToMap(actual, identity), expected);
190191
assert.equal(actual.length, expected.length, `${caption}: incorrect actual number of files, expected:\r\n${expected.join("\r\n")}\r\ngot: ${actual.join("\r\n")}`);
191192
for (const f of expected) {
192-
assert.equal(true, contains(actual, f), `${caption}: expected to find ${f} in ${actual}`);
193+
assert.isTrue(contains(actual, f), `${caption}: expected to find ${f} in ${actual}`);
193194
}
194195
}
195196

@@ -934,7 +935,12 @@ interface Array<T> {}`
934935
const folder = this.fs.get(base) as FsFolder;
935936
Debug.assert(isFsFolder(folder));
936937

937-
this.addFileOrFolderInFolder(folder, file);
938+
if (!this.fs.has(file.path)) {
939+
this.addFileOrFolderInFolder(folder, file);
940+
}
941+
else {
942+
this.modifyFile(path, content);
943+
}
938944
}
939945

940946
write(message: string) {

0 commit comments

Comments
 (0)