Merge pull request #2485 from Microsoft/transitiveExports

Fix completion lists for transitive exports
This commit is contained in:
Daniel Rosenwasser 2015-04-01 13:50:29 -07:00
commit 490dfef41b
16 changed files with 208 additions and 55 deletions

View file

@ -74,7 +74,7 @@ module ts {
isImplementationOfOverload,
getAliasedSymbol: resolveAlias,
getEmitResolver,
getExportsOfExternalModule,
getExportsOfModule: getExportsOfModuleAsArray,
};
let unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown");
@ -898,6 +898,10 @@ module ts {
return moduleSymbol.exports["export="];
}
function getExportsOfModuleAsArray(moduleSymbol: Symbol): Symbol[] {
return symbolsToArray(getExportsOfModule(moduleSymbol));
}
function getExportsOfSymbol(symbol: Symbol): SymbolTable {
return symbol.flags & SymbolFlags.Module ? getExportsOfModule(symbol) : symbol.exports || emptySymbols;
}
@ -3032,17 +3036,6 @@ module ts {
return result;
}
function getExportsOfExternalModule(node: ImportDeclaration): Symbol[] {
if (!node.moduleSpecifier) {
return emptyArray;
}
let module = resolveExternalModuleName(node, node.moduleSpecifier);
if (!module) {
return emptyArray;
}
return symbolsToArray(getExportsOfModule(module));
}
function getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature {
let links = getNodeLinks(declaration);
if (!links.resolvedSignature) {

View file

@ -933,7 +933,7 @@ module ts {
// import "mod" => importClause = undefined, moduleSpecifier = "mod"
// In rest of the cases, module specifier is string literal corresponding to module
// ImportClause information is shown at its declaration below.
export interface ImportDeclaration extends Statement, ModuleElement {
export interface ImportDeclaration extends ModuleElement {
importClause?: ImportClause;
moduleSpecifier: Expression;
}
@ -1146,7 +1146,7 @@ module ts {
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
getAliasedSymbol(symbol: Symbol): Symbol;
getExportsOfExternalModule(node: ImportDeclaration): Symbol[];
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
// Should not be called directly. Should only be accessed through the Program instance.
/* @internal */ getDiagnostics(sourceFile?: SourceFile): Diagnostic[];

View file

@ -2598,7 +2598,8 @@ module ts {
if (symbol && symbol.flags & SymbolFlags.HasExports) {
// Extract module or enum members
forEachValue(symbol.exports, symbol => {
let exportedSymbols = typeInfoResolver.getExportsOfModule(symbol);
forEach(exportedSymbols, symbol => {
if (typeInfoResolver.isValidPropertyAccess(<PropertyAccessExpression>(node.parent), symbol.name)) {
symbols.push(symbol);
}
@ -2642,8 +2643,17 @@ module ts {
if (showCompletionsInImportsClause(contextToken)) {
let importDeclaration = <ImportDeclaration>getAncestor(contextToken, SyntaxKind.ImportDeclaration);
Debug.assert(importDeclaration !== undefined);
let exports = typeInfoResolver.getExportsOfExternalModule(importDeclaration);
symbols = filterModuleExports(exports, importDeclaration);
let exports: Symbol[];
if (importDeclaration.moduleSpecifier) {
let moduleSpecifierSymbol = typeInfoResolver.getSymbolAtLocation(importDeclaration.moduleSpecifier);
if (moduleSpecifierSymbol) {
exports = typeInfoResolver.getExportsOfModule(moduleSpecifierSymbol);
}
}
//let exports = typeInfoResolver.getExportsOfImportDeclaration(importDeclaration);
symbols = exports ? filterModuleExports(exports, importDeclaration) : emptyArray;
}
}
else {

View file

@ -760,7 +760,7 @@ declare module "typescript" {
interface ExternalModuleReference extends Node {
expression?: Expression;
}
interface ImportDeclaration extends Statement, ModuleElement {
interface ImportDeclaration extends ModuleElement {
importClause?: ImportClause;
moduleSpecifier: Expression;
}
@ -902,7 +902,7 @@ declare module "typescript" {
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
getAliasedSymbol(symbol: Symbol): Symbol;
getExportsOfExternalModule(node: ImportDeclaration): Symbol[];
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
}
interface SymbolDisplayBuilder {
buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;

View file

@ -2307,9 +2307,8 @@ declare module "typescript" {
>expression : Expression
>Expression : Expression
}
interface ImportDeclaration extends Statement, ModuleElement {
interface ImportDeclaration extends ModuleElement {
>ImportDeclaration : ImportDeclaration
>Statement : Statement
>ModuleElement : ModuleElement
importClause?: ImportClause;
@ -2818,10 +2817,10 @@ declare module "typescript" {
>Symbol : Symbol
>Symbol : Symbol
getExportsOfExternalModule(node: ImportDeclaration): Symbol[];
>getExportsOfExternalModule : (node: ImportDeclaration) => Symbol[]
>node : ImportDeclaration
>ImportDeclaration : ImportDeclaration
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
>getExportsOfModule : (moduleSymbol: Symbol) => Symbol[]
>moduleSymbol : Symbol
>Symbol : Symbol
>Symbol : Symbol
}
interface SymbolDisplayBuilder {

View file

@ -791,7 +791,7 @@ declare module "typescript" {
interface ExternalModuleReference extends Node {
expression?: Expression;
}
interface ImportDeclaration extends Statement, ModuleElement {
interface ImportDeclaration extends ModuleElement {
importClause?: ImportClause;
moduleSpecifier: Expression;
}
@ -933,7 +933,7 @@ declare module "typescript" {
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
getAliasedSymbol(symbol: Symbol): Symbol;
getExportsOfExternalModule(node: ImportDeclaration): Symbol[];
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
}
interface SymbolDisplayBuilder {
buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;

View file

@ -2453,9 +2453,8 @@ declare module "typescript" {
>expression : Expression
>Expression : Expression
}
interface ImportDeclaration extends Statement, ModuleElement {
interface ImportDeclaration extends ModuleElement {
>ImportDeclaration : ImportDeclaration
>Statement : Statement
>ModuleElement : ModuleElement
importClause?: ImportClause;
@ -2964,10 +2963,10 @@ declare module "typescript" {
>Symbol : Symbol
>Symbol : Symbol
getExportsOfExternalModule(node: ImportDeclaration): Symbol[];
>getExportsOfExternalModule : (node: ImportDeclaration) => Symbol[]
>node : ImportDeclaration
>ImportDeclaration : ImportDeclaration
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
>getExportsOfModule : (moduleSymbol: Symbol) => Symbol[]
>moduleSymbol : Symbol
>Symbol : Symbol
>Symbol : Symbol
}
interface SymbolDisplayBuilder {

View file

@ -2453,9 +2453,8 @@ declare module "typescript" {
>expression : Expression
>Expression : Expression
}
interface ImportDeclaration extends Statement, ModuleElement {
interface ImportDeclaration extends ModuleElement {
>ImportDeclaration : ImportDeclaration
>Statement : Statement
>ModuleElement : ModuleElement
importClause?: ImportClause;
@ -2964,10 +2963,10 @@ declare module "typescript" {
>Symbol : Symbol
>Symbol : Symbol
getExportsOfExternalModule(node: ImportDeclaration): Symbol[];
>getExportsOfExternalModule : (node: ImportDeclaration) => Symbol[]
>node : ImportDeclaration
>ImportDeclaration : ImportDeclaration
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
>getExportsOfModule : (moduleSymbol: Symbol) => Symbol[]
>moduleSymbol : Symbol
>Symbol : Symbol
>Symbol : Symbol
}
interface SymbolDisplayBuilder {

View file

@ -792,7 +792,7 @@ declare module "typescript" {
interface ExternalModuleReference extends Node {
expression?: Expression;
}
interface ImportDeclaration extends Statement, ModuleElement {
interface ImportDeclaration extends ModuleElement {
importClause?: ImportClause;
moduleSpecifier: Expression;
}
@ -934,7 +934,7 @@ declare module "typescript" {
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
getAliasedSymbol(symbol: Symbol): Symbol;
getExportsOfExternalModule(node: ImportDeclaration): Symbol[];
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
}
interface SymbolDisplayBuilder {
buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;

View file

@ -2403,9 +2403,8 @@ declare module "typescript" {
>expression : Expression
>Expression : Expression
}
interface ImportDeclaration extends Statement, ModuleElement {
interface ImportDeclaration extends ModuleElement {
>ImportDeclaration : ImportDeclaration
>Statement : Statement
>ModuleElement : ModuleElement
importClause?: ImportClause;
@ -2914,10 +2913,10 @@ declare module "typescript" {
>Symbol : Symbol
>Symbol : Symbol
getExportsOfExternalModule(node: ImportDeclaration): Symbol[];
>getExportsOfExternalModule : (node: ImportDeclaration) => Symbol[]
>node : ImportDeclaration
>ImportDeclaration : ImportDeclaration
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
>getExportsOfModule : (moduleSymbol: Symbol) => Symbol[]
>moduleSymbol : Symbol
>Symbol : Symbol
>Symbol : Symbol
}
interface SymbolDisplayBuilder {

View file

@ -829,7 +829,7 @@ declare module "typescript" {
interface ExternalModuleReference extends Node {
expression?: Expression;
}
interface ImportDeclaration extends Statement, ModuleElement {
interface ImportDeclaration extends ModuleElement {
importClause?: ImportClause;
moduleSpecifier: Expression;
}
@ -971,7 +971,7 @@ declare module "typescript" {
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
getAliasedSymbol(symbol: Symbol): Symbol;
getExportsOfExternalModule(node: ImportDeclaration): Symbol[];
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
}
interface SymbolDisplayBuilder {
buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;

View file

@ -2576,9 +2576,8 @@ declare module "typescript" {
>expression : Expression
>Expression : Expression
}
interface ImportDeclaration extends Statement, ModuleElement {
interface ImportDeclaration extends ModuleElement {
>ImportDeclaration : ImportDeclaration
>Statement : Statement
>ModuleElement : ModuleElement
importClause?: ImportClause;
@ -3087,10 +3086,10 @@ declare module "typescript" {
>Symbol : Symbol
>Symbol : Symbol
getExportsOfExternalModule(node: ImportDeclaration): Symbol[];
>getExportsOfExternalModule : (node: ImportDeclaration) => Symbol[]
>node : ImportDeclaration
>ImportDeclaration : ImportDeclaration
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
>getExportsOfModule : (moduleSymbol: Symbol) => Symbol[]
>moduleSymbol : Symbol
>Symbol : Symbol
>Symbol : Symbol
}
interface SymbolDisplayBuilder {

View file

@ -0,0 +1,39 @@
///<reference path="fourslash.ts" />
// @Filename: A.ts
////export interface I1 { one: number }
////export interface I2 { two: string }
////export type I1_OR_I2 = I1 | I2;
////
////export class C1 {
//// one: string;
////}
////
////export module Inner {
//// export interface I3 {
//// three: boolean
//// }
////
//// export var varVar = 100;
//// export let letVar = 200;
//// export const constVar = 300;
////}
// @Filename: B.ts
////export var bVar = "bee!";
// @Filename: C.ts
////export var cVar = "see!";
////export * from "A";
////export * from "B"
// @Filename: D.ts
////import * as c from "C";
////var x = c./**/
goTo.marker();
verify.completionListContains("C1");
verify.completionListContains("Inner");
verify.completionListContains("bVar");
verify.completionListContains("cVar");
verify.not.completionListContains("__export");

View file

@ -0,0 +1,39 @@
///<reference path="fourslash.ts" />
// @Filename: A.ts
////export interface I1 { one: number }
////export interface I2 { two: string }
////export type I1_OR_I2 = I1 | I2;
////
////export class C1 {
//// one: string;
////}
////
////export module Inner {
//// export interface I3 {
//// three: boolean
//// }
////
//// export var varVar = 100;
//// export let letVar = 200;
//// export const constVar = 300;
////}
// @Filename: B.ts
////export var bVar = "bee!";
// @Filename: C.ts
////export var cVar = "see!";
////export * from "A";
////export * from "B"
// @Filename: D.ts
////import * as c from "C";
////var x = c.Inner./**/
goTo.marker();
verify.completionListContains("varVar");
verify.completionListContains("letVar");
verify.completionListContains("constVar");
verify.not.completionListContains("__export");

View file

@ -0,0 +1,40 @@
///<reference path="fourslash.ts" />
// @Filename: A.ts
////export interface I1 { one: number }
////export interface I2 { two: string }
////export type I1_OR_I2 = I1 | I2;
////
////export class C1 {
//// one: string;
////}
////
////export module Inner {
//// export interface I3 {
//// three: boolean
//// }
////
//// export var varVar = 100;
//// export let letVar = 200;
//// export const constVar = 300;
////}
// @Filename: B.ts
////export var bVar = "bee!";
// @Filename: C.ts
////export var cVar = "see!";
////export * from "A";
////export * from "B"
// @Filename: D.ts
////import * as c from "C";
////var x: c./**/
goTo.marker();
verify.completionListContains("I1");
verify.completionListContains("I2");
verify.completionListContains("I1_OR_I2");
verify.completionListContains("C1");
verify.not.completionListContains("__export");

View file

@ -0,0 +1,37 @@
///<reference path="fourslash.ts" />
// @Filename: A.ts
////export interface I1 { one: number }
////export interface I2 { two: string }
////export type I1_OR_I2 = I1 | I2;
////
////export class C1 {
//// one: string;
////}
////
////export module Inner {
//// export interface I3 {
//// three: boolean
//// }
////
//// export var varVar = 100;
//// export let letVar = 200;
//// export const constVar = 300;
////}
// @Filename: B.ts
////export var bVar = "bee!";
// @Filename: C.ts
////export var cVar = "see!";
////export * from "A";
////export * from "B"
// @Filename: D.ts
////import * as c from "C";
////var x: c.Inner./**/
goTo.marker();
verify.completionListContains("I3");
verify.not.completionListContains("__export");