mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 21:36:50 -05:00
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:
@@ -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');
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
11
tests/cases/fourslash/completionsDefaultExport.ts
Normal file
11
tests/cases/fourslash/completionsDefaultExport.ts
Normal 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");
|
||||
@@ -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");
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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');
|
||||
|
||||
12
tests/cases/fourslash/typeOfSymbol_localSymbolOfExport.ts
Normal file
12
tests/cases/fourslash/typeOfSymbol_localSymbolOfExport.ts
Normal 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");
|
||||
Reference in New Issue
Block a user