For path completions, include extension as a kindModifier (#28148)

This commit is contained in:
Andy 2018-10-30 11:56:34 -07:00 committed by GitHub
parent 33568795e0
commit 437bc41e99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
81 changed files with 405 additions and 147 deletions

View File

@ -796,8 +796,8 @@ namespace FourSlash {
}
private verifyCompletionEntry(actual: ts.CompletionEntry, expected: FourSlashInterface.ExpectedCompletionEntry) {
const { insertText, replacementSpan, hasAction, isRecommended, kind, text, documentation, tags, source, sourceDisplay } = typeof expected === "string"
? { insertText: undefined, replacementSpan: undefined, hasAction: undefined, isRecommended: undefined, kind: undefined, text: undefined, documentation: undefined, tags: undefined, source: undefined, sourceDisplay: undefined }
const { insertText, replacementSpan, hasAction, isRecommended, kind, kindModifiers, text, documentation, tags, source, sourceDisplay } = typeof expected === "string"
? { insertText: undefined, replacementSpan: undefined, hasAction: undefined, isRecommended: undefined, kind: undefined, kindModifiers: undefined, text: undefined, documentation: undefined, tags: undefined, source: undefined, sourceDisplay: undefined }
: expected;
if (actual.insertText !== insertText) {
@ -811,8 +811,12 @@ namespace FourSlash {
this.raiseError(`Expected completion replacementSpan to be ${stringify(convertedReplacementSpan)}, got ${stringify(actual.replacementSpan)}`);
}
if (kind !== undefined) assert.equal(actual.kind, kind);
if (typeof expected !== "string" && "kindModifiers" in expected) assert.equal(actual.kindModifiers, expected.kindModifiers);
if (kind !== undefined || kindModifiers !== undefined) {
assert.equal(actual.kind, kind);
if (actual.kindModifiers !== (kindModifiers || "")) {
this.raiseError(`Bad kind modifiers for ${actual.name}: Expected ${kindModifiers || ""}, actual ${actual.kindModifiers}`);
}
}
assert.equal(actual.hasAction, hasAction);
assert.equal(actual.isRecommended, isRecommended);
@ -4916,7 +4920,7 @@ namespace FourSlashInterface {
readonly hasAction?: boolean, // If not specified, will assert that this is false.
readonly isRecommended?: boolean; // If not specified, will assert that this is false.
readonly kind?: string, // If not specified, won't assert about this
readonly kindModifiers?: string;
readonly kindModifiers?: string, // Must be paired with 'kind'
readonly text?: string;
readonly documentation?: string;
readonly sourceDisplay?: string;

View File

@ -101,9 +101,23 @@ namespace ts.Completions {
function convertPathCompletions(pathCompletions: ReadonlyArray<PathCompletions.PathCompletion>): CompletionInfo {
const isGlobalCompletion = false; // We don't want the editor to offer any other completions, such as snippets, inside a comment.
const isNewIdentifierLocation = true; // The user may type in a path that doesn't yet exist, creating a "new identifier" with respect to the collection of identifiers the server is aware of.
const entries = pathCompletions.map(({ name, kind, span }) => ({ name, kind, kindModifiers: ScriptElementKindModifier.none, sortText: "0", replacementSpan: span }));
const entries = pathCompletions.map(({ name, kind, span, extension }): CompletionEntry =>
({ name, kind, kindModifiers: kindModifiersFromExtension(extension), sortText: "0", replacementSpan: span }));
return { isGlobalCompletion, isMemberCompletion: false, isNewIdentifierLocation, entries };
}
function kindModifiersFromExtension(extension: Extension | undefined): ScriptElementKindModifier {
switch (extension) {
case Extension.Dts: return ScriptElementKindModifier.dtsModifier;
case Extension.Js: return ScriptElementKindModifier.jsModifier;
case Extension.Json: return ScriptElementKindModifier.jsonModifier;
case Extension.Jsx: return ScriptElementKindModifier.jsxModifier;
case Extension.Ts: return ScriptElementKindModifier.tsModifier;
case Extension.Tsx: return ScriptElementKindModifier.tsxModifier;
case undefined: return ScriptElementKindModifier.none;
default:
return Debug.assertNever(extension);
}
}
function jsdocCompletionInfo(entries: CompletionEntry[]): CompletionInfo {
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries };
@ -638,7 +652,7 @@ namespace ts.Completions {
switch (completion.kind) {
case StringLiteralCompletionKind.Paths: {
const match = find(completion.paths, p => p.name === name);
return match && createCompletionDetails(name, ScriptElementKindModifier.none, match.kind, [textPart(name)]);
return match && createCompletionDetails(name, kindModifiersFromExtension(match.extension), match.kind, [textPart(name)]);
}
case StringLiteralCompletionKind.Properties: {
const match = find(completion.symbols, s => s.name === name);

View File

@ -3,17 +3,22 @@ namespace ts.Completions.PathCompletions {
export interface NameAndKind {
readonly name: string;
readonly kind: ScriptElementKind.scriptElement | ScriptElementKind.directory | ScriptElementKind.externalModuleName;
readonly extension: Extension | undefined;
}
export interface PathCompletion extends NameAndKind {
readonly span: TextSpan | undefined;
}
function nameAndKind(name: string, kind: NameAndKind["kind"]): NameAndKind {
return { name, kind };
function nameAndKind(name: string, kind: NameAndKind["kind"], extension: Extension | undefined): NameAndKind {
return { name, kind, extension };
}
function directoryResult(name: string): NameAndKind {
return nameAndKind(name, ScriptElementKind.directory, /*extension*/ undefined);
}
function addReplacementSpans(text: string, textStart: number, names: ReadonlyArray<NameAndKind>): ReadonlyArray<PathCompletion> {
const span = getDirectoryFragmentTextSpan(text, textStart);
return names.map(({ name, kind }): PathCompletion => ({ name, kind, span }));
return names.map(({ name, kind, extension }): PathCompletion => ({ name, kind, extension, span }));
}
export function getStringLiteralCompletionsFromModuleNames(sourceFile: SourceFile, node: LiteralExpression, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): ReadonlyArray<PathCompletion> {
@ -129,7 +134,7 @@ namespace ts.Completions.PathCompletions {
*
* both foo.ts and foo.tsx become foo
*/
const foundFiles = createMap<true>();
const foundFiles = createMap<Extension | undefined>(); // maps file to its extension
for (let filePath of files) {
filePath = normalizePath(filePath);
if (exclude && comparePaths(filePath, exclude, scriptPath, ignoreCase) === Comparison.EqualTo) {
@ -137,14 +142,11 @@ namespace ts.Completions.PathCompletions {
}
const foundFileName = includeExtensions || fileExtensionIs(filePath, Extension.Json) ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath));
if (!foundFiles.has(foundFileName)) {
foundFiles.set(foundFileName, true);
}
foundFiles.set(foundFileName, tryGetExtensionFromPath(filePath));
}
forEachKey(foundFiles, foundFile => {
result.push(nameAndKind(foundFile, ScriptElementKind.scriptElement));
foundFiles.forEach((ext, foundFile) => {
result.push(nameAndKind(foundFile, ScriptElementKind.scriptElement, ext));
});
}
@ -155,7 +157,7 @@ namespace ts.Completions.PathCompletions {
for (const directory of directories) {
const directoryName = getBaseFileName(normalizePath(directory));
if (directoryName !== "@types") {
result.push(nameAndKind(directoryName, ScriptElementKind.directory));
result.push(directoryResult(directoryName));
}
}
}
@ -183,10 +185,10 @@ namespace ts.Completions.PathCompletions {
if (!hasProperty(paths, path)) continue;
const patterns = paths[path];
if (patterns) {
for (const { name, kind } of getCompletionsForPathMapping(path, patterns, fragment, baseDirectory, fileExtensions, host)) {
for (const { name, kind, extension } of getCompletionsForPathMapping(path, patterns, fragment, baseDirectory, fileExtensions, host)) {
// Path mappings may provide a duplicate way to get to something we've already added, so don't add again.
if (!result.some(entry => entry.name === name)) {
result.push(nameAndKind(name, kind));
result.push(nameAndKind(name, kind, extension));
}
}
}
@ -200,7 +202,7 @@ namespace ts.Completions.PathCompletions {
* Modules from node_modules (i.e. those listed in package.json)
* This includes all files that are found in node_modules/moduleName/ with acceptable file extensions
*/
function getCompletionEntriesForNonRelativeModules(fragment: string, scriptPath: string, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): NameAndKind[] {
function getCompletionEntriesForNonRelativeModules(fragment: string, scriptPath: string, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): ReadonlyArray<NameAndKind> {
const { baseUrl, paths } = compilerOptions;
const result: NameAndKind[] = [];
@ -217,7 +219,7 @@ namespace ts.Completions.PathCompletions {
const fragmentDirectory = getFragmentDirectory(fragment);
for (const ambientName of getAmbientModuleCompletions(fragment, fragmentDirectory, typeChecker)) {
result.push(nameAndKind(ambientName, ScriptElementKind.externalModuleName));
result.push(nameAndKind(ambientName, ScriptElementKind.externalModuleName, /*extension*/ undefined));
}
getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, fragmentDirectory, extensionOptions, result);
@ -230,7 +232,7 @@ namespace ts.Completions.PathCompletions {
for (const moduleName of enumerateNodeModulesVisibleToScript(host, scriptPath)) {
if (!result.some(entry => entry.name === moduleName)) {
foundGlobal = true;
result.push(nameAndKind(moduleName, ScriptElementKind.externalModuleName));
result.push(nameAndKind(moduleName, ScriptElementKind.externalModuleName, /*extension*/ undefined));
}
}
}
@ -265,7 +267,7 @@ namespace ts.Completions.PathCompletions {
getModulesForPathsPattern(remainingFragment, baseUrl, pattern, fileExtensions, host));
function justPathMappingName(name: string): ReadonlyArray<NameAndKind> {
return startsWith(name, fragment) ? [{ name, kind: ScriptElementKind.directory }] : emptyArray;
return startsWith(name, fragment) ? [directoryResult(name)] : emptyArray;
}
}
@ -301,15 +303,21 @@ namespace ts.Completions.PathCompletions {
// doesn't support. For now, this is safer but slower
const includeGlob = normalizedSuffix ? "**/*" : "./*";
const matches = tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]).map<NameAndKind>(name => ({ name, kind: ScriptElementKind.scriptElement }));
const directories = tryGetDirectories(host, baseDirectory).map(d => combinePaths(baseDirectory, d)).map<NameAndKind>(name => ({ name, kind: ScriptElementKind.directory }));
// Trim away prefix and suffix
return mapDefined<NameAndKind, NameAndKind>(concatenate(matches, directories), ({ name, kind }) => {
const normalizedMatch = normalizePath(name);
const inner = withoutStartAndEnd(normalizedMatch, completePrefix, normalizedSuffix);
return inner !== undefined ? { name: removeLeadingDirectorySeparator(removeFileExtension(inner)), kind } : undefined;
const matches = mapDefined(tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]), match => {
const extension = tryGetExtensionFromPath(match);
const name = trimPrefixAndSuffix(match);
return name === undefined ? undefined : nameAndKind(removeFileExtension(name), ScriptElementKind.scriptElement, extension);
});
const directories = mapDefined(tryGetDirectories(host, baseDirectory).map(d => combinePaths(baseDirectory, d)), dir => {
const name = trimPrefixAndSuffix(dir);
return name === undefined ? undefined : directoryResult(name);
});
return [...matches, ...directories];
function trimPrefixAndSuffix(path: string): string | undefined {
const inner = withoutStartAndEnd(normalizePath(path), completePrefix, normalizedSuffix);
return inner === undefined ? undefined : removeLeadingDirectorySeparator(inner);
}
}
function withoutStartAndEnd(s: string, start: string, end: string): string | undefined {
@ -382,7 +390,10 @@ namespace ts.Completions.PathCompletions {
if (options.types && !contains(options.types, packageName)) continue;
if (fragmentDirectory === undefined) {
pushResult(packageName);
if (!seen.has(packageName)) {
result.push(nameAndKind(packageName, ScriptElementKind.externalModuleName, /*extension*/ undefined));
seen.set(packageName, true);
}
}
else {
const baseDirectory = combinePaths(directory, typeDirectoryName);
@ -393,13 +404,6 @@ namespace ts.Completions.PathCompletions {
}
}
}
function pushResult(moduleName: string) {
if (!seen.has(moduleName)) {
result.push(nameAndKind(moduleName, ScriptElementKind.externalModuleName));
seen.set(moduleName, true);
}
}
}
function findPackageJsons(directory: string, host: LanguageServiceHost): string[] {

View File

@ -1126,7 +1126,14 @@ namespace ts {
ambientModifier = "declare",
staticModifier = "static",
abstractModifier = "abstract",
optionalModifier = "optional"
optionalModifier = "optional",
dtsModifier = ".d.ts",
tsModifier = ".ts",
tsxModifier = ".tsx",
jsModifier = ".js",
jsxModifier = ".jsx",
jsonModifier = ".json",
}
export const enum ClassificationTypeNames {

View File

@ -5369,7 +5369,13 @@ declare namespace ts {
ambientModifier = "declare",
staticModifier = "static",
abstractModifier = "abstract",
optionalModifier = "optional"
optionalModifier = "optional",
dtsModifier = ".d.ts",
tsModifier = ".ts",
tsxModifier = ".tsx",
jsModifier = ".js",
jsxModifier = ".jsx",
jsonModifier = ".json"
}
enum ClassificationTypeNames {
comment = "comment",

View File

@ -5369,7 +5369,13 @@ declare namespace ts {
ambientModifier = "declare",
staticModifier = "static",
abstractModifier = "abstract",
optionalModifier = "optional"
optionalModifier = "optional",
dtsModifier = ".d.ts",
tsModifier = ".ts",
tsxModifier = ".tsx",
jsModifier = ".js",
jsxModifier = ".jsx",
jsonModifier = ".json"
}
enum ClassificationTypeNames {
comment = "comment",

View File

@ -189,18 +189,18 @@
////}
const validInstanceMembersOfBaseClassB: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntryObject> = [
{ name: "protectedMethod", text: "(method) B.protectedMethod(): void" },
{ name: "protectedMethod", text: "(method) B.protectedMethod(): void", kindModifiers: "protected" },
{ name: "getValue", text: "(method) B.getValue(): string | boolean" },
];
const validStaticMembersOfBaseClassB: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntryObject> = [
{ name: "staticMethod", text: "(method) B.staticMethod(): void" },
{ name: "staticMethod", text: "(method) B.staticMethod(): void", kindModifiers: "static" },
];
const privateMembersOfBaseClassB: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntryObject> = [
{ name: "privateMethod", text: "(method) B.privateMethod(): void" },
];
const protectedPropertiesOfBaseClassB0: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntryObject> = [
{ name: "protectedMethod", text: "(method) B0.protectedMethod(): void" },
{ name: "protectedMethod1", text: "(method) B0.protectedMethod1(): void" },
{ name: "protectedMethod", text: "(method) B0.protectedMethod(): void", kindModifiers: "protected" },
{ name: "protectedMethod1", text: "(method) B0.protectedMethod1(): void", kindModifiers: "protected" },
];
const publicPropertiesOfBaseClassB0: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntryObject> = [
{ name: "getValue", text: "(method) B0.getValue(): string | boolean" },
@ -214,12 +214,12 @@ const validInstanceMembersOfBaseClassB0_2 : ReadonlyArray<FourSlashInterface.Exp
publicPropertiesOfBaseClassB0[1],
];
const validStaticMembersOfBaseClassB0: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntryObject> = [
{ name: "staticMethod", text: "(method) B0.staticMethod(): void" },
{ name: "staticMethod1", text: "(method) B0.staticMethod1(): void" },
{ name: "staticMethod", text: "(method) B0.staticMethod(): void", kindModifiers: "static" },
{ name: "staticMethod1", text: "(method) B0.staticMethod1(): void", kindModifiers: "static" },
];
const privateMembersOfBaseClassB0: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntryObject> = [
{ name: "privateMethod", text: "(method) B0.privateMethod(): void" },
{ name: "privateMethod1", text: "(method) B0.privateMethod1(): void" },
{ name: "privateMethod", text: "(method) B0.privateMethod(): void", kindModifiers: "private" },
{ name: "privateMethod1", text: "(method) B0.privateMethod1(): void", kindModifiers: "private" },
];
const membersOfI: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntryObject> = [
{ name: "methodOfInterface", text: "(method) I.methodOfInterface(): number" },

View File

@ -18,7 +18,7 @@
////o["/*prop*/"];
verify.completions(
{ marker: "path", includes: { name: "other", text: "other", kind: "script" }, isNewIdentifierLocation: true },
{ marker: "path", includes: { name: "other", text: "other", kind: "script", kindModifiers: ".ts" }, isNewIdentifierLocation: true },
{ marker: "type", exact: { name: "a", text: "a", kind: "string" } },
{
marker: "prop",

View File

@ -11,4 +11,13 @@
/////** @type {Foo./**/} */
////const x = 0;
verify.completions({ marker: "", includes: { name: "T", text: "type T = number", documentation: "tee", kind: "type" } });
verify.completions({
marker: "",
includes: {
name: "T",
text: "type T = number",
documentation: "tee",
kind: "type",
kindModifiers: "export,declare",
},
});

View File

@ -13,12 +13,14 @@ verify.completions({
text: "(property) Array<number>.length: number",
documentation: "Gets or sets the length of the array. This is a number one higher than the highest element defined in an array.",
kind: "property",
kindModifiers: "declare",
},
{
name: "toString",
text: "(method) Array<number>.toString(): string",
documentation: "Returns a string representation of an array.",
kind: "method",
kindModifiers: "declare",
},
],
});

View File

@ -23,6 +23,7 @@ verify.completions({
sourceDisplay: "./a",
text: "const foo: 0",
kind: "const",
kindModifiers: "export",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },

View File

@ -27,6 +27,6 @@
verify.completions({ marker: ["b", "c", "d"], excludes: "foo", preferences: { includeCompletionsForModuleExports: true } });
verify.completions({
marker: ["c2", "d2"],
includes: [{ name: "foo", source: "/node_modules/a/index", text: "const foo: 0", kind: "const", hasAction: true, sourceDisplay: "a" }],
includes: [{ name: "foo", source: "/node_modules/a/index", text: "const foo: 0", kind: "const", kindModifiers: "export,declare", hasAction: true, sourceDisplay: "a" }],
preferences: { includeCompletionsForModuleExports: true },
});

View File

@ -14,9 +14,15 @@ goTo.file("/a.ts");
verify.completions({
marker: "",
includes: [
{ name: "concat", source: "/node_modules/bar/concat", sourceDisplay: "bar/concat", text: "const concat: 0", kind: "const", hasAction: true },
],
includes: {
name: "concat",
source: "/node_modules/bar/concat",
sourceDisplay: "bar/concat",
text: "const concat: 0",
kind: "const",
kindModifiers: "export,declare",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },
});

View File

@ -16,6 +16,7 @@ verify.completions({
sourceDisplay: "./a",
text: "function foo(): void",
kind: "function",
kindModifiers: "export",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },

View File

@ -9,7 +9,15 @@
verify.completions({
marker: "",
includes: { name: "foo", source: "/a", sourceDisplay: "./a", text: "function foo(): void", kind: "function", hasAction: true },
includes: {
name: "foo",
source: "/a",
sourceDisplay: "./a",
text: "function foo(): void",
kind: "function",
kindModifiers: "export",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },
});
verify.applyCodeActionFromCompletion("", {

View File

@ -9,7 +9,15 @@
verify.completions({
marker: "",
includes: { name: "foo", source: "/a", sourceDisplay: "./a", text: "function foo(): void", kind: "function", hasAction: true },
includes: {
name: "foo",
source: "/a",
sourceDisplay: "./a",
text: "function foo(): void",
kind: "function",
kindModifiers: "export",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },
});
verify.applyCodeActionFromCompletion("", {

View File

@ -14,10 +14,7 @@
goTo.marker("0");
const preferences: FourSlashInterface.UserPreferences = { includeCompletionsForModuleExports: true };
verify.completions(
{
marker: "0",
exact: ["undefined", ...completion.statementKeywordsWithTypes],
},
{ marker: "0", exact: ["undefined", ...completion.statementKeywordsWithTypes], preferences },
{
marker: "1",
includes: { name: "fooBar", source: "/src/foo-bar", sourceDisplay: "./foo-bar", text: "(property) default: 0", kind: "property", hasAction: true },

View File

@ -10,7 +10,15 @@
verify.completions({
marker: "",
includes: { name: "foo", source: "/a", sourceDisplay: "./a", text: "function foo(): void", kind: "function", hasAction: true },
includes: {
name: "foo",
source: "/a",
sourceDisplay: "./a",
text: "function foo(): void",
kind: "function",
kindModifiers: "export",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },
});
verify.applyCodeActionFromCompletion("", {

View File

@ -17,7 +17,15 @@
verify.completions({
marker: "",
includes: { name: "M", source: "m", sourceDisplay: "m", text: "class M", kind: "class", hasAction: true },
includes: {
name: "M",
source: "m",
sourceDisplay: "m",
text: "class M",
kind: "class",
kindModifiers: "export,declare",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },
});
verify.applyCodeActionFromCompletion("", {

View File

@ -17,7 +17,7 @@
verify.completions({
marker: "",
includes: ["bdf", "abcdef", "BDF"].map(name =>
({ name, source: "/a", text: `function ${name}(): void`, hasAction: true, kind: "function", sourceDisplay: "./a" })),
({ name, source: "/a", text: `function ${name}(): void`, hasAction: true, kind: "function", kindModifiers: "export", sourceDisplay: "./a" })),
excludes: ["abcde", "dbf"],
preferences: { includeCompletionsForModuleExports: true },
})

View File

@ -20,10 +20,26 @@ goTo.marker("");
verify.completions({
marker: "",
exact: [
{ name: "foo", text: "var foo: number", kind: "var" },
{ name: "foo", text: "var foo: number", kind: "var", kindModifiers: "declare" },
"undefined",
{ name: "foo", source: "/a", sourceDisplay: "./a", text: "const foo: 0", kind: "const", hasAction: true },
{ name: "foo", source: "/b", sourceDisplay: "./b", text: "const foo: 1", kind: "const", hasAction: true },
{
name: "foo",
source: "/a",
sourceDisplay: "./a",
text: "const foo: 0",
kind: "const",
kindModifiers: "export",
hasAction: true,
},
{
name: "foo",
source: "/b",
sourceDisplay: "./b",
text: "const foo: 1",
kind: "const",
kindModifiers: "export",
hasAction: true,
},
...completion.statementKeywordsWithTypes,
],
preferences: { includeCompletionsForModuleExports: true },

View File

@ -10,7 +10,15 @@
verify.completions({
marker: "",
includes: { name: "foo", source: "/a", sourceDisplay: "./a", text: "function foo(): void", kind: "function", hasAction: true },
includes: {
name: "foo",
source: "/a",
sourceDisplay: "./a",
text: "function foo(): void",
kind: "function",
kindModifiers: "export",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },
});
verify.applyCodeActionFromCompletion("", {

View File

@ -15,7 +15,7 @@ verify.completions({
exact: [
{ name: "Test2", text: "(alias) function Test2(): void\nimport Test2", kind: "alias" },
"undefined",
{ name: "Test1", source: "/a", sourceDisplay: "./a", text: "function Test1(): void", kind: "function", hasAction: true },
{ name: "Test1", source: "/a", sourceDisplay: "./a", text: "function Test1(): void", kind: "function", kindModifiers: "export", hasAction: true },
...completion.statementKeywordsWithTypes,
],
preferences: { includeCompletionsForModuleExports: true },

View File

@ -13,7 +13,15 @@
verify.completions({
marker: "",
includes: { name: "foo", source: "/a", sourceDisplay: "./a", text: "const N.foo: 0", kind: "const", hasAction: true },
includes: {
name: "foo",
source: "/a",
sourceDisplay: "./a",
text: "const N.foo: 0",
kind: "const",
kindModifiers: "export,declare",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },
});
verify.applyCodeActionFromCompletion("", {

View File

@ -18,6 +18,14 @@
verify.completions({
marker: "",
includes: { name: "foo", source: "n", sourceDisplay: "n", text: "const N.foo: number", kind: "const", hasAction: true },
includes: {
name: "foo",
source: "n",
sourceDisplay: "n",
text: "const N.foo: number",
kind: "const",
kindModifiers: "export,declare",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },
});

View File

@ -9,7 +9,15 @@
verify.completions({
marker: "",
includes: { name: "foo", source: "/a", sourceDisplay: "./a", text: "function foo(): void", kind: "function", hasAction: true },
includes: {
name: "foo",
source: "/a",
sourceDisplay: "./a",
text: "function foo(): void",
kind: "function",
kindModifiers: "export",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },
});
verify.applyCodeActionFromCompletion("", {

View File

@ -18,7 +18,15 @@
for (const [marker, sourceDisplay] of [["0", "./src"], ["1", "./a"], ["2", "../a"]]) {
verify.completions({
marker,
includes: { name: "x", source: "/src/a", sourceDisplay, text: "const x: 0", kind: "const", hasAction: true },
includes: {
name: "x",
source: "/src/a",
sourceDisplay,
text: "const x: 0",
kind: "const",
kindModifiers: "export",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },
});
verify.applyCodeActionFromCompletion(marker, {

View File

@ -20,7 +20,7 @@ verify.completions({
marker: "",
exact: [
"undefined",
{ name: "foo", source: "/foo/lib/foo", sourceDisplay: "./foo", text: "const foo: 0", kind: "const", hasAction: true },
{ name: "foo", source: "/foo/lib/foo", sourceDisplay: "./foo", text: "const foo: 0", kind: "const", kindModifiers: "export", hasAction: true },
...completion.statementKeywordsWithTypes,
],
preferences: { includeCompletionsForModuleExports: true },

View File

@ -9,6 +9,14 @@
verify.completions({
marker: "",
includes: { name: "foo", source: "/a", sourceDisplay: "./a", text: "function foo(): void", kind: "function", hasAction: true },
includes: {
name: "foo",
source: "/a",
sourceDisplay: "./a",
text: "function foo(): void",
kind: "function",
kindModifiers: "export",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },
});

View File

@ -17,8 +17,23 @@ verify.completions({
exact: [
...completion.globalsVars,
"undefined",
{ name: "foo", source: "/a/b/impl", sourceDisplay: "./a", text: "function foo(): void", kind: "function", hasAction: true },
{ name: "foo", source: "/a/index", sourceDisplay: "./a", text: "(alias) function foo(): void\nexport foo", kind: "alias", hasAction: true },
{
name: "foo",
source: "/a/b/impl",
sourceDisplay: "./a",
text: "function foo(): void",
kind: "function",
kindModifiers: "export",
hasAction: true,
},
{
name: "foo",
source: "/a/index",
sourceDisplay: "./a",
text: "(alias) function foo(): void\nexport foo",
kind: "alias",
hasAction: true,
},
...completion.globalKeywords,
],
preferences: { includeCompletionsForModuleExports: true },

View File

@ -11,7 +11,15 @@
verify.completions({
marker: "b",
includes: { name: "foo", source: "/a", sourceDisplay: "./a", text: "const foo: 0", kind: "const", hasAction: true },
includes: {
name: "foo",
source: "/a",
sourceDisplay: "./a",
text: "const foo: 0",
kind: "const",
kindModifiers: "export",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },
});
verify.applyCodeActionFromCompletion("b", {

View File

@ -19,4 +19,13 @@
//// }
////}
verify.completions({ marker: ["1", "2"], exact: { name: "foo", text: "(JSX attribute) foo: string", documentation: "Doc", kind: "JSX attribute" } });
verify.completions({
marker: ["1", "2"],
exact: {
name: "foo",
text: "(JSX attribute) foo: string",
documentation: "Doc",
kind: "JSX attribute",
kindModifiers: "declare",
},
});

View File

@ -17,8 +17,8 @@
////<div /**/></div>;
const exact: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry> = [
{ name: "foo", kind: "JSX attribute", text: "(JSX attribute) foo: boolean", documentation: "Doc" },
{ name: "bar", kind: "JSX attribute", text: "(JSX attribute) bar: string" },
{ name: "foo", kind: "JSX attribute", kindModifiers: "declare", text: "(JSX attribute) foo: boolean", documentation: "Doc" },
{ name: "bar", kind: "JSX attribute", kindModifiers: "declare", text: "(JSX attribute) bar: string" },
];
verify.completions({ marker: "", exact });
edit.insert("f");

View File

@ -8,7 +8,7 @@
verify.completions({
marker: "a",
exact: [
{ name: "a", kindModifiers: "optional" },
{ name: "method", kindModifiers: "optional" },
{ name: "a", kind: "property", kindModifiers: "optional" },
{ name: "method", kind: "method", kindModifiers: "optional" },
],
});

View File

@ -24,6 +24,14 @@
////const foo = require(`x//*4*/`);
verify.completions(
{ marker: "1", exact: ["y", "x"], isNewIdentifierLocation: true },
{ marker: ["2", "3", "4"], exact: ["bar", "foo"], isNewIdentifierLocation: true },
{
marker: "1",
exact: ["y", "x"].map(name => ({ name, kind: "directory" })),
isNewIdentifierLocation: true,
},
{
marker: ["2", "3", "4"],
exact: ["bar", "foo"].map(name => ({ name, kind: "script", kindModifiers: ".d.ts" })),
isNewIdentifierLocation: true,
},
);

View File

@ -9,4 +9,8 @@
// @Filename: /project/index.ts
////import { } from "/**/";
verify.completions({ marker: "", exact: "test.json", isNewIdentifierLocation: true });
verify.completions({
marker: "",
exact: { name: "test.json", kind: "script", kindModifiers: ".json" },
isNewIdentifierLocation: true,
});

View File

@ -9,4 +9,8 @@
// @Filename: /project/index.ts
////import { } from ".//**/";
verify.completions({ marker: "", exact: "test.json", isNewIdentifierLocation: true });
verify.completions({
marker: "",
exact: { name: "test.json", kind: "script", kindModifiers: ".json" },
isNewIdentifierLocation: true,
});

View File

@ -13,6 +13,9 @@
verify.completions(
{ marker: "0", exact: [], isNewIdentifierLocation: true },
{ marker: "1", exact: ["bar", "index"], isNewIdentifierLocation: true },
{ marker: "2", exact: ["bar", "index"], isNewIdentifierLocation: true },
{
marker: ["1", "2"],
exact: ["bar", "index"].map(name => ({ name, kind: "script", kindModifiers: ".d.ts" })),
isNewIdentifierLocation: true,
},
);

View File

@ -17,7 +17,19 @@
/////** @type {import("/*3*/")} */
verify.completions(
{ marker: "1", exact: "package", isNewIdentifierLocation: true },
{ marker: "2", exact: ["lib", "ns", "user", "node_modules"], isNewIdentifierLocation: true },
{ marker: "3", exact: ["package"], isNewIdentifierLocation: true },
{
marker: ["1", "3"],
exact: { name: "package", kind: "directory" },
isNewIdentifierLocation: true,
},
{
marker: "2",
exact: [
{ name: "lib", kind: "script", kindModifiers: ".d.ts" },
{ name: "ns", kind: "script", kindModifiers: ".ts" },
{ name: "user", kind: "script", kindModifiers: ".js" },
{ name: "node_modules", kind: "directory" },
],
isNewIdentifierLocation: true
},
);

View File

@ -22,6 +22,9 @@
verify.completions({
marker: ["0", "1"],
exact: [{ name: "b", kind: "script" }, { name: "dir", kind: "directory" }],
exact: [
{ name: "b", kind: "script", kindModifiers: ".ts" },
{ name: "dir", kind: "directory" },
],
isNewIdentifierLocation: true
});

View File

@ -22,6 +22,18 @@
const [r0, r1] = test.ranges();
verify.completions(
{ marker: "0", exact: ["a", "b", "dir"], isNewIdentifierLocation: true },
{ marker: "1", exact: "x", isNewIdentifierLocation: true },
{
marker: "0",
exact: [
{ name: "a", kind: "script", kindModifiers: ".ts" },
{ name: "b", kind: "script", kindModifiers: ".ts" },
{ name: "dir", kind: "directory" },
],
isNewIdentifierLocation: true,
},
{
marker: "1",
exact: { name: "x", kind: "script", kindModifiers: ".ts" },
isNewIdentifierLocation: true,
},
);

View File

@ -16,4 +16,8 @@
//// }
////}
verify.completions({ marker: "", exact: ["x"], isNewIdentifierLocation: true });
verify.completions({
marker: "",
exact: { name: "x", kind: "script", kindModifiers: ".ts" },
isNewIdentifierLocation: true,
});

View File

@ -19,4 +19,8 @@
//// }
////}
verify.completions({ marker: "", exact: ["a", "b"], isNewIdentifierLocation: true });
verify.completions({
marker: "",
exact: ["a", "b"].map(name => ({ name, kind: "script", kindModifiers: ".ts" })),
isNewIdentifierLocation: true,
});

View File

@ -13,4 +13,8 @@
//// }
////}
verify.completions({ marker: "", exact: ["src", "foo/"], isNewIdentifierLocation: true });
verify.completions({
marker: "",
exact: ["src", "foo/"].map(name => ({ name, kind: "directory" })),
isNewIdentifierLocation: true,
});

View File

@ -24,6 +24,7 @@ const classEntry = (isConstructor: boolean): FourSlashInterface.ExpectedCompleti
source: "/a",
sourceDisplay: "./a",
kind: "class",
kindModifiers: "export",
text: isConstructor ? "constructor Cls(): Cls" : "class Cls",
hasAction: true,
isRecommended: true,

View File

@ -27,6 +27,7 @@ const abs = (ctr: boolean): FourSlashInterface.ExpectedCompletionEntry => ({
name: "Abs",
text: ctr ? "constructor Abs(): Abs" : "class Abs",
kind: "class",
kindModifiers: "abstract",
});
verify.completions(

View File

@ -23,10 +23,22 @@
////alpha.f(new /*c1*/);
verify.completions(
{ marker: ["a0", "a1"], includes: { name: "Name", text: "namespace Name", kind: "module", isRecommended: true } },
{
marker: ["a0", "a1"],
includes: { name: "Name", text: "namespace Name", kind: "module", kindModifiers: "export", isRecommended: true },
},
{
marker: ["b0", "b1"],
includes: { name: "Name", source: "/a", sourceDisplay: "./a", text: "namespace Name", kind: "module", hasAction: true, isRecommended: true, },
includes: {
name: "Name",
source: "/a",
sourceDisplay: "./a",
text: "namespace Name",
kind: "module",
kindModifiers: "export",
hasAction: true,
isRecommended: true,
},
preferences: { includeCompletionsForModuleExports: true },
},
{ marker: ["c0", "c1"], includes: { name: "alpha", text: "import alpha", kind: "alias", isRecommended: true } },

View File

@ -5,4 +5,4 @@
////}
//// /*2*/
verify.completions({ marker: test.markers(), includes: { name: "C", text: "class C", kind: "class" } });
verify.completions({ marker: test.markers(), includes: { name: "C", text: "class C", kind: "class", kindModifiers: "export" } });

View File

@ -7,5 +7,5 @@
verify.completions({
marker: test.markers(),
includes: { name: "func", text: "function func(): void", kind: "function" },
includes: { name: "func", text: "function func(): void", kind: "function", kindModifiers: "export" },
});

View File

@ -6,4 +6,4 @@
////var v;
////v./**/
verify.completions({ marker: "", includes: { name: "toExponential", kind: "method" } });
verify.completions({ marker: "", includes: { name: "toExponential", kind: "method", kindModifiers: "declare" } });

View File

@ -7,4 +7,4 @@
//// */
////function f() { this./**/ }
verify.completions({ marker: "", includes: { name: "toExponential", kind: "method" } });
verify.completions({ marker: "", includes: { name: "toExponential", kind: "method", kindModifiers: "declare" } });

View File

@ -9,7 +9,7 @@
verify.completions({
marker: "",
includes: [
{ name: "toExponential", kind: "method" },
{ name: "charCodeAt", kind: "method" },
{ name: "toExponential", kind: "method", kindModifiers: "declare" },
{ name: "charCodeAt", kind: "method", kindModifiers: "declare" },
],
});

View File

@ -24,7 +24,7 @@
////var test1 = function(x) { return x./*4*/ }, test2 = function(a) { return a./*5*/ };
verify.completions(
{ marker: "1", includes: { name: "charCodeAt", kind: "method" } },
{ marker: ["2", "3", "4"], includes: { name: "toExponential", kind: "method" } },
{ marker: "1", includes: { name: "charCodeAt", kind: "method", kindModifiers: "declare" } },
{ marker: ["2", "3", "4"], includes: { name: "toExponential", kind: "method", kindModifiers: "declare" } },
{ marker: "5", includes: { name: "test1", kind: "warning" } },
);

View File

@ -24,7 +24,7 @@
goTo.marker('body');
edit.insert('.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });
edit.backspace();
verify.signatureHelp({
@ -35,4 +35,4 @@ verify.signatureHelp({
goTo.marker('method');
edit.insert('.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });

View File

@ -13,8 +13,8 @@
goTo.marker('a');
edit.insert('.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });
goTo.marker('b');
edit.insert('.');
verify.completions({ includes: { name: "substr", kind: "method" } });
verify.completions({ includes: { name: "substr", kind: "method", kindModifiers: "declare" } });

View File

@ -18,8 +18,8 @@
goTo.marker('str');
edit.insert('.');
verify.completions({ includes: { name: "substr", kind: "method" } });
verify.completions({ includes: { name: "substr", kind: "method", kindModifiers: "declare" } });
goTo.marker('num');
edit.insert('.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });

View File

@ -6,4 +6,4 @@
////var v;
////v./**/
verify.completions({ marker: "", includes: { name: "valueOf", kind: "method" } });
verify.completions({ marker: "", includes: { name: "valueOf", kind: "method", kindModifiers: "declare" } });

View File

@ -6,4 +6,4 @@
////var v;
////v./**/
verify.completions({ marker: "", includes: { name: "concat", kind: "method" } });
verify.completions({ marker: "", includes: { name: "concat", kind: "method", kindModifiers: "declare" } });

View File

@ -6,4 +6,4 @@
////function foo(a,b) { }
////foo(1,2)./**/
verify.completions({ marker: "", includes: { name: "toExponential", kind: "method" } });
verify.completions({ marker: "", includes: { name: "toExponential", kind: "method", kindModifiers: "declare" } });

View File

@ -10,4 +10,4 @@
//// let x = foo;
//// foo(1)./**/
verify.completions({ marker: "", includes: { name: "toExponential", kind: "method" } });
verify.completions({ marker: "", includes: { name: "toExponential", kind: "method", kindModifiers: "declare" } });

View File

@ -8,4 +8,4 @@
////var v;
////v()./**/
verify.completions({ marker: "", includes: { name: "toExponential", kind: "method" } });
verify.completions({ marker: "", includes: { name: "toExponential", kind: "method", kindModifiers: "declare" } });

View File

@ -8,4 +8,4 @@
////var v;
////new v()./**/
verify.completions({ marker: "", includes: { name: "toExponential", kind: "method" } });
verify.completions({ marker: "", includes: { name: "toExponential", kind: "method", kindModifiers: "declare" } });

View File

@ -21,9 +21,9 @@
goTo.marker('1');
edit.insert('.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });
edit.backspace();
goTo.marker('2');
edit.insert('.');
verify.completions({ includes: { name: "substr", kind: "method" } });
verify.completions({ includes: { name: "substr", kind: "method", kindModifiers: "declare" } });

View File

@ -13,4 +13,4 @@ goTo.marker();
edit.insert('.');
verify.completions({ includes: ["n", "s", "b"].map(name => ({ name, kind: "property" })) });
edit.insert('n.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });

View File

@ -23,4 +23,4 @@ verify.completions({
],
});
edit.insert('n.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });

View File

@ -26,11 +26,11 @@ goTo.marker();
edit.insert('.');
verify.completions({ includes: ["n", "s", "b"].map(name => ({ name, kind: "property" })) });;
edit.insert('n.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });
edit.backspace(4);
edit.insert('y.');
verify.completions({ includes: { name: "toUpperCase", kind: "method" } });
verify.completions({ includes: { name: "toUpperCase", kind: "method", kindModifiers: "declare" } });
edit.backspace(2);
edit.insert('z(');
verify.signatureHelp({

View File

@ -14,4 +14,4 @@ goTo.marker();
edit.insert('.');
verify.completions({ includes: ["n", "s", "b"].map(name => ({ name, kind: "property" })) });;
edit.insert('n.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });

View File

@ -18,4 +18,4 @@
goTo.marker();
edit.insert('.baz.');
verify.completions({ includes: { name: "substr", kind: "method" } });
verify.completions({ includes: { name: "substr", kind: "method", kindModifiers: "declare" } });

View File

@ -24,4 +24,4 @@ verify.completions({ marker: "", includes: "y", excludes: "invisible" });
edit.insert('x.');
verify.completions({ includes: { name: "a", kind: "property" } });
edit.insert('a.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });

View File

@ -22,4 +22,4 @@ goTo.marker();
edit.insert('.');
verify.completions({ includes: ["s", "b", "n"].map(name => ({ name, kind: "property" })) });
edit.insert('n.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });

View File

@ -22,4 +22,4 @@ verify.completions({
],
});
edit.insert('n.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });

View File

@ -13,4 +13,4 @@ goTo.marker();
edit.insert('.');
verify.completions({ includes: ["n", "s", "b"].map(name => ({ name, kind: "property" })) });
edit.insert('n.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });

View File

@ -22,4 +22,4 @@ verify.completions({ marker: "", includes: "y", excludes: "invisible" });
edit.insert('x.');
verify.completions({ includes: { name: "a", kind: "property" } });
edit.insert('a.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });

View File

@ -28,7 +28,7 @@ edit.backspace();
// Members of a class method (1)
goTo.marker('2');
edit.insert('.');
verify.completions({ includes: { name: "length", kind: "property" } });
verify.completions({ includes: { name: "length", kind: "property", kindModifiers: "declare" } });
edit.backspace();
// Members of the invocation of a class method (1)

View File

@ -26,7 +26,7 @@ edit.backspace();
// Verify the type of the instance property
goTo.marker('2');
edit.insert('.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });
goTo.marker('3');
edit.insert('.');

View File

@ -23,10 +23,10 @@
goTo.marker('1');
edit.insert('.');
verify.completions({ includes: { name: "substr", kind: "method" } });
verify.completions({ includes: { name: "substr", kind: "method", kindModifiers: "declare" } });
edit.backspace();
goTo.marker('2');
edit.insert('.');
verify.completions({ includes: { name: "toFixed", kind: "method" } });
verify.completions({ includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });
edit.backspace();

View File

@ -23,4 +23,4 @@
//// var x;
//// x[0].a./*3*/
verify.completions({ marker: test.markers(), includes: { name: "toFixed", kind: "method" } });
verify.completions({ marker: test.markers(), includes: { name: "toFixed", kind: "method", kindModifiers: "declare" } });

View File

@ -26,10 +26,10 @@ const values: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntryObject> =
const typeMembers: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntryObject> = [
{ name: "NumberLike", kind: "type" },
{ name: "People", kind: "type" },
{ name: "O", kind: "module" },
{ name: "O", kind: "module", kindModifiers: "export" },
];
function warnings(entries: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntryObject>): ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry> {
return entries.map(e => ({ ...e, kind: "warning" }));
return entries.map(e => ({ ...e, kind: "warning", kindModifiers: undefined }));
}
verify.completions(

View File

@ -44,7 +44,7 @@ verify.completions(
{
marker: "typeFooMember",
exact: [
{ name: "Namespace", kind: "module" },
{ name: "Namespace", kind: "module", kindModifiers: "export" },
...warnings(["Foo", "value", "property1", "method1", "method3", "method4", "foo", "age", "SomeType", "x", "x1"]),
],
},
@ -84,7 +84,7 @@ verify.completions(
marker: "valueMemberOfFoo",
exact: [
{ name: "prototype", kind: "property" },
{ name: "method1", kind: "method" },
{ name: "method1", kind: "method", kindModifiers: "static" },
...completion.functionMembers,
...warnings(["Foo", "value", "property1", "method3", "method4", "foo", "age", "Namespace", "SomeType", "x", "x1"]),
],

View File

@ -41,11 +41,11 @@ verify.completions(
},
{
marker: "typeFooMember",
exact: { name: "Namespace", kind: "module" },
exact: { name: "Namespace", kind: "module", kindModifiers: "export" },
},
{
marker: "NamespaceMember",
exact: { name: "SomeType", kind: "interface" },
exact: { name: "SomeType", kind: "interface", kindModifiers: "export" },
},
{
marker: "globalValue",
@ -71,7 +71,7 @@ verify.completions(
marker: "valueMemberOfFoo",
exact: [
"prototype",
{ name: "method1", kind: "method" },
{ name: "method1", kind: "method", kindModifiers: "static" },
...completion.functionMembers,
],
},

View File

@ -23,6 +23,7 @@ verify.completions({
sourceDisplay: "./node_modules/foo/index",
text: "const fail: number",
kind: "const",
kindModifiers: "export,declare",
hasAction: true,
},
preferences: { includeCompletionsForModuleExports: true },