diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 457f9ad676d..c517a3aee45 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5156,15 +5156,15 @@ module ts { } } - function checkPropertyAccess(node: PropertyAccessExpression) { - return checkPropertyAccessCore(node, node.left, node.right); + function checkPropertyAccessExpression(node: PropertyAccessExpression) { + return checkPropertyAccessExpressionOrQualifiedName(node, node.left, node.right); } function checkQualifiedName(node: QualifiedName) { - return checkPropertyAccessCore(node, node.left, node.right); + return checkPropertyAccessExpressionOrQualifiedName(node, node.left, node.right); } - function checkPropertyAccessCore(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) { + function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) { var type = checkExpression(left); if (type === unknownType) return type; if (type !== anyType) { @@ -6575,7 +6575,7 @@ module ts { case SyntaxKind.ObjectLiteralExpression: return checkObjectLiteral(node, contextualMapper); case SyntaxKind.PropertyAccessExpression: - return checkPropertyAccess(node); + return checkPropertyAccessExpression(node); case SyntaxKind.ElementAccessExpression: return checkIndexedAccess(node); case SyntaxKind.CallExpression: @@ -8817,27 +8817,29 @@ module ts { } function isRightSideOfQualifiedNameOrPropertyAccess(node: Node) { - return (node.parent.kind === SyntaxKind.QualifiedName || node.parent.kind === SyntaxKind.PropertyAccessExpression) && - (node.parent).right === node; + return (node.parent.kind === SyntaxKind.QualifiedName && (node.parent).right === node) || + (node.parent.kind === SyntaxKind.PropertyAccessExpression && (node.parent).right === node); } - function getSymbolOfEntityName(entityName: EntityName): Symbol { + function getSymbolOfEntityNameOrPropertyAccessExpression(entityName: EntityName | PropertyAccessExpression): Symbol { if (isDeclarationOrFunctionExpressionOrCatchVariableName(entityName)) { return getSymbolOfNode(entityName.parent); } if (entityName.parent.kind === SyntaxKind.ExportAssignment) { - return resolveEntityName(/*location*/ entityName.parent.parent, entityName, + return resolveEntityName(/*location*/ entityName.parent.parent, entityName, /*all meanings*/ SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Import); } - if (isInRightSideOfImportOrExportAssignment(entityName)) { - // Since we already checked for ExportAssignment, this really could only be an Import - return getSymbolOfPartOfRightHandSideOfImport(entityName); + if (entityName.kind !== SyntaxKind.PropertyAccessExpression) { + if (isInRightSideOfImportOrExportAssignment(entityName)) { + // Since we already checked for ExportAssignment, this really could only be an Import + return getSymbolOfPartOfRightHandSideOfImport(entityName); + } } if (isRightSideOfQualifiedNameOrPropertyAccess(entityName)) { - entityName = entityName.parent; + entityName = entityName.parent; } if (isExpression(entityName)) { @@ -8845,9 +8847,16 @@ module ts { // Include Import in the meaning, this ensures that we do not follow aliases to where they point and instead // return the alias symbol. var meaning: SymbolFlags = SymbolFlags.Value | SymbolFlags.Import; - return resolveEntityName(entityName, entityName, meaning); + return resolveEntityName(entityName, entityName, meaning); } - else if (entityName.kind === SyntaxKind.QualifiedName || entityName.kind === SyntaxKind.PropertyAccessExpression) { + else if (entityName.kind === SyntaxKind.PropertyAccessExpression) { + var symbol = getNodeLinks(entityName).resolvedSymbol; + if (!symbol) { + checkPropertyAccessExpression(entityName); + } + return getNodeLinks(entityName).resolvedSymbol; + } + else if (entityName.kind === SyntaxKind.QualifiedName) { var symbol = getNodeLinks(entityName).resolvedSymbol; if (!symbol) { checkQualifiedName(entityName); @@ -8859,12 +8868,12 @@ module ts { return; } } - else if (isTypeReferenceIdentifier(entityName)) { + else if (isTypeReferenceIdentifier(entityName)) { var meaning = entityName.parent.kind === SyntaxKind.TypeReference ? SymbolFlags.Type : SymbolFlags.Namespace; // Include Import in the meaning, this ensures that we do not follow aliases to where they point and instead // return the alias symbol. meaning |= SymbolFlags.Import; - return resolveEntityName(entityName, entityName, meaning); + return resolveEntityName(entityName, entityName, meaning); } // Do we want to return undefined here? @@ -8884,7 +8893,7 @@ module ts { if (node.kind === SyntaxKind.Identifier && isInRightSideOfImportOrExportAssignment(node)) { return node.parent.kind === SyntaxKind.ExportAssignment - ? getSymbolOfEntityName(node) + ? getSymbolOfEntityNameOrPropertyAccessExpression(node) : getSymbolOfPartOfRightHandSideOfImport(node); } @@ -8892,7 +8901,7 @@ module ts { case SyntaxKind.Identifier: case SyntaxKind.PropertyAccessExpression: case SyntaxKind.QualifiedName: - return getSymbolOfEntityName(node); + return getSymbolOfEntityNameOrPropertyAccessExpression(node); case SyntaxKind.ThisKeyword: case SyntaxKind.SuperKeyword: diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index df6c2488b0f..8a9f6c4e80a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -537,7 +537,10 @@ module ts { case SyntaxKind.OmittedExpression: return true; case SyntaxKind.QualifiedName: - while (node.parent.kind === SyntaxKind.QualifiedName) node = node.parent; + while (node.parent.kind === SyntaxKind.QualifiedName) { + node = node.parent; + } + return node.parent.kind === SyntaxKind.TypeQuery; case SyntaxKind.Identifier: if (node.parent.kind === SyntaxKind.TypeQuery) {