Merge branch 'master' into buildWatchCaching

This commit is contained in:
Sheetal Nandi
2019-04-30 11:24:43 -07:00
207 changed files with 5395 additions and 819 deletions
+355 -107
View File
@@ -94,8 +94,6 @@ namespace ts {
const globalThisSymbol = createSymbol(SymbolFlags.Module, "globalThis" as __String, CheckFlags.Readonly);
globalThisSymbol.exports = globals;
globalThisSymbol.valueDeclaration = createNode(SyntaxKind.Identifier) as Identifier;
(globalThisSymbol.valueDeclaration as Identifier).escapedText = "globalThis" as __String;
globals.set(globalThisSymbol.escapedName, globalThisSymbol);
const argumentsSymbol = createSymbol(SymbolFlags.Property, "arguments" as __String);
@@ -500,6 +498,7 @@ namespace ts {
* This is only used if there is no exact match.
*/
let patternAmbientModules: PatternAmbientModule[];
let patternAmbientModuleAugmentations: Map<Symbol> | undefined;
let globalObjectType: ObjectType;
let globalFunctionType: ObjectType;
@@ -890,7 +889,7 @@ namespace ts {
* Note: if target is transient, then it is mutable, and mergeSymbol with both mutate and return it.
* If target is not transient, mergeSymbol will produce a transient clone, mutate that and return it.
*/
function mergeSymbol(target: Symbol, source: Symbol): Symbol {
function mergeSymbol(target: Symbol, source: Symbol, unidirectional = false): Symbol {
if (!(target.flags & getExcludedSymbolFlags(source.flags)) ||
(source.flags | target.flags) & SymbolFlags.Assignment) {
Debug.assert(source !== target);
@@ -917,16 +916,24 @@ namespace ts {
addRange(target.declarations, source.declarations);
if (source.members) {
if (!target.members) target.members = createSymbolTable();
mergeSymbolTable(target.members, source.members);
mergeSymbolTable(target.members, source.members, unidirectional);
}
if (source.exports) {
if (!target.exports) target.exports = createSymbolTable();
mergeSymbolTable(target.exports, source.exports);
mergeSymbolTable(target.exports, source.exports, unidirectional
);
}
if (!unidirectional) {
recordMergedSymbol(target, source);
}
recordMergedSymbol(target, source);
}
else if (target.flags & SymbolFlags.NamespaceModule) {
error(getNameOfDeclaration(source.declarations[0]), Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target));
// Do not report an error when merging `var globalThis` with the built-in `globalThis`,
// as we will already report a "Declaration name conflicts..." error, and this error
// won't make much sense.
if (target !== globalThisSymbol) {
error(getNameOfDeclaration(source.declarations[0]), Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target));
}
}
else { // error
const isEitherEnum = !!(target.flags & SymbolFlags.Enum || source.flags & SymbolFlags.Enum);
@@ -990,10 +997,10 @@ namespace ts {
return combined;
}
function mergeSymbolTable(target: SymbolTable, source: SymbolTable) {
function mergeSymbolTable(target: SymbolTable, source: SymbolTable, unidirectional = false) {
source.forEach((sourceSymbol, id) => {
const targetSymbol = target.get(id);
target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol) : sourceSymbol);
target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol, unidirectional) : sourceSymbol);
});
}
@@ -1023,7 +1030,22 @@ namespace ts {
// obtain item referenced by 'export='
mainModule = resolveExternalModuleSymbol(mainModule);
if (mainModule.flags & SymbolFlags.Namespace) {
mainModule = mergeSymbol(mainModule, moduleAugmentation.symbol);
// If were merging an augmentation to a pattern ambient module, we want to
// perform the merge unidirectionally from the augmentation ('a.foo') to
// the pattern ('*.foo'), so that 'getMergedSymbol()' on a.foo gives you
// all the exports both from the pattern and from the augmentation, but
// 'getMergedSymbol()' on *.foo only gives you exports from *.foo.
if (some(patternAmbientModules, module => mainModule === module.symbol)) {
const merged = mergeSymbol(moduleAugmentation.symbol, mainModule, /*unidirectional*/ true);
if (!patternAmbientModuleAugmentations) {
patternAmbientModuleAugmentations = createMap();
}
// moduleName will be a StringLiteral since this is not `declare global`.
patternAmbientModuleAugmentations.set((moduleName as StringLiteral).text, merged);
}
else {
mergeSymbol(mainModule, moduleAugmentation.symbol);
}
}
else {
// moduleName will be a StringLiteral since this is not `declare global`.
@@ -2452,6 +2474,14 @@ namespace ts {
if (patternAmbientModules) {
const pattern = findBestPatternMatch(patternAmbientModules, _ => _.pattern, moduleReference);
if (pattern) {
// If the module reference matched a pattern ambient module ('*.foo') but theres also a
// module augmentation by the specific name requested ('a.foo'), we store the merged symbol
// by the augmentation name ('a.foo'), because asking for *.foo should not give you exports
// from a.foo.
const augmentation = patternAmbientModuleAugmentations && patternAmbientModuleAugmentations.get(moduleReference);
if (augmentation) {
return getMergedSymbol(augmentation);
}
return getMergedSymbol(pattern.symbol);
}
}
@@ -8562,7 +8592,7 @@ namespace ts {
function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: ReadonlyArray<TypeParameter>): Signature {
const instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
if (inferredTypeParameters) {
const returnSignature = getSingleCallSignature(getReturnTypeOfSignature(instantiatedSignature));
const returnSignature = getSingleCallOrConstructSignature(getReturnTypeOfSignature(instantiatedSignature));
if (returnSignature) {
const newReturnSignature = cloneSignature(returnSignature);
newReturnSignature.typeParameters = inferredTypeParameters;
@@ -8638,7 +8668,8 @@ namespace ts {
// object type literal or interface (using the new keyword). Each way of declaring a constructor
// will result in a different declaration kind.
if (!signature.isolatedSignatureType) {
const isConstructor = signature.declaration!.kind === SyntaxKind.Constructor || signature.declaration!.kind === SyntaxKind.ConstructSignature; // TODO: GH#18217
const kind = signature.declaration ? signature.declaration.kind : SyntaxKind.Unknown;
const isConstructor = kind === SyntaxKind.Constructor || kind === SyntaxKind.ConstructSignature || kind === SyntaxKind.ConstructorType;
const type = createObjectType(ObjectFlags.Anonymous);
type.members = emptySymbols;
type.properties = emptyArray;
@@ -10080,7 +10111,7 @@ namespace ts {
error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
return indexInfo.type;
}
if (indexInfo.isReadonly && (accessFlags & AccessFlags.Writing || accessExpression && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression)))) {
if (indexInfo.isReadonly && accessExpression && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression))) {
if (accessExpression) {
error(accessExpression, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
return indexInfo.type;
@@ -10114,7 +10145,13 @@ namespace ts {
}
}
else {
error(accessExpression, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(objectType));
const suggestion = getSuggestionForNonexistentIndexSignature(objectType, accessExpression);
if (suggestion !== undefined) {
error(accessExpression, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1, typeToString(objectType), suggestion);
}
else {
error(accessExpression, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(objectType));
}
}
}
}
@@ -10383,11 +10420,11 @@ namespace ts {
// We attempt to resolve the conditional type only when the check and extends types are non-generic
if (!checkTypeInstantiable && !maybeTypeOfKind(inferredExtendsType, TypeFlags.Instantiable | TypeFlags.GenericMappedType)) {
if (inferredExtendsType.flags & TypeFlags.AnyOrUnknown) {
return trueType;
return combinedMapper ? instantiateType(root.trueType, combinedMapper) : trueType;
}
// Return union of trueType and falseType for 'any' since it matches anything
if (checkType.flags & TypeFlags.Any) {
return getUnionType([instantiateType(root.trueType, combinedMapper || mapper), falseType]);
return getUnionType([combinedMapper ? instantiateType(root.trueType, combinedMapper) : trueType, falseType]);
}
// Return falseType for a definitely false extends check. We check an instantiations of the two
// types with type parameters mapped to the wildcard type, the most permissive instantiations
@@ -10402,7 +10439,7 @@ namespace ts {
// type Foo<T extends { x: any }> = T extends { x: string } ? string : number
// doesn't immediately resolve to 'string' instead of being deferred.
if (isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(inferredExtendsType))) {
return instantiateType(root.trueType, combinedMapper || mapper);
return combinedMapper ? instantiateType(root.trueType, combinedMapper) : trueType;
}
}
// Return a deferred type for a check that is neither definitely true nor definitely false
@@ -12319,6 +12356,15 @@ namespace ts {
function reportRelationError(message: DiagnosticMessage | undefined, source: Type, target: Type) {
const [sourceType, targetType] = getTypeNamesForErrorDisplay(source, target);
if (target.flags & TypeFlags.TypeParameter && target.immediateBaseConstraint !== undefined && isTypeAssignableTo(source, target.immediateBaseConstraint)) {
reportError(
Diagnostics._0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2,
sourceType,
targetType,
typeToString(target.immediateBaseConstraint),
);
}
if (!message) {
if (relation === comparableRelation) {
message = Diagnostics.Type_0_is_not_comparable_to_type_1;
@@ -12482,7 +12528,7 @@ namespace ts {
if (result && isPerformingExcessPropertyChecks) {
// Validate against excess props using the original `source`
const discriminantType = target.flags & TypeFlags.Union ? findMatchingDiscriminantType(source, target as UnionType) : undefined;
if (!propertiesRelatedTo(source, discriminantType || target, reportErrors)) {
if (!propertiesRelatedTo(source, discriminantType || target, reportErrors, /*excludedProperties*/ undefined)) {
return Ternary.False;
}
}
@@ -12492,7 +12538,7 @@ namespace ts {
result = typeRelatedToEachType(getRegularTypeOfObjectLiteral(source), target as IntersectionType, reportErrors);
if (result && isPerformingExcessPropertyChecks) {
// Validate against excess props using the original `source`
if (!propertiesRelatedTo(source, target, reportErrors)) {
if (!propertiesRelatedTo(source, target, reportErrors, /*excludedProperties*/ undefined)) {
return Ternary.False;
}
}
@@ -13170,7 +13216,7 @@ namespace ts {
if (source.flags & (TypeFlags.Object | TypeFlags.Intersection) && target.flags & TypeFlags.Object) {
// Report structural errors only if we haven't reported any errors yet
const reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo && !sourceIsPrimitive;
result = propertiesRelatedTo(source, target, reportStructuralErrors);
result = propertiesRelatedTo(source, target, reportStructuralErrors, /*excludedProperties*/ undefined);
if (result) {
result &= signaturesRelatedTo(source, target, SignatureKind.Call, reportStructuralErrors);
if (result) {
@@ -13190,6 +13236,19 @@ namespace ts {
return result;
}
}
// If S is an object type and T is a discriminated union, S may be related to T if
// there exists a constituent of T for every combination of the discriminants of S
// with respect to T. We do not report errors here, as we will use the existing
// error result from checking each constituent of the union.
if (source.flags & (TypeFlags.Object | TypeFlags.Intersection) && target.flags & TypeFlags.Union) {
const objectOnlyTarget = extractTypesOfKind(target, TypeFlags.Object);
if (objectOnlyTarget.flags & TypeFlags.Union) {
const result = typeRelatedToDiscriminatedType(source, objectOnlyTarget as UnionType);
if (result) {
return result;
}
}
}
}
return Ternary.False;
@@ -13253,9 +13312,185 @@ namespace ts {
return Ternary.False;
}
function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary {
function typeRelatedToDiscriminatedType(source: Type, target: UnionType) {
// 1. Generate the combinations of discriminant properties & types 'source' can satisfy.
// a. If the number of combinations is above a set limit, the comparison is too complex.
// 2. Filter 'target' to the subset of types whose discriminants exist in the matrix.
// a. If 'target' does not satisfy all discriminants in the matrix, 'source' is not related.
// 3. For each type in the filtered 'target', determine if all non-discriminant properties of
// 'target' are related to a property in 'source'.
//
// NOTE: See ~/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts
// for examples.
const sourceProperties = getPropertiesOfObjectType(source);
const sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target);
if (!sourcePropertiesFiltered) return Ternary.False;
// Though we could compute the number of combinations as we generate
// the matrix, this would incur additional memory overhead due to
// array allocations. To reduce this overhead, we first compute
// the number of combinations to ensure we will not surpass our
// fixed limit before incurring the cost of any allocations:
let numCombinations = 1;
for (const sourceProperty of sourcePropertiesFiltered) {
numCombinations *= countTypes(getTypeOfSymbol(sourceProperty));
if (numCombinations > 25) {
// We've reached the complexity limit.
return Ternary.False;
}
}
// Compute the set of types for each discriminant property.
const sourceDiscriminantTypes: Type[][] = new Array<Type[]>(sourcePropertiesFiltered.length);
const excludedProperties = createUnderscoreEscapedMap<true>();
for (let i = 0; i < sourcePropertiesFiltered.length; i++) {
const sourceProperty = sourcePropertiesFiltered[i];
const sourcePropertyType = getTypeOfSymbol(sourceProperty);
sourceDiscriminantTypes[i] = sourcePropertyType.flags & TypeFlags.Union
? (sourcePropertyType as UnionType).types
: [sourcePropertyType];
excludedProperties.set(sourceProperty.escapedName, true);
}
// Match each combination of the cartesian product of discriminant properties to one or more
// constituents of 'target'. If any combination does not have a match then 'source' is not relatable.
const discriminantCombinations = cartesianProduct(sourceDiscriminantTypes);
const matchingTypes: Type[] = [];
for (const combination of discriminantCombinations) {
let hasMatch = false;
outer: for (const type of target.types) {
for (let i = 0; i < sourcePropertiesFiltered.length; i++) {
const sourceProperty = sourcePropertiesFiltered[i];
const targetProperty = getPropertyOfObjectType(type, sourceProperty.escapedName);
if (!targetProperty) continue outer;
if (sourceProperty === targetProperty) continue;
// We compare the source property to the target in the context of a single discriminant type.
const related = propertyRelatedTo(source, target, sourceProperty, targetProperty, _ => combination[i], /*reportErrors*/ false);
// If the target property could not be found, or if the properties were not related,
// then this constituent is not a match.
if (!related) {
continue outer;
}
}
pushIfUnique(matchingTypes, type, equateValues);
hasMatch = true;
}
if (!hasMatch) {
// We failed to match any type for this combination.
return Ternary.False;
}
}
// Compare the remaining non-discriminant properties of each match.
let result = Ternary.True;
for (const type of matchingTypes) {
result &= propertiesRelatedTo(source, type, /*reportErrors*/ false, excludedProperties);
if (result) {
result &= signaturesRelatedTo(source, type, SignatureKind.Call, /*reportStructuralErrors*/ false);
if (result) {
result &= signaturesRelatedTo(source, type, SignatureKind.Construct, /*reportStructuralErrors*/ false);
if (result) {
result &= indexTypesRelatedTo(source, type, IndexKind.String, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false);
if (result) {
result &= indexTypesRelatedTo(source, type, IndexKind.Number, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false);
}
}
}
}
if (!result) {
return result;
}
}
return result;
}
function excludeProperties(properties: Symbol[], excludedProperties: UnderscoreEscapedMap<true> | undefined) {
if (!excludedProperties || properties.length === 0) return properties;
let result: Symbol[] | undefined;
for (let i = 0; i < properties.length; i++) {
if (!excludedProperties.has(properties[i].escapedName)) {
if (result) {
result.push(properties[i]);
}
}
else if (!result) {
result = properties.slice(0, i);
}
}
return result || properties;
}
function propertyRelatedTo(source: Type, target: Type, sourceProp: Symbol, targetProp: Symbol, getTypeOfSourceProperty: (sym: Symbol) => Type, reportErrors: boolean): Ternary {
const sourcePropFlags = getDeclarationModifierFlagsFromSymbol(sourceProp);
const targetPropFlags = getDeclarationModifierFlagsFromSymbol(targetProp);
if (sourcePropFlags & ModifierFlags.Private || targetPropFlags & ModifierFlags.Private) {
const hasDifferingDeclarations = sourceProp.valueDeclaration !== targetProp.valueDeclaration;
if (getCheckFlags(sourceProp) & CheckFlags.ContainsPrivate && hasDifferingDeclarations) {
if (reportErrors) {
reportError(Diagnostics.Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1, symbolToString(sourceProp), typeToString(source));
}
return Ternary.False;
}
if (hasDifferingDeclarations) {
if (reportErrors) {
if (sourcePropFlags & ModifierFlags.Private && targetPropFlags & ModifierFlags.Private) {
reportError(Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp));
}
else {
reportError(Diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp),
typeToString(sourcePropFlags & ModifierFlags.Private ? source : target),
typeToString(sourcePropFlags & ModifierFlags.Private ? target : source));
}
}
return Ternary.False;
}
}
else if (targetPropFlags & ModifierFlags.Protected) {
if (!isValidOverrideOf(sourceProp, targetProp)) {
if (reportErrors) {
reportError(Diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, symbolToString(targetProp),
typeToString(getDeclaringClass(sourceProp) || source), typeToString(getDeclaringClass(targetProp) || target));
}
return Ternary.False;
}
}
else if (sourcePropFlags & ModifierFlags.Protected) {
if (reportErrors) {
reportError(Diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2,
symbolToString(targetProp), typeToString(source), typeToString(target));
}
return Ternary.False;
}
// If the target comes from a partial union prop, allow `undefined` in the target type
const related = isRelatedTo(getTypeOfSourceProperty(sourceProp), addOptionality(getTypeOfSymbol(targetProp), !!(getCheckFlags(targetProp) & CheckFlags.Partial)), reportErrors);
if (!related) {
if (reportErrors) {
reportError(Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp));
}
return Ternary.False;
}
// When checking for comparability, be more lenient with optional properties.
if (relation !== comparableRelation && sourceProp.flags & SymbolFlags.Optional && !(targetProp.flags & SymbolFlags.Optional)) {
// TypeScript 1.0 spec (April 2014): 3.8.3
// S is a subtype of a type T, and T is a supertype of S if ...
// S' and T are object types and, for each member M in T..
// M is a property and S' contains a property N where
// if M is a required property, N is also a required property
// (M - property in T)
// (N - property in S)
if (reportErrors) {
reportError(Diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2,
symbolToString(targetProp), typeToString(source), typeToString(target));
}
return Ternary.False;
}
return related;
}
function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean, excludedProperties: UnderscoreEscapedMap<true> | undefined): Ternary {
if (relation === identityRelation) {
return propertiesIdenticalTo(source, target);
return propertiesIdenticalTo(source, target, excludedProperties);
}
const requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType(source) && !isEmptyArrayLiteralType(source) && !isTupleType(source);
const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false);
@@ -13285,7 +13520,7 @@ namespace ts {
return Ternary.False;
}
if (isObjectLiteralType(target)) {
for (const sourceProp of getPropertiesOfType(source)) {
for (const sourceProp of excludeProperties(getPropertiesOfType(source), excludedProperties)) {
if (!getPropertyOfObjectType(target, sourceProp.escapedName)) {
const sourceType = getTypeOfSymbol(sourceProp);
if (!(sourceType === undefinedType || sourceType === undefinedWideningType)) {
@@ -13328,89 +13563,30 @@ namespace ts {
// We only call this for union target types when we're attempting to do excess property checking - in those cases, we want to get _all possible props_
// from the target union, across all members
const properties = target.flags & TypeFlags.Union ? getPossiblePropertiesOfUnionType(target as UnionType) : getPropertiesOfType(target);
for (const targetProp of properties) {
for (const targetProp of excludeProperties(properties, excludedProperties)) {
if (!(targetProp.flags & SymbolFlags.Prototype)) {
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
if (sourceProp && sourceProp !== targetProp) {
if (isIgnoredJsxProperty(source, sourceProp, getTypeOfSymbol(targetProp))) {
continue;
}
const sourcePropFlags = getDeclarationModifierFlagsFromSymbol(sourceProp);
const targetPropFlags = getDeclarationModifierFlagsFromSymbol(targetProp);
if (sourcePropFlags & ModifierFlags.Private || targetPropFlags & ModifierFlags.Private) {
const hasDifferingDeclarations = sourceProp.valueDeclaration !== targetProp.valueDeclaration;
if (getCheckFlags(sourceProp) & CheckFlags.ContainsPrivate && hasDifferingDeclarations) {
if (reportErrors) {
reportError(Diagnostics.Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1, symbolToString(sourceProp), typeToString(source));
}
return Ternary.False;
}
if (hasDifferingDeclarations) {
if (reportErrors) {
if (sourcePropFlags & ModifierFlags.Private && targetPropFlags & ModifierFlags.Private) {
reportError(Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp));
}
else {
reportError(Diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp),
typeToString(sourcePropFlags & ModifierFlags.Private ? source : target),
typeToString(sourcePropFlags & ModifierFlags.Private ? target : source));
}
}
return Ternary.False;
}
}
else if (targetPropFlags & ModifierFlags.Protected) {
if (!isValidOverrideOf(sourceProp, targetProp)) {
if (reportErrors) {
reportError(Diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, symbolToString(targetProp),
typeToString(getDeclaringClass(sourceProp) || source), typeToString(getDeclaringClass(targetProp) || target));
}
return Ternary.False;
}
}
else if (sourcePropFlags & ModifierFlags.Protected) {
if (reportErrors) {
reportError(Diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2,
symbolToString(targetProp), typeToString(source), typeToString(target));
}
return Ternary.False;
}
// If the target comes from a partial union prop, allow `undefined` in the target type
const related = isRelatedTo(getTypeOfSymbol(sourceProp), addOptionality(getTypeOfSymbol(targetProp), !!(getCheckFlags(targetProp) & CheckFlags.Partial)), reportErrors);
const related = propertyRelatedTo(source, target, sourceProp, targetProp, getTypeOfSymbol, reportErrors);
if (!related) {
if (reportErrors) {
reportError(Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp));
}
return Ternary.False;
}
result &= related;
// When checking for comparability, be more lenient with optional properties.
if (relation !== comparableRelation && sourceProp.flags & SymbolFlags.Optional && !(targetProp.flags & SymbolFlags.Optional)) {
// TypeScript 1.0 spec (April 2014): 3.8.3
// S is a subtype of a type T, and T is a supertype of S if ...
// S' and T are object types and, for each member M in T..
// M is a property and S' contains a property N where
// if M is a required property, N is also a required property
// (M - property in T)
// (N - property in S)
if (reportErrors) {
reportError(Diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2,
symbolToString(targetProp), typeToString(source), typeToString(target));
}
return Ternary.False;
}
}
}
}
return result;
}
function propertiesIdenticalTo(source: Type, target: Type): Ternary {
function propertiesIdenticalTo(source: Type, target: Type, excludedProperties: UnderscoreEscapedMap<true> | undefined): Ternary {
if (!(source.flags & TypeFlags.Object && target.flags & TypeFlags.Object)) {
return Ternary.False;
}
const sourceProperties = getPropertiesOfObjectType(source);
const targetProperties = getPropertiesOfObjectType(target);
const sourceProperties = excludeProperties(getPropertiesOfObjectType(source), excludedProperties);
const targetProperties = excludeProperties(getPropertiesOfObjectType(target), excludedProperties);
if (sourceProperties.length !== targetProperties.length) {
return Ternary.False;
}
@@ -15949,6 +16125,10 @@ namespace ts {
return f(type) ? type : neverType;
}
function countTypes(type: Type) {
return type.flags & TypeFlags.Union ? (type as UnionType).types.length : 1;
}
// Apply a mapping function to a type and return the resulting type. If the source type
// is a union type, the mapping function is applied to each constituent type and a union
// of the resulting types is returned.
@@ -18433,7 +18613,7 @@ namespace ts {
case SyntaxKind.ParenthesizedExpression: {
// Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
const tag = isInJSFile(parent) ? getJSDocTypeTag(parent) : undefined;
return tag ? getTypeFromTypeNode(tag.typeExpression!.type) : getContextualType(<ParenthesizedExpression>parent, contextFlags);
return tag ? getTypeFromTypeNode(tag.typeExpression.type) : getContextualType(<ParenthesizedExpression>parent, contextFlags);
}
case SyntaxKind.JsxExpression:
return getContextualTypeForJsxExpression(<JsxExpression>parent);
@@ -20049,6 +20229,35 @@ namespace ts {
return suggestion && symbolName(suggestion);
}
function getSuggestionForNonexistentIndexSignature(objectType: Type, expr: ElementAccessExpression): string | undefined {
// check if object type has setter or getter
const hasProp = (name: "set" | "get", argCount = 1) => {
const prop = getPropertyOfObjectType(objectType, <__String>name);
if (prop) {
const s = getSingleCallSignature(getTypeOfSymbol(prop));
if (s && getMinArgumentCount(s) === argCount && typeToString(getTypeAtPosition(s, 0)) === "string") {
return true;
}
}
return false;
};
const suggestedMethod = isAssignmentTarget(expr) ? "set" : "get";
if (!hasProp(suggestedMethod)) {
return undefined;
}
let suggestion = tryGetPropertyAccessOrIdentifierToString(expr);
if (suggestion === undefined) {
suggestion = suggestedMethod;
}
else {
suggestion += "." + suggestedMethod;
}
return suggestion;
}
/**
* Given a name and a list of symbols whose names are *not* equal to the name, return a spelling suggestion if there is one that is close enough.
* Names less than length 3 only check for case-insensitive equality, not levenshtein distance.
@@ -20449,11 +20658,24 @@ namespace ts {
// If type has a single call signature and no other members, return that signature. Otherwise, return undefined.
function getSingleCallSignature(type: Type): Signature | undefined {
return getSingleSignature(type, SignatureKind.Call, /*allowMembers*/ false);
}
function getSingleCallOrConstructSignature(type: Type): Signature | undefined {
return getSingleSignature(type, SignatureKind.Call, /*allowMembers*/ false) ||
getSingleSignature(type, SignatureKind.Construct, /*allowMembers*/ false);
}
function getSingleSignature(type: Type, kind: SignatureKind, allowMembers: boolean): Signature | undefined {
if (type.flags & TypeFlags.Object) {
const resolved = resolveStructuredTypeMembers(<ObjectType>type);
if (resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0 &&
resolved.properties.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
return resolved.callSignatures[0];
if (allowMembers || resolved.properties.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
if (kind === SignatureKind.Call && resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0) {
return resolved.callSignatures[0];
}
if (kind === SignatureKind.Construct && resolved.constructSignatures.length === 1 && resolved.callSignatures.length === 0) {
return resolved.constructSignatures[0];
}
}
}
return undefined;
@@ -23795,16 +24017,18 @@ namespace ts {
function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration | QualifiedName, type: Type, checkMode?: CheckMode) {
if (checkMode && checkMode & (CheckMode.Inferential | CheckMode.SkipGenericFunctions)) {
const signature = getSingleCallSignature(type);
const callSignature = getSingleSignature(type, SignatureKind.Call, /*allowMembers*/ true);
const constructSignature = getSingleSignature(type, SignatureKind.Construct, /*allowMembers*/ true);
const signature = callSignature || constructSignature;
if (signature && signature.typeParameters) {
if (checkMode & CheckMode.SkipGenericFunctions) {
skippedGenericFunction(node, checkMode);
return anyFunctionType;
}
const contextualType = getApparentTypeOfContextualType(<Expression>node);
if (contextualType) {
const contextualSignature = getSingleCallSignature(getNonNullableType(contextualType));
if (contextualType && !isMixinConstructorType(contextualType)) {
const contextualSignature = getSingleSignature(getNonNullableType(contextualType), callSignature ? SignatureKind.Call : SignatureKind.Construct, /*allowMembers*/ false);
if (contextualSignature && !contextualSignature.typeParameters) {
if (checkMode & CheckMode.SkipGenericFunctions) {
skippedGenericFunction(node, checkMode);
return anyFunctionType;
}
const context = getInferenceContext(node)!;
// We have an expression that is an argument of a generic function for which we are performing
// type argument inference. The expression is of a function type with a single generic call
@@ -23812,7 +24036,8 @@ namespace ts {
// if the outer function returns a function type with a single non-generic call signature and
// if some of the outer function type parameters have no inferences so far. If so, we can
// potentially add inferred type parameters to the outer function return type.
const returnSignature = context.signature && getSingleCallSignature(getReturnTypeOfSignature(context.signature));
const returnType = context.signature && getReturnTypeOfSignature(context.signature);
const returnSignature = returnType && getSingleCallOrConstructSignature(returnType);
if (returnSignature && !returnSignature.typeParameters && !every(context.inferences, hasInferenceCandidates)) {
// Instantiate the signature with its own type parameters as type arguments, possibly
// renaming the type parameters to ensure they have unique names.
@@ -24006,7 +24231,7 @@ namespace ts {
function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type {
const tag = isInJSFile(node) ? getJSDocTypeTag(node) : undefined;
if (tag) {
return checkAssertionWorker(tag, tag.typeExpression!.type, node.expression, checkMode);
return checkAssertionWorker(tag, tag.typeExpression.type, node.expression, checkMode);
}
return checkExpression(node.expression, checkMode);
}
@@ -26462,14 +26687,28 @@ namespace ts {
}
// For a binding pattern, validate the initializer and exit
if (isBindingPattern(node.name)) {
// Don't validate for-in initializer as it is already an error
if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) {
const initializerType = checkExpressionCached(node.initializer);
if (strictNullChecks && node.name.elements.length === 0) {
checkNonNullNonVoidType(initializerType, node);
const needCheckInitializer = node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement;
const needCheckWidenedType = node.name.elements.length === 0;
if (needCheckInitializer || needCheckWidenedType) {
// Don't validate for-in initializer as it is already an error
const widenedType = getWidenedTypeForVariableLikeDeclaration(node);
if (needCheckInitializer) {
const initializerType = checkExpressionCached(node.initializer!);
if (strictNullChecks && needCheckWidenedType) {
checkNonNullNonVoidType(initializerType, node);
}
else {
checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
}
}
else {
checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
// check the binding pattern with empty elements
if (needCheckWidenedType) {
if (isArrayBindingPattern(node.name)) {
checkIteratedTypeOrElementType(widenedType, node, /* allowStringInput */ false, /* allowAsyncIterables */ false);
}
else if (strictNullChecks) {
checkNonNullNonVoidType(widenedType, node);
}
}
}
return;
@@ -30442,6 +30681,14 @@ namespace ts {
continue;
}
if (!isExternalOrCommonJsModule(file)) {
// It is an error for a non-external-module (i.e. script) to declare its own `globalThis`.
// We can't use `builtinGlobals` for this due to synthetic expando-namespace generation in JS files.
const fileGlobalThisSymbol = file.locals!.get("globalThis" as __String);
if (fileGlobalThisSymbol) {
for (const declaration of fileGlobalThisSymbol.declarations) {
diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "globalThis"));
}
}
mergeSymbolTable(globals, file.locals!);
}
if (file.jsGlobalAugmentations) {
@@ -30487,6 +30734,7 @@ namespace ts {
getSymbolLinks(undefinedSymbol).type = undefinedWideningType;
getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments" as __String, /*arity*/ 0, /*reportErrors*/ true);
getSymbolLinks(unknownSymbol).type = errorType;
getSymbolLinks(globalThisSymbol).type = createObjectType(ObjectFlags.Anonymous, globalThisSymbol);
// Initialize special types
globalArrayType = getGlobalType("Array" as __String, /*arity*/ 1, /*reportErrors*/ true);
+76 -40
View File
@@ -45,6 +45,7 @@ namespace ts {
["es2018.promise", "lib.es2018.promise.d.ts"],
["es2018.regexp", "lib.es2018.regexp.d.ts"],
["es2019.array", "lib.es2019.array.d.ts"],
["es2019.object", "lib.es2019.object.d.ts"],
["es2019.string", "lib.es2019.string.d.ts"],
["es2019.symbol", "lib.es2019.symbol.d.ts"],
["es2020.string", "lib.es2020.string.d.ts"],
@@ -218,6 +219,7 @@ namespace ts {
}),
affectsSourceFile: true,
affectsModuleResolution: true,
affectsEmit: true,
paramType: Diagnostics.VERSION,
showInSimplifiedHelpView: true,
category: Diagnostics.Basic_Options,
@@ -1345,7 +1347,12 @@ namespace ts {
/**
* Reads the config file, reports errors if any and exits if the config file cannot be found
*/
export function getParsedCommandLineOfConfigFile(configFileName: string, optionsToExtend: CompilerOptions, host: ParseConfigFileHost): ParsedCommandLine | undefined {
export function getParsedCommandLineOfConfigFile(
configFileName: string,
optionsToExtend: CompilerOptions,
host: ParseConfigFileHost,
extendedConfigCache?: Map<ExtendedConfigCacheEntry>
): ParsedCommandLine | undefined {
let configFileText: string | undefined;
try {
configFileText = host.readFile(configFileName);
@@ -1366,7 +1373,16 @@ namespace ts {
result.path = toPath(configFileName, cwd, createGetCanonicalFileName(host.useCaseSensitiveFileNames));
result.resolvedPath = result.path;
result.originalFileName = result.fileName;
return parseJsonSourceFileConfigFileContent(result, host, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), optionsToExtend, getNormalizedAbsolutePath(configFileName, cwd));
return parseJsonSourceFileConfigFileContent(
result,
host,
getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd),
optionsToExtend,
getNormalizedAbsolutePath(configFileName, cwd),
/*resolutionStack*/ undefined,
/*extraFileExtension*/ undefined,
extendedConfigCache
);
}
/**
@@ -1980,8 +1996,8 @@ namespace ts {
* @param basePath A root directory to resolve relative path entries in the config
* file to. e.g. outDir
*/
export function parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: ReadonlyArray<FileExtensionInfo>): ParsedCommandLine {
return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions);
export function parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: ReadonlyArray<FileExtensionInfo>, /*@internal*/ extendedConfigCache?: Map<ExtendedConfigCacheEntry>): ParsedCommandLine {
return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache);
}
/*@internal*/
@@ -2020,11 +2036,12 @@ namespace ts {
configFileName?: string,
resolutionStack: Path[] = [],
extraFileExtensions: ReadonlyArray<FileExtensionInfo> = [],
extendedConfigCache?: Map<ExtendedConfigCacheEntry>
): ParsedCommandLine {
Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined));
const errors: Diagnostic[] = [];
const parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, resolutionStack, errors);
const parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, resolutionStack, errors, extendedConfigCache);
const { raw } = parsedConfig;
const options = extend(existingOptions, parsedConfig.options || {});
options.configFilePath = configFileName && normalizeSlashes(configFileName);
@@ -2172,7 +2189,7 @@ namespace ts {
return existingErrors !== configParseDiagnostics.length;
}
interface ParsedTsconfig {
export interface ParsedTsconfig {
raw: any;
options?: CompilerOptions;
typeAcquisition?: TypeAcquisition;
@@ -2191,13 +2208,14 @@ namespace ts {
* It does *not* resolve the included files.
*/
function parseConfig(
json: any,
sourceFile: TsConfigSourceFile | undefined,
host: ParseConfigHost,
basePath: string,
configFileName: string | undefined,
resolutionStack: string[],
errors: Push<Diagnostic>,
json: any,
sourceFile: TsConfigSourceFile | undefined,
host: ParseConfigHost,
basePath: string,
configFileName: string | undefined,
resolutionStack: string[],
errors: Push<Diagnostic>,
extendedConfigCache?: Map<ExtendedConfigCacheEntry>
): ParsedTsconfig {
basePath = normalizeSlashes(basePath);
const resolvedPath = getNormalizedAbsolutePath(configFileName || "", basePath);
@@ -2214,7 +2232,7 @@ namespace ts {
if (ownConfig.extendedConfigPath) {
// copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios.
resolutionStack = resolutionStack.concat([resolvedPath]);
const extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, resolutionStack, errors);
const extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, resolutionStack, errors, extendedConfigCache);
if (extendedConfig && isSuccessfulParsedTsconfig(extendedConfig)) {
const baseRaw = extendedConfig.raw;
const raw = ownConfig.raw;
@@ -2358,6 +2376,11 @@ namespace ts {
return undefined;
}
export interface ExtendedConfigCacheEntry {
extendedResult: TsConfigSourceFile;
extendedConfig: ParsedTsconfig | undefined;
}
function getExtendedConfig(
sourceFile: TsConfigSourceFile | undefined,
extendedConfigPath: string,
@@ -2365,40 +2388,53 @@ namespace ts {
basePath: string,
resolutionStack: string[],
errors: Push<Diagnostic>,
extendedConfigCache?: Map<ExtendedConfigCacheEntry>
): ParsedTsconfig | undefined {
const extendedResult = readJsonConfigFile(extendedConfigPath, path => host.readFile(path));
const path = host.useCaseSensitiveFileNames ? extendedConfigPath : toLowerCase(extendedConfigPath);
let value: ExtendedConfigCacheEntry | undefined;
let extendedResult: TsConfigSourceFile;
let extendedConfig: ParsedTsconfig | undefined;
if (extendedConfigCache && (value = extendedConfigCache.get(path))) {
({ extendedResult, extendedConfig } = value);
}
else {
extendedResult = readJsonConfigFile(extendedConfigPath, path => host.readFile(path));
if (!extendedResult.parseDiagnostics.length) {
const extendedDirname = getDirectoryPath(extendedConfigPath);
extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname,
getBaseFileName(extendedConfigPath), resolutionStack, errors, extendedConfigCache);
if (isSuccessfulParsedTsconfig(extendedConfig)) {
// Update the paths to reflect base path
const relativeDifference = convertToRelativePath(extendedDirname, basePath, identity);
const updatePath = (path: string) => isRootedDiskPath(path) ? path : combinePaths(relativeDifference, path);
const mapPropertiesInRawIfNotUndefined = (propertyName: string) => {
if (raw[propertyName]) {
raw[propertyName] = map(raw[propertyName], updatePath);
}
};
const { raw } = extendedConfig;
mapPropertiesInRawIfNotUndefined("include");
mapPropertiesInRawIfNotUndefined("exclude");
mapPropertiesInRawIfNotUndefined("files");
}
}
if (extendedConfigCache) {
extendedConfigCache.set(path, { extendedResult, extendedConfig });
}
}
if (sourceFile) {
sourceFile.extendedSourceFiles = [extendedResult.fileName];
if (extendedResult.extendedSourceFiles) {
sourceFile.extendedSourceFiles.push(...extendedResult.extendedSourceFiles);
}
}
if (extendedResult.parseDiagnostics.length) {
errors.push(...extendedResult.parseDiagnostics);
return undefined;
}
const extendedDirname = getDirectoryPath(extendedConfigPath);
const extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname,
getBaseFileName(extendedConfigPath), resolutionStack, errors);
if (sourceFile && extendedResult.extendedSourceFiles) {
sourceFile.extendedSourceFiles!.push(...extendedResult.extendedSourceFiles);
}
if (isSuccessfulParsedTsconfig(extendedConfig)) {
// Update the paths to reflect base path
const relativeDifference = convertToRelativePath(extendedDirname, basePath, identity);
const updatePath = (path: string) => isRootedDiskPath(path) ? path : combinePaths(relativeDifference, path);
const mapPropertiesInRawIfNotUndefined = (propertyName: string) => {
if (raw[propertyName]) {
raw[propertyName] = map(raw[propertyName], updatePath);
}
};
const { raw } = extendedConfig;
mapPropertiesInRawIfNotUndefined("include");
mapPropertiesInRawIfNotUndefined("exclude");
mapPropertiesInRawIfNotUndefined("files");
}
return extendedConfig;
return extendedConfig!;
}
function convertCompileOnSaveOptionFromJson(jsonOption: any, basePath: string, errors: Push<Diagnostic>): boolean {
+25
View File
@@ -2284,4 +2284,29 @@ namespace ts {
}
return result;
}
export function cartesianProduct<T>(arrays: readonly T[][]) {
const result: T[][] = [];
cartesianProductWorker(arrays, result, /*outer*/ undefined, 0);
return result;
}
function cartesianProductWorker<T>(arrays: readonly (readonly T[])[], result: (readonly T[])[], outer: readonly T[] | undefined, index: number) {
for (const element of arrays[index]) {
let inner: T[];
if (outer) {
inner = outer.slice();
inner.push(element);
}
else {
inner = [element];
}
if (index === arrays.length - 1) {
result.push(inner);
}
else {
cartesianProductWorker(arrays, result, inner, index + 1);
}
}
}
}
+8 -1
View File
@@ -3096,6 +3096,10 @@
"category": "Error",
"code": 5074
},
"'{0}' is assignable to the constraint of type '{1}', but '{1}' could be instantiated with a different subtype of constraint '{2}'.": {
"category": "Error",
"code": 5075
},
"Generates a sourcemap for each corresponding '.d.ts' file.": {
"category": "Message",
@@ -4272,7 +4276,10 @@
"category": "Error",
"code": 7051
},
"Element implicitly has an 'any' type because type '{0}' has no index signature. Did you mean to call '{1}' ?": {
"category": "Error",
"code": 7052
},
"You cannot rename this element.": {
"category": "Error",
"code": 8000
+1 -1
View File
@@ -2189,7 +2189,7 @@ namespace ts {
}
/* @internal */
export function createJSDocTypeTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocTypeTag {
export function createJSDocTypeTag(typeExpression: JSDocTypeExpression, comment?: string): JSDocTypeTag {
const tag = createJSDocTag<JSDocTypeTag>(SyntaxKind.JSDocTypeTag, "type");
tag.typeExpression = typeExpression;
tag.comment = comment;
+3 -18
View File
@@ -6855,7 +6855,7 @@ namespace ts {
}
function parseReturnTag(start: number, tagName: Identifier): JSDocReturnTag {
if (forEach(tags, t => t.kind === SyntaxKind.JSDocReturnTag)) {
if (some(tags, isJSDocReturnTag)) {
parseErrorAt(tagName.pos, scanner.getTokenPos(), Diagnostics._0_tag_already_specified, tagName.escapedText);
}
@@ -6866,7 +6866,7 @@ namespace ts {
}
function parseTypeTag(start: number, tagName: Identifier): JSDocTypeTag {
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTypeTag)) {
if (some(tags, isJSDocTypeTag)) {
parseErrorAt(tagName.pos, scanner.getTokenPos(), Diagnostics._0_tag_already_specified, tagName.escapedText);
}
@@ -7782,24 +7782,9 @@ namespace ts {
/*@internal*/
export function processCommentPragmas(context: PragmaContext, sourceText: string): void {
const triviaScanner = createScanner(context.languageVersion, /*skipTrivia*/ false, LanguageVariant.Standard, sourceText);
const pragmas: PragmaPseudoMapEntry[] = [];
// Keep scanning all the leading trivia in the file until we get to something that
// isn't trivia. Any single line comment will be analyzed to see if it is a
// reference comment.
while (true) {
const kind = triviaScanner.scan();
if (!isTrivia(kind)) {
break;
}
const range = {
kind: <SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia>triviaScanner.getToken(),
pos: triviaScanner.getTokenPos(),
end: triviaScanner.getTextPos(),
};
for (const range of getLeadingCommentRanges(sourceText, 0) || emptyArray) {
const comment = sourceText.substring(range.pos, range.end);
extractPragmas(pragmas, range, comment);
}
+25 -11
View File
@@ -2678,18 +2678,32 @@ namespace ts {
return fromCache || undefined;
}
// An absolute path pointing to the containing directory of the config file
const basePath = getNormalizedAbsolutePath(getDirectoryPath(refPath), host.getCurrentDirectory());
const sourceFile = host.getSourceFile(refPath, ScriptTarget.JSON) as JsonSourceFile | undefined;
addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined);
if (sourceFile === undefined) {
projectReferenceRedirects.set(sourceFilePath, false);
return undefined;
let commandLine: ParsedCommandLine | undefined;
let sourceFile: JsonSourceFile | undefined;
if (host.getParsedCommandLine) {
commandLine = host.getParsedCommandLine(refPath);
if (!commandLine) {
addFileToFilesByName(/*sourceFile*/ undefined, sourceFilePath, /*redirectedPath*/ undefined);
projectReferenceRedirects.set(sourceFilePath, false);
return undefined;
}
sourceFile = Debug.assertDefined(commandLine.options.configFile);
addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined);
}
else {
// An absolute path pointing to the containing directory of the config file
const basePath = getNormalizedAbsolutePath(getDirectoryPath(refPath), host.getCurrentDirectory());
sourceFile = host.getSourceFile(refPath, ScriptTarget.JSON) as JsonSourceFile | undefined;
addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined);
if (sourceFile === undefined) {
projectReferenceRedirects.set(sourceFilePath, false);
return undefined;
}
sourceFile.path = sourceFilePath;
sourceFile.resolvedPath = sourceFilePath;
sourceFile.originalFileName = refPath;
commandLine = parseJsonSourceFileConfigFileContent(sourceFile, configParsingHost, basePath, /*existingOptions*/ undefined, refPath);
}
sourceFile.path = sourceFilePath;
sourceFile.resolvedPath = sourceFilePath;
sourceFile.originalFileName = refPath;
const commandLine = parseJsonSourceFileConfigFileContent(sourceFile, configParsingHost, basePath, /*existingOptions*/ undefined, refPath);
const resolvedRef: ResolvedProjectReference = { commandLine, sourceFile };
projectReferenceRedirects.set(sourceFilePath, resolvedRef);
if (commandLine.projectReferences) {
+4 -1
View File
@@ -399,6 +399,7 @@ namespace ts {
let projectCompilerOptions = baseCompilerOptions;
const compilerHost = createCompilerHostFromProgramHost(host, () => projectCompilerOptions);
setGetSourceFileAsHashVersioned(compilerHost, host);
compilerHost.getParsedCommandLine = parseConfigFile;
compilerHost.resolveModuleNames = maybeBind(host, host.resolveModuleNames);
compilerHost.resolveTypeReferenceDirectives = maybeBind(host, host.resolveTypeReferenceDirectives);
@@ -415,6 +416,7 @@ namespace ts {
} | undefined;
const buildInfoChecked = createFileMap<true>(toPath);
const extendedConfigCache = createMap<ExtendedConfigCacheEntry>();
// Watch state
const builderPrograms = createFileMap<T>(toPath);
@@ -491,7 +493,7 @@ namespace ts {
let diagnostic: Diagnostic | undefined;
parseConfigFileHost.onUnRecoverableConfigFileDiagnostic = d => diagnostic = d;
const parsed = getParsedCommandLineOfConfigFile(configFilePath, baseCompilerOptions, parseConfigFileHost);
const parsed = getParsedCommandLineOfConfigFile(configFilePath, baseCompilerOptions, parseConfigFileHost, extendedConfigCache);
parseConfigFileHost.onUnRecoverableConfigFileDiagnostic = noop;
configFileCache.setValue(configFilePath, parsed || diagnostic!);
return parsed;
@@ -1439,6 +1441,7 @@ namespace ts {
compilerHost.getSourceFile = cacheState.originalGetSourceFile;
readFileWithCache = cacheState.originalReadFileWithCache;
compilerHost.resolveModuleNames = cacheState.originalResolveModuleNames;
extendedConfigCache.clear();
if (moduleResolutionCache) {
moduleResolutionCache.directoryToModuleNameMap.clear();
moduleResolutionCache.moduleNameToDirectoryMap.clear();
+2 -1
View File
@@ -2482,7 +2482,7 @@ namespace ts {
export interface JSDocTypeTag extends JSDocTag {
kind: SyntaxKind.JSDocTypeTag;
typeExpression?: JSDocTypeExpression;
typeExpression: JSDocTypeExpression;
}
export interface JSDocTypedefTag extends JSDocTag, NamedDeclaration {
@@ -5131,6 +5131,7 @@ namespace ts {
/* @internal */ hasInvalidatedResolution?: HasInvalidatedResolution;
/* @internal */ hasChangedAutomaticTypeDirectiveNames?: boolean;
createHash?(data: string): string;
getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined;
// TODO: later handle this in better way in builder host instead once the api for tsbuild finalizes and doesnt use compilerHost as base
/*@internal*/createDirectory?(directory: string): void;
+10
View File
@@ -3960,6 +3960,16 @@ namespace ts {
return isPropertyAccessExpression(node) && isEntityNameExpression(node.expression);
}
export function tryGetPropertyAccessOrIdentifierToString(expr: Expression): string | undefined {
if (isPropertyAccessExpression(expr)) {
return tryGetPropertyAccessOrIdentifierToString(expr.expression) + "." + expr.name;
}
if (isIdentifier(expr)) {
return unescapeLeadingUnderscores(expr.escapedText);
}
return undefined;
}
export function isPrototypeAccess(node: Node): node is PropertyAccessExpression {
return isPropertyAccessExpression(node) && node.name.escapedText === "prototype";
}
+4 -4
View File
@@ -9,7 +9,7 @@ interface Array<T> {
* predicate. If it is not provided, undefined is used instead.
*/
find<S extends T>(predicate: (this: void, value: T, index: number, obj: T[]) => value is S, thisArg?: any): S | undefined;
find(predicate: (value: T, index: number, obj: T[]) => boolean, thisArg?: any): T | undefined;
find(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T | undefined;
/**
* Returns the index of the first element in the array where predicate is true, and -1
@@ -20,7 +20,7 @@ interface Array<T> {
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findIndex(predicate: (value: T, index: number, obj: T[]) => boolean, thisArg?: any): number;
findIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number;
/**
* Returns the this object after filling the section identified by start and end with value
@@ -330,7 +330,7 @@ interface ReadonlyArray<T> {
* predicate. If it is not provided, undefined is used instead.
*/
find<S extends T>(predicate: (this: void, value: T, index: number, obj: ReadonlyArray<T>) => value is S, thisArg?: any): S | undefined;
find(predicate: (value: T, index: number, obj: ReadonlyArray<T>) => boolean, thisArg?: any): T | undefined;
find(predicate: (value: T, index: number, obj: ReadonlyArray<T>) => unknown, thisArg?: any): T | undefined;
/**
* Returns the index of the first element in the array where predicate is true, and -1
@@ -341,7 +341,7 @@ interface ReadonlyArray<T> {
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findIndex(predicate: (value: T, index: number, obj: ReadonlyArray<T>) => boolean, thisArg?: any): number;
findIndex(predicate: (value: T, index: number, obj: ReadonlyArray<T>) => unknown, thisArg?: any): number;
}
interface RegExp {
+3 -67
View File
@@ -98,79 +98,15 @@ interface PromiseConstructor {
* @param values An array of Promises.
* @returns A new Promise.
*/
race<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>, T10 | PromiseLike<T10>]): Promise<T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8 | T9 | T10>;
race<T>(values: T[]): Promise<T extends PromiseLike<infer U> ? U : T>;
/**
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @param values An iterable of Promises.
* @returns A new Promise.
*/
race<T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>]): Promise<T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8 | T9>;
/**
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
race<T1, T2, T3, T4, T5, T6, T7, T8>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>]): Promise<T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8>;
/**
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
race<T1, T2, T3, T4, T5, T6, T7>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>]): Promise<T1 | T2 | T3 | T4 | T5 | T6 | T7>;
/**
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
race<T1, T2, T3, T4, T5, T6>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>]): Promise<T1 | T2 | T3 | T4 | T5 | T6>;
/**
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
race<T1, T2, T3, T4, T5>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>]): Promise<T1 | T2 | T3 | T4 | T5>;
/**
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
race<T1, T2, T3, T4>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>]): Promise<T1 | T2 | T3 | T4>;
/**
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
race<T1, T2, T3>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]): Promise<T1 | T2 | T3>;
/**
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
race<T1, T2>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<T1 | T2>;
/**
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new Promise.
*/
race<T>(values: (T | PromiseLike<T>)[]): Promise<T>;
race<T>(values: Iterable<T>): Promise<T extends PromiseLike<infer U> ? U : T>;
/**
* Creates a new rejected promise for the provided reason.
+1
View File
@@ -1,4 +1,5 @@
/// <reference lib="es2018" />
/// <reference lib="es2019.array" />
/// <reference lib="es2019.object" />
/// <reference lib="es2019.string" />
/// <reference lib="es2019.symbol" />
+15
View File
@@ -0,0 +1,15 @@
/// <reference lib="es2015.iterable" />
interface ObjectConstructor {
/**
* Returns an object created by key-value entries for properties and methods
* @param entries An iterable object that contains key-value entries for properties and methods.
*/
fromEntries<T = any>(entries: Iterable<readonly [PropertyKey, T]>): { [k in PropertyKey]: T };
/**
* Returns an object created by key-value entries for properties and methods
* @param entries An iterable object that contains key-value entries for properties and methods.
*/
fromEntries(entries: Iterable<readonly any[]>): any;
}
+5 -5
View File
@@ -60,7 +60,7 @@ declare function encodeURI(uri: string): string;
* Encodes a text string as a valid component of a Uniform Resource Identifier (URI).
* @param uriComponent A value representing an encoded URI component.
*/
declare function encodeURIComponent(uriComponent: string): string;
declare function encodeURIComponent(uriComponent: string | number | boolean): string;
/**
* Computes a new string in which certain characters have been replaced by a hexadecimal escape sequence.
@@ -513,7 +513,7 @@ interface Boolean {
interface BooleanConstructor {
new(value?: any): Boolean;
(value?: any): boolean;
<T>(value?: T): value is Exclude<T, false | null | undefined | '' | 0>;
readonly prototype: Boolean;
}
@@ -1273,13 +1273,13 @@ interface Array<T> {
* @param callbackfn A function that accepts up to three arguments. The every method calls the callbackfn function for each element in array1 until the callbackfn returns false, or until the end of the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean;
every(callbackfn: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
/**
* Determines whether the specified callback function returns true for any element of an array.
* @param callbackfn A function that accepts up to three arguments. The some method calls the callbackfn function for each element in array1 until the callbackfn returns true, or until the end of the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean;
some(callbackfn: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
/**
* Performs the specified action for each element in an array.
* @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.
@@ -1303,7 +1303,7 @@ interface Array<T> {
* @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[];
filter(callbackfn: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
/**
* Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
+1
View File
@@ -36,6 +36,7 @@
"es2018.promise",
"es2018.intl",
"es2019.array",
"es2019.object",
"es2019.string",
"es2019.symbol",
"es2020.string",
+1 -1
View File
@@ -134,7 +134,7 @@ namespace ts.JsDoc {
case SyntaxKind.JSDocTemplateTag:
return withList((tag as JSDocTemplateTag).typeParameters);
case SyntaxKind.JSDocTypeTag:
return withNode((tag as JSDocTypeTag).typeExpression!);
return withNode((tag as JSDocTypeTag).typeExpression);
case SyntaxKind.JSDocTypedefTag:
case SyntaxKind.JSDocCallbackTag:
case SyntaxKind.JSDocPropertyTag:
@@ -57,7 +57,7 @@ namespace ts {
assertParseResult(["--lib", "es5,invalidOption", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.string', 'es2019.symbol', 'es2020.string', 'es2020.symbol.wellknown', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.object', 'es2019.string', 'es2019.symbol', 'es2020.string', 'es2020.symbol.wellknown', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint'.",
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
file: undefined,
@@ -259,7 +259,7 @@ namespace ts {
assertParseResult(["--lib", "es5,", "es7", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.string', 'es2019.symbol', 'es2020.string', 'es2020.symbol.wellknown', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.object', 'es2019.string', 'es2019.symbol', 'es2020.string', 'es2020.symbol.wellknown', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint'.",
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
file: undefined,
@@ -278,7 +278,7 @@ namespace ts {
assertParseResult(["--lib", "es5, ", "es7", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.string', 'es2019.symbol', 'es2020.string', 'es2020.symbol.wellknown', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.object', 'es2019.string', 'es2019.symbol', 'es2020.string', 'es2020.symbol.wellknown', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint'.",
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
file: undefined,
+1 -1
View File
@@ -62,7 +62,7 @@ namespace ts {
}
}
const libContent = `${TestFSWithWatch.libFile.content}
export const libContent = `${TestFSWithWatch.libFile.content}
interface ReadonlyArray<T> {}
declare const console: { log(msg: any): void; };`;
+51 -3
View File
@@ -279,7 +279,6 @@ namespace ts {
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/logic/tsconfig.json", "src/logic/index.ts", "src/logic/index.js"],
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/tests/tsconfig.json", "src/tests/index.js", "src/tests/tsconfig.json"],
[Diagnostics.Building_project_0, "/src/tests/tsconfig.json"],
[Diagnostics.Updating_unchanged_output_timestamps_of_project_0, "/src/tests/tsconfig.json"]
);
});
@@ -309,8 +308,7 @@ namespace ts {
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/core/tsconfig.json", "src/core/anotherModule.ts", "src/core/anotherModule.js"],
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/logic/tsconfig.json", "src/logic/index.ts", "src/logic/index.js"],
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/tests/tsconfig.json", "src/tests/index.js", "src/tests/tsconfig.base.json"],
[Diagnostics.Building_project_0, "/src/tests/tsconfig.json"],
[Diagnostics.Updating_unchanged_output_timestamps_of_project_0, "/src/tests/tsconfig.json"]
[Diagnostics.Building_project_0, "/src/tests/tsconfig.json"]
);
});
});
@@ -761,6 +759,56 @@ class someClass { }`),
baselineOnly: true,
verifyDiagnostics: true
});
verifyTsbuildOutput({
scenario: "when target option changes",
projFs: () => projFs,
time,
tick,
proj: "sample1",
rootNames: ["/src/core"],
expectedMapFileNames: emptyArray,
lastProjectOutputJs: "/src/core/index.js",
initialBuild: {
modifyFs: fs => {
fs.writeFileSync("/lib/lib.esnext.full.d.ts", `/// <reference no-default-lib="true"/>
/// <reference lib="esnext" />`);
fs.writeFileSync("/lib/lib.esnext.d.ts", libContent);
fs.writeFileSync("/lib/lib.d.ts", `/// <reference no-default-lib="true"/>
/// <reference lib="esnext" />`);
fs.writeFileSync("/src/core/tsconfig.json", `{
"compilerOptions": {
"incremental": true,
"listFiles": true,
"listEmittedFiles": true,
"target": "esnext",
}
}`);
},
expectedDiagnostics: [
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json"),
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"],
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"],
]
},
incrementalDtsChangedBuild: {
modifyFs: fs => replaceText(fs, "/src/core/tsconfig.json", "esnext", "es5"),
expectedDiagnostics: [
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json"),
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/core/tsconfig.json", "src/core/anotherModule.js", "src/core/tsconfig.json"],
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"]
]
},
outputFiles: [
"/src/core/anotherModule.js",
"/src/core/anotherModule.d.ts",
"/src/core/index.js",
"/src/core/index.d.ts",
"/src/core/tsconfig.tsbuildinfo",
],
baselineOnly: true,
verifyDiagnostics: true
});
});
});
}