Completion for default export should be '.default' (#16742)

* Completion for default export should be '.default'

* Don't include empty string in name table

* getSymbolsInScope() should return local symbols, not exported symbols

* Fix bug: getSymbolAtLocation should work for local symbol too
This commit is contained in:
Andy
2017-07-11 07:23:32 -07:00
committed by GitHub
parent a94e0c36b0
commit aa2d1008bf
20 changed files with 200 additions and 158 deletions

View File

@@ -35,7 +35,7 @@ goTo.file("commentsExternalModules_file0.ts");
verify.quickInfoAt("1", "namespace m1", "Namespace comment");
goTo.marker('2');
verify.completionListContains("b", "var m1.b: number", "b's comment");
verify.completionListContains("b", "var b: number", "b's comment");
verify.completionListContains("foo", "function foo(): number", "foo's comment");
goTo.marker('3');

View File

@@ -99,7 +99,7 @@
verify.quickInfoAt("1", "namespace m1", "Namespace comment");
goTo.marker('2');
verify.completionListContains("b", "var m1.b: number", "b's comment");
verify.completionListContains("b", "var b: number", "b's comment");
verify.completionListContains("foo", "function foo(): number", "foo's comment");
goTo.marker('3');

View File

@@ -6,8 +6,8 @@
/////*3*/
goTo.marker("0");
verify.not.completionListContains("B");
verify.not.completionListContains("\u0042");
verify.completionListContains("B");
verify.completionListContains("\u0042");
goTo.marker("2");
verify.not.completionListContains("C");
@@ -18,10 +18,9 @@ verify.not.completionListContains("A");
verify.not.completionListContains("\u0041");
goTo.marker("3");
verify.not.completionListContains("B");
verify.not.completionListContains("\u0042");
verify.not.completionListContains("A");
verify.not.completionListContains("\u0041");
verify.not.completionListContains("C");
verify.not.completionListContains("\u0043");
verify.completionListContains("B");
verify.completionListContains("\u0042");
verify.completionListContains("A");
verify.completionListContains("\u0041");
verify.completionListContains("C");
verify.completionListContains("\u0043");

View File

@@ -0,0 +1,13 @@
/// <reference path="fourslash.ts" />
// @Filename: /a.ts
////import * as self from "./a";
////
////declare module "a" {
//// export const a: number;
////}
////
/////**/
goTo.marker();
verify.not.completionListContains("a");

View File

@@ -19,6 +19,7 @@ verify.completionListContains("bar");
verify.completionListContains("break");
verify.completionListContains("any");
verify.completionListContains("$");
verify.completionListContains("b");
// Nothing else should show up
verify.completionListCount(4);
verify.completionListCount(5);

View File

@@ -41,19 +41,16 @@ function getVerify(isTypeLocation?: boolean) {
verifyValueOrType: verify
};
}
function typeLocationVerify(valueMarker: string, verify: (typeMarker: string) => void) {
verify(valueMarker + "Type");
return valueMarker;
}
function verifyModuleM(marker: string) {
const isTypeLocation = marker.indexOf("Type") !== -1;
const { verifyValue, verifyType, verifyValueOrType } = getVerify(isTypeLocation);
if (!isTypeLocation) {
marker = typeLocationVerify(marker, verifyModuleM);
}
verifyModuleMWorker(marker, /*isTypeLocation*/ false);
verifyModuleMWorker(`${marker}Type`, /*isTypeLocation*/ true);
}
function verifyModuleMWorker(marker: string, isTypeLocation: boolean): void {
goTo.marker(marker);
const { verifyValue, verifyType, verifyValueOrType } = getVerify(isTypeLocation);
verifyType.completionListContains("I");
verifyValueOrType.completionListContains("C");
verifyValueOrType.completionListContains("E");
@@ -63,8 +60,9 @@ function verifyModuleM(marker: string) {
verifyValueOrType.completionListContains("A");
}
// Module m
goTo.marker("1");
verify.completionListContains("A");
verifyModuleM("1");
// Class C

View File

@@ -232,6 +232,7 @@
interface GotoMarkVerifyOptions {
isClassScope?: boolean;
isTypeLocation?: boolean;
insideMod1?: boolean;
}
function getVerify(isTypeLocation: boolean) {
@@ -243,30 +244,30 @@ function getVerify(isTypeLocation: boolean) {
};
}
function goToMarkAndGeneralVerify(marker: string, { isClassScope, isTypeLocation }: GotoMarkVerifyOptions = {})
{
function goToMarkAndGeneralVerify(marker: string, { isClassScope, isTypeLocation, insideMod1 }: GotoMarkVerifyOptions = {}) {
goTo.marker(marker);
const mod1Dot = insideMod1 ? "" : "mod1.";
const verifyValueInModule = isClassScope || isTypeLocation ? verify.not : verify;
const verifyValueOrTypeInModule = isClassScope ? verify.not : verify;
const verifyTypeInModule = isTypeLocation ? verify : verify.not;
verifyValueInModule.completionListContains('mod1var', 'var mod1var: number');
verifyValueInModule.completionListContains('mod1fn', 'function mod1fn(): void');
verifyValueInModule.completionListContains('mod1evar', 'var mod1.mod1evar: number');
verifyValueInModule.completionListContains('mod1efn', 'function mod1.mod1efn(): void');
verifyValueInModule.completionListContains('mod1eexvar', 'var mod1.mod1eexvar: number');
verifyValueInModule.completionListContains('mod1evar', `var ${mod1Dot}mod1evar: number`);
verifyValueInModule.completionListContains('mod1efn', `function ${mod1Dot}mod1efn(): void`);
verifyValueInModule.completionListContains('mod1eexvar', `var mod1.mod1eexvar: number`);
verifyValueInModule.completionListContains('mod3', 'namespace mod3');
verifyValueInModule.completionListContains('shwvar', 'var shwvar: number');
verifyValueInModule.completionListContains('shwfn', 'function shwfn(): void');
verifyTypeInModule.completionListContains('mod1int', 'interface mod1int');
verifyTypeInModule.completionListContains('mod1eint', 'interface mod1.mod1eint');
verifyTypeInModule.completionListContains('mod1eint', `interface ${mod1Dot}mod1eint`);
verifyTypeInModule.completionListContains('shwint', 'interface shwint');
verifyValueOrTypeInModule.completionListContains('mod1cls', 'class mod1cls');
verifyValueOrTypeInModule.completionListContains('mod1mod', 'namespace mod1mod');
verifyValueOrTypeInModule.completionListContains('mod1ecls', 'class mod1.mod1ecls');
verifyValueOrTypeInModule.completionListContains('mod1emod', 'namespace mod1.mod1emod');
verifyValueOrTypeInModule.completionListContains('mod1ecls', `class ${mod1Dot}mod1ecls`);
verifyValueOrTypeInModule.completionListContains('mod1emod', `namespace ${mod1Dot}mod1emod`);
verifyValueOrTypeInModule.completionListContains('mod2', 'namespace mod2');
verifyValueOrTypeInModule.completionListContains('shwcls', 'class shwcls');
@@ -295,12 +296,12 @@ function goToMarkAndGeneralVerify(marker: string, { isClassScope, isTypeLocation
}
// from mod1
goToMarkAndGeneralVerify('mod1');
goToMarkAndGeneralVerify('mod1', { insideMod1: true });
// from mod1 in type position
goToMarkAndGeneralVerify('mod1Type', { isTypeLocation: true });
goToMarkAndGeneralVerify('mod1Type', { isTypeLocation: true, insideMod1: true });
// from function in mod1
goToMarkAndGeneralVerify('function');
goToMarkAndGeneralVerify('function', { insideMod1: true });
verify.completionListContains('bar', '(local var) bar: number');
verify.completionListContains('foob', '(local function) foob(): void');
@@ -310,34 +311,34 @@ goToMarkAndGeneralVerify('class', { isClassScope: true });
//verify.not.completionListContains('ceVar');
// from interface in mod1
goToMarkAndGeneralVerify('interface');
goToMarkAndGeneralVerify('interface', { insideMod1: true });
// from namespace in mod1
verifyNamespaceInMod1('namespace');
verifyNamespaceInMod1('namespaceType', /*isTypeLocation*/ true);
function verifyNamespaceInMod1(marker: string, isTypeLocation?: boolean) {
goToMarkAndGeneralVerify(marker, { isTypeLocation });
goToMarkAndGeneralVerify(marker, { isTypeLocation, insideMod1: true });
const { verifyValue, verifyType, verifyValueOrType, verifyNotValueOrType } = getVerify(isTypeLocation);
verifyValue.completionListContains('m1X', 'var m1X: number');
verifyValue.completionListContains('m1Func', 'function m1Func(): void');
verifyValue.completionListContains('m1eX', 'var mod1mod.m1eX: number');
verifyValue.completionListContains('m1eFunc', 'function mod1mod.m1eFunc(): void');
verifyValue.completionListContains('m1eX', 'var m1eX: number');
verifyValue.completionListContains('m1eFunc', 'function m1eFunc(): void');
verifyType.completionListContains('m1Int', 'interface m1Int');
verifyType.completionListContains('m1eInt', 'interface mod1mod.m1eInt');
verifyType.completionListContains('m1eInt', 'interface m1eInt');
verifyValueOrType.completionListContains('m1Class', 'class m1Class');
verifyValueOrType.completionListContains('m1eClass', 'class mod1mod.m1eClass');
verifyValueOrType.completionListContains('m1eClass', 'class m1eClass');
verifyNotValueOrType.completionListContains('m1Mod', 'namespace m1Mod');
verifyNotValueOrType.completionListContains('m1eMod', 'namespace mod1mod.m1eMod');
verifyNotValueOrType.completionListContains('m1eMod', 'namespace m1eMod');
}
// from exported function in mod1
goToMarkAndGeneralVerify('exportedFunction');
goToMarkAndGeneralVerify('exportedFunction', { insideMod1: true });
verify.completionListContains('bar', '(local var) bar: number');
verify.completionListContains('foob', '(local function) foob(): void');
@@ -347,27 +348,27 @@ verify.not.completionListContains('ceFunc');
verify.not.completionListContains('ceVar');
// from exported interface in mod1
goToMarkAndGeneralVerify('exportedInterface');
goToMarkAndGeneralVerify('exportedInterface', { insideMod1: true });
// from exported namespace in mod1
verifyExportedNamespace('exportedNamespace');
verifyExportedNamespace('exportedNamespaceType', /*isTypeLocation*/ true);
function verifyExportedNamespace(marker: string, isTypeLocation?: boolean) {
goToMarkAndGeneralVerify(marker, { isTypeLocation });
goToMarkAndGeneralVerify(marker, { isTypeLocation, insideMod1: true });
const { verifyValue, verifyType, verifyValueOrType, verifyNotValueOrType } = getVerify(isTypeLocation);
verifyValue.completionListContains('mX', 'var mX: number');
verifyValue.completionListContains('mFunc', 'function mFunc(): void');
verifyValue.completionListContains('meX', 'var mod1.mod1emod.meX: number');
verifyValue.completionListContains('meFunc', 'function mod1.mod1emod.meFunc(): void');
verifyValue.completionListContains('meX', 'var meX: number');
verifyValue.completionListContains('meFunc', 'function meFunc(): void');
verifyType.completionListContains('mInt', 'interface mInt');
verifyType.completionListContains('meInt', 'interface mod1.mod1emod.meInt');
verifyType.completionListContains('meInt', 'interface meInt');
verifyValueOrType.completionListContains('mClass', 'class mClass');
verifyValueOrType.completionListContains('meClass', 'class mod1.mod1emod.meClass');
verifyValueOrType.completionListContains('meClass', 'class meClass');
verifyNotValueOrType.completionListContains('mMod', 'namespace mMod');
verifyNotValueOrType.completionListContains('meMod', 'namespace mod1.mod1emod.meMod');
verifyNotValueOrType.completionListContains('meMod', 'namespace meMod');
}
// from extended namespace
@@ -380,7 +381,7 @@ function verifyExtendedNamespace(marker: string, isTypeLocation?: boolean) {
verifyValue.completionListContains('mod1evar', 'var mod1.mod1evar: number');
verifyValue.completionListContains('mod1efn', 'function mod1.mod1efn(): void');
verifyValue.completionListContains('mod1eexvar', 'var mod1.mod1eexvar: number');
verifyValue.completionListContains('mod1eexvar', 'var mod1eexvar: number');
verifyValue.completionListContains('mod3', 'namespace mod3');
verifyValue.completionListContains('shwvar', 'var shwvar: number');
verifyValue.completionListContains('shwfn', 'function shwfn(): void');
@@ -415,4 +416,4 @@ function verifyExtendedNamespace(marker: string, isTypeLocation?: boolean) {
verify.not.completionListContains('sivar');
verify.not.completionListContains('sifn');
verify.not.completionListContains('mod2eexvar');
}
}

View File

@@ -0,0 +1,11 @@
/// <reference path="fourslash.ts" />
// @Filename: /a.ts
////export default function f() {}
// @Filename: /b.ts
////import * as a from "./a";
////a./**/;
goTo.marker();
verify.completionListContains("default", "function f(): void");

View File

@@ -9,4 +9,4 @@ goTo.marker('1');
verify.completionListContains("func", "function func(): void", /*documentation*/ undefined, "function");
goTo.marker('2');
verify.completionListContains("func", "function func(): void", /*documentation*/ undefined, "function");
verify.completionListContains("func", "function func(): void", /*documentation*/ undefined, "function");

View File

@@ -15,8 +15,9 @@
const ranges = test.ranges();
const [r0, r1, r2, r3, r4] = ranges;
const fnRanges = [r0, r1, r2, r3];
verify.singleReferenceGroup("function DefaultExportedFunction(): () => typeof DefaultExportedFunction", fnRanges);
const fn = "function DefaultExportedFunction(): () => typeof DefaultExportedFunction";
verify.singleReferenceGroup(fn, fnRanges);
// The namespace and function do not merge,
// so the namespace should be all alone.
verify.singleReferenceGroup("namespace DefaultExportedFunction", [r4]);
verify.singleReferenceGroup(`namespace DefaultExportedFunction\n${fn}`, [r4]);

View File

@@ -10,6 +10,8 @@
////namespace [|{| "isWriteAccess": true, "isDefinition": true |}DefaultExportedClass|] {
////}
verify.noErrors();
// The namespace and class do not merge,
// so the namespace should be all alone.
verify.singleReferenceGroup("namespace DefaultExportedClass");
verify.singleReferenceGroup("class DefaultExportedClass\nnamespace DefaultExportedClass");

View File

@@ -116,6 +116,7 @@ declare namespace FourSlashInterface {
ranges(): Range[];
rangesByText(): ts.Map<Range[]>;
markerByName(s: string): Marker;
symbolsInScope(range: Range): any[];
}
class goTo {
marker(name?: string | Marker): void;
@@ -192,6 +193,7 @@ declare namespace FourSlashInterface {
verifyGetEmitOutputContentsForCurrentFile(expected: ts.OutputFile[]): void;
noReferences(markerNameOrRange?: string | Range): void;
symbolAtLocation(startRange: Range, ...declarationRanges: Range[]): void;
typeOfSymbolAtLocation(range: Range, symbol: any, expected: string): void;
/**
* @deprecated, prefer 'referenceGroups'
* Like `referencesAre`, but goes to `start` first.

View File

@@ -7,7 +7,7 @@
//// var num: number;
//// var str: string;
//// if (typeof /*1*/nonExportedStrOrNum === "number") {
//// num = /*2*/nonExportedStrOrNum;
//// num = /*2*/nonExportedStrOrNum;
//// }
//// else {
//// str = /*3*/nonExportedStrOrNum.length;
@@ -40,15 +40,15 @@ verify.completionListContains("nonExportedStrOrNum", "var nonExportedStrOrNum: s
goTo.marker('4');
verify.quickInfoIs('var m.exportedStrOrNum: string | number');
verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: string | number");
verify.completionListContains("exportedStrOrNum", "var exportedStrOrNum: string | number");
goTo.marker('5');
verify.quickInfoIs('var m.exportedStrOrNum: number');
verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: number");
verify.completionListContains("exportedStrOrNum", "var exportedStrOrNum: number");
goTo.marker('6');
verify.quickInfoIs('var m.exportedStrOrNum: string');
verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: string");
verify.completionListContains("exportedStrOrNum", "var exportedStrOrNum: string");
goTo.marker('7');
verify.quickInfoIs('var m.exportedStrOrNum: string | number');

View File

@@ -0,0 +1,12 @@
/// <reference path='fourslash.ts'/>
////export function f() {}
////[|1|];
const ranges = test.ranges();
const symbolsInScope = test.symbolsInScope(ranges[0]);
const f = symbolsInScope.find(s => s.name === "f");
if (f === undefined) throw new Error("'f' not in scope");
if (f.exportSymbol === undefined) throw new Error("Expected to get the local symbol");
verify.typeOfSymbolAtLocation(ranges[0], f, "() => void");