Skip to content

Commit 1b37830

Browse files
committed
Merge branch 'master' into incrementalBuild
2 parents 42484b5 + 85e6c2f commit 1b37830

File tree

86 files changed

+12509
-10571
lines changed

Some content is hidden

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

86 files changed

+12509
-10571
lines changed

scripts/build/baselineAccept.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function baselineAccept(subfolder = "") {
1212
}
1313

1414
function baselineCopy(subfolder = "") {
15-
return gulp.src([`${localBaseline}${subfolder ? `${subfolder}/` : ``}**`, `!${localBaseline}${subfolder}/**/*.delete`], { base: localBaseline, read: false })
15+
return gulp.src([`${localBaseline}${subfolder ? `${subfolder}/` : ``}**`, `!${localBaseline}${subfolder}/**/*.delete`], { base: localBaseline })
1616
.pipe(gulp.dest(refBaseline));
1717
}
1818

@@ -21,4 +21,4 @@ function baselineDelete(subfolder = "") {
2121
.pipe(rm())
2222
.pipe(rename({ extname: "" }))
2323
.pipe(rm(refBaseline));
24-
}
24+
}

scripts/tslint/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"module": "commonjs",
1313
"outDir": "../../built/local/tslint",
1414
"baseUrl": "../..",
15+
"types": ["node"],
1516
"paths": {
1617
"typescript": ["lib/typescript.d.ts"]
1718
}

src/compiler/builder.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ namespace ts {
8585
state.program = newProgram;
8686
const compilerOptions = newProgram.getCompilerOptions();
8787
state.compilerOptions = compilerOptions;
88-
if (!compilerOptions.outFile && !compilerOptions.out) {
88+
// With --out or --outFile, any change affects all semantic diagnostics so no need to cache them
89+
// With --isolatedModules, emitting changed file doesnt emit dependent files so we cant know of dependent files to retrieve errors so dont cache the errors
90+
if (!compilerOptions.outFile && !compilerOptions.out && !compilerOptions.isolatedModules) {
8991
state.semanticDiagnosticsPerFile = createMap<ReadonlyArray<Diagnostic>>();
9092
}
9193
state.changedFilesSet = createMap<true>();
@@ -361,10 +363,19 @@ namespace ts {
361363
}
362364

363365
// If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
364-
return !!forEachEntry(state.exportedModulesMap!, (exportedModules, exportedFromPath) =>
366+
if (forEachEntry(state.exportedModulesMap!, (exportedModules, exportedFromPath) =>
365367
!state.currentAffectedFilesExportedModulesMap!.has(exportedFromPath) && // If we already iterated this through cache, ignore it
366368
exportedModules.has(filePath) &&
367369
removeSemanticDiagnosticsOfFileAndExportsOfFile(state, exportedFromPath as Path, seenFileAndExportsOfFile)
370+
)) {
371+
return true;
372+
}
373+
374+
// Remove diagnostics of files that import this file (without going to exports of referencing files)
375+
return !!forEachEntry(state.referencedMap!, (referencesInFile, referencingFilePath) =>
376+
referencesInFile.has(filePath) &&
377+
!seenFileAndExportsOfFile.has(referencingFilePath) && // Not already removed diagnostic file
378+
removeSemanticDiagnosticsOf(state, referencingFilePath as Path) // Dont add to seen since this is not yet done with the export removal
368379
);
369380
}
370381

@@ -415,15 +426,19 @@ namespace ts {
415426
*/
416427
function getSemanticDiagnosticsOfFile(state: BuilderProgramState, sourceFile: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic> {
417428
const path = sourceFile.path;
418-
const cachedDiagnostics = state.semanticDiagnosticsPerFile!.get(path);
419-
// Report the semantic diagnostics from the cache if we already have those diagnostics present
420-
if (cachedDiagnostics) {
421-
return cachedDiagnostics;
429+
if (state.semanticDiagnosticsPerFile) {
430+
const cachedDiagnostics = state.semanticDiagnosticsPerFile.get(path);
431+
// Report the semantic diagnostics from the cache if we already have those diagnostics present
432+
if (cachedDiagnostics) {
433+
return cachedDiagnostics;
434+
}
422435
}
423436

424437
// Diagnostics werent cached, get them from program, and cache the result
425438
const diagnostics = Debug.assertDefined(state.program).getSemanticDiagnostics(sourceFile, cancellationToken);
426-
state.semanticDiagnosticsPerFile!.set(path, diagnostics);
439+
if (state.semanticDiagnosticsPerFile) {
440+
state.semanticDiagnosticsPerFile.set(path, diagnostics);
441+
}
427442
return diagnostics;
428443
}
429444

src/compiler/checker.ts

Lines changed: 85 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4919,7 +4919,7 @@ namespace ts {
49194919
if (strictNullChecks && declaration.initializer && !(getFalsyFlags(checkDeclarationInitializer(declaration)) & TypeFlags.Undefined)) {
49204920
type = getTypeWithFacts(type, TypeFacts.NEUndefined);
49214921
}
4922-
return declaration.initializer && !getContextualTypeForVariableLikeDeclaration(walkUpBindingElementsAndPatterns(declaration)) ?
4922+
return declaration.initializer && !getEffectiveTypeAnnotationNode(walkUpBindingElementsAndPatterns(declaration)) ?
49234923
getUnionType([type, checkDeclarationInitializer(declaration)], UnionReduction.Subtype) :
49244924
type;
49254925
}
@@ -6930,7 +6930,7 @@ namespace ts {
69306930
function resolveUnionTypeMembers(type: UnionType) {
69316931
// The members and properties collections are empty for union types. To get all properties of a union
69326932
// type use getPropertiesOfType (only the language service uses this).
6933-
const callSignatures = getUnionSignatures(map(type.types, t => getSignaturesOfType(t, SignatureKind.Call)));
6933+
const callSignatures = getUnionSignatures(map(type.types, t => t === globalFunctionType ? [unknownSignature] : getSignaturesOfType(t, SignatureKind.Call)));
69346934
const constructSignatures = getUnionSignatures(map(type.types, t => getSignaturesOfType(t, SignatureKind.Construct)));
69356935
const stringIndexInfo = getUnionIndexInfo(type.types, IndexKind.String);
69366936
const numberIndexInfo = getUnionIndexInfo(type.types, IndexKind.Number);
@@ -7084,6 +7084,39 @@ namespace ts {
70847084
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined);
70857085
}
70867086

7087+
// Return the lower bound of the key type in a mapped type. Intuitively, the lower
7088+
// bound includes those keys that are known to always be present, for example because
7089+
// because of constraints on type parameters (e.g. 'keyof T' for a constrained T).
7090+
function getLowerBoundOfKeyType(type: Type): Type {
7091+
if (type.flags & (TypeFlags.Any | TypeFlags.Primitive)) {
7092+
return type;
7093+
}
7094+
if (type.flags & TypeFlags.Index) {
7095+
return getIndexType(getApparentType((<IndexType>type).type));
7096+
}
7097+
if (type.flags & TypeFlags.Conditional) {
7098+
return getLowerBoundOfConditionalType(<ConditionalType>type);
7099+
}
7100+
if (type.flags & TypeFlags.Union) {
7101+
return getUnionType(sameMap((<UnionType>type).types, getLowerBoundOfKeyType));
7102+
}
7103+
if (type.flags & TypeFlags.Intersection) {
7104+
return getIntersectionType(sameMap((<UnionType>type).types, getLowerBoundOfKeyType));
7105+
}
7106+
return neverType;
7107+
}
7108+
7109+
function getLowerBoundOfConditionalType(type: ConditionalType) {
7110+
if (type.root.isDistributive) {
7111+
const constraint = getLowerBoundOfKeyType(type.checkType);
7112+
if (constraint !== type.checkType) {
7113+
const mapper = makeUnaryTypeMapper(type.root.checkType, constraint);
7114+
return getConditionalTypeInstantiation(type, combineTypeMappers(mapper, type.mapper));
7115+
}
7116+
}
7117+
return type;
7118+
}
7119+
70877120
/** Resolve the members of a mapped type { [P in K]: T } */
70887121
function resolveMappedTypeMembers(type: MappedType) {
70897122
const members: SymbolTable = createSymbolTable();
@@ -7112,10 +7145,7 @@ namespace ts {
71127145
}
71137146
}
71147147
else {
7115-
// If the key type is a 'keyof X', obtain 'keyof C' where C is the base constraint of X.
7116-
// Then iterate over the constituents of the key type.
7117-
const iterationType = constraintType.flags & TypeFlags.Index ? getIndexType(getApparentType((<IndexType>constraintType).type)) : constraintType;
7118-
forEachType(iterationType, addMemberForKeyType);
7148+
forEachType(getLowerBoundOfKeyType(constraintType), addMemberForKeyType);
71197149
}
71207150
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
71217151

@@ -7669,38 +7699,37 @@ namespace ts {
76697699
return props[0];
76707700
}
76717701
let declarations: Declaration[] | undefined;
7672-
let commonType: Type | undefined;
7702+
let firstType: Type | undefined;
76737703
let nameType: Type | undefined;
76747704
const propTypes: Type[] = [];
7675-
let first = true;
7676-
let commonValueDeclaration: Declaration | undefined;
7705+
let firstValueDeclaration: Declaration | undefined;
76777706
let hasNonUniformValueDeclaration = false;
76787707
for (const prop of props) {
7679-
if (!commonValueDeclaration) {
7680-
commonValueDeclaration = prop.valueDeclaration;
7708+
if (!firstValueDeclaration) {
7709+
firstValueDeclaration = prop.valueDeclaration;
76817710
}
7682-
else if (prop.valueDeclaration !== commonValueDeclaration) {
7711+
else if (prop.valueDeclaration !== firstValueDeclaration) {
76837712
hasNonUniformValueDeclaration = true;
76847713
}
76857714
declarations = addRange(declarations, prop.declarations);
76867715
const type = getTypeOfSymbol(prop);
7687-
if (first) {
7688-
commonType = type;
7716+
if (!firstType) {
7717+
firstType = type;
76897718
nameType = prop.nameType;
7690-
first = false;
76917719
}
7692-
else {
7693-
if (type !== commonType) {
7694-
checkFlags |= CheckFlags.HasNonUniformType;
7695-
}
7720+
else if (type !== firstType) {
7721+
checkFlags |= CheckFlags.HasNonUniformType;
7722+
}
7723+
if (isLiteralType(type)) {
7724+
checkFlags |= CheckFlags.HasLiteralType;
76967725
}
76977726
propTypes.push(type);
76987727
}
76997728
addRange(propTypes, indexTypes);
77007729
const result = createSymbol(SymbolFlags.Property | commonFlags, name, syntheticFlag | checkFlags);
77017730
result.containingType = containingType;
7702-
if (!hasNonUniformValueDeclaration && commonValueDeclaration) {
7703-
result.valueDeclaration = commonValueDeclaration;
7731+
if (!hasNonUniformValueDeclaration && firstValueDeclaration) {
7732+
result.valueDeclaration = firstValueDeclaration;
77047733
}
77057734
result.declarations = declarations!;
77067735
result.nameType = nameType;
@@ -7928,22 +7957,17 @@ namespace ts {
79287957
const numTypeArguments = length(typeArguments);
79297958
if (isJavaScriptImplicitAny || (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters)) {
79307959
const result = typeArguments ? typeArguments.slice() : [];
7931-
7932-
// Map an unsatisfied type parameter with a default type.
7933-
// If a type parameter does not have a default type, or if the default type
7934-
// is a forward reference, the empty object type is used.
7935-
const baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
7936-
const circularityMapper = createTypeMapper(typeParameters!, map(typeParameters!, () => baseDefaultType));
7960+
// Map invalid forward references in default types to the error type
79377961
for (let i = numTypeArguments; i < numTypeParameters; i++) {
7938-
result[i] = instantiateType(getConstraintFromTypeParameter(typeParameters![i]) || baseDefaultType, circularityMapper);
7962+
result[i] = errorType;
79397963
}
7964+
const baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
79407965
for (let i = numTypeArguments; i < numTypeParameters; i++) {
7941-
const mapper = createTypeMapper(typeParameters!, result);
79427966
let defaultType = getDefaultFromTypeParameter(typeParameters![i]);
79437967
if (isJavaScriptImplicitAny && defaultType && isTypeIdenticalTo(defaultType, emptyObjectType)) {
79447968
defaultType = anyType;
79457969
}
7946-
result[i] = defaultType ? instantiateType(defaultType, mapper) : baseDefaultType;
7970+
result[i] = defaultType ? instantiateType(defaultType, createTypeMapper(typeParameters!, result)) : baseDefaultType;
79477971
}
79487972
result.length = typeParameters!.length;
79497973
return result;
@@ -11016,8 +11040,7 @@ namespace ts {
1101611040

1101711041
function hasContextSensitiveReturnExpression(node: FunctionLikeDeclaration) {
1101811042
// TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value.
11019-
const body = node.body!;
11020-
return body.kind === SyntaxKind.Block ? false : isContextSensitive(body);
11043+
return !!node.body && node.body.kind !== SyntaxKind.Block && isContextSensitive(node.body);
1102111044
}
1102211045

1102311046
function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration {
@@ -14814,25 +14837,18 @@ namespace ts {
1481414837
}
1481514838

1481614839
function isDiscriminantType(type: Type): boolean {
14817-
if (type.flags & TypeFlags.Union) {
14818-
if (type.flags & (TypeFlags.Boolean | TypeFlags.EnumLiteral)) {
14819-
return true;
14820-
}
14821-
let combined = 0;
14822-
for (const t of (<UnionType>type).types) combined |= t.flags;
14823-
if (combined & TypeFlags.Unit && !(combined & TypeFlags.Instantiable)) {
14824-
return true;
14825-
}
14826-
}
14827-
return false;
14840+
return !!(type.flags & TypeFlags.Union &&
14841+
(type.flags & (TypeFlags.Boolean | TypeFlags.EnumLiteral) || !isGenericIndexType(type)));
1482814842
}
1482914843

1483014844
function isDiscriminantProperty(type: Type | undefined, name: __String) {
1483114845
if (type && type.flags & TypeFlags.Union) {
1483214846
const prop = getUnionOrIntersectionProperty(<UnionType>type, name);
1483314847
if (prop && getCheckFlags(prop) & CheckFlags.SyntheticProperty) {
1483414848
if ((<TransientSymbol>prop).isDiscriminantProperty === undefined) {
14835-
(<TransientSymbol>prop).isDiscriminantProperty = !!((<TransientSymbol>prop).checkFlags & CheckFlags.HasNonUniformType) && isDiscriminantType(getTypeOfSymbol(prop));
14849+
(<TransientSymbol>prop).isDiscriminantProperty =
14850+
((<TransientSymbol>prop).checkFlags & CheckFlags.Discriminant) === CheckFlags.Discriminant &&
14851+
isDiscriminantType(getTypeOfSymbol(prop));
1483614852
}
1483714853
return !!(<TransientSymbol>prop).isDiscriminantProperty;
1483814854
}
@@ -19263,8 +19279,8 @@ namespace ts {
1926319279
}
1926419280
}
1926519281

19266-
function isValidPropertyAccessForCompletions(node: PropertyAccessExpression | ImportTypeNode, type: Type, property: Symbol): boolean {
19267-
return isValidPropertyAccessWithType(node, node.kind !== SyntaxKind.ImportType && node.expression.kind === SyntaxKind.SuperKeyword, property.escapedName, type)
19282+
function isValidPropertyAccessForCompletions(node: PropertyAccessExpression | ImportTypeNode | QualifiedName, type: Type, property: Symbol): boolean {
19283+
return isValidPropertyAccessWithType(node, node.kind === SyntaxKind.PropertyAccessExpression && node.expression.kind === SyntaxKind.SuperKeyword, property.escapedName, type)
1926819284
&& (!(property.flags & SymbolFlags.Method) || isValidMethodAccess(property, type));
1926919285
}
1927019286
function isValidMethodAccess(method: Symbol, actualThisType: Type): boolean {
@@ -20490,9 +20506,9 @@ namespace ts {
2049020506
* If FuncExpr is of type Any, or of an object type that has no call or construct signatures
2049120507
* but is a subtype of the Function interface, the call is an untyped function call.
2049220508
*/
20493-
function isUntypedFunctionCall(funcType: Type, apparentFuncType: Type, numCallSignatures: number, numConstructSignatures: number) {
20509+
function isUntypedFunctionCall(funcType: Type, apparentFuncType: Type, numCallSignatures: number, numConstructSignatures: number): boolean {
2049420510
// We exclude union types because we may have a union of function types that happen to have no common signatures.
20495-
return isTypeAny(funcType) || isTypeAny(apparentFuncType) && funcType.flags & TypeFlags.TypeParameter ||
20511+
return isTypeAny(funcType) || isTypeAny(apparentFuncType) && !!(funcType.flags & TypeFlags.TypeParameter) ||
2049620512
!numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & (TypeFlags.Union | TypeFlags.Never)) && isTypeAssignableTo(funcType, globalFunctionType);
2049720513
}
2049820514

@@ -22810,7 +22826,8 @@ namespace ts {
2281022826
const type = getTypeOfExpression(initializer, /*cache*/ true);
2281122827
const widened = getCombinedNodeFlags(declaration) & NodeFlags.Const ||
2281222828
isDeclarationReadonly(declaration) ||
22813-
isTypeAssertion(initializer) ? type : getWidenedLiteralType(type);
22829+
isTypeAssertion(initializer) ||
22830+
isLiteralOfContextualType(type, getContextualType(initializer)) ? type : getWidenedLiteralType(type);
2281422831
if (isInJSFile(declaration)) {
2281522832
if (widened.flags & TypeFlags.Nullable) {
2281622833
reportImplicitAny(declaration, anyType);
@@ -26465,6 +26482,7 @@ namespace ts {
2646526482
if (produceDiagnostics) {
2646626483
if (node.default) {
2646726484
seenDefault = true;
26485+
checkTypeParametersNotReferenced(node.default, typeParameterDeclarations, i);
2646826486
}
2646926487
else if (seenDefault) {
2647026488
error(node, Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters);
@@ -26479,6 +26497,24 @@ namespace ts {
2647926497
}
2648026498
}
2648126499

26500+
/** Check that type parameter defaults only reference previously declared type parameters */
26501+
function checkTypeParametersNotReferenced(root: TypeNode, typeParameters: ReadonlyArray<TypeParameterDeclaration>, index: number) {
26502+
visit(root);
26503+
function visit(node: Node) {
26504+
if (node.kind === SyntaxKind.TypeReference) {
26505+
const type = getTypeFromTypeReference(<TypeReferenceNode>node);
26506+
if (type.flags & TypeFlags.TypeParameter) {
26507+
for (let i = index; i < typeParameters.length; i++) {
26508+
if (type.symbol === getSymbolOfNode(typeParameters[i])) {
26509+
error(node, Diagnostics.Type_parameter_defaults_can_only_reference_previously_declared_type_parameters);
26510+
}
26511+
}
26512+
}
26513+
}
26514+
forEachChild(node, visit);
26515+
}
26516+
}
26517+
2648226518
/** Check that type parameter lists are identical across multiple declarations */
2648326519
function checkTypeParameterListsIdentical(symbol: Symbol) {
2648426520
if (symbol.declarations.length === 1) {

0 commit comments

Comments
 (0)