Address PR feedback

This commit is contained in:
Jason Freeman 2014-08-18 18:51:18 -07:00
parent 58a99f3aea
commit a08aa14a74
3 changed files with 35 additions and 26 deletions

View file

@ -2296,6 +2296,12 @@ module ts {
return getTypeFromArrayTypeNode(<ArrayTypeNode>node); return getTypeFromArrayTypeNode(<ArrayTypeNode>node);
case SyntaxKind.TypeLiteral: case SyntaxKind.TypeLiteral:
return getTypeFromTypeLiteralNode(<TypeLiteralNode>node); return getTypeFromTypeLiteralNode(<TypeLiteralNode>node);
// This function assumes that an identifier or qualified name is a type expression
// Callers should first ensure this by calling isTypeNode
case SyntaxKind.Identifier:
case SyntaxKind.QualifiedName:
var symbol = getSymbolInfo(node);
return getDeclaredTypeOfSymbol(symbol);
default: default:
return unknownType; return unknownType;
} }
@ -6544,13 +6550,15 @@ module ts {
return mapToArray(symbols); return mapToArray(symbols);
} }
// True if the given identifier, string literal, or number literal is the name of a declaration node // True if the given identifier is the name of a type declaration node (class, interface, enum, type parameter, etc)
function isTypeDeclarationName(name: Node): boolean { function isTypeDeclarationName(name: Node): boolean {
return name.kind == SyntaxKind.Identifier && isTypeDeclaration(name.parent); return name.kind == SyntaxKind.Identifier &&
isTypeDeclaration(name.parent) &&
(<Declaration>name.parent).name === name;
} }
// True if the given identifier, string literal, or number literal is the name of a declaration node // True if the given identifier, string literal, or number literal is the name of a declaration node
function isDeclarationName(name: Node): boolean { function isDeclarationOrFunctionExpressionOrCatchVariableName(name: Node): boolean {
if (name.kind !== SyntaxKind.Identifier && name.kind !== SyntaxKind.StringLiteral && name.kind !== SyntaxKind.NumericLiteral) { if (name.kind !== SyntaxKind.Identifier && name.kind !== SyntaxKind.StringLiteral && name.kind !== SyntaxKind.NumericLiteral) {
return false; return false;
} }
@ -6607,7 +6615,6 @@ module ts {
} }
function isExpression(node: Node): boolean { function isExpression(node: Node): boolean {
// Omitted expression?
switch (node.kind) { switch (node.kind) {
case SyntaxKind.ThisKeyword: case SyntaxKind.ThisKeyword:
case SyntaxKind.SuperKeyword: case SyntaxKind.SuperKeyword:
@ -6629,6 +6636,7 @@ module ts {
case SyntaxKind.PostfixOperator: case SyntaxKind.PostfixOperator:
case SyntaxKind.BinaryExpression: case SyntaxKind.BinaryExpression:
case SyntaxKind.ConditionalExpression: case SyntaxKind.ConditionalExpression:
case SyntaxKind.OmittedExpression:
return true; return true;
case SyntaxKind.QualifiedName: case SyntaxKind.QualifiedName:
while (node.parent.kind === SyntaxKind.QualifiedName) node = node.parent; while (node.parent.kind === SyntaxKind.QualifiedName) node = node.parent;
@ -6641,14 +6649,6 @@ module ts {
case SyntaxKind.NumericLiteral: case SyntaxKind.NumericLiteral:
case SyntaxKind.StringLiteral: case SyntaxKind.StringLiteral:
var parent = node.parent; var parent = node.parent;
if (parent.kind === SyntaxKind.TypeAssertion) {
return node === (<TypeAssertion>parent).operand;
}
if (isExpression(parent)) {
return true;
}
switch (parent.kind) { switch (parent.kind) {
case SyntaxKind.VariableDeclaration: case SyntaxKind.VariableDeclaration:
case SyntaxKind.Parameter: case SyntaxKind.Parameter:
@ -6667,10 +6667,18 @@ module ts {
case SyntaxKind.SwitchStatement: case SyntaxKind.SwitchStatement:
return (<ExpressionStatement>parent).expression === node; return (<ExpressionStatement>parent).expression === node;
case SyntaxKind.ForStatement: case SyntaxKind.ForStatement:
return (<ForStatement>parent).initializer === node || (<ForStatement>parent).condition === node || return (<ForStatement>parent).initializer === node ||
(<ForStatement>parent).condition === node ||
(<ForStatement>parent).iterator === node; (<ForStatement>parent).iterator === node;
case SyntaxKind.ForInStatement: case SyntaxKind.ForInStatement:
return (<ForInStatement>parent).variable === node || (<ForInStatement>parent).expression === node; return (<ForInStatement>parent).variable === node ||
(<ForInStatement>parent).expression === node;
case SyntaxKind.TypeAssertion:
return node === (<TypeAssertion>parent).operand;
default:
if (isExpression(parent)) {
return true;
}
} }
} }
return false; return false;
@ -6690,6 +6698,7 @@ module ts {
case SyntaxKind.VoidKeyword: case SyntaxKind.VoidKeyword:
return node.parent.kind !== SyntaxKind.PrefixOperator; return node.parent.kind !== SyntaxKind.PrefixOperator;
case SyntaxKind.StringLiteral: case SyntaxKind.StringLiteral:
// Specialized signatures can have string literals as their parameters' type names
return node.parent.kind === SyntaxKind.Parameter; return node.parent.kind === SyntaxKind.Parameter;
// Identifiers and qualified names may be type nodes, depending on their context. Climb // Identifiers and qualified names may be type nodes, depending on their context. Climb
// above them to find the lowest container // above them to find the lowest container
@ -6700,6 +6709,7 @@ module ts {
} }
// Fall through // Fall through
case SyntaxKind.QualifiedName: case SyntaxKind.QualifiedName:
// At this point, node is either a qualified name or an identifier
var parent = node.parent; var parent = node.parent;
if (parent.kind === SyntaxKind.TypeQuery) { if (parent.kind === SyntaxKind.TypeQuery) {
return false; return false;
@ -6710,7 +6720,7 @@ module ts {
// //
// Calling isTypeNode would consider the qualified name A.B a type node. Only C or // Calling isTypeNode would consider the qualified name A.B a type node. Only C or
// A.B.C is a type node. // A.B.C is a type node.
if (node.kind >= SyntaxKind.FirstTypeNode && node.kind <= SyntaxKind.LastTypeNode) { if (parent.kind >= SyntaxKind.FirstTypeNode && parent.kind <= SyntaxKind.LastTypeNode) {
return true; return true;
} }
switch (parent.kind) { switch (parent.kind) {
@ -6764,7 +6774,7 @@ module ts {
} }
function getSymbolOfIdentifier(identifier: Identifier) { function getSymbolOfIdentifier(identifier: Identifier) {
if (isDeclarationName(identifier)) { if (isDeclarationOrFunctionExpressionOrCatchVariableName(identifier)) {
return getSymbolOfNode(identifier.parent); return getSymbolOfNode(identifier.parent);
} }
@ -6852,10 +6862,6 @@ module ts {
return getTypeOfExpression(<Expression>node); return getTypeOfExpression(<Expression>node);
} }
if (isTypeNode(node)) { if (isTypeNode(node)) {
if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) {
var symbol = getSymbolInfo(node);
return getDeclaredTypeOfSymbol(symbol);
}
return getTypeFromTypeNode(<TypeNode>node); return getTypeFromTypeNode(<TypeNode>node);
} }
@ -6876,7 +6882,7 @@ module ts {
return getTypeOfSymbol(symbol); return getTypeOfSymbol(symbol);
} }
if (isDeclarationName(node)) { if (isDeclarationOrFunctionExpressionOrCatchVariableName(node)) {
var symbol = getSymbolInfo(node); var symbol = getSymbolInfo(node);
return getTypeOfSymbol(symbol); return getTypeOfSymbol(symbol);
} }

View file

@ -76,15 +76,18 @@ class TypeWriterWalker {
private log(node: ts.Node, type: ts.Type): void { private log(node: ts.Node, type: ts.Type): void {
var actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos); var actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos);
var lineAndCharacter = this.currentSourceFile.getLineAndCharacterFromPosition(actualPos); var lineAndCharacter = this.currentSourceFile.getLineAndCharacterFromPosition(actualPos);
var name = ts.getSourceTextOfNodeFromSourceText(this.currentSourceFile.text, node); var sourceText = ts.getSourceTextOfNodeFromSourceText(this.currentSourceFile.text, node);
var isUnkownType = (<ts.IntrinsicType>type).intrinsicName === "unknown"; var isUnknownType = (<ts.IntrinsicType>type).intrinsicName === "unknown";
// If we got an unknown type, we temporarily want to fall back to just pretending the name
// (source text) of the node is the type. This is to align with the old typeWriter to make
// baseline comparisons easier. In the long term, we will want to just call typeToString
this.results.push({ this.results.push({
line: lineAndCharacter.line - 1, line: lineAndCharacter.line - 1,
column: lineAndCharacter.character, column: lineAndCharacter.character,
syntaxKind: ts.SyntaxKind[node.kind], syntaxKind: ts.SyntaxKind[node.kind],
identifierName: name, identifierName: sourceText,
type: isUnkownType ? name : this.checker.typeToString(type) type: isUnknownType ? sourceText : this.checker.typeToString(type)
}); });
} }

View file

@ -1693,7 +1693,7 @@ module ts {
// Right of dot member completion list // Right of dot member completion list
if (isRightOfDot) { if (isRightOfDot) {
var type: Type = typeInfoResolver.getApparentType(typeInfoResolver.getTypeOfNode(mappedNode)); var type: ApparentType = typeInfoResolver.getApparentType(typeInfoResolver.getTypeOfNode(mappedNode));
if (!type) { if (!type) {
return undefined; return undefined;
} }