mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-27 22:39:59 -05:00
Merge pull request #676 from Microsoft/completionFixes
Completion fixes
This commit is contained in:
@@ -2432,7 +2432,7 @@ module ts {
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.QualifiedName:
|
||||
var symbol = getSymbolInfo(node);
|
||||
return getDeclaredTypeOfSymbol(symbol);
|
||||
return symbol && getDeclaredTypeOfSymbol(symbol);
|
||||
default:
|
||||
return unknownType;
|
||||
}
|
||||
@@ -3472,41 +3472,6 @@ module ts {
|
||||
return getAncestor(node, kind) !== undefined;
|
||||
}
|
||||
|
||||
function getAncestor(node: Node, kind: SyntaxKind): Node {
|
||||
switch (kind) {
|
||||
// special-cases that can be come first
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
while (node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return <ClassDeclaration>node;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
// early exit cases - declarations cannot be nested in classes
|
||||
return undefined;
|
||||
default:
|
||||
node = node.parent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
while (node) {
|
||||
if (node.kind === kind) {
|
||||
return node;
|
||||
}
|
||||
else {
|
||||
node = node.parent;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// EXPRESSION TYPE CHECKING
|
||||
|
||||
function checkIdentifier(node: Identifier): Type {
|
||||
@@ -3853,6 +3818,11 @@ module ts {
|
||||
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
|
||||
// be "pushed" onto a node using the contextualType property.
|
||||
function getContextualType(node: Expression): Type {
|
||||
if (isInsideWithStatementBody(node)) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (node.contextualType) {
|
||||
return node.contextualType;
|
||||
}
|
||||
@@ -6718,7 +6688,20 @@ module ts {
|
||||
return findChildAtPosition(sourceFile);
|
||||
}
|
||||
|
||||
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] {
|
||||
function isInsideWithStatementBody(node: Node): boolean {
|
||||
if (node) {
|
||||
while (node.parent) {
|
||||
if (node.parent.kind === SyntaxKind.WithStatement && (<WithStatement>node.parent).statement === node) {
|
||||
return true;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]{
|
||||
var symbols: SymbolTable = {};
|
||||
var memberFlags: NodeFlags = 0;
|
||||
function copySymbol(symbol: Symbol, meaning: SymbolFlags) {
|
||||
@@ -6738,6 +6721,12 @@ module ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isInsideWithStatementBody(location)) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return [];
|
||||
}
|
||||
|
||||
while (location) {
|
||||
if (location.locals && !isGlobalSourceFile(location)) {
|
||||
copySymbols(location.locals, meaning);
|
||||
@@ -7010,6 +6999,11 @@ module ts {
|
||||
}
|
||||
|
||||
function getSymbolInfo(node: Node) {
|
||||
if (isInsideWithStatementBody(node)) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (isDeclarationOrFunctionExpressionOrCatchVariableName(node)) {
|
||||
// This is a declaration, call getSymbolOfNode
|
||||
return getSymbolOfNode(node.parent);
|
||||
@@ -7064,9 +7058,15 @@ module ts {
|
||||
}
|
||||
|
||||
function getTypeOfNode(node: Node): Type {
|
||||
if (isInsideWithStatementBody(node)) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
if (isExpression(node)) {
|
||||
return getTypeOfExpression(<Expression>node);
|
||||
}
|
||||
|
||||
if (isTypeNode(node)) {
|
||||
return getTypeFromTypeNode(<TypeNode>node);
|
||||
}
|
||||
@@ -7079,7 +7079,7 @@ module ts {
|
||||
|
||||
if (isTypeDeclarationName(node)) {
|
||||
var symbol = getSymbolInfo(node);
|
||||
return getDeclaredTypeOfSymbol(symbol);
|
||||
return symbol && getDeclaredTypeOfSymbol(symbol);
|
||||
}
|
||||
|
||||
if (isDeclaration(node)) {
|
||||
@@ -7090,12 +7090,12 @@ module ts {
|
||||
|
||||
if (isDeclarationOrFunctionExpressionOrCatchVariableName(node)) {
|
||||
var symbol = getSymbolInfo(node);
|
||||
return getTypeOfSymbol(symbol);
|
||||
return symbol && getTypeOfSymbol(symbol);
|
||||
}
|
||||
|
||||
if (isInRightSideOfImportOrExportAssignment(node)) {
|
||||
var symbol = getSymbolInfo(node);
|
||||
var declaredType = getDeclaredTypeOfSymbol(symbol);
|
||||
var declaredType = symbol && getDeclaredTypeOfSymbol(symbol);
|
||||
return declaredType !== unknownType ? declaredType : getTypeOfSymbol(symbol);
|
||||
}
|
||||
|
||||
@@ -7147,7 +7147,7 @@ module ts {
|
||||
}
|
||||
|
||||
function getRootSymbol(symbol: Symbol) {
|
||||
return (symbol.flags & SymbolFlags.Transient) ? getSymbolLinks(symbol).target : symbol;
|
||||
return ((symbol.flags & SymbolFlags.Transient) && getSymbolLinks(symbol).target) || symbol;
|
||||
}
|
||||
|
||||
// Emitter support
|
||||
|
||||
@@ -531,6 +531,39 @@ module ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getAncestor(node: Node, kind: SyntaxKind): Node {
|
||||
switch (kind) {
|
||||
// special-cases that can be come first
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
while (node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return <ClassDeclaration>node;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
// early exit cases - declarations cannot be nested in classes
|
||||
return undefined;
|
||||
default:
|
||||
node = node.parent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
while (node) {
|
||||
if (node.kind === kind) {
|
||||
return node;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
enum ParsingContext {
|
||||
SourceElements, // Elements in source file
|
||||
ModuleElements, // Elements in module declaration
|
||||
@@ -2200,10 +2233,38 @@ module ts {
|
||||
|
||||
function parseCallAndAccess(expr: Expression, inNewExpression: boolean): Expression {
|
||||
while (true) {
|
||||
var dotStart = scanner.getTokenPos();
|
||||
if (parseOptional(SyntaxKind.DotToken)) {
|
||||
var propertyAccess = <PropertyAccess>createNode(SyntaxKind.PropertyAccess, expr.pos);
|
||||
// Technically a keyword is valid here as all keywords are identifier names.
|
||||
// However, often we'll encounter this in error situations when the keyword
|
||||
// is actually starting another valid construct.
|
||||
//
|
||||
// So, we check for the following specific case:
|
||||
//
|
||||
// name.
|
||||
// keyword identifierNameOrKeyword
|
||||
//
|
||||
// Note: the newlines are important here. For example, if that above code
|
||||
// were rewritten into:
|
||||
//
|
||||
// name.keyword
|
||||
// identifierNameOrKeyword
|
||||
//
|
||||
// Then we would consider it valid. That's because ASI would take effect and
|
||||
// the code would be implicitly: "name.keyword; identifierNameOrKeyword".
|
||||
// In the first case though, ASI will not take effect because there is not a
|
||||
// line terminator after the keyword.
|
||||
if (scanner.hasPrecedingLineBreak() && scanner.isReservedWord() && lookAhead(() => scanner.isReservedWord())) {
|
||||
grammarErrorAtPos(dotStart, scanner.getStartPos() - dotStart, Diagnostics.Identifier_expected);
|
||||
var id = <Identifier>createMissingNode();
|
||||
}
|
||||
else {
|
||||
var id = parseIdentifierName();
|
||||
}
|
||||
|
||||
propertyAccess.left = expr;
|
||||
propertyAccess.right = parseIdentifierName();
|
||||
propertyAccess.right = id;
|
||||
expr = finishNode(propertyAccess);
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user