Address CR feedback

This commit is contained in:
Anders Hejlsberg 2019-09-10 16:24:00 -07:00
parent 2c36249ed6
commit 21528748c6
3 changed files with 24 additions and 16 deletions

View file

@ -1281,7 +1281,8 @@ namespace ts {
function isDottedName(node: Expression): boolean {
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword ||
node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((<PropertyAccessExpression>node).expression);
node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((<PropertyAccessExpression>node).expression) ||
node.kind === SyntaxKind.ParenthesizedExpression && isDottedName((<ParenthesizedExpression>node).expression);
}
function bindExpressionStatement(node: ExpressionStatement): void {

View file

@ -16852,7 +16852,7 @@ namespace ts {
return !!(declaration && (
declaration.kind === SyntaxKind.VariableDeclaration || declaration.kind === SyntaxKind.Parameter ||
declaration.kind === SyntaxKind.PropertyDeclaration || declaration.kind === SyntaxKind.PropertySignature) &&
(declaration as VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature).type);
getEffectiveTypeAnnotationNode(declaration as VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature));
}
function getExplicitTypeOfSymbol(symbol: Symbol) {
@ -16861,11 +16861,11 @@ namespace ts {
getTypeOfSymbol(symbol) : undefined;
}
function getTypeOfDottedName(node: Expression) {
// We require the dotted function name in an assertion expression to be comprised of identifiers
// that reference function, method, class or value module symbols; or variable, property or
// parameter symbols with declarations that have explicit type annotations. Such references are
// resolvable with no possibility of triggering circularities in control flow analysis.
// We require the dotted function name in an assertion expression to be comprised of identifiers
// that reference function, method, class or value module symbols; or variable, property or
// parameter symbols with declarations that have explicit type annotations. Such references are
// resolvable with no possibility of triggering circularities in control flow analysis.
function getTypeOfDottedName(node: Expression): Type | undefined {
switch (node.kind) {
case SyntaxKind.Identifier:
const symbol = getResolvedSymbol(<Identifier>node);
@ -16874,10 +16874,10 @@ namespace ts {
return checkThisExpression(node);
case SyntaxKind.PropertyAccessExpression:
const type = getTypeOfDottedName((<PropertyAccessExpression>node).expression);
if (type) {
const prop = getPropertyOfType(type, (<PropertyAccessExpression>node).name.escapedText);
return prop && getExplicitTypeOfSymbol(prop);
}
const prop = type && getPropertyOfType(type, (<PropertyAccessExpression>node).name.escapedText);
return prop && getExplicitTypeOfSymbol(prop);
case SyntaxKind.ParenthesizedExpression:
return getTypeOfDottedName((<ParenthesizedExpression>node).expression);
}
}
@ -16886,7 +16886,9 @@ namespace ts {
let signature = links.effectsSignature;
if (signature === undefined) {
// A call expression parented by an expression statement is a potential assertion. Other call
// expressions are potential type predicate function calls.
// expressions are potential type predicate function calls. In order to avoid triggering
// circularities in control flow analysis, we use getTypeOfDottedName when resolving the call
// target expression of an assertion.
const funcType = node.parent.kind === SyntaxKind.ExpressionStatement ? getTypeOfDottedName(node.expression) :
node.expression.kind !== SyntaxKind.SuperKeyword ? checkNonNullExpression(node.expression) :
undefined;

View file

@ -3518,28 +3518,33 @@ namespace ts {
AssertsIdentifier
}
export interface ThisTypePredicate {
export interface TypePredicateBase {
kind: TypePredicateKind;
type: Type | undefined;
}
export interface ThisTypePredicate extends TypePredicateBase {
kind: TypePredicateKind.This;
parameterName: undefined;
parameterIndex: undefined;
type: Type;
}
export interface IdentifierTypePredicate {
export interface IdentifierTypePredicate extends TypePredicateBase {
kind: TypePredicateKind.Identifier;
parameterName: string;
parameterIndex: number;
type: Type;
}
export interface AssertsThisTypePredicate {
export interface AssertsThisTypePredicate extends TypePredicateBase {
kind: TypePredicateKind.AssertsThis;
parameterName: undefined;
parameterIndex: undefined;
type: Type | undefined;
}
export interface AssertsIdentifierTypePredicate {
export interface AssertsIdentifierTypePredicate extends TypePredicateBase {
kind: TypePredicateKind.AssertsIdentifier;
parameterName: string;
parameterIndex: number;