Skip to content

Commit a4091ae

Browse files
committed
Merge branch 'master' into incrementalFromCommandLine
2 parents 35470b3 + 307bf39 commit a4091ae

File tree

54 files changed

+1132
-340
lines changed

Some content is hidden

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

54 files changed

+1132
-340
lines changed

scripts/perf-result-post.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// @ts-check
2+
/// <reference lib="esnext.asynciterable" />
3+
// Must reference esnext.asynciterable lib, since octokit uses AsyncIterable internally
4+
const Octokit = require("@octokit/rest");
5+
const fs = require("fs");
6+
7+
const requester = process.env.requesting_user;
8+
const source = process.env.source_issue;
9+
const postedComment = process.env.status_comment;
10+
console.log(`Loading fragment from ${process.argv[3]}...`);
11+
const outputTableText = fs.readFileSync(process.argv[3], { encoding: "utf8" });
12+
console.log(`Fragment contents:
13+
${outputTableText}`);
14+
15+
const gh = new Octokit();
16+
gh.authenticate({
17+
type: "token",
18+
token: process.argv[2]
19+
});
20+
gh.issues.createComment({
21+
number: +source,
22+
owner: "Microsoft",
23+
repo: "TypeScript",
24+
body: `@${requester}
25+
The results of the perf run you requested are in! Here they are:
26+
27+
${outputTableText}`
28+
}).then(async data => {
29+
console.log(`Results posted!`);
30+
const newCommentUrl = data.data.html_url;
31+
const comment = await gh.issues.getComment({
32+
owner: "Microsoft",
33+
repo: "TypeScript",
34+
comment_id: +postedComment
35+
});
36+
const newBody = `${comment.data.body}
37+
38+
Update: [The results are in!](${newCommentUrl})`;
39+
return await gh.issues.updateComment({
40+
owner: "Microsoft",
41+
repo: "TypeScript",
42+
comment_id: +postedComment,
43+
body: newBody
44+
});
45+
}).catch(e => {
46+
console.error(e);
47+
process.exit(1);
48+
});

src/compiler/builderState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ namespace ts.BuilderState {
230230

231231
// Create the reference map, and set the file infos
232232
for (const sourceFile of newProgram.getSourceFiles()) {
233-
const version = sourceFile.version;
233+
const version = Debug.assertDefined(sourceFile.version, "Program intended to be used with Builder should have source files with versions set");
234234
const oldInfo = useOldState ? oldState!.fileInfos.get(sourceFile.path) : undefined;
235235
if (referencedMap) {
236236
const newReferences = getReferencedFiles(newProgram, sourceFile, getCanonicalFileName);

src/compiler/checker.ts

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2352,19 +2352,12 @@ namespace ts {
23522352
}
23532353

23542354
if (moduleNotFoundError) {
2355-
// For relative paths, see if this was possibly a projectReference redirect
2356-
if (pathIsRelative(moduleReference)) {
2357-
const sourceFile = getSourceFileOfNode(location);
2358-
const redirects = sourceFile.redirectedReferences;
2359-
if (redirects) {
2360-
const normalizedTargetPath = getNormalizedAbsolutePath(moduleReference, getDirectoryPath(sourceFile.fileName));
2361-
for (const ext of [Extension.Ts, Extension.Tsx]) {
2362-
const probePath = normalizedTargetPath + ext;
2363-
if (redirects.indexOf(probePath) >= 0) {
2364-
error(errorNode, Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, moduleReference, probePath);
2365-
return undefined;
2366-
}
2367-
}
2355+
// See if this was possibly a projectReference redirect
2356+
if (resolvedModule) {
2357+
const redirect = host.getProjectReferenceRedirect(resolvedModule.resolvedFileName);
2358+
if (redirect) {
2359+
error(errorNode, Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect, resolvedModule.resolvedFileName);
2360+
return undefined;
23682361
}
23692362
}
23702363

@@ -5481,9 +5474,6 @@ namespace ts {
54815474
}
54825475
return type;
54835476
}
5484-
if (declaration.kind === SyntaxKind.ExportAssignment) {
5485-
return widenTypeForVariableLikeDeclaration(checkExpressionCached((<ExportAssignment>declaration).expression), declaration);
5486-
}
54875477

54885478
// Handle variable, parameter or property
54895479
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
@@ -5494,7 +5484,10 @@ namespace ts {
54945484
return reportCircularityError(symbol);
54955485
}
54965486
let type: Type | undefined;
5497-
if (isInJSFile(declaration) &&
5487+
if (declaration.kind === SyntaxKind.ExportAssignment) {
5488+
type = widenTypeForVariableLikeDeclaration(checkExpressionCached((<ExportAssignment>declaration).expression), declaration);
5489+
}
5490+
else if (isInJSFile(declaration) &&
54985491
(isCallExpression(declaration) || isBinaryExpression(declaration) || isPropertyAccessExpression(declaration) && isBinaryExpression(declaration.parent))) {
54995492
type = getWidenedTypeFromAssignmentDeclaration(symbol);
55005493
}
@@ -7123,6 +7116,15 @@ namespace ts {
71237116
let stringIndexInfo: IndexInfo | undefined;
71247117
if (symbol.exports) {
71257118
members = getExportsOfSymbol(symbol);
7119+
if (symbol === globalThisSymbol) {
7120+
const varsOnly = createMap<Symbol>() as SymbolTable;
7121+
members.forEach(p => {
7122+
if (!(p.flags & SymbolFlags.BlockScoped)) {
7123+
varsOnly.set(p.escapedName, p);
7124+
}
7125+
});
7126+
members = varsOnly;
7127+
}
71267128
}
71277129
setStructuredTypeMembers(type, members, emptyArray, emptyArray, undefined, undefined);
71287130
if (symbol.flags & SymbolFlags.Class) {
@@ -7779,7 +7781,7 @@ namespace ts {
77797781
}
77807782

77817783
function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol | undefined {
7782-
let props: Symbol[] | undefined;
7784+
const propSet = createMap<Symbol>();
77837785
let indexTypes: Type[] | undefined;
77847786
const isUnion = containingType.flags & TypeFlags.Union;
77857787
const excludeModifiers = isUnion ? ModifierFlags.NonPublicAccessibilityModifier : 0;
@@ -7794,7 +7796,10 @@ namespace ts {
77947796
const modifiers = prop ? getDeclarationModifierFlagsFromSymbol(prop) : 0;
77957797
if (prop && !(modifiers & excludeModifiers)) {
77967798
commonFlags &= prop.flags;
7797-
props = appendIfUnique(props, prop);
7799+
const id = "" + getSymbolId(prop);
7800+
if (!propSet.has(id)) {
7801+
propSet.set(id, prop);
7802+
}
77987803
checkFlags |= (isReadonlySymbol(prop) ? CheckFlags.Readonly : 0) |
77997804
(!(modifiers & ModifierFlags.NonPublicAccessibilityModifier) ? CheckFlags.ContainsPublic : 0) |
78007805
(modifiers & ModifierFlags.Protected ? CheckFlags.ContainsProtected : 0) |
@@ -7816,9 +7821,10 @@ namespace ts {
78167821
}
78177822
}
78187823
}
7819-
if (!props) {
7824+
if (!propSet.size) {
78207825
return undefined;
78217826
}
7827+
const props = arrayFrom(propSet.values());
78227828
if (props.length === 1 && !(checkFlags & CheckFlags.Partial) && !indexTypes) {
78237829
return props[0];
78247830
}
@@ -9880,6 +9886,7 @@ namespace ts {
98809886
getNodeLinks(accessNode!).resolvedSymbol = prop;
98819887
}
98829888
}
9889+
98839890
const propType = getTypeOfSymbol(prop);
98849891
return accessExpression && getAssignmentTargetKind(accessExpression) !== AssignmentKind.Definite ?
98859892
getFlowTypeOfReference(accessExpression, propType) :
@@ -9923,7 +9930,10 @@ namespace ts {
99239930
return anyType;
99249931
}
99259932
if (accessExpression && !isConstEnumObjectType(objectType)) {
9926-
if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) {
9933+
if (objectType.symbol === globalThisSymbol && propName !== undefined && globalThisSymbol.exports!.has(propName) && (globalThisSymbol.exports!.get(propName)!.flags & SymbolFlags.BlockScoped)) {
9934+
error(accessExpression, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType));
9935+
}
9936+
else if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) {
99279937
if (propName !== undefined && typeHasStaticProperty(propName, objectType)) {
99289938
error(accessExpression, Diagnostics.Property_0_is_a_static_member_of_type_1, propName as string, typeToString(objectType));
99299939
}
@@ -19518,7 +19528,10 @@ namespace ts {
1951819528
return anyType;
1951919529
}
1952019530
if (leftType.symbol === globalThisSymbol) {
19521-
if (noImplicitAny) {
19531+
if (globalThisSymbol.exports!.has(right.escapedText) && (globalThisSymbol.exports!.get(right.escapedText)!.flags & SymbolFlags.BlockScoped)) {
19532+
error(right, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(right.escapedText), typeToString(leftType));
19533+
}
19534+
else if (noImplicitAny) {
1952219535
error(right, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(leftType));
1952319536
}
1952419537
return anyType;

src/compiler/program.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,7 @@ namespace ts {
7474
// TODO(shkamat): update this after reworking ts build API
7575
export function createCompilerHostWorker(options: CompilerOptions, setParentNodes?: boolean, system = sys): CompilerHost {
7676
const existingDirectories = createMap<boolean>();
77-
function getCanonicalFileName(fileName: string): string {
78-
// if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form.
79-
// otherwise use toLowerCase as a canonical form.
80-
return system.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
81-
}
82-
77+
const getCanonicalFileName = createGetCanonicalFileName(system.useCaseSensitiveFileNames);
8378
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile | undefined {
8479
let text: string | undefined;
8580
try {
@@ -2273,7 +2268,6 @@ namespace ts {
22732268
if (refFile) {
22742269
const redirect = getProjectReferenceRedirect(fileName);
22752270
if (redirect) {
2276-
((refFile.redirectedReferences || (refFile.redirectedReferences = [])) as string[]).push(fileName);
22772271
fileName = redirect;
22782272
// Once we start redirecting to a file, we can potentially come back to it
22792273
// via a back-reference from another file in the .d.ts folder. If that happens we'll

src/compiler/types.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2740,12 +2740,6 @@ namespace ts {
27402740
/* @internal */ resolvedModules?: Map<ResolvedModuleFull | undefined>;
27412741
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective | undefined>;
27422742
/* @internal */ imports: ReadonlyArray<StringLiteralLike>;
2743-
/**
2744-
* When a file's references are redirected due to project reference directives,
2745-
* the original names of the references are stored in this array
2746-
*/
2747-
/* @internal*/
2748-
redirectedReferences?: ReadonlyArray<string>;
27492743
// Identifier only if `declare global`
27502744
/* @internal */ moduleAugmentations: ReadonlyArray<StringLiteral | Identifier>;
27512745
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
@@ -3074,6 +3068,7 @@ namespace ts {
30743068
getSourceFiles(): ReadonlyArray<SourceFile>;
30753069
getSourceFile(fileName: string): SourceFile | undefined;
30763070
getResolvedTypeReferenceDirectives(): ReadonlyMap<ResolvedTypeReferenceDirective | undefined>;
3071+
getProjectReferenceRedirect(fileName: string): string | undefined;
30773072

30783073
readonly redirectTargetsMap: RedirectTargetsMap;
30793074
}

src/compiler/watch.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ namespace ts {
275275
}
276276
}
277277

278-
export function setGetSourceFileAsHashVersioned(compilerHost: CompilerHost, host: ProgramHost<any>) {
278+
export function setGetSourceFileAsHashVersioned(compilerHost: CompilerHost, host: { createHash?(data: string): string; }) {
279279
const originalGetSourceFile = compilerHost.getSourceFile;
280280
const computeHash = host.createHash || generateDjb2Hash;
281281
compilerHost.getSourceFile = (...args) => {
@@ -383,6 +383,56 @@ namespace ts {
383383
if (!buildInfo.program) return undefined;
384384
return createBuildProgramUsingProgramBuildInfo(buildInfo.program);
385385
}
386+
387+
export function createIncrementalCompilerHost(options: CompilerOptions, system = sys): CompilerHost {
388+
const host = createCompilerHostWorker(options, /*setParentNodes*/ undefined, system);
389+
host.createHash = maybeBind(system, system.createHash);
390+
setGetSourceFileAsHashVersioned(host, system);
391+
changeCompilerHostLikeToUseCache(host, fileName => toPath(fileName, host.getCurrentDirectory(), host.getCanonicalFileName));
392+
return host;
393+
}
394+
395+
interface IncrementalProgramOptions<T extends BuilderProgram> {
396+
rootNames: ReadonlyArray<string>;
397+
options: CompilerOptions;
398+
configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>;
399+
projectReferences?: ReadonlyArray<ProjectReference>;
400+
host?: CompilerHost;
401+
createProgram?: CreateProgram<T>;
402+
}
403+
function createIncrementalProgram<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>({
404+
rootNames, options, configFileParsingDiagnostics, projectReferences, host, createProgram
405+
}: IncrementalProgramOptions<T>): T {
406+
host = host || createIncrementalCompilerHost(options);
407+
createProgram = createProgram || createEmitAndSemanticDiagnosticsBuilderProgram as any as CreateProgram<T>;
408+
const oldProgram = readBuilderProgram(options, path => host!.readFile(path)) as any as T;
409+
return createProgram(rootNames, options, host, oldProgram, configFileParsingDiagnostics, projectReferences);
410+
}
411+
412+
export interface IncrementalCompilationOptions {
413+
rootNames: ReadonlyArray<string>;
414+
options: CompilerOptions;
415+
configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>;
416+
projectReferences?: ReadonlyArray<ProjectReference>;
417+
host?: CompilerHost;
418+
reportDiagnostic?: DiagnosticReporter;
419+
reportErrorSummary?: ReportEmitErrorSummary;
420+
afterProgramEmitAndDiagnostics?(program: EmitAndSemanticDiagnosticsBuilderProgram): void;
421+
system?: System;
422+
}
423+
export function performIncrementalCompilation(input: IncrementalCompilationOptions) {
424+
const system = input.system || sys;
425+
const host = input.host || (input.host = createIncrementalCompilerHost(input.options, system));
426+
const builderProgram = createIncrementalProgram(input);
427+
const exitStatus = emitFilesAndReportErrors(
428+
builderProgram,
429+
input.reportDiagnostic || createDiagnosticReporter(system),
430+
s => host.trace && host.trace(s),
431+
input.reportErrorSummary || input.options.pretty ? errorCount => system.write(getErrorSummaryText(errorCount, system.newLine)) : undefined
432+
);
433+
if (input.afterProgramEmitAndDiagnostics) input.afterProgramEmitAndDiagnostics(builderProgram);
434+
return exitStatus;
435+
}
386436
}
387437

388438
namespace ts {

0 commit comments

Comments
 (0)