Merge branch 'master' into incrementalBuildInfo

This commit is contained in:
Sheetal Nandi
2019-02-20 10:37:44 -08:00
47 changed files with 1811 additions and 311 deletions
+143 -114
View File
@@ -390,10 +390,10 @@ namespace ts {
const wildcardType = createIntrinsicType(TypeFlags.Any, "any");
const errorType = createIntrinsicType(TypeFlags.Any, "error");
const unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown");
const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined");
const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsWideningType, "undefined");
const nullType = createIntrinsicType(TypeFlags.Null, "null");
const nullWideningType = strictNullChecks ? nullType : createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsWideningType, "null");
const undefinedType = createNullableType(TypeFlags.Undefined, "undefined", 0);
const undefinedWideningType = strictNullChecks ? undefinedType : createNullableType(TypeFlags.Undefined, "undefined", ObjectFlags.ContainsWideningType);
const nullType = createNullableType(TypeFlags.Null, "null", 0);
const nullWideningType = strictNullChecks ? nullType : createNullableType(TypeFlags.Null, "null", ObjectFlags.ContainsWideningType);
const stringType = createIntrinsicType(TypeFlags.String, "string");
const numberType = createIntrinsicType(TypeFlags.Number, "number");
const bigintType = createIntrinsicType(TypeFlags.BigInt, "bigint");
@@ -439,7 +439,7 @@ namespace ts {
const anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
// The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated
// in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes.
anyFunctionType.flags |= TypeFlags.ContainsAnyFunctionType;
anyFunctionType.objectFlags |= ObjectFlags.ContainsAnyFunctionType;
const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
const circularConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
@@ -1518,7 +1518,8 @@ namespace ts {
!checkAndReportErrorForExtendingInterface(errorLocation) &&
!checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) &&
!checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) &&
!checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning)) {
!checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) &&
!checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning)) {
let suggestion: Symbol | undefined;
if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) {
suggestion = getSuggestedSymbolForNonexistentSymbol(originalLocation, name, meaning);
@@ -1708,6 +1709,17 @@ namespace ts {
return false;
}
function checkAndReportErrorForUsingValueAsType(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean {
if (meaning & (SymbolFlags.Type & ~SymbolFlags.Namespace)) {
const symbol = resolveSymbol(resolveName(errorLocation, name, ~SymbolFlags.Type & SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false));
if (symbol && !(symbol.flags & SymbolFlags.Namespace)) {
error(errorLocation, Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here, unescapeLeadingUnderscores(name));
return true;
}
}
return false;
}
function checkAndReportErrorForUsingTypeAsValue(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean {
if (meaning & (SymbolFlags.Value & ~SymbolFlags.NamespaceModule)) {
if (name === "any" || name === "string" || name === "number" || name === "boolean" || name === "never") {
@@ -2741,6 +2753,12 @@ namespace ts {
return type;
}
function createNullableType(kind: TypeFlags, intrinsicName: string, objectFlags: ObjectFlags): NullableType {
const type = createIntrinsicType(kind, intrinsicName);
type.objectFlags = objectFlags;
return type;
}
function createBooleanType(trueFalseTypes: ReadonlyArray<Type>): IntrinsicType & UnionType {
const type = <IntrinsicType & UnionType>getUnionType(trueFalseTypes);
type.flags |= TypeFlags.Boolean;
@@ -5128,7 +5146,7 @@ namespace ts {
definedInConstructor = true;
}
}
const sourceTypes = some(constructorTypes, t => !!(t.flags & ~(TypeFlags.Nullable | TypeFlags.ContainsWideningType))) ? constructorTypes : types; // TODO: GH#18217
const sourceTypes = some(constructorTypes, t => !!(t.flags & ~TypeFlags.Nullable)) ? constructorTypes : types; // TODO: GH#18217
type = getUnionType(sourceTypes!, UnionReduction.Subtype);
}
const widened = getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor));
@@ -5293,7 +5311,7 @@ namespace ts {
function getTypeFromObjectBindingPattern(pattern: ObjectBindingPattern, includePatternInType: boolean, reportErrors: boolean): Type {
const members = createSymbolTable();
let stringIndexInfo: IndexInfo | undefined;
let objectFlags = ObjectFlags.ObjectLiteral;
let objectFlags = ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral;
forEach(pattern.elements, e => {
const name = e.propertyName || <Identifier>e.name;
if (e.dotDotDotToken) {
@@ -5315,7 +5333,6 @@ namespace ts {
members.set(symbol.escapedName, symbol);
});
const result = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, undefined);
result.flags |= TypeFlags.ContainsObjectLiteral;
result.objectFlags |= objectFlags;
if (includePatternInType) {
result.pattern = pattern;
@@ -5408,7 +5425,16 @@ namespace ts {
function getTypeOfVariableOrParameterOrProperty(symbol: Symbol): Type {
const links = getSymbolLinks(symbol);
return links.type || (links.type = getTypeOfVariableOrParameterOrPropertyWorker(symbol));
if (!links.type) {
const type = getTypeOfVariableOrParameterOrPropertyWorker(symbol);
// For a contextually typed parameter it is possible that a type has already
// been assigned (in assignTypeToParameterAndFixTypeParameters), and we want
// to preserve this type.
if (!links.type) {
links.type = type;
}
}
return links.type;
}
function getTypeOfVariableOrParameterOrPropertyWorker(symbol: Symbol) {
@@ -5452,7 +5478,7 @@ namespace ts {
if (symbol.flags & SymbolFlags.ValueModule) {
return getTypeOfFuncClassEnumModule(symbol);
}
return errorType;
return reportCircularityError(symbol);
}
let type: Type | undefined;
if (isInJSFile(declaration) &&
@@ -5511,7 +5537,7 @@ namespace ts {
if (symbol.flags & SymbolFlags.ValueModule) {
return getTypeOfFuncClassEnumModule(symbol);
}
type = reportCircularityError(symbol);
return reportCircularityError(symbol);
}
return type;
}
@@ -8540,14 +8566,14 @@ namespace ts {
// It is only necessary to do so if a constituent type might be the undefined type, the null type, the type
// of an object literal or the anyFunctionType. This is because there are operations in the type checker
// that care about the presence of such types at arbitrary depth in a containing type.
function getPropagatingFlagsOfTypes(types: ReadonlyArray<Type>, excludeKinds: TypeFlags): TypeFlags {
let result: TypeFlags = 0;
function getPropagatingFlagsOfTypes(types: ReadonlyArray<Type>, excludeKinds: TypeFlags): ObjectFlags {
let result: ObjectFlags = 0;
for (const type of types) {
if (!(type.flags & excludeKinds)) {
result |= type.flags;
result |= getObjectFlags(type);
}
}
return result & TypeFlags.PropagatingFlags;
return result & ObjectFlags.PropagatingFlags;
}
function createTypeReference(target: GenericType, typeArguments: ReadonlyArray<Type> | undefined): TypeReference {
@@ -8556,7 +8582,7 @@ namespace ts {
if (!type) {
type = <TypeReference>createObjectType(ObjectFlags.Reference, target.symbol);
target.instantiations.set(id, type);
type.flags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0;
type.objectFlags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0;
type.target = target;
type.typeArguments = typeArguments;
}
@@ -9235,10 +9261,11 @@ namespace ts {
// intersections of unit types into 'never' upon construction, but deferring the reduction makes it
// easier to reason about their origin.
if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(<IntersectionType>type))) {
includes |= flags & ~TypeFlags.ConstructionFlags;
if (type === wildcardType) includes |= TypeFlags.Wildcard;
includes |= flags & TypeFlags.IncludesMask;
if (flags & TypeFlags.StructuredOrInstantiable) includes |= TypeFlags.IncludesStructuredOrInstantiable;
if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
if (!strictNullChecks && flags & TypeFlags.Nullable) {
if (!(flags & TypeFlags.ContainsWideningType)) includes |= TypeFlags.NonWideningType;
if (!(getObjectFlags(type) & ObjectFlags.ContainsWideningType)) includes |= TypeFlags.IncludesNonWideningType;
}
else {
const len = typeSet.length;
@@ -9349,27 +9376,27 @@ namespace ts {
const includes = addTypesToUnion(typeSet, 0, types);
if (unionReduction !== UnionReduction.None) {
if (includes & TypeFlags.AnyOrUnknown) {
return includes & TypeFlags.Any ? includes & TypeFlags.Wildcard ? wildcardType : anyType : unknownType;
return includes & TypeFlags.Any ? includes & TypeFlags.IncludesWildcard ? wildcardType : anyType : unknownType;
}
switch (unionReduction) {
case UnionReduction.Literal:
if (includes & TypeFlags.StringOrNumberLiteralOrUnique | TypeFlags.BooleanLiteral) {
if (includes & (TypeFlags.Literal | TypeFlags.UniqueESSymbol)) {
removeRedundantLiteralTypes(typeSet, includes);
}
break;
case UnionReduction.Subtype:
if (!removeSubtypes(typeSet, !(includes & TypeFlags.StructuredOrInstantiable))) {
if (!removeSubtypes(typeSet, !(includes & TypeFlags.IncludesStructuredOrInstantiable))) {
return errorType;
}
break;
}
if (typeSet.length === 0) {
return includes & TypeFlags.Null ? includes & TypeFlags.NonWideningType ? nullType : nullWideningType :
includes & TypeFlags.Undefined ? includes & TypeFlags.NonWideningType ? undefinedType : undefinedWideningType :
return includes & TypeFlags.Null ? includes & TypeFlags.IncludesNonWideningType ? nullType : nullWideningType :
includes & TypeFlags.Undefined ? includes & TypeFlags.IncludesNonWideningType ? undefinedType : undefinedWideningType :
neverType;
}
}
return getUnionTypeFromSortedList(typeSet, !(includes & TypeFlags.NotPrimitiveUnion), aliasSymbol, aliasTypeArguments);
return getUnionTypeFromSortedList(typeSet, includes & TypeFlags.NotPrimitiveUnion ? 0 : ObjectFlags.PrimitiveUnion, aliasSymbol, aliasTypeArguments);
}
function getUnionTypePredicate(signatures: ReadonlyArray<Signature>): TypePredicate | undefined {
@@ -9409,7 +9436,7 @@ namespace ts {
}
// This function assumes the constituent type list is sorted and deduplicated.
function getUnionTypeFromSortedList(types: Type[], primitiveTypesOnly: boolean, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray<Type>): Type {
function getUnionTypeFromSortedList(types: Type[], objectFlags: ObjectFlags, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray<Type>): Type {
if (types.length === 0) {
return neverType;
}
@@ -9419,11 +9446,10 @@ namespace ts {
const id = getTypeListId(types);
let type = unionTypes.get(id);
if (!type) {
const propagatedFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable);
type = <UnionType>createType(TypeFlags.Union | propagatedFlags);
type = <UnionType>createType(TypeFlags.Union);
unionTypes.set(id, type);
type.objectFlags = objectFlags | getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable);
type.types = types;
type.primitiveTypesOnly = primitiveTypesOnly;
/*
Note: This is the alias symbol (or lack thereof) that we see when we first encounter this union type.
For aliases of identical unions, eg `type T = A | B; type U = A | B`, the symbol of the first alias encountered is the aliasSymbol.
@@ -9452,15 +9478,15 @@ namespace ts {
return addTypesToIntersection(typeSet, includes, (<IntersectionType>type).types);
}
if (isEmptyAnonymousObjectType(type)) {
if (!(includes & TypeFlags.EmptyObject)) {
includes |= TypeFlags.EmptyObject;
if (!(includes & TypeFlags.IncludesEmptyObject)) {
includes |= TypeFlags.IncludesEmptyObject;
typeSet.push(type);
}
}
else {
includes |= flags & ~TypeFlags.ConstructionFlags;
includes |= flags & TypeFlags.IncludesMask;
if (flags & TypeFlags.AnyOrUnknown) {
if (type === wildcardType) includes |= TypeFlags.Wildcard;
if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
}
else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type)) {
typeSet.push(type);
@@ -9518,7 +9544,7 @@ namespace ts {
// other unions and return true. Otherwise, do nothing and return false.
function intersectUnionsOfPrimitiveTypes(types: Type[]) {
let unionTypes: UnionType[] | undefined;
const index = findIndex(types, t => !!(t.flags & TypeFlags.Union) && (<UnionType>t).primitiveTypesOnly);
const index = findIndex(types, t => !!(getObjectFlags(t) & ObjectFlags.PrimitiveUnion));
if (index < 0) {
return false;
}
@@ -9527,7 +9553,7 @@ namespace ts {
// the unionTypes array.
while (i < types.length) {
const t = types[i];
if (t.flags & TypeFlags.Union && (<UnionType>t).primitiveTypesOnly) {
if (getObjectFlags(t) & ObjectFlags.PrimitiveUnion) {
(unionTypes || (unionTypes = [<UnionType>types[index]])).push(<UnionType>t);
orderedRemoveItemAt(types, i);
}
@@ -9554,7 +9580,7 @@ namespace ts {
}
}
// Finally replace the first union with the result
types[index] = getUnionTypeFromSortedList(result, /*primitiveTypesOnly*/ true);
types[index] = getUnionTypeFromSortedList(result, ObjectFlags.PrimitiveUnion);
return true;
}
@@ -9575,7 +9601,7 @@ namespace ts {
return neverType;
}
if (includes & TypeFlags.Any) {
return includes & TypeFlags.Wildcard ? wildcardType : anyType;
return includes & TypeFlags.IncludesWildcard ? wildcardType : anyType;
}
if (!strictNullChecks && includes & TypeFlags.Nullable) {
return includes & TypeFlags.Undefined ? undefinedType : nullType;
@@ -9586,7 +9612,7 @@ namespace ts {
includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol) {
removeRedundantPrimitiveTypes(typeSet, includes);
}
if (includes & TypeFlags.EmptyObject && includes & TypeFlags.Object) {
if (includes & TypeFlags.IncludesEmptyObject && includes & TypeFlags.Object) {
orderedRemoveItemAt(typeSet, findIndex(typeSet, isEmptyAnonymousObjectType));
}
if (typeSet.length === 0) {
@@ -9612,9 +9638,9 @@ namespace ts {
const id = getTypeListId(typeSet);
let type = intersectionTypes.get(id);
if (!type) {
const propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Nullable);
type = <IntersectionType>createType(TypeFlags.Intersection | propagatedFlags);
type = <IntersectionType>createType(TypeFlags.Intersection);
intersectionTypes.set(id, type);
type.objectFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Nullable);
type.types = typeSet;
type.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`.
type.aliasTypeArguments = aliasTypeArguments;
@@ -10273,7 +10299,7 @@ namespace ts {
* this function should be called in a left folding style, with left = previous result of getSpreadType
* and right = the new element to be spread.
*/
function getSpreadType(left: Type, right: Type, symbol: Symbol | undefined, typeFlags: TypeFlags, objectFlags: ObjectFlags, readonly: boolean): Type {
function getSpreadType(left: Type, right: Type, symbol: Symbol | undefined, objectFlags: ObjectFlags, readonly: boolean): Type {
if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) {
return anyType;
}
@@ -10287,10 +10313,10 @@ namespace ts {
return left;
}
if (left.flags & TypeFlags.Union) {
return mapType(left, t => getSpreadType(t, right, symbol, typeFlags, objectFlags, readonly));
return mapType(left, t => getSpreadType(t, right, symbol, objectFlags, readonly));
}
if (right.flags & TypeFlags.Union) {
return mapType(right, t => getSpreadType(left, t, symbol, typeFlags, objectFlags, readonly));
return mapType(right, t => getSpreadType(left, t, symbol, objectFlags, readonly));
}
if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index)) {
return left;
@@ -10307,7 +10333,7 @@ namespace ts {
const types = (<IntersectionType>left).types;
const lastLeft = types[types.length - 1];
if (isNonGenericObjectType(lastLeft) && isNonGenericObjectType(right)) {
return getIntersectionType(concatenate(types.slice(0, types.length - 1), [getSpreadType(lastLeft, right, symbol, typeFlags, objectFlags, readonly)]));
return getIntersectionType(concatenate(types.slice(0, types.length - 1), [getSpreadType(lastLeft, right, symbol, objectFlags, readonly)]));
}
}
return getIntersectionType([left, right]);
@@ -10367,8 +10393,7 @@ namespace ts {
emptyArray,
getIndexInfoWithReadonly(stringIndexInfo, readonly),
getIndexInfoWithReadonly(numberIndexInfo, readonly));
spread.flags |= TypeFlags.ContainsObjectLiteral | typeFlags;
spread.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsSpread | objectFlags;
spread.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral | ObjectFlags.ContainsSpread | objectFlags;
return spread;
}
@@ -12570,6 +12595,7 @@ namespace ts {
let result: Ternary;
let originalErrorInfo: DiagnosticMessageChain | undefined;
let varianceCheckFailed = false;
const saveErrorInfo = errorInfo;
// We limit alias variance probing to only object and conditional types since their alias behavior
@@ -12579,11 +12605,10 @@ namespace ts {
source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol &&
!(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) {
const variances = getAliasVariances(source.aliasSymbol);
if (result = typeArgumentsRelatedTo(source.aliasTypeArguments, target.aliasTypeArguments, variances, reportErrors)) {
return result;
const varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances);
if (varianceResult !== undefined) {
return varianceResult;
}
originalErrorInfo = errorInfo;
errorInfo = saveErrorInfo;
}
if (target.flags & TypeFlags.TypeParameter) {
@@ -12748,31 +12773,9 @@ namespace ts {
// type references (which are intended by be compared structurally). Obtain the variance
// information for the type parameters and relate the type arguments accordingly.
const variances = getVariances((<TypeReference>source).target);
if (result = typeArgumentsRelatedTo((<TypeReference>source).typeArguments, (<TypeReference>target).typeArguments, variances, reportErrors)) {
return result;
}
// The type arguments did not relate appropriately, but it may be because we have no variance
// information (in which case typeArgumentsRelatedTo defaulted to covariance for all type
// arguments). It might also be the case that the target type has a 'void' type argument for
// a covariant type parameter that is only used in return positions within the generic type
// (in which case any type argument is permitted on the source side). In those cases we proceed
// with a structural comparison. Otherwise, we know for certain the instantiations aren't
// related and we can return here.
if (variances !== emptyArray && !hasCovariantVoidArgument(<TypeReference>target, variances)) {
// In some cases generic types that are covariant in regular type checking mode become
// invariant in --strictFunctionTypes mode because one or more type parameters are used in
// both co- and contravariant positions. In order to make it easier to diagnose *why* such
// types are invariant, if any of the type parameters are invariant we reset the reported
// errors and instead force a structural comparison (which will include elaborations that
// reveal the reason).
if (!(reportErrors && some(variances, v => v === Variance.Invariant))) {
return Ternary.False;
}
// We remember the original error information so we can restore it in case the structural
// comparison unexpectedly succeeds. This can happen when the structural comparison result
// is a Ternary.Maybe for example caused by the recursion depth limiter.
originalErrorInfo = errorInfo;
errorInfo = saveErrorInfo;
const varianceResult = relateVariances((<TypeReference>source).typeArguments, (<TypeReference>target).typeArguments, variances);
if (varianceResult !== undefined) {
return varianceResult;
}
}
else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) {
@@ -12799,16 +12802,48 @@ namespace ts {
}
}
}
if (result) {
if (!originalErrorInfo) {
errorInfo = saveErrorInfo;
return result;
}
errorInfo = originalErrorInfo;
if (varianceCheckFailed && result) {
errorInfo = originalErrorInfo || errorInfo || saveErrorInfo; // Use variance error (there is no structural one) and return false
}
else if (result) {
return result;
}
}
}
return Ternary.False;
function relateVariances(sourceTypeArguments: ReadonlyArray<Type> | undefined, targetTypeArguments: ReadonlyArray<Type> | undefined, variances: Variance[]) {
if (result = typeArgumentsRelatedTo(sourceTypeArguments, targetTypeArguments, variances, reportErrors)) {
return result;
}
const isCovariantVoid = targetTypeArguments && hasCovariantVoidArgument(targetTypeArguments, variances);
varianceCheckFailed = !isCovariantVoid;
// The type arguments did not relate appropriately, but it may be because we have no variance
// information (in which case typeArgumentsRelatedTo defaulted to covariance for all type
// arguments). It might also be the case that the target type has a 'void' type argument for
// a covariant type parameter that is only used in return positions within the generic type
// (in which case any type argument is permitted on the source side). In those cases we proceed
// with a structural comparison. Otherwise, we know for certain the instantiations aren't
// related and we can return here.
if (variances !== emptyArray && !isCovariantVoid) {
// In some cases generic types that are covariant in regular type checking mode become
// invariant in --strictFunctionTypes mode because one or more type parameters are used in
// both co- and contravariant positions. In order to make it easier to diagnose *why* such
// types are invariant, if any of the type parameters are invariant we reset the reported
// errors and instead force a structural comparison (which will include elaborations that
// reveal the reason).
// We can switch on `reportErrors` here, since varianceCheckFailed guarantees we return `False`,
// we can return `False` early here to skip calculating the structural error message we don't need.
if (varianceCheckFailed && !(reportErrors && some(variances, v => v === Variance.Invariant))) {
return Ternary.False;
}
// We remember the original error information so we can restore it in case the structural
// comparison unexpectedly succeeds. This can happen when the structural comparison result
// is a Ternary.Maybe for example caused by the recursion depth limiter.
originalErrorInfo = errorInfo;
errorInfo = saveErrorInfo;
}
}
}
// A type [P in S]: X is related to a type [Q in T]: Y if T is related to S and X' is
@@ -13317,7 +13352,7 @@ namespace ts {
function getVariances(type: GenericType): Variance[] {
// Arrays and tuples are known to be covariant, no need to spend time computing this (emptyArray implies covariance for all parameters)
if (!strictFunctionTypes || type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ObjectFlags.Tuple) {
if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ObjectFlags.Tuple) {
return emptyArray;
}
return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference);
@@ -13325,9 +13360,9 @@ namespace ts {
// Return true if the given type reference has a 'void' type argument for a covariant type parameter.
// See comment at call in recursiveTypeRelatedTo for when this case matters.
function hasCovariantVoidArgument(type: TypeReference, variances: Variance[]): boolean {
function hasCovariantVoidArgument(typeArguments: ReadonlyArray<Type>, variances: Variance[]): boolean {
for (let i = 0; i < variances.length; i++) {
if (variances[i] === Variance.Covariant && type.typeArguments![i].flags & TypeFlags.Void) {
if (variances[i] === Variance.Covariant && typeArguments[i].flags & TypeFlags.Void) {
return true;
}
}
@@ -13853,7 +13888,7 @@ namespace ts {
resolved.stringIndexInfo,
resolved.numberIndexInfo);
regularNew.flags = resolved.flags;
regularNew.objectFlags |= ObjectFlags.ObjectLiteral | (getObjectFlags(resolved) & ObjectFlags.JSLiteral);
regularNew.objectFlags |= resolved.objectFlags & ~ObjectFlags.FreshLiteral;
(<FreshObjectLiteralType>type).regularType = regularNew;
return regularNew;
}
@@ -13944,7 +13979,7 @@ namespace ts {
}
function getWidenedTypeWithContext(type: Type, context: WideningContext | undefined): Type {
if (type.flags & TypeFlags.RequiresWidening) {
if (getObjectFlags(type) & ObjectFlags.RequiresWidening) {
if (type.flags & TypeFlags.Nullable) {
return anyType;
}
@@ -13982,7 +14017,7 @@ namespace ts {
*/
function reportWideningErrorsInType(type: Type): boolean {
let errorReported = false;
if (type.flags & TypeFlags.ContainsWideningType) {
if (getObjectFlags(type) & ObjectFlags.ContainsWideningType) {
if (type.flags & TypeFlags.Union) {
if (some((<UnionType>type).types, isEmptyObjectType)) {
errorReported = true;
@@ -14005,7 +14040,7 @@ namespace ts {
if (isObjectLiteralType(type)) {
for (const p of getPropertiesOfObjectType(type)) {
const t = getTypeOfSymbol(p);
if (t.flags & TypeFlags.ContainsWideningType) {
if (getObjectFlags(t) & ObjectFlags.ContainsWideningType) {
if (!reportWideningErrorsInType(t)) {
error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolToString(p), typeToString(getWidenedType(t)));
}
@@ -14080,7 +14115,7 @@ namespace ts {
}
function reportErrorsFromWidening(declaration: Declaration, type: Type) {
if (produceDiagnostics && noImplicitAny && type.flags & TypeFlags.ContainsWideningType) {
if (produceDiagnostics && noImplicitAny && getObjectFlags(type) & ObjectFlags.ContainsWideningType) {
// Report implicit any error within type if possible, otherwise report error on declaration
if (!reportWideningErrorsInType(type)) {
reportImplicitAny(declaration, type);
@@ -14225,7 +14260,7 @@ namespace ts {
// If any property contains context sensitive functions that have been skipped, the source type
// is incomplete and we can't infer a meaningful input type.
for (const prop of properties) {
if (getTypeOfSymbol(prop).flags & TypeFlags.ContainsAnyFunctionType) {
if (getObjectFlags(getTypeOfSymbol(prop)) & ObjectFlags.ContainsAnyFunctionType) {
return undefined;
}
}
@@ -14383,7 +14418,7 @@ namespace ts {
// not contain anyFunctionType when we come back to this argument for its second round
// of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard
// when constructing types from type parameters that had no inference candidates).
if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType || (priority & InferencePriority.ReturnType && (source === autoType || source === autoArrayType))) {
if (getObjectFlags(source) & ObjectFlags.ContainsAnyFunctionType || source === silentNeverType || (priority & InferencePriority.ReturnType && (source === autoType || source === autoArrayType))) {
return;
}
const inference = getInferenceInfoForType(target);
@@ -14686,7 +14721,7 @@ namespace ts {
const sourceLen = sourceSignatures.length;
const targetLen = targetSignatures.length;
const len = sourceLen < targetLen ? sourceLen : targetLen;
const skipParameters = !!(source.flags & TypeFlags.ContainsAnyFunctionType);
const skipParameters = !!(getObjectFlags(source) & ObjectFlags.ContainsAnyFunctionType);
for (let i = 0; i < len; i++) {
inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getBaseSignature(targetSignatures[targetLen - len + i]), skipParameters);
}
@@ -15444,7 +15479,7 @@ namespace ts {
if (type.flags & TypeFlags.Union) {
const types = (<UnionType>type).types;
const filtered = filter(types, f);
return filtered === types ? type : getUnionTypeFromSortedList(filtered, (<UnionType>type).primitiveTypesOnly);
return filtered === types ? type : getUnionTypeFromSortedList(filtered, (<UnionType>type).objectFlags);
}
return f(type) ? type : neverType;
}
@@ -18350,7 +18385,6 @@ namespace ts {
let propertiesTable: SymbolTable;
let propertiesArray: Symbol[] = [];
let spread: Type = emptyObjectType;
let propagatedFlags: TypeFlags = 0;
const contextualType = getApparentTypeOfContextualType(node);
const contextualTypeHasPattern = contextualType && contextualType.pattern &&
@@ -18360,7 +18394,7 @@ namespace ts {
const isInJavascript = isInJSFile(node) && !isInJsonFile(node);
const enumTag = getJSDocEnumTag(node);
const isJSObjectLiteral = !contextualType && isInJavascript && !enumTag;
let typeFlags: TypeFlags = 0;
let objectFlags: ObjectFlags = freshObjectLiteralFlag;
let patternWithComputedProperties = false;
let hasComputedStringProperty = false;
let hasComputedNumberProperty = false;
@@ -18388,7 +18422,7 @@ namespace ts {
checkTypeAssignableTo(type, getTypeFromTypeNode(enumTag.typeExpression), memberDecl);
}
}
typeFlags |= type.flags;
objectFlags |= getObjectFlags(type) & ObjectFlags.PropagatingFlags;
const nameType = computedNameType && isTypeUsableAsPropertyName(computedNameType) ? computedNameType : undefined;
const prop = nameType ?
createSymbol(SymbolFlags.Property | member.flags, getPropertyNameFromType(nameType), checkFlags | CheckFlags.Late) :
@@ -18436,19 +18470,18 @@ namespace ts {
checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign);
}
if (propertiesArray.length > 0) {
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags, ObjectFlags.FreshLiteral, inConstContext);
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext);
propertiesArray = [];
propertiesTable = createSymbolTable();
hasComputedStringProperty = false;
hasComputedNumberProperty = false;
typeFlags = 0;
}
const type = checkExpression(memberDecl.expression);
if (!isValidSpreadType(type)) {
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
return errorType;
}
spread = getSpreadType(spread, type, node.symbol, propagatedFlags, ObjectFlags.FreshLiteral, inConstContext);
spread = getSpreadType(spread, type, node.symbol, objectFlags, inConstContext);
offset = i + 1;
continue;
}
@@ -18498,7 +18531,7 @@ namespace ts {
if (spread !== emptyObjectType) {
if (propertiesArray.length > 0) {
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags, ObjectFlags.FreshLiteral, inConstContext);
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext);
}
return spread;
}
@@ -18509,8 +18542,7 @@ namespace ts {
const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, IndexKind.String) : undefined;
const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, IndexKind.Number) : undefined;
const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
result.flags |= TypeFlags.ContainsObjectLiteral | typeFlags & TypeFlags.PropagatingFlags;
result.objectFlags |= ObjectFlags.ObjectLiteral | freshObjectLiteralFlag;
result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral;
if (isJSObjectLiteral) {
result.objectFlags |= ObjectFlags.JSLiteral;
}
@@ -18520,7 +18552,6 @@ namespace ts {
if (inDestructuringPattern) {
result.pattern = node;
}
propagatedFlags |= result.flags & TypeFlags.PropagatingFlags;
return result;
}
}
@@ -18611,7 +18642,6 @@ namespace ts {
let hasSpreadAnyType = false;
let typeToIntersect: Type | undefined;
let explicitlySpecifyChildrenAttribute = false;
let typeFlags: TypeFlags = 0;
let objectFlags: ObjectFlags = ObjectFlags.JsxAttributes;
const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(openingLikeElement));
@@ -18619,7 +18649,7 @@ namespace ts {
const member = attributeDecl.symbol;
if (isJsxAttribute(attributeDecl)) {
const exprType = checkJsxAttribute(attributeDecl, checkMode);
typeFlags |= exprType.flags & TypeFlags.PropagatingFlags;
objectFlags |= getObjectFlags(exprType) & ObjectFlags.PropagatingFlags;
const attributeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.escapedName);
attributeSymbol.declarations = member.declarations;
@@ -18637,7 +18667,7 @@ namespace ts {
else {
Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute);
if (attributesTable.size > 0) {
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, typeFlags, objectFlags, /*readonly*/ false);
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false);
attributesTable = createSymbolTable();
}
const exprType = checkExpressionCached(attributeDecl.expression, checkMode);
@@ -18645,7 +18675,7 @@ namespace ts {
hasSpreadAnyType = true;
}
if (isValidSpreadType(exprType)) {
spread = getSpreadType(spread, exprType, attributes.symbol, typeFlags, objectFlags, /*readonly*/ false);
spread = getSpreadType(spread, exprType, attributes.symbol, objectFlags, /*readonly*/ false);
}
else {
typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
@@ -18655,7 +18685,7 @@ namespace ts {
if (!hasSpreadAnyType) {
if (attributesTable.size > 0) {
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, typeFlags, objectFlags, /*readonly*/ false);
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false);
}
}
@@ -18687,7 +18717,7 @@ namespace ts {
const childPropMap = createSymbolTable();
childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol);
spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined),
attributes.symbol, typeFlags, objectFlags, /*readonly*/ false);
attributes.symbol, objectFlags, /*readonly*/ false);
}
}
@@ -18708,8 +18738,7 @@ namespace ts {
function createJsxAttributesType() {
objectFlags |= freshObjectLiteralFlag;
const result = createAnonymousType(attributes.symbol, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
result.flags |= TypeFlags.ContainsObjectLiteral | typeFlags;
result.objectFlags |= ObjectFlags.ObjectLiteral | objectFlags;
result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral;
return result;
}
}
@@ -21374,7 +21403,7 @@ namespace ts {
const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type);
const defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
anonymousSymbol.type = defaultContainingObject;
synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*typeFLags*/ 0, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject;
synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject;
}
else {
synthType.syntheticType = type;
@@ -22052,7 +22081,7 @@ namespace ts {
const returnType = getReturnTypeFromBody(node, checkMode);
const returnOnlySignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
const returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], emptyArray, undefined, undefined);
returnOnlyType.flags |= TypeFlags.ContainsAnyFunctionType;
returnOnlyType.objectFlags |= ObjectFlags.ContainsAnyFunctionType;
return links.contextFreeType = returnOnlyType;
}
return anyFunctionType;
+4
View File
@@ -2581,6 +2581,10 @@
"category": "Error",
"code": 2748
},
"'{0}' refers to a value, but is being used as a type here.": {
"category": "Error",
"code": 2749
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
+1 -7
View File
@@ -632,7 +632,7 @@ namespace ts {
getModifiedTime,
setModifiedTime,
deleteFile,
createHash: _crypto ? createMD5HashUsingNativeCrypto : generateDjb2Hash,
createHash: _crypto ? createSHA256Hash : generateDjb2Hash,
createSHA256Hash: _crypto ? createSHA256Hash : undefined,
getMemoryUsage() {
if (global.gc) {
@@ -1125,12 +1125,6 @@ namespace ts {
}
}
function createMD5HashUsingNativeCrypto(data: string): string {
const hash = _crypto!.createHash("md5");
hash.update(data);
return hash.digest("hex");
}
function createSHA256Hash(data: string): string {
const hash = _crypto!.createHash("sha256");
hash.update(data);
+60 -45
View File
@@ -3881,39 +3881,33 @@ namespace ts {
}
export const enum TypeFlags {
Any = 1 << 0,
Unknown = 1 << 1,
String = 1 << 2,
Number = 1 << 3,
Boolean = 1 << 4,
Enum = 1 << 5,
BigInt = 1 << 6,
StringLiteral = 1 << 7,
NumberLiteral = 1 << 8,
BooleanLiteral = 1 << 9,
EnumLiteral = 1 << 10, // Always combined with StringLiteral, NumberLiteral, or Union
BigIntLiteral = 1 << 11,
ESSymbol = 1 << 12, // Type of symbol primitive introduced in ES6
UniqueESSymbol = 1 << 13, // unique symbol
Void = 1 << 14,
Undefined = 1 << 15,
Null = 1 << 16,
Never = 1 << 17, // Never type
TypeParameter = 1 << 18, // Type parameter
Object = 1 << 19, // Object type
Union = 1 << 20, // Union (T | U)
Intersection = 1 << 21, // Intersection (T & U)
Index = 1 << 22, // keyof T
IndexedAccess = 1 << 23, // T[K]
Conditional = 1 << 24, // T extends U ? X : Y
Substitution = 1 << 25, // Type parameter substitution
NonPrimitive = 1 << 26, // intrinsic object type
/* @internal */
ContainsWideningType = 1 << 27, // Type is or contains undefined or null widening type
/* @internal */
ContainsObjectLiteral = 1 << 28, // Type is or contains object literal type
/* @internal */
ContainsAnyFunctionType = 1 << 29, // Type is or contains the anyFunctionType
Any = 1 << 0,
Unknown = 1 << 1,
String = 1 << 2,
Number = 1 << 3,
Boolean = 1 << 4,
Enum = 1 << 5,
BigInt = 1 << 6,
StringLiteral = 1 << 7,
NumberLiteral = 1 << 8,
BooleanLiteral = 1 << 9,
EnumLiteral = 1 << 10, // Always combined with StringLiteral, NumberLiteral, or Union
BigIntLiteral = 1 << 11,
ESSymbol = 1 << 12, // Type of symbol primitive introduced in ES6
UniqueESSymbol = 1 << 13, // unique symbol
Void = 1 << 14,
Undefined = 1 << 15,
Null = 1 << 16,
Never = 1 << 17, // Never type
TypeParameter = 1 << 18, // Type parameter
Object = 1 << 19, // Object type
Union = 1 << 20, // Union (T | U)
Intersection = 1 << 21, // Intersection (T & U)
Index = 1 << 22, // keyof T
IndexedAccess = 1 << 23, // T[K]
Conditional = 1 << 24, // T extends U ? X : Y
Substitution = 1 << 25, // Type parameter substitution
NonPrimitive = 1 << 26, // intrinsic object type
/* @internal */
AnyOrUnknown = Any | Unknown,
@@ -3947,29 +3941,29 @@ namespace ts {
InstantiablePrimitive = Index,
Instantiable = InstantiableNonPrimitive | InstantiablePrimitive,
StructuredOrInstantiable = StructuredType | Instantiable,
/* @internal */
ObjectFlagsType = Nullable | Object | Union | Intersection,
// 'Narrowable' types are types where narrowing actually narrows.
// This *should* be every type other than null, undefined, void, and never
Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
NotUnionOrUnit = Any | Unknown | ESSymbol | Object | NonPrimitive,
/* @internal */
NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | StructuredOrInstantiable,
// The following flags are aggregated during union and intersection type construction
/* @internal */
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
/* @internal */
PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType,
IncludesMask = Any | Unknown | Primitive | Never | Object | Union,
// The following flags are used for different purposes during union and intersection type construction
/* @internal */
NonWideningType = ContainsWideningType,
IncludesStructuredOrInstantiable = TypeParameter,
/* @internal */
Wildcard = ContainsObjectLiteral,
IncludesNonWideningType = Intersection,
/* @internal */
EmptyObject = ContainsAnyFunctionType,
IncludesWildcard = Index,
/* @internal */
ConstructionFlags = NonWideningType | Wildcard | EmptyObject,
IncludesEmptyObject = IndexedAccess,
// The following flag is used for different purposes by maybeTypeOfKind
/* @internal */
GenericMappedType = ContainsWideningType
GenericMappedType = Never,
}
export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression;
@@ -3996,6 +3990,12 @@ namespace ts {
// Intrinsic types (TypeFlags.Intrinsic)
export interface IntrinsicType extends Type {
intrinsicName: string; // Name of intrinsic type
objectFlags: ObjectFlags;
}
/* @internal */
export interface NullableType extends IntrinsicType {
objectFlags: ObjectFlags;
}
/* @internal */
@@ -4055,9 +4055,24 @@ namespace ts {
MarkerType = 1 << 13, // Marker type used for variance probing
JSLiteral = 1 << 14, // Object type declared in JS - disables errors on read/write of nonexisting members
FreshLiteral = 1 << 15, // Fresh object literal
ClassOrInterface = Class | Interface
/* @internal */
PrimitiveUnion = 1 << 16, // Union of only primitive types
/* @internal */
ContainsWideningType = 1 << 17, // Type is or contains undefined or null widening type
/* @internal */
ContainsObjectLiteral = 1 << 18, // Type is or contains object literal type
/* @internal */
ContainsAnyFunctionType = 1 << 19, // Type is or contains the anyFunctionType
ClassOrInterface = Class | Interface,
/* @internal */
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
/* @internal */
PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType
}
/* @internal */
export type ObjectFlagsType = NullableType | ObjectType | UnionType | IntersectionType;
// Object types (TypeFlags.ObjectType)
export interface ObjectType extends Type {
objectFlags: ObjectFlags;
@@ -4138,6 +4153,8 @@ namespace ts {
export interface UnionOrIntersectionType extends Type {
types: Type[]; // Constituent types
/* @internal */
objectFlags: ObjectFlags;
/* @internal */
propertyCache: SymbolTable; // Cache of resolved properties
/* @internal */
resolvedProperties: Symbol[];
@@ -4152,8 +4169,6 @@ namespace ts {
}
export interface UnionType extends UnionOrIntersectionType {
/* @internal */
primitiveTypesOnly: boolean;
}
export interface IntersectionType extends UnionOrIntersectionType {
+1 -1
View File
@@ -4520,7 +4520,7 @@ namespace ts {
}
export function getObjectFlags(type: Type): ObjectFlags {
return type.flags & TypeFlags.Object ? (<ObjectType>type).objectFlags : 0;
return type.flags & TypeFlags.ObjectFlagsType ? (<ObjectFlagsType>type).objectFlags : 0;
}
export function typeHasCallOrConstructSignatures(type: Type, checker: TypeChecker) {
+5 -5
View File
@@ -361,9 +361,9 @@ namespace ts {
function getWatchFactoryWith<X, Y = undefined>(watchLogLevel: WatchLogLevel, log: (s: string) => void, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined,
watchFile: (host: WatchFileHost, file: string, callback: FileWatcherCallback, watchPriority: PollingInterval) => FileWatcher,
watchDirectory: (host: WatchDirectoryHost, directory: string, callback: DirectoryWatcherCallback, flags: WatchDirectoryFlags) => FileWatcher): WatchFactory<X, Y> {
const createFileWatcher: CreateFileWatcher<WatchFileHost, PollingInterval, FileWatcherEventKind, undefined, X, Y> = getCreateFileWatcher(watchLogLevel, watchFile);
const createFileWatcher: CreateFileWatcher<WatchFileHost, PollingInterval, FileWatcherEventKind, never, X, Y> = getCreateFileWatcher(watchLogLevel, watchFile);
const createFilePathWatcher: CreateFileWatcher<WatchFileHost, PollingInterval, FileWatcherEventKind, Path, X, Y> = watchLogLevel === WatchLogLevel.None ? watchFilePath : createFileWatcher;
const createDirectoryWatcher: CreateFileWatcher<WatchDirectoryHost, WatchDirectoryFlags, undefined, undefined, X, Y> = getCreateFileWatcher(watchLogLevel, watchDirectory);
const createDirectoryWatcher: CreateFileWatcher<WatchDirectoryHost, WatchDirectoryFlags, undefined, never, X, Y> = getCreateFileWatcher(watchLogLevel, watchDirectory);
return {
watchFile: (host, file, callback, pollingInterval, detailInfo1, detailInfo2) =>
createFileWatcher(host, file, callback, pollingInterval, /*passThrough*/ undefined, detailInfo1, detailInfo2, watchFile, log, "FileWatcher", getDetailWatchInfo),
@@ -402,7 +402,7 @@ namespace ts {
}
}
function createFileWatcherWithLogging<H, T, U, V, X, Y>(host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch<H, T, U, undefined>, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined): FileWatcher {
function createFileWatcherWithLogging<H, T, U, V, X, Y>(host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch<H, T, U, V>, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined): FileWatcher {
log(`${watchCaption}:: Added:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`);
const watcher = createFileWatcherWithTriggerLogging(host, file, cb, flags, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo);
return {
@@ -413,7 +413,7 @@ namespace ts {
};
}
function createDirectoryWatcherWithLogging<H, T, U, V, X, Y>(host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch<H, T, U, undefined>, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined): FileWatcher {
function createDirectoryWatcherWithLogging<H, T, U, V, X, Y>(host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch<H, T, U, V>, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined): FileWatcher {
const watchInfo = `${watchCaption}:: Added:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
log(watchInfo);
const start = timestamp();
@@ -432,7 +432,7 @@ namespace ts {
};
}
function createFileWatcherWithTriggerLogging<H, T, U, V, X, Y>(host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch<H, T, U, undefined>, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined): FileWatcher {
function createFileWatcherWithTriggerLogging<H, T, U, V, X, Y>(host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch<H, T, U, V>, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined): FileWatcher {
return addWatch(host, file, (fileName, cbOptional) => {
const triggerredInfo = `${watchCaption}:: Triggered with ${fileName} ${cbOptional !== undefined ? cbOptional : ""}:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
log(triggerredInfo);
+3 -1
View File
@@ -7,7 +7,7 @@ namespace Harness.Parallel.Host {
const Base = Mocha.reporters.Base;
const color = Base.color;
const cursor = Base.cursor;
const ms = require("mocha/lib/ms") as typeof import("mocha/lib/ms");
const ms = require("ms") as typeof import("ms");
const readline = require("readline") as typeof import("readline");
const os = require("os") as typeof import("os");
const tty = require("tty") as typeof import("tty");
@@ -530,6 +530,8 @@ namespace Harness.Parallel.Host {
const replayRunner = new Mocha.Runner(new Mocha.Suite(""), /*delay*/ false);
replayRunner.started = true;
const createStatsCollector = require("mocha/lib/stats-collector");
createStatsCollector(replayRunner); // manually init stats collector like mocha.run would
const consoleReporter = new Base(replayRunner);
patchStats(consoleReporter.stats);
@@ -1684,9 +1684,9 @@ namespace ts.projectSystem {
TI.getNpmCommandForInstallation(npmPath, tsVersion, packageNames, packageNames.length - Math.ceil(packageNames.length / 2)).command
];
it("works when the command is too long to install all packages at once", () => {
const commands: string[] = [];
const hasError = TI.installNpmPackages(npmPath, tsVersion, packageNames, command => {
commands.push(command);
const commands: [string, string[]][] = [];
const hasError = TI.installNpmPackages(npmPath, tsVersion, packageNames, (file, args) => {
commands.push([file, args]);
return false;
});
assert.isFalse(hasError);
@@ -1694,9 +1694,9 @@ namespace ts.projectSystem {
});
it("installs remaining packages when one of the partial command fails", () => {
const commands: string[] = [];
const hasError = TI.installNpmPackages(npmPath, tsVersion, packageNames, command => {
commands.push(command);
const commands: [string, string[]][] = [];
const hasError = TI.installNpmPackages(npmPath, tsVersion, packageNames, (file, args) => {
commands.push([file, args]);
return commands.length === 1;
});
assert.isTrue(hasError);
+8 -8
View File
@@ -70,10 +70,10 @@ namespace ts.server.typingsInstaller {
cwd: string;
encoding: "utf-8";
}
type ExecSync = (command: string, options: ExecSyncOptions) => string;
type ExecFileSync = (file: string, args: string[], options: ExecSyncOptions) => string;
export class NodeTypingsInstaller extends TypingsInstaller {
private readonly nodeExecSync: ExecSync;
private readonly nodeExecFileSync: ExecFileSync;
private readonly npmPath: string;
readonly typesRegistry: Map<MapLike<string>>;
@@ -97,7 +97,7 @@ namespace ts.server.typingsInstaller {
this.log.writeLine(`Process id: ${process.pid}`);
this.log.writeLine(`NPM location: ${this.npmPath} (explicit '${Arguments.NpmLocation}' ${npmLocation === undefined ? "not " : ""} provided)`);
}
({ execSync: this.nodeExecSync } = require("child_process"));
({ execFileSync: this.nodeExecFileSync } = require("child_process"));
this.ensurePackageDirectoryExists(globalTypingsCacheLocation);
@@ -105,7 +105,7 @@ namespace ts.server.typingsInstaller {
if (this.log.isEnabled()) {
this.log.writeLine(`Updating ${typesRegistryPackageName} npm package...`);
}
this.execSyncAndLog(`${this.npmPath} install --ignore-scripts ${typesRegistryPackageName}@${this.latestDistTag}`, { cwd: globalTypingsCacheLocation });
this.execFileSyncAndLog(this.npmPath, ["install", "--ignore-scripts", `${typesRegistryPackageName}@${this.latestDistTag}`], { cwd: globalTypingsCacheLocation });
if (this.log.isEnabled()) {
this.log.writeLine(`Updated ${typesRegistryPackageName} npm package`);
}
@@ -189,7 +189,7 @@ namespace ts.server.typingsInstaller {
this.log.writeLine(`#${requestId} with arguments'${JSON.stringify(packageNames)}'.`);
}
const start = Date.now();
const hasError = installNpmPackages(this.npmPath, version, packageNames, command => this.execSyncAndLog(command, { cwd }));
const hasError = installNpmPackages(this.npmPath, version, packageNames, (file, args) => this.execFileSyncAndLog(file, args, { cwd }));
if (this.log.isEnabled()) {
this.log.writeLine(`npm install #${requestId} took: ${Date.now() - start} ms`);
}
@@ -197,12 +197,12 @@ namespace ts.server.typingsInstaller {
}
/** Returns 'true' in case of error. */
private execSyncAndLog(command: string, options: Pick<ExecSyncOptions, "cwd">): boolean {
private execFileSyncAndLog(file: string, args: string[], options: Pick<ExecSyncOptions, "cwd">): boolean {
if (this.log.isEnabled()) {
this.log.writeLine(`Exec: ${command}`);
this.log.writeLine(`Exec: ${file} ${args.join(" ")}`);
}
try {
const stdout = this.nodeExecSync(command, { ...options, encoding: "utf-8" });
const stdout = this.nodeExecFileSync(file, args, { ...options, encoding: "utf-8" });
if (this.log.isEnabled()) {
this.log.writeLine(` Succeeded. stdout:${indent(sys.newLine, stdout)}`);
}
+12 -5
View File
@@ -31,28 +31,35 @@ namespace ts.server.typingsInstaller {
}
/*@internal*/
export function installNpmPackages(npmPath: string, tsVersion: string, packageNames: string[], install: (command: string) => boolean) {
export function installNpmPackages(npmPath: string, tsVersion: string, packageNames: string[], install: (file: string, args: string[]) => boolean) {
let hasError = false;
for (let remaining = packageNames.length; remaining > 0;) {
const result = getNpmCommandForInstallation(npmPath, tsVersion, packageNames, remaining);
remaining = result.remaining;
hasError = install(result.command) || hasError;
hasError = install(result.command[0], result.command[1]) || hasError;
}
return hasError;
}
function getUserAgent(tsVersion: string) {
return `--user-agent="typesInstaller/${tsVersion}"`;
}
const npmInstall = "install", ignoreScripts = "--ignore-scripts", saveDev = "--save-dev";
const commandBaseLength = npmInstall.length + ignoreScripts.length + saveDev.length + getUserAgent("").length + 5;
/*@internal*/
export function getNpmCommandForInstallation(npmPath: string, tsVersion: string, packageNames: string[], remaining: number) {
const sliceStart = packageNames.length - remaining;
let command: string, toSlice = remaining;
let packages: string[], toSlice = remaining;
while (true) {
command = `${npmPath} install --ignore-scripts ${(toSlice === packageNames.length ? packageNames : packageNames.slice(sliceStart, sliceStart + toSlice)).join(" ")} --save-dev --user-agent="typesInstaller/${tsVersion}"`;
if (command.length < 8000) {
packages = toSlice === packageNames.length ? packageNames : packageNames.slice(sliceStart, sliceStart + toSlice);
const commandLength = npmPath.length + commandBaseLength + packages.join(" ").length + tsVersion.length;
if (commandLength < 8000) {
break;
}
toSlice = toSlice - Math.floor(toSlice / 2);
}
const command: [string, string[]] = [npmPath, [npmInstall, ignoreScripts, ...packages, saveDev, getUserAgent(tsVersion)]];
return { command, remaining: remaining - toSlice };
}