Merge branch 'master' into tsconfigChangeDetection

This commit is contained in:
Sheetal Nandi
2019-03-19 16:54:25 -07:00
56 changed files with 2639 additions and 652 deletions
+75 -84
View File
@@ -232,6 +232,7 @@ namespace ts {
getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, agumentCount) =>
getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, CheckMode.IsForSignatureHelp),
getExpandedParameters,
hasEffectiveRestParameter,
getConstantValue: nodeIn => {
const node = getParseTreeNode(nodeIn, canHaveConstantValue);
return node ? getConstantValue(node) : undefined;
@@ -304,6 +305,8 @@ namespace ts {
getNeverType: () => neverType,
isSymbolAccessible,
getObjectFlags,
isArrayType,
isTupleType,
isArrayLikeType,
isTypeInvalidDueToUnionDiscriminant,
getAllPossiblePropertiesOfTypes,
@@ -388,7 +391,7 @@ namespace ts {
const intersectionTypes = createMap<IntersectionType>();
const literalTypes = createMap<LiteralType>();
const indexedAccessTypes = createMap<IndexedAccessType>();
const conditionalTypes = createMap<Type | undefined>();
const conditionalTypes = createMap<Type>();
const evolvingArrayTypes: EvolvingArrayType[] = [];
const undefinedProperties = createMap<Symbol>() as UnderscoreEscapedMap<Symbol>;
@@ -1471,7 +1474,14 @@ namespace ts {
// @y method(x, y) {} // <-- decorator y should be resolved at the class declaration, not the method.
// }
//
if (location.parent && isClassElement(location.parent)) {
// class Decorators are resolved outside of the class to avoid referencing type parameters of that class.
//
// type T = number;
// declare function y(x: T): any;
// @param(1 as T) // <-- T should resolve to the type alias outside of class C
// class C<T> {}
if (location.parent && (isClassElement(location.parent) || location.parent.kind === SyntaxKind.ClassDeclaration)) {
location = location.parent;
}
break;
@@ -8298,7 +8308,7 @@ namespace ts {
}
}
signature.resolvedTypePredicate = type && isTypePredicateNode(type) ?
createTypePredicateFromTypePredicateNode(type, signature.declaration!) :
createTypePredicateFromTypePredicateNode(type, signature) :
jsdocPredicate || noTypePredicate;
}
Debug.assert(!!signature.resolvedTypePredicate);
@@ -8306,13 +8316,13 @@ namespace ts {
return signature.resolvedTypePredicate === noTypePredicate ? undefined : signature.resolvedTypePredicate;
}
function createTypePredicateFromTypePredicateNode(node: TypePredicateNode, func: SignatureDeclaration | JSDocSignature): IdentifierTypePredicate | ThisTypePredicate {
function createTypePredicateFromTypePredicateNode(node: TypePredicateNode, signature: Signature): IdentifierTypePredicate | ThisTypePredicate {
const { parameterName } = node;
const type = getTypeFromTypeNode(node.type);
if (parameterName.kind === SyntaxKind.Identifier) {
return createIdentifierTypePredicate(
parameterName.escapedText as string,
getTypePredicateParameterIndex(func.parameters, parameterName),
findIndex(signature.parameters, p => p.escapedName === parameterName.escapedText),
type);
}
else {
@@ -8320,16 +8330,6 @@ namespace ts {
}
}
function getTypePredicateParameterIndex(parameterList: ReadonlyArray<ParameterDeclaration | JSDocParameterTag>, parameter: Identifier): number {
for (let i = 0; i < parameterList.length; i++) {
const param = parameterList[i];
if (param.name.kind === SyntaxKind.Identifier && param.name.escapedText === parameter.escapedText) {
return i;
}
}
return -1;
}
function getReturnTypeOfSignature(signature: Signature): Type {
if (!signature.resolvedReturnType) {
if (!pushTypeResolution(signature, TypeSystemPropertyName.ResolvedReturnType)) {
@@ -10138,24 +10138,11 @@ namespace ts {
const trueType = instantiateType(root.trueType, mapper);
const falseType = instantiateType(root.falseType, mapper);
const instantiationId = `${root.isDistributive ? "d" : ""}${getTypeId(checkType)}>${getTypeId(extendsType)}?${getTypeId(trueType)}:${getTypeId(falseType)}`;
if (conditionalTypes.has(instantiationId)) {
const result = conditionalTypes.get(instantiationId);
if (result !== undefined) {
return result;
}
// Somehow the conditional type depends on itself - usually via `infer` types in the `extends` clause
// paired with a (potentially deferred) circularly constrained type.
// The conditional _must_ be deferred.
const deferred = getDeferredConditionalType(root, mapper, /*combinedMapper*/ undefined, checkType, extendsType, trueType, falseType);
conditionalTypes.set(instantiationId, deferred);
return deferred;
const result = conditionalTypes.get(instantiationId);
if (result) {
return result;
}
conditionalTypes.set(instantiationId, undefined);
const newResult = getConditionalTypeWorker(root, mapper, checkType, extendsType, trueType, falseType);
const cachedRecursiveResult = conditionalTypes.get(instantiationId);
if (cachedRecursiveResult) {
return cachedRecursiveResult;
}
conditionalTypes.set(instantiationId, newResult);
return newResult;
}
@@ -11832,7 +11819,7 @@ namespace ts {
if (targetTypePredicate) {
const sourceTypePredicate = getTypePredicateOfSignature(source);
if (sourceTypePredicate) {
result &= compareTypePredicateRelatedTo(sourceTypePredicate, targetTypePredicate, source.declaration!, target.declaration!, reportErrors, errorReporter, compareTypes); // TODO: GH#18217
result &= compareTypePredicateRelatedTo(sourceTypePredicate, targetTypePredicate, reportErrors, errorReporter, compareTypes);
}
else if (isIdentifierTypePredicate(targetTypePredicate)) {
if (reportErrors) {
@@ -11857,8 +11844,6 @@ namespace ts {
function compareTypePredicateRelatedTo(
source: TypePredicate,
target: TypePredicate,
sourceDeclaration: SignatureDeclaration | JSDocSignature,
targetDeclaration: SignatureDeclaration | JSDocSignature,
reportErrors: boolean,
errorReporter: ErrorReporter | undefined,
compareTypes: (s: Type, t: Type, reportErrors?: boolean) => Ternary): Ternary {
@@ -11871,12 +11856,9 @@ namespace ts {
}
if (source.kind === TypePredicateKind.Identifier) {
const targetPredicate = target as IdentifierTypePredicate;
const sourceIndex = source.parameterIndex - (getThisParameter(sourceDeclaration) ? 1 : 0);
const targetIndex = targetPredicate.parameterIndex - (getThisParameter(targetDeclaration) ? 1 : 0);
if (sourceIndex !== targetIndex) {
if (source.parameterIndex !== (target as IdentifierTypePredicate).parameterIndex) {
if (reportErrors) {
errorReporter!(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, source.parameterName, targetPredicate.parameterName);
errorReporter!(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, source.parameterName, (target as IdentifierTypePredicate).parameterName);
errorReporter!(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
}
return Ternary.False;
@@ -14283,7 +14265,7 @@ namespace ts {
}
}
function forEachMatchingParameterType(source: Signature, target: Signature, callback: (s: Type, t: Type) => void) {
function applyToParameterTypes(source: Signature, target: Signature, callback: (s: Type, t: Type) => void) {
const sourceCount = getParameterCount(source);
const targetCount = getParameterCount(target);
const sourceRestType = getEffectiveRestType(source);
@@ -14305,6 +14287,18 @@ namespace ts {
}
}
function applyToReturnTypes(source: Signature, target: Signature, callback: (s: Type, t: Type) => void) {
const sourceTypePredicate = getTypePredicateOfSignature(source);
const targetTypePredicate = getTypePredicateOfSignature(target);
if (sourceTypePredicate && targetTypePredicate && sourceTypePredicate.kind === targetTypePredicate.kind &&
(sourceTypePredicate.kind === TypePredicateKind.This || sourceTypePredicate.parameterIndex === (<IdentifierTypePredicate>targetTypePredicate).parameterIndex)) {
callback(sourceTypePredicate.type, targetTypePredicate.type);
}
else {
callback(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
}
}
function createInferenceContext(typeParameters: ReadonlyArray<TypeParameter>, signature: Signature | undefined, flags: InferenceFlags, compareTypes?: TypeComparer): InferenceContext {
return createInferenceContextWorker(typeParameters.map(createInferenceInfo), signature, flags, compareTypes || compareTypesAssignable);
}
@@ -14523,10 +14517,9 @@ namespace ts {
emptyObjectType;
}
function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) {
function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0, contravariant = false) {
let symbolStack: Symbol[];
let visited: Map<boolean>;
let contravariant = false;
let bivariant = false;
let propagationType: Type;
let allowComplexConstraintInference = true;
@@ -14617,9 +14610,11 @@ namespace ts {
const candidate = propagationType || source;
// We make contravariant inferences only if we are in a pure contravariant position,
// i.e. only if we have not descended into a bivariant position.
if (contravariant && !bivariant && !contains(inference.contraCandidates, candidate)) {
inference.contraCandidates = append(inference.contraCandidates, candidate);
inference.inferredType = undefined;
if (contravariant && !bivariant) {
if (!contains(inference.contraCandidates, candidate)) {
inference.contraCandidates = append(inference.contraCandidates, candidate);
inference.inferredType = undefined;
}
}
else if (!contains(inference.candidates, candidate)) {
inference.candidates = append(inference.candidates, candidate);
@@ -14924,17 +14919,10 @@ namespace ts {
const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown;
// Once we descend into a bivariant signature we remain bivariant for all nested inferences
bivariant = bivariant || kind === SyntaxKind.MethodDeclaration || kind === SyntaxKind.MethodSignature || kind === SyntaxKind.Constructor;
forEachMatchingParameterType(source, target, inferFromContravariantTypes);
applyToParameterTypes(source, target, inferFromContravariantTypes);
bivariant = saveBivariant;
}
const sourceTypePredicate = getTypePredicateOfSignature(source);
const targetTypePredicate = getTypePredicateOfSignature(target);
if (sourceTypePredicate && targetTypePredicate && sourceTypePredicate.kind === targetTypePredicate.kind) {
inferFromTypes(sourceTypePredicate.type, targetTypePredicate.type);
}
else {
inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
}
applyToReturnTypes(source, target, inferFromTypes);
}
function inferFromIndexTypes(source: Type, target: Type) {
@@ -16600,7 +16588,7 @@ namespace ts {
}
if (isIdentifierTypePredicate(predicate)) {
const predicateArgument = callExpression.arguments[predicate.parameterIndex - (signature.thisParameter ? 1 : 0)];
const predicateArgument = callExpression.arguments[predicate.parameterIndex];
if (predicateArgument) {
if (isMatchingReference(reference, predicateArgument)) {
return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf);
@@ -20170,18 +20158,14 @@ namespace ts {
const restType = getEffectiveRestType(contextualSignature);
const mapper = inferenceContext && (restType && restType.flags & TypeFlags.TypeParameter ? inferenceContext.nonFixingMapper : inferenceContext.mapper);
const sourceSignature = mapper ? instantiateSignature(contextualSignature, mapper) : contextualSignature;
forEachMatchingParameterType(sourceSignature, signature, (source, target) => {
applyToParameterTypes(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 (!inferenceContext) {
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);
}
applyToReturnTypes(contextualSignature, signature, (source, target) => {
inferTypes(context.inferences, source, target, InferencePriority.ReturnType);
});
}
return getSignatureInstantiation(signature, getInferredTypes(context), isInJSFile(contextualSignature.declaration));
}
@@ -23520,23 +23504,30 @@ namespace ts {
// 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.
// Instantiate the signature with its own type parameters as type arguments, possibly
// renaming the type parameters to ensure they have unique names.
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 instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, uniqueTypeParameters);
// Infer from the parameters of the instantiated signature to the parameters of the
// contextual signature starting with an empty set of inference candidates.
const inferences = map(context.inferences, info => createInferenceInfo(info.typeParameter));
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;
applyToParameterTypes(instantiatedSignature, contextualSignature, (source, target) => {
inferTypes(inferences, source, target, /*priority*/ 0, /*contravariant*/ true);
});
if (some(inferences, hasInferenceCandidates)) {
// We have inference candidates, indicating that one or more type parameters are referenced
// in the parameter types of the contextual signature. Now also infer from the return type.
applyToReturnTypes(instantiatedSignature, contextualSignature, (source, target) => {
inferTypes(inferences, source, target);
});
// If the type parameters for which we produced candidates do not have any inferences yet,
// 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 (!hasOverlappingInferences(context.inferences, inferences)) {
mergeInferences(context.inferences, inferences);
context.inferredTypeParameters = concatenate(context.inferredTypeParameters, uniqueTypeParameters);
return getOrCreateTypeFromSignature(instantiatedSignature);
}
}
}
return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, context));
@@ -23880,7 +23871,8 @@ namespace ts {
return;
}
const typePredicate = getTypePredicateOfSignature(getSignatureFromDeclaration(parent));
const signature = getSignatureFromDeclaration(parent);
const typePredicate = getTypePredicateOfSignature(signature);
if (!typePredicate) {
return;
}
@@ -23893,14 +23885,13 @@ namespace ts {
}
else {
if (typePredicate.parameterIndex >= 0) {
if (parent.parameters[typePredicate.parameterIndex].dotDotDotToken) {
error(parameterName,
Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
if (signature.hasRestParameter && typePredicate.parameterIndex === signature.parameters.length - 1) {
error(parameterName, Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
}
else {
const leadingError = () => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type);
checkTypeAssignableTo(typePredicate.type,
getTypeOfNode(parent.parameters[typePredicate.parameterIndex]),
getTypeOfSymbol(signature.parameters[typePredicate.parameterIndex]),
node.type,
/*headMessage*/ undefined,
leadingError);
@@ -27985,8 +27976,8 @@ namespace ts {
// The following checks only apply on a non-ambient instantiated module declaration.
if (symbol.flags & SymbolFlags.ValueModule
&& symbol.declarations.length > 1
&& !inAmbientContext
&& symbol.declarations.length > 1
&& isInstantiatedModule(node, !!compilerOptions.preserveConstEnums || !!compilerOptions.isolatedModules)) {
const firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol);
if (firstNonAmbientClassOrFunc) {
+32 -13
View File
@@ -420,8 +420,10 @@ namespace ts {
const savedCapturedSuperProperties = capturedSuperProperties;
const savedHasSuperElementAccess = hasSuperElementAccess;
capturedSuperProperties = createUnderscoreEscapedMap<true>();
hasSuperElementAccess = false;
if (!isArrowFunction) {
capturedSuperProperties = createUnderscoreEscapedMap<true>();
hasSuperElementAccess = false;
}
let result: ConciseBody;
if (!isArrowFunction) {
@@ -446,9 +448,11 @@ namespace ts {
if (emitSuperHelpers) {
enableSubstitutionForAsyncMethodsWithSuper();
const variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
substitutedSuperAccessors[getNodeId(variableStatement)] = true;
insertStatementsAfterStandardPrologue(statements, [variableStatement]);
if (hasEntries(capturedSuperProperties)) {
const variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
substitutedSuperAccessors[getNodeId(variableStatement)] = true;
insertStatementsAfterStandardPrologue(statements, [variableStatement]);
}
}
const block = createBlock(statements, /*multiLine*/ true);
@@ -485,8 +489,10 @@ namespace ts {
}
enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
capturedSuperProperties = savedCapturedSuperProperties;
hasSuperElementAccess = savedHasSuperElementAccess;
if (!isArrowFunction) {
capturedSuperProperties = savedCapturedSuperProperties;
hasSuperElementAccess = savedHasSuperElementAccess;
}
return result;
}
@@ -684,9 +690,15 @@ namespace ts {
/* parameters */ [],
/* type */ undefined,
/* equalsGreaterThanToken */ undefined,
createPropertyAccess(
createSuper(),
name
setEmitFlags(
createPropertyAccess(
setEmitFlags(
createSuper(),
EmitFlags.NoSubstitution
),
name
),
EmitFlags.NoSubstitution
)
)
));
@@ -711,9 +723,16 @@ namespace ts {
/* type */ undefined,
/* equalsGreaterThanToken */ undefined,
createAssignment(
createPropertyAccess(
createSuper(),
name),
setEmitFlags(
createPropertyAccess(
setEmitFlags(
createSuper(),
EmitFlags.NoSubstitution
),
name
),
EmitFlags.NoSubstitution
),
createIdentifier("v")
)
)
+1
View File
@@ -1189,6 +1189,7 @@ namespace ts {
}
function getOldProgram(proj: ResolvedConfigFileName, parsed: ParsedCommandLine) {
if (options.force) return undefined;
const value = builderPrograms.getValue(proj);
if (value) return value;
return readBuilderProgram(parsed.options, readFileWithCache) as any as T;
+3
View File
@@ -3171,6 +3171,7 @@ namespace ts {
getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined;
/* @internal */ getResolvedSignatureForSignatureHelp(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined;
/* @internal */ getExpandedParameters(sig: Signature): ReadonlyArray<Symbol>;
/* @internal */ hasEffectiveRestParameter(sig: Signature): boolean;
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature | undefined;
isImplementationOfOverload(node: SignatureDeclaration): boolean | undefined;
isUndefinedSymbol(symbol: Symbol): boolean;
@@ -3251,6 +3252,8 @@ namespace ts {
/* @internal */ getSymbolCount(): number;
/* @internal */ getTypeCount(): number;
/* @internal */ isArrayType(type: Type): boolean;
/* @internal */ isTupleType(type: Type): boolean;
/* @internal */ isArrayLikeType(type: Type): boolean;
/* @internal */ getObjectFlags(type: Type): ObjectFlags;