Merge branch 'master' into incrementalBuildInfo

This commit is contained in:
Sheetal Nandi
2019-03-08 11:42:19 -08:00
117 changed files with 4728 additions and 5649 deletions
+242 -107
View File
@@ -228,9 +228,9 @@ namespace ts {
isContextSensitive,
getFullyQualifiedName,
getResolvedSignature: (node, candidatesOutArray, agumentCount) =>
getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, /*isForSignatureHelp*/ false),
getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, CheckMode.Normal),
getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, agumentCount) =>
getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, /*isForSignatureHelp*/ true),
getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, CheckMode.IsForSignatureHelp),
getConstantValue: nodeIn => {
const node = getParseTreeNode(nodeIn, canHaveConstantValue);
return node ? getConstantValue(node) : undefined;
@@ -374,10 +374,10 @@ namespace ts {
getLocalTypeParametersOfClassOrInterfaceOrTypeAlias,
};
function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, isForSignatureHelp: boolean): Signature | undefined {
function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, checkMode: CheckMode): Signature | undefined {
const node = getParseTreeNode(nodeIn, isCallLikeExpression);
apparentArgumentCount = argumentCount;
const res = node ? getResolvedSignature(node, candidatesOutArray, isForSignatureHelp) : undefined;
const res = node ? getResolvedSignature(node, candidatesOutArray, checkMode) : undefined;
apparentArgumentCount = undefined;
return res;
}
@@ -688,10 +688,12 @@ namespace ts {
}
const enum CheckMode {
Normal = 0, // Normal type checking
SkipContextSensitive = 1, // Skip context sensitive function expressions
Inferential = 2, // Inferential typing
Contextual = 3, // Normal type checking informed by a contextual type, therefore not cacheable
Normal = 0, // Normal type checking
Contextual = 1 << 0, // Explicitly assigned contextual type, therefore not cacheable
Inferential = 1 << 1, // Inferential typing
SkipContextSensitive = 1 << 2, // Skip context sensitive function expressions
SkipGenericFunctions = 1 << 3, // Skip single signature generic functions
IsForSignatureHelp = 1 << 4, // Call resolution for purposes of signature help
}
const enum CallbackCheck {
@@ -3981,7 +3983,7 @@ namespace ts {
context.flags &= ~NodeBuilderFlags.WriteTypeParametersInQualifiedName; // Avoids potential infinite loop when building for a claimspace with a generic
const shouldUseGeneratedName =
context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams &&
type.symbol.declarations[0] &&
type.symbol.declarations && type.symbol.declarations[0] &&
isTypeParameterDeclaration(type.symbol.declarations[0]) &&
typeParameterShadowsNameInScope(type, context);
const name = shouldUseGeneratedName
@@ -8373,9 +8375,23 @@ namespace ts {
return undefined;
}
function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean): Signature {
return getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
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));
if (returnSignature) {
const newReturnSignature = cloneSignature(returnSignature);
newReturnSignature.typeParameters = inferredTypeParameters;
newReturnSignature.target = returnSignature.target;
newReturnSignature.mapper = returnSignature.mapper;
const newInstantiatedSignature = cloneSignature(instantiatedSignature);
newInstantiatedSignature.resolvedReturnType = getOrCreateTypeFromSignature(newReturnSignature);
return newInstantiatedSignature;
}
}
return instantiatedSignature;
}
function getSignatureInstantiationWithoutFillingInTypeArguments(signature: Signature, typeArguments: ReadonlyArray<Type> | undefined): Signature {
const instantiations = signature.instantiations || (signature.instantiations = createMap<Signature>());
const id = getTypeListId(typeArguments);
@@ -8389,6 +8405,7 @@ namespace ts {
function createSignatureInstantiation(signature: Signature, typeArguments: ReadonlyArray<Type> | undefined): Signature {
return instantiateSignature(signature, createSignatureTypeMapper(signature, typeArguments), /*eraseTypeParameters*/ true);
}
function createSignatureTypeMapper(signature: Signature, typeArguments: ReadonlyArray<Type> | undefined): TypeMapper {
return createTypeMapper(signature.typeParameters!, typeArguments);
}
@@ -8790,7 +8807,7 @@ namespace ts {
function getTypeReferenceTypeWorker(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: Type[] | undefined): Type | undefined {
if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
if (symbol.valueDeclaration && isBinaryExpression(symbol.valueDeclaration.parent)) {
if (symbol.valueDeclaration && symbol.valueDeclaration.parent && isBinaryExpression(symbol.valueDeclaration.parent)) {
const jsdocType = getJSDocTypeReference(node, symbol, typeArguments);
if (jsdocType) {
return jsdocType;
@@ -20035,27 +20052,36 @@ namespace ts {
// Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper?: TypeMapper, compareTypes?: TypeComparer): Signature {
const context = createInferenceContext(signature.typeParameters!, signature, InferenceFlags.None, compareTypes);
const sourceSignature = contextualMapper ? instantiateSignature(contextualSignature, contextualMapper) : contextualSignature;
// We clone the contextualMapper to avoid fixing. For example, when the source signature is <T>(x: T) => T[] and
// the contextual signature is (...args: A) => B, we want to infer the element type of A's constraint (say 'any')
// for T but leave it possible to later infer '[any]' back to A.
const restType = getEffectiveRestType(contextualSignature);
const mapper = contextualMapper && restType && restType.flags & TypeFlags.TypeParameter ? cloneTypeMapper(contextualMapper) : contextualMapper;
const sourceSignature = mapper ? instantiateSignature(contextualSignature, mapper) : contextualSignature;
forEachMatchingParameterType(sourceSignature, signature, (source, target) => {
// Type parameters from outer context referenced by source type are fixed by instantiation of the source type
inferTypes(context.inferences, source, target);
});
if (!contextualMapper) {
inferTypes(context.inferences, getReturnTypeOfSignature(contextualSignature), getReturnTypeOfSignature(signature), InferencePriority.ReturnType);
const signaturePredicate = getTypePredicateOfSignature(signature);
const contextualPredicate = getTypePredicateOfSignature(sourceSignature);
if (signaturePredicate && contextualPredicate && signaturePredicate.kind === contextualPredicate.kind &&
(signaturePredicate.kind === TypePredicateKind.This || signaturePredicate.parameterIndex === (contextualPredicate as IdentifierTypePredicate).parameterIndex)) {
inferTypes(context.inferences, contextualPredicate.type, signaturePredicate.type, InferencePriority.ReturnType);
}
}
return getSignatureInstantiation(signature, getInferredTypes(context), isInJSFile(contextualSignature.declaration));
}
function inferJsxTypeArguments(node: JsxOpeningLikeElement, signature: Signature, excludeArgument: ReadonlyArray<boolean> | undefined, context: InferenceContext): Type[] {
function inferJsxTypeArguments(node: JsxOpeningLikeElement, signature: Signature, checkMode: CheckMode, context: InferenceContext): Type[] {
const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
const checkAttrType = checkExpressionWithContextualType(node.attributes, paramType, excludeArgument && excludeArgument[0] !== undefined ? identityMapper : context);
const checkAttrType = checkExpressionWithContextualType(node.attributes, paramType, context, checkMode);
inferTypes(context.inferences, checkAttrType, paramType);
return getInferredTypes(context);
}
function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray<Expression>, excludeArgument: ReadonlyArray<boolean> | undefined, context: InferenceContext): Type[] {
function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray<Expression>, checkMode: CheckMode, context: InferenceContext): Type[] {
// Clear out all the inference results from the last time inferTypeArguments was called on this context
for (const inference of context.inferences) {
// As an optimization, we don't have to clear (and later recompute) inferred types
@@ -20068,7 +20094,7 @@ namespace ts {
}
if (isJsxOpeningLikeElement(node)) {
return inferJsxTypeArguments(node, signature, excludeArgument, context);
return inferJsxTypeArguments(node, signature, checkMode, context);
}
// If a contextual type is available, infer from that type to the return type of the call expression. For
@@ -20115,10 +20141,7 @@ namespace ts {
const arg = args[i];
if (arg.kind !== SyntaxKind.OmittedExpression) {
const paramType = getTypeAtPosition(signature, i);
// For context sensitive arguments we pass the identityMapper, which is a signal to treat all
// context sensitive function expressions as wildcards
const mapper = excludeArgument && excludeArgument[i] !== undefined ? identityMapper : context;
const argType = checkExpressionWithContextualType(arg, paramType, mapper);
const argType = checkExpressionWithContextualType(arg, paramType, context, checkMode);
inferTypes(context.inferences, argType, paramType);
}
}
@@ -20146,7 +20169,7 @@ namespace ts {
// and the argument are ...x forms.
return arg.kind === SyntaxKind.SyntheticExpression ?
createArrayType((<SyntheticExpression>arg).type) :
getArrayifiedType(checkExpressionWithContextualType((<SpreadElement>arg).expression, restType, context));
getArrayifiedType(checkExpressionWithContextualType((<SpreadElement>arg).expression, restType, context, CheckMode.Normal));
}
}
const contextualType = getIndexTypeOfType(restType, IndexKind.Number) || anyType;
@@ -20154,7 +20177,7 @@ namespace ts {
const types = [];
let spreadIndex = -1;
for (let i = index; i < argCount; i++) {
const argType = checkExpressionWithContextualType(args[i], contextualType, context);
const argType = checkExpressionWithContextualType(args[i], contextualType, context, CheckMode.Normal);
if (spreadIndex < 0 && isSpreadArgument(args[i])) {
spreadIndex = i - index;
}
@@ -20212,14 +20235,13 @@ namespace ts {
* @param node a JSX opening-like element we are trying to figure its call signature
* @param signature a candidate signature we are trying whether it is a call signature
* @param relation a relationship to check parameter and argument type
* @param excludeArgument
*/
function checkApplicableSignatureForJsxOpeningLikeElement(node: JsxOpeningLikeElement, signature: Signature, relation: Map<RelationComparisonResult>, excludeArgument: boolean[] | undefined, reportErrors: boolean) {
function checkApplicableSignatureForJsxOpeningLikeElement(node: JsxOpeningLikeElement, signature: Signature, relation: Map<RelationComparisonResult>, checkMode: CheckMode, reportErrors: boolean) {
// Stateless function components can have maximum of three arguments: "props", "context", and "updater".
// However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
// can be specified by users through attributes property.
const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
const attributesType = checkExpressionWithContextualType(node.attributes, paramType, excludeArgument && excludeArgument[0] ? identityMapper : undefined);
const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*contextualMapper*/ undefined, checkMode);
return checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes);
}
@@ -20228,10 +20250,10 @@ namespace ts {
args: ReadonlyArray<Expression>,
signature: Signature,
relation: Map<RelationComparisonResult>,
excludeArgument: boolean[] | undefined,
checkMode: CheckMode,
reportErrors: boolean) {
if (isJsxOpeningLikeElement(node)) {
return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, excludeArgument, reportErrors);
return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors);
}
const thisType = getThisTypeOfSignature(signature);
if (thisType && thisType !== voidType && node.kind !== SyntaxKind.NewExpression) {
@@ -20253,11 +20275,11 @@ namespace ts {
const arg = args[i];
if (arg.kind !== SyntaxKind.OmittedExpression) {
const paramType = getTypeAtPosition(signature, i);
const argType = checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
// If one or more arguments are still excluded (as indicated by a non-null excludeArgument parameter),
const argType = checkExpressionWithContextualType(arg, paramType, /*contextualMapper*/ undefined, checkMode);
// If one or more arguments are still excluded (as indicated by CheckMode.SkipContextSensitive),
// we obtain the regular type of any object literal arguments because we may not have inferred complete
// parameter types yet and therefore excess property checks may yield false positives (see #17041).
const checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType;
const checkArgType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(argType) : argType;
if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage)) {
return false;
}
@@ -20473,7 +20495,7 @@ namespace ts {
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount);
}
function resolveCall(node: CallLikeExpression, signatures: ReadonlyArray<Signature>, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean, fallbackError?: DiagnosticMessage): Signature {
function resolveCall(node: CallLikeExpression, signatures: ReadonlyArray<Signature>, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, fallbackError?: DiagnosticMessage): Signature {
const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression;
const isDecorator = node.kind === SyntaxKind.Decorator;
const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node);
@@ -20515,7 +20537,7 @@ namespace ts {
// For a decorator, no arguments are susceptible to contextual typing due to the fact
// decorators are applied to a declaration by the emitter, and not to an expression.
const isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters;
let excludeArgument = !isDecorator && !isSingleNonGenericCandidate ? getExcludeArgument(args) : undefined;
let argCheckMode = !isDecorator && !isSingleNonGenericCandidate && some(args, isContextSensitive) ? CheckMode.SkipContextSensitive : CheckMode.Normal;
// The following variables are captured and modified by calls to chooseOverload.
// If overload resolution or type argument inference fails, we want to report the
@@ -20546,7 +20568,7 @@ namespace ts {
// If we are in signature help, a trailing comma indicates that we intend to provide another argument,
// so we will only accept overloads with arity at least 1 higher than the current number of provided arguments.
const signatureHelpTrailingComma =
isForSignatureHelp && node.kind === SyntaxKind.CallExpression && node.arguments.hasTrailingComma;
!!(checkMode & CheckMode.IsForSignatureHelp) && node.kind === SyntaxKind.CallExpression && node.arguments.hasTrailingComma;
// Section 4.12.1:
// if the candidate list contains one or more signatures for which the type of each argument
@@ -20574,12 +20596,7 @@ namespace ts {
// skip the checkApplicableSignature check.
if (reportErrors) {
if (candidateForArgumentError) {
// excludeArgument is undefined, in this case also equivalent to [undefined, undefined, ...]
// The importance of excludeArgument is to prevent us from typing function expression parameters
// in arguments too early. If possible, we'd like to only type them once we know the correct
// overload. However, this matters for the case where the call is correct. When the call is
// an error, we don't need to exclude any arguments, although it would cause no harm to do so.
checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true);
checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, CheckMode.Normal, /*reportErrors*/ true);
}
else if (candidateForArgumentArityError) {
diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args));
@@ -20613,7 +20630,7 @@ namespace ts {
if (typeArguments || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
return undefined;
}
if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
if (!checkApplicableSignature(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false)) {
candidateForArgumentError = candidate;
return undefined;
}
@@ -20640,9 +20657,10 @@ namespace ts {
}
else {
inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext);
argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal;
}
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration));
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
// If the original signature has a generic rest type, instantiation may produce a
// signature with different arity and we need to perform another arity check.
if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
@@ -20653,21 +20671,21 @@ namespace ts {
else {
checkCandidate = candidate;
}
if (!checkApplicableSignature(node, args, checkCandidate, relation, excludeArgument, /*reportErrors*/ false)) {
if (!checkApplicableSignature(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false)) {
// Give preference to error candidates that have no rest parameters (as they are more specific)
if (!candidateForArgumentError || getEffectiveRestType(candidateForArgumentError) || !getEffectiveRestType(checkCandidate)) {
candidateForArgumentError = checkCandidate;
}
continue;
}
if (excludeArgument) {
if (argCheckMode) {
// If one or more context sensitive arguments were excluded, we start including
// them now (and keeping do so for any subsequent candidates) and perform a second
// round of type inference and applicability checking for this particular candidate.
excludeArgument = undefined;
argCheckMode = CheckMode.Normal;
if (inferenceContext) {
const typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration));
const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext);
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
// If the original signature has a generic rest type, instantiation may produce a
// signature with different arity and we need to perform another arity check.
if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
@@ -20675,7 +20693,7 @@ namespace ts {
continue;
}
}
if (!checkApplicableSignature(node, args, checkCandidate, relation, excludeArgument, /*reportErrors*/ false)) {
if (!checkApplicableSignature(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false)) {
// Give preference to error candidates that have no rest parameters (as they are more specific)
if (!candidateForArgumentError || getEffectiveRestType(candidateForArgumentError) || !getEffectiveRestType(checkCandidate)) {
candidateForArgumentError = checkCandidate;
@@ -20691,21 +20709,6 @@ namespace ts {
}
}
function getExcludeArgument(args: ReadonlyArray<Expression>): boolean[] | undefined {
let excludeArgument: boolean[] | undefined;
// We do not need to call `getEffectiveArgumentCount` here as it only
// applies when calculating the number of arguments for a decorator.
for (let i = 0; i < args.length; i++) {
if (isContextSensitive(args[i])) {
if (!excludeArgument) {
excludeArgument = new Array(args.length);
}
excludeArgument[i] = true;
}
}
return excludeArgument;
}
// No signature was applicable. We have already reported the errors for the invalid signature.
// If this is a type resolution session, e.g. Language Service, try to get better information than anySignature.
function getCandidateForOverloadFailure(
@@ -20805,7 +20808,7 @@ namespace ts {
function inferSignatureInstantiationForOverloadFailure(node: CallLikeExpression, typeParameters: ReadonlyArray<TypeParameter>, candidate: Signature, args: ReadonlyArray<Expression>): Signature {
const inferenceContext = createInferenceContext(typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
const typeArgumentTypes = inferTypeArguments(node, candidate, args, getExcludeArgument(args), inferenceContext);
const typeArgumentTypes = inferTypeArguments(node, candidate, args, CheckMode.SkipContextSensitive | CheckMode.SkipGenericFunctions, inferenceContext);
return createSignatureInstantiation(candidate, typeArgumentTypes);
}
@@ -20828,7 +20831,7 @@ namespace ts {
return maxParamsIndex;
}
function resolveCallExpression(node: CallExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
function resolveCallExpression(node: CallExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
if (node.expression.kind === SyntaxKind.SuperKeyword) {
const superType = checkSuperExpression(node.expression);
if (isTypeAny(superType)) {
@@ -20843,7 +20846,7 @@ namespace ts {
const baseTypeNode = getEffectiveBaseTypeNode(getContainingClass(node)!);
if (baseTypeNode) {
const baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode);
return resolveCall(node, baseConstructors, candidatesOutArray, isForSignatureHelp);
return resolveCall(node, baseConstructors, candidatesOutArray, checkMode);
}
}
return resolveUntypedCall(node);
@@ -20903,12 +20906,32 @@ namespace ts {
}
return resolveErrorCall(node);
}
// When a call to a generic function is an argument to an outer call to a generic function for which
// inference is in process, we have a choice to make. If the inner call relies on inferences made from
// its contextual type to its return type, deferring the inner call processing allows the best possible
// contextual type to accumulate. But if the outer call relies on inferences made from the return type of
// the inner call, the inner call should be processed early. There's no sure way to know which choice is
// right (only a full unification algorithm can determine that), so we resort to the following heuristic:
// If no type arguments are specified in the inner call and at least one call signature is generic and
// returns a function type, we choose to defer processing. This narrowly permits function composition
// operators to flow inferences through return types, but otherwise processes calls right away. We
// use the resolvingSignature singleton to indicate that we deferred processing. This result will be
// propagated out and eventually turned into silentNeverType (a type that is assignable to anything and
// from which we never make inferences).
if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
skippedGenericFunction(node, checkMode);
return resolvingSignature;
}
// If the function is explicitly marked with `@class`, then it must be constructed.
if (callSignatures.some(sig => isInJSFile(sig.declaration) && !!getJSDocClassTag(sig.declaration!))) {
error(node, Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
return resolveErrorCall(node);
}
return resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp);
return resolveCall(node, callSignatures, candidatesOutArray, checkMode);
}
function isGenericFunctionReturningFunction(signature: Signature) {
return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature)));
}
/**
@@ -20922,7 +20945,7 @@ namespace ts {
!numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & (TypeFlags.Union | TypeFlags.Never)) && isTypeAssignableTo(funcType, globalFunctionType);
}
function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
if (node.arguments && languageVersion < ScriptTarget.ES5) {
const spreadIndex = getSpreadArgumentIndex(node.arguments);
if (spreadIndex >= 0) {
@@ -20975,7 +20998,7 @@ namespace ts {
return resolveErrorCall(node);
}
return resolveCall(node, constructSignatures, candidatesOutArray, isForSignatureHelp);
return resolveCall(node, constructSignatures, candidatesOutArray, checkMode);
}
// If expressionType's apparent type is an object type with no construct signatures but
@@ -20984,7 +21007,7 @@ namespace ts {
// operation is Any. It is an error to have a Void this type.
const callSignatures = getSignaturesOfType(expressionType, SignatureKind.Call);
if (callSignatures.length) {
const signature = resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp);
const signature = resolveCall(node, callSignatures, candidatesOutArray, checkMode);
if (!noImplicitAny) {
if (signature.declaration && !isJSConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) {
error(node, Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
@@ -21094,7 +21117,7 @@ namespace ts {
}
}
function resolveTaggedTemplateExpression(node: TaggedTemplateExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
function resolveTaggedTemplateExpression(node: TaggedTemplateExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
const tagType = checkExpression(node.tag);
const apparentType = getApparentType(tagType);
@@ -21115,7 +21138,7 @@ namespace ts {
return resolveErrorCall(node);
}
return resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp);
return resolveCall(node, callSignatures, candidatesOutArray, checkMode);
}
/**
@@ -21146,7 +21169,7 @@ namespace ts {
/**
* Resolves a decorator as if it were a call expression.
*/
function resolveDecorator(node: Decorator, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
function resolveDecorator(node: Decorator, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
const funcType = checkExpression(node.expression);
const apparentType = getApparentType(funcType);
if (apparentType === errorType) {
@@ -21175,7 +21198,7 @@ namespace ts {
return resolveErrorCall(node);
}
return resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp, headMessage);
return resolveCall(node, callSignatures, candidatesOutArray, checkMode, headMessage);
}
function createSignatureForJSXIntrinsic(node: JsxOpeningLikeElement, result: Type): Signature {
@@ -21204,11 +21227,11 @@ namespace ts {
);
}
function resolveJsxOpeningLikeElement(node: JsxOpeningLikeElement, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
function resolveJsxOpeningLikeElement(node: JsxOpeningLikeElement, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
if (isJsxIntrinsicIdentifier(node.tagName)) {
const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
const fakeSignature = createSignatureForJSXIntrinsic(node, result);
checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*mapper*/ undefined), result, node.tagName, node.attributes);
checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*mapper*/ undefined, CheckMode.Normal), result, node.tagName, node.attributes);
return fakeSignature;
}
const exprTypes = checkExpression(node.tagName);
@@ -21228,7 +21251,7 @@ namespace ts {
return resolveErrorCall(node);
}
return resolveCall(node, signatures, candidatesOutArray, isForSignatureHelp);
return resolveCall(node, signatures, candidatesOutArray, checkMode);
}
/**
@@ -21243,19 +21266,19 @@ namespace ts {
signature.parameters.length < getDecoratorArgumentCount(decorator, signature));
}
function resolveSignature(node: CallLikeExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
function resolveSignature(node: CallLikeExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
switch (node.kind) {
case SyntaxKind.CallExpression:
return resolveCallExpression(node, candidatesOutArray, isForSignatureHelp);
return resolveCallExpression(node, candidatesOutArray, checkMode);
case SyntaxKind.NewExpression:
return resolveNewExpression(node, candidatesOutArray, isForSignatureHelp);
return resolveNewExpression(node, candidatesOutArray, checkMode);
case SyntaxKind.TaggedTemplateExpression:
return resolveTaggedTemplateExpression(node, candidatesOutArray, isForSignatureHelp);
return resolveTaggedTemplateExpression(node, candidatesOutArray, checkMode);
case SyntaxKind.Decorator:
return resolveDecorator(node, candidatesOutArray, isForSignatureHelp);
return resolveDecorator(node, candidatesOutArray, checkMode);
case SyntaxKind.JsxOpeningElement:
case SyntaxKind.JsxSelfClosingElement:
return resolveJsxOpeningLikeElement(node, candidatesOutArray, isForSignatureHelp);
return resolveJsxOpeningLikeElement(node, candidatesOutArray, checkMode);
}
throw Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable.");
}
@@ -21267,7 +21290,7 @@ namespace ts {
* the function will fill it up with appropriate candidate signatures
* @return a signature of the call-like expression or undefined if one can't be found
*/
function getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[] | undefined, isForSignatureHelp = false): Signature {
function getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[] | undefined, checkMode?: CheckMode): Signature {
const links = getNodeLinks(node);
// If getResolvedSignature has already been called, we will have cached the resolvedSignature.
// However, it is possible that either candidatesOutArray was not passed in the first time,
@@ -21278,11 +21301,15 @@ namespace ts {
return cached;
}
links.resolvedSignature = resolvingSignature;
const result = resolveSignature(node, candidatesOutArray, isForSignatureHelp);
// If signature resolution originated in control flow type analysis (for example to compute the
// assigned type in a flow assignment) we don't cache the result as it may be based on temporary
// types from the control flow analysis.
links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
const result = resolveSignature(node, candidatesOutArray, checkMode || CheckMode.Normal);
// When CheckMode.SkipGenericFunctions is set we use resolvingSignature to indicate that call
// resolution should be deferred.
if (result !== resolvingSignature) {
// If signature resolution originated in control flow type analysis (for example to compute the
// assigned type in a flow assignment) we don't cache the result as it may be based on temporary
// types from the control flow analysis.
links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
}
return result;
}
@@ -21366,10 +21393,15 @@ namespace ts {
* @param node The call/new expression to be checked.
* @returns On success, the expression's signature's return type. On failure, anyType.
*/
function checkCallExpression(node: CallExpression | NewExpression): Type {
function checkCallExpression(node: CallExpression | NewExpression, checkMode?: CheckMode): Type {
if (!checkGrammarTypeArguments(node, node.typeArguments)) checkGrammarArguments(node.arguments);
const signature = getResolvedSignature(node);
const signature = getResolvedSignature(node, /*candidatesOutArray*/ undefined, checkMode);
if (signature === resolvingSignature) {
// CheckMode.SkipGenericFunctions is enabled and this is a call to a generic function that
// returns a function type. We defer checking and return anyFunctionType.
return silentNeverType;
}
if (node.expression.kind === SyntaxKind.SuperKeyword) {
return voidType;
@@ -21870,7 +21902,7 @@ namespace ts {
const functionFlags = getFunctionFlags(func);
let type: Type;
if (func.body.kind !== SyntaxKind.Block) {
type = checkExpressionCached(func.body, checkMode);
type = checkExpressionCached(func.body, checkMode && checkMode & ~CheckMode.SkipGenericFunctions);
if (functionFlags & FunctionFlags.Async) {
// From within an async function you can return either a non-promise value or a promise. Any
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
@@ -22060,7 +22092,7 @@ namespace ts {
forEachReturnStatement(<Block>func.body, returnStatement => {
const expr = returnStatement.expression;
if (expr) {
let type = checkExpressionCached(expr, checkMode);
let type = checkExpressionCached(expr, checkMode && checkMode & ~CheckMode.SkipGenericFunctions);
if (functionFlags & FunctionFlags.Async) {
// From within an async function you can return either a non-promise value or a promise. Any
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
@@ -22160,7 +22192,7 @@ namespace ts {
checkNodeDeferred(node);
// The identityMapper object is used to indicate that function expressions are wildcards
if (checkMode === CheckMode.SkipContextSensitive && isContextSensitive(node)) {
if (checkMode && checkMode & CheckMode.SkipContextSensitive && isContextSensitive(node)) {
// Skip parameters, return signature with return type that retains noncontextual parts so inferences can still be drawn in an early stage
if (!getEffectiveReturnTypeNode(node) && hasContextSensitiveReturnExpression(node)) {
const links = getNodeLinks(node);
@@ -22200,7 +22232,7 @@ namespace ts {
const signature = getSignaturesOfType(type, SignatureKind.Call)[0];
if (isContextSensitive(node)) {
const contextualMapper = getContextualMapper(node);
if (checkMode === CheckMode.Inferential) {
if (checkMode && checkMode & CheckMode.Inferential) {
inferFromAnnotatedParameters(signature, contextualSignature, contextualMapper);
}
const instantiatedContextualSignature = contextualMapper === identityMapper ?
@@ -23211,15 +23243,13 @@ namespace ts {
return node;
}
function checkExpressionWithContextualType(node: Expression, contextualType: Type, contextualMapper: TypeMapper | undefined): Type {
function checkExpressionWithContextualType(node: Expression, contextualType: Type, contextualMapper: TypeMapper | undefined, checkMode: CheckMode): Type {
const context = getContextNode(node);
const saveContextualType = context.contextualType;
const saveContextualMapper = context.contextualMapper;
context.contextualType = contextualType;
context.contextualMapper = contextualMapper;
const checkMode = contextualMapper === identityMapper ? CheckMode.SkipContextSensitive :
contextualMapper ? CheckMode.Inferential : CheckMode.Contextual;
const type = checkExpression(node, checkMode);
const type = checkExpression(node, checkMode | CheckMode.Contextual | (contextualMapper ? CheckMode.Inferential : 0));
// We strip literal freshness when an appropriate contextual type is present such that contextually typed
// literals always preserve their literal types (otherwise they might widen during type inference). An alternative
// here would be to not mark contextually typed literals as fresh in the first place.
@@ -23233,7 +23263,7 @@ namespace ts {
function checkExpressionCached(node: Expression, checkMode?: CheckMode): Type {
const links = getNodeLinks(node);
if (!links.resolvedType) {
if (checkMode) {
if (checkMode && checkMode !== CheckMode.Normal) {
return checkExpression(node, checkMode);
}
// When computing a type that we're going to cache, we need to ignore any ongoing control flow
@@ -23341,22 +23371,127 @@ namespace ts {
}
function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration | QualifiedName, type: Type, checkMode?: CheckMode) {
if (checkMode === CheckMode.Inferential) {
if (checkMode && checkMode & (CheckMode.Inferential | CheckMode.SkipGenericFunctions)) {
const signature = getSingleCallSignature(type);
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 (contextualSignature && !contextualSignature.typeParameters) {
return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, getContextualMapper(node)));
const context = <InferenceContext>getContextualMapper(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
// signature and a contextual function type with a single non-generic call signature. Now check
// 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));
if (returnSignature && !returnSignature.typeParameters && !every(context.inferences, hasInferenceCandidates)) {
// Instantiate the expression type with its own type parameters as type arguments. This
// ensures that the type parameters are not erased to type any during type inference such
// that they can be inferred as actual types.
const uniqueTypeParameters = getUniqueTypeParameters(context, signature.typeParameters);
const strippedType = getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(signature, uniqueTypeParameters));
// Infer from the stripped expression type to the contextual type starting with an empty
// set of inference candidates.
const inferences = map(context.typeParameters, createInferenceInfo);
inferTypes(inferences, strippedType, contextualType);
// If we produced some inference candidates and if the type parameters for which we produced
// candidates do not already have existing inferences, we adopt the new inference candidates and
// add the type parameters of the expression type to the set of inferred type parameters for
// the outer function return type.
if (some(inferences, hasInferenceCandidates) && !hasOverlappingInferences(context.inferences, inferences)) {
mergeInferences(context.inferences, inferences);
context.inferredTypeParameters = concatenate(context.inferredTypeParameters, uniqueTypeParameters);
return strippedType;
}
}
return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, context));
}
}
}
}
return type;
}
function skippedGenericFunction(node: Node, checkMode: CheckMode) {
if (checkMode & CheckMode.Inferential) {
// We have skipped a generic function during inferential typing. Obtain the inference context and
// indicate this has occurred such that we know a second pass of inference is be needed.
const context = <InferenceContext>getContextualMapper(node);
context.flags |= InferenceFlags.SkippedGenericFunction;
}
}
function hasInferenceCandidates(info: InferenceInfo) {
return !!(info.candidates || info.contraCandidates);
}
function hasOverlappingInferences(a: InferenceInfo[], b: InferenceInfo[]) {
for (let i = 0; i < a.length; i++) {
if (hasInferenceCandidates(a[i]) && hasInferenceCandidates(b[i])) {
return true;
}
}
return false;
}
function mergeInferences(target: InferenceInfo[], source: InferenceInfo[]) {
for (let i = 0; i < target.length; i++) {
if (!hasInferenceCandidates(target[i]) && hasInferenceCandidates(source[i])) {
target[i] = source[i];
}
}
}
function getUniqueTypeParameters(context: InferenceContext, typeParameters: ReadonlyArray<TypeParameter>): ReadonlyArray<TypeParameter> {
const result: TypeParameter[] = [];
let oldTypeParameters: TypeParameter[] | undefined;
let newTypeParameters: TypeParameter[] | undefined;
for (const tp of typeParameters) {
const name = tp.symbol.escapedName;
if (hasTypeParameterByName(context.inferredTypeParameters, name) || hasTypeParameterByName(result, name)) {
const newName = getUniqueTypeParameterName(concatenate(context.inferredTypeParameters, result), name);
const symbol = createSymbol(SymbolFlags.TypeParameter, newName);
const newTypeParameter = createTypeParameter(symbol);
newTypeParameter.target = tp;
oldTypeParameters = append(oldTypeParameters, tp);
newTypeParameters = append(newTypeParameters, newTypeParameter);
result.push(newTypeParameter);
}
else {
result.push(tp);
}
}
if (newTypeParameters) {
const mapper = createTypeMapper(oldTypeParameters!, newTypeParameters);
for (const tp of newTypeParameters) {
tp.mapper = mapper;
}
}
return result;
}
function hasTypeParameterByName(typeParameters: ReadonlyArray<TypeParameter> | undefined, name: __String) {
return some(typeParameters, tp => tp.symbol.escapedName === name);
}
function getUniqueTypeParameterName(typeParameters: ReadonlyArray<TypeParameter>, baseName: __String) {
let len = (<string>baseName).length;
while (len > 1 && (<string>baseName).charCodeAt(len - 1) >= CharacterCodes._0 && (<string>baseName).charCodeAt(len - 1) <= CharacterCodes._9) len--;
const s = (<string>baseName).slice(0, len);
for (let index = 1; true; index++) {
const augmentedName = <__String>(s + index);
if (!hasTypeParameterByName(typeParameters, augmentedName)) {
return augmentedName;
}
}
}
/**
* Returns the type of an expression. Unlike checkExpression, this function is simply concerned
* with computing the type and may not fully check all contained sub-expressions for errors.
@@ -23496,7 +23631,7 @@ namespace ts {
}
/* falls through */
case SyntaxKind.NewExpression:
return checkCallExpression(<CallExpression>node);
return checkCallExpression(<CallExpression>node, checkMode);
case SyntaxKind.TaggedTemplateExpression:
return checkTaggedTemplateExpression(<TaggedTemplateExpression>node);
case SyntaxKind.ParenthesizedExpression:
+16 -1
View File
@@ -917,7 +917,7 @@ namespace ts {
/**
* Deduplicates an unsorted array.
* @param equalityComparer An optional `EqualityComparer` used to determine if two values are duplicates.
* @param equalityComparer An `EqualityComparer` used to determine if two values are duplicates.
* @param comparer An optional `Comparer` used to sort entries before comparison, though the
* result will remain in the original order in `array`.
*/
@@ -1173,6 +1173,21 @@ namespace ts {
}};
}
export function arrayReverseIterator<T>(array: ReadonlyArray<T>): Iterator<T> {
let i = array.length;
return {
next: () => {
if (i === 0) {
return { value: undefined as never, done: true };
}
else {
i--;
return { value: array[i], done: false };
}
}
};
}
/**
* Stable sort of an array. Elements equal to each other maintain their relative position in the array.
*/
+8
View File
@@ -2927,6 +2927,10 @@
"category": "Error",
"code": 4102
},
"Type parameter '{0}' of exported mapped object type is using private name '{1}'.": {
"category": "Error",
"code": 4103
},
"The current host does not support the '{0}' option.": {
"category": "Error",
@@ -4910,5 +4914,9 @@
"Enable the 'experimentalDecorators' option in your configuration file": {
"category": "Message",
"code": 95074
},
"Convert to named parameters": {
"category": "Message",
"code": 95075
}
}
+3 -3
View File
@@ -71,8 +71,8 @@ namespace ts {
nonRecursive?: boolean;
}
export function isPathInNodeModulesStartingWithDot(path: Path) {
return stringContains(path, "/node_modules/.");
export function isPathIgnored(path: Path) {
return some(ignoredPaths, searchPath => stringContains(path, searchPath));
}
export const maxNumberOfFilesToIterateForInvalidation = 256;
@@ -696,7 +696,7 @@ namespace ts {
}
else {
// If something to do with folder/file starting with "." in node_modules folder, skip it
if (isPathInNodeModulesStartingWithDot(fileOrDirectoryPath)) return false;
if (isPathIgnored(fileOrDirectoryPath)) return false;
// Some file or directory in the watching directory is created
// Return early if it does not have any of the watching extension or not the custom failed lookup path
+16 -1
View File
@@ -326,6 +326,9 @@ namespace ts {
: FileWatcherEventKind.Changed;
}
/*@internal*/
export const ignoredPaths = ["/node_modules/.", "/.git"];
/*@internal*/
export interface RecursiveDirectoryWatcherHost {
watchDirectory: HostWatchDirectory;
@@ -371,6 +374,8 @@ namespace ts {
else {
directoryWatcher = {
watcher: host.watchDirectory(dirName, fileName => {
if (isIgnoredPath(fileName)) return;
// Call the actual callback
callbackCache.forEach((callbacks, rootDirName) => {
if (rootDirName === dirPath || (startsWith(dirPath, rootDirName) && dirPath[rootDirName.length] === directorySeparator)) {
@@ -426,7 +431,7 @@ namespace ts {
const childFullName = getNormalizedAbsolutePath(child, parentDir);
// Filter our the symbolic link directories since those arent included in recursive watch
// which is same behaviour when recursive: true is passed to fs.watch
return filePathComparer(childFullName, normalizePath(host.realpath(childFullName))) === Comparison.EqualTo ? childFullName : undefined;
return !isIgnoredPath(childFullName) && filePathComparer(childFullName, normalizePath(host.realpath(childFullName))) === Comparison.EqualTo ? childFullName : undefined;
}) : emptyArray,
existingChildWatches,
(child, childWatcher) => filePathComparer(child, childWatcher.dirName),
@@ -452,6 +457,16 @@ namespace ts {
(newChildWatches || (newChildWatches = [])).push(childWatcher);
}
}
function isIgnoredPath(path: string) {
return some(ignoredPaths, searchPath => isInPath(path, searchPath));
}
function isInPath(path: string, searchPath: string) {
if (stringContains(path, searchPath)) return true;
if (host.useCaseSensitiveFileNames) return false;
return stringContains(toCanonicalFilePath(path), searchPath);
}
}
/*@internal*/
@@ -391,6 +391,10 @@ namespace ts {
diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1;
break;
case SyntaxKind.MappedType:
diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1;
break;
case SyntaxKind.ConstructorType:
case SyntaxKind.ConstructSignature:
diagnosticMessage = Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
+2
View File
@@ -4423,6 +4423,7 @@ namespace ts {
NoDefault = 1 << 0, // Infer unknownType for no inferences (otherwise anyType or emptyObjectType)
AnyDefault = 1 << 1, // Infer anyType for no inferences (otherwise emptyObjectType)
NoFixing = 1 << 2, // Disable type parameter fixing
SkippedGenericFunction = 1 << 3,
}
/**
@@ -4452,6 +4453,7 @@ namespace ts {
flags: InferenceFlags; // Inference flags
compareTypes: TypeComparer; // Type comparer function
returnMapper?: TypeMapper; // Type mapper for inferences from return types (if any)
inferredTypeParameters?: ReadonlyArray<TypeParameter>;
}
/* @internal */
+1 -1
View File
@@ -987,7 +987,7 @@ namespace ts {
}
nextSourceFileVersion(fileOrDirectoryPath);
if (isPathInNodeModulesStartingWithDot(fileOrDirectoryPath)) return;
if (isPathIgnored(fileOrDirectoryPath)) return;
// If the the added or created file or directory is not supported file name, ignore the file
// But when watched directory is added/removed, we need to reload the file list