Completions sorting overhaul (#46703)

* Sort resolved auto-import completions by number of directory separators

* Sort completions in services layer

* Finish tests

* Fix more tests

* Respect SortText in completions

* Update tests to use `unsorted` assertion
This commit is contained in:
Andrew Branch
2021-12-03 14:54:51 -08:00
committed by GitHub
parent 240ba0acef
commit 2ce05a8292
153 changed files with 131192 additions and 131017 deletions
+8 -1
View File
@@ -770,7 +770,11 @@ namespace ts {
return deduplicated as any as SortedReadonlyArray<T>;
}
export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>): void {
export function createSortedArray<T>(): SortedArray<T> {
return [] as any as SortedArray<T>; // TODO: GH#19873
}
export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>, allowDuplicates?: boolean): void {
if (array.length === 0) {
array.push(insert);
return;
@@ -780,6 +784,9 @@ namespace ts {
if (insertIndex < 0) {
array.splice(~insertIndex, 0, insert);
}
else if (allowDuplicates) {
array.splice(insertIndex, 0, insert);
}
}
export function sortAndDeduplicate<T>(array: readonly string[]): SortedReadonlyArray<string>;
+34 -3
View File
@@ -914,9 +914,26 @@ namespace FourSlash {
}
if (ts.hasProperty(options, "exact")) {
ts.Debug.assert(!ts.hasProperty(options, "includes") && !ts.hasProperty(options, "excludes"));
ts.Debug.assert(!ts.hasProperty(options, "includes") && !ts.hasProperty(options, "excludes") && !ts.hasProperty(options, "unsorted"));
if (options.exact === undefined) throw this.raiseError("Expected no completions");
this.verifyCompletionsAreExactly(actualCompletions.entries, toArray(options.exact), options.marker);
this.verifyCompletionsAreExactly(actualCompletions.entries, options.exact, options.marker);
}
else if (options.unsorted) {
ts.Debug.assert(!ts.hasProperty(options, "includes") && !ts.hasProperty(options, "excludes"));
for (const expectedEntry of options.unsorted) {
const name = typeof expectedEntry === "string" ? expectedEntry : expectedEntry.name;
const found = nameToEntries.get(name);
if (!found) throw this.raiseError(`Unsorted: completion '${name}' not found.`);
if (!found.length) throw this.raiseError(`Unsorted: no completions with name '${name}' remain unmatched.`);
this.verifyCompletionEntry(found.shift()!, expectedEntry);
}
if (actualCompletions.entries.length !== options.unsorted.length) {
const unmatched: string[] = [];
nameToEntries.forEach(entries => {
unmatched.push(...entries.map(e => e.name));
});
this.raiseError(`Additional completions found not included in 'unsorted': ${unmatched.join("\n")}`);
}
}
else {
if (options.includes) {
@@ -993,7 +1010,11 @@ namespace FourSlash {
}
}
private verifyCompletionsAreExactly(actual: readonly ts.CompletionEntry[], expected: readonly FourSlashInterface.ExpectedCompletionEntry[], marker?: ArrayOrSingle<string | Marker>) {
private verifyCompletionsAreExactly(actual: readonly ts.CompletionEntry[], expected: ArrayOrSingle<FourSlashInterface.ExpectedCompletionEntry> | FourSlashInterface.ExpectedExactCompletionsPlus, marker?: ArrayOrSingle<string | Marker>) {
if (!ts.isArray(expected)) {
expected = [expected];
}
// First pass: test that names are right. Then we'll test details.
assert.deepEqual(actual.map(a => a.name), expected.map(e => typeof e === "string" ? e : e.name), marker ? "At marker " + JSON.stringify(marker) : undefined);
@@ -1004,6 +1025,16 @@ namespace FourSlash {
}
this.verifyCompletionEntry(completion, expectedCompletion);
});
// All completions were correct in the sort order given. If that order was produced by a function
// like `completion.globalsPlus`, ensure the "plus" array was sorted in the same way.
const { plusArgument, plusFunctionName } = expected as FourSlashInterface.ExpectedExactCompletionsPlus;
if (plusArgument) {
assert.deepEqual(
plusArgument,
expected.filter(entry => plusArgument.includes(entry)),
`At marker ${JSON.stringify(marker)}: Argument to '${plusFunctionName}' was incorrectly sorted.`);
}
}
/** Use `getProgram` instead of accessing this directly. */
+207 -138
View File
@@ -1024,8 +1024,48 @@ namespace FourSlashInterface {
export const keywordsWithUndefined: readonly ExpectedCompletionEntryObject[] = res;
export const keywords: readonly ExpectedCompletionEntryObject[] = keywordsWithUndefined.filter(k => k.name !== "undefined");
export const typeKeywords: readonly ExpectedCompletionEntryObject[] =
["false", "null", "true", "void", "asserts", "any", "boolean", "infer", "keyof", "never", "readonly", "number", "object", "string", "symbol", "undefined", "unique", "unknown", "bigint"].map(keywordEntry);
export const typeKeywords: readonly ExpectedCompletionEntryObject[] = [
"any",
"asserts",
"bigint",
"boolean",
"false",
"infer",
"keyof",
"never",
"null",
"number",
"object",
"readonly",
"string",
"symbol",
"true",
"undefined",
"unique",
"unknown",
"void",
].map(keywordEntry);
export function sorted(entries: readonly ExpectedCompletionEntry[]): readonly ExpectedCompletionEntry[] {
return ts.stableSort(entries, compareExpectedCompletionEntries);
}
// If you want to use a function like `globalsPlus`, that function needs to sort
// the concatted array since the entries provided as "plus" could be interleaved
// among the "globals." However, we still want to assert that the "plus" array
// was internally sorted correctly, so we tack it onto the sorted concatted array
// so `verify.completions` can assert that it represents the same order as the response.
function combineExpectedCompletionEntries(
functionName: string,
providedByHarness: readonly ExpectedCompletionEntry[],
providedByTest: readonly ExpectedCompletionEntry[],
): ExpectedExactCompletionsPlus {
return Object.assign(sorted([...providedByHarness, ...providedByTest]), { plusFunctionName: functionName, plusArgument: providedByTest });
}
export function typeKeywordsPlus(plus: readonly ExpectedCompletionEntry[]) {
return combineExpectedCompletionEntries("typeKeywordsPlus", typeKeywords, plus);
}
const globalTypeDecls: readonly ExpectedCompletionEntryObject[] = [
interfaceEntry("Symbol"),
@@ -1139,13 +1179,12 @@ namespace FourSlashInterface {
sortText: SortText.GlobalsOrKeywords
};
export const globalTypes = globalTypesPlus([]);
export function globalTypesPlus(plus: readonly ExpectedCompletionEntry[]): readonly ExpectedCompletionEntry[] {
return [
globalThisEntry,
...globalTypeDecls,
...plus,
...typeKeywords,
];
export function globalTypesPlus(plus: readonly ExpectedCompletionEntry[]) {
return combineExpectedCompletionEntries(
"globalTypesPlus",
[globalThisEntry, ...globalTypeDecls, ...typeKeywords],
plus
);
}
export const typeAssertionKeywords: readonly ExpectedCompletionEntry[] =
@@ -1188,13 +1227,25 @@ namespace FourSlashInterface {
});
}
export const classElementKeywords: readonly ExpectedCompletionEntryObject[] =
["private", "protected", "public", "static", "abstract", "async", "constructor", "declare", "get", "readonly", "set", "override"].map(keywordEntry);
export const classElementKeywords: readonly ExpectedCompletionEntryObject[] = [
"abstract",
"async",
"constructor",
"declare",
"get",
"override",
"private",
"protected",
"public",
"readonly",
"set",
"static",
].map(keywordEntry);
export const classElementInJsKeywords = getInJsKeywords(classElementKeywords);
export const constructorParameterKeywords: readonly ExpectedCompletionEntryObject[] =
["private", "protected", "public", "readonly", "override"].map((name): ExpectedCompletionEntryObject => ({
["override", "private", "protected", "public", "readonly"].map((name): ExpectedCompletionEntryObject => ({
name,
kind: "keyword",
sortText: SortText.GlobalsOrKeywords
@@ -1208,7 +1259,11 @@ namespace FourSlashInterface {
propertyEntry("length"),
{ name: "arguments", kind: "property", kindModifiers: "declare", text: "(property) Function.arguments: any" },
propertyEntry("caller"),
];
].sort(compareExpectedCompletionEntries);
export function functionMembersPlus(plus: readonly ExpectedCompletionEntryObject[]) {
return combineExpectedCompletionEntries("functionMembersPlus", functionMembers, plus);
}
export const stringMembers: readonly ExpectedCompletionEntryObject[] = [
methodEntry("toString"),
@@ -1232,16 +1287,27 @@ namespace FourSlashInterface {
propertyEntry("length"),
deprecatedMethodEntry("substr"),
methodEntry("valueOf"),
];
].sort(compareExpectedCompletionEntries);
export const functionMembersWithPrototype: readonly ExpectedCompletionEntryObject[] = [
...functionMembers.slice(0, 4),
...functionMembers,
propertyEntry("prototype"),
...functionMembers.slice(4),
];
].sort(compareExpectedCompletionEntries);
export function functionMembersWithPrototypePlus(plus: readonly ExpectedCompletionEntryObject[]) {
return [...functionMembersWithPrototype, ...plus].sort(compareExpectedCompletionEntries);
}
// TODO: Shouldn't propose type keywords in statement position
export const statementKeywordsWithTypes: readonly ExpectedCompletionEntryObject[] = [
"abstract",
"any",
"as",
"asserts",
"async",
"await",
"bigint",
"boolean",
"break",
"case",
"catch",
@@ -1249,6 +1315,7 @@ namespace FourSlashInterface {
"const",
"continue",
"debugger",
"declare",
"default",
"delete",
"do",
@@ -1261,50 +1328,41 @@ namespace FourSlashInterface {
"for",
"function",
"if",
"implements",
"import",
"in",
"infer",
"instanceof",
"interface",
"keyof",
"let",
"module",
"namespace",
"never",
"new",
"null",
"number",
"object",
"package",
"readonly",
"return",
"string",
"super",
"switch",
"symbol",
"this",
"throw",
"true",
"try",
"type",
"typeof",
"unique",
"unknown",
"var",
"void",
"while",
"with",
"implements",
"interface",
"let",
"package",
"yield",
"abstract",
"as",
"asserts",
"any",
"async",
"await",
"boolean",
"declare",
"infer",
"keyof",
"module",
"namespace",
"never",
"readonly",
"number",
"object",
"string",
"symbol",
"type",
"unique",
"unknown",
"bigint",
].map(keywordEntry);
export const statementKeywords: readonly ExpectedCompletionEntryObject[] = statementKeywordsWithTypes.filter(k => {
@@ -1326,51 +1384,54 @@ namespace FourSlashInterface {
export const statementInJsKeywords = getInJsKeywords(statementKeywords);
export const globalsVars: readonly ExpectedCompletionEntryObject[] = [
functionEntry("eval"),
functionEntry("parseInt"),
functionEntry("parseFloat"),
functionEntry("isNaN"),
functionEntry("isFinite"),
varEntry("Array"),
varEntry("ArrayBuffer"),
varEntry("Boolean"),
varEntry("DataView"),
varEntry("Date"),
functionEntry("decodeURI"),
functionEntry("decodeURIComponent"),
functionEntry("encodeURI"),
functionEntry("encodeURIComponent"),
deprecatedFunctionEntry("escape"),
deprecatedFunctionEntry("unescape"),
varEntry("NaN"),
varEntry("Infinity"),
varEntry("Object"),
varEntry("Function"),
varEntry("String"),
varEntry("Boolean"),
varEntry("Number"),
varEntry("Math"),
varEntry("Date"),
varEntry("RegExp"),
varEntry("Error"),
deprecatedFunctionEntry("escape"),
functionEntry("eval"),
varEntry("EvalError"),
varEntry("RangeError"),
varEntry("ReferenceError"),
varEntry("SyntaxError"),
varEntry("TypeError"),
varEntry("URIError"),
varEntry("JSON"),
varEntry("Array"),
varEntry("ArrayBuffer"),
varEntry("DataView"),
varEntry("Int8Array"),
varEntry("Uint8Array"),
varEntry("Uint8ClampedArray"),
varEntry("Int16Array"),
varEntry("Uint16Array"),
varEntry("Int32Array"),
varEntry("Uint32Array"),
varEntry("Float32Array"),
varEntry("Float64Array"),
varEntry("Function"),
varEntry("Infinity"),
moduleEntry("Intl"),
varEntry("Int16Array"),
varEntry("Int32Array"),
varEntry("Int8Array"),
functionEntry("isFinite"),
functionEntry("isNaN"),
varEntry("JSON"),
varEntry("Math"),
varEntry("NaN"),
varEntry("Number"),
varEntry("Object"),
functionEntry("parseFloat"),
functionEntry("parseInt"),
varEntry("RangeError"),
varEntry("ReferenceError"),
varEntry("RegExp"),
varEntry("String"),
varEntry("SyntaxError"),
varEntry("TypeError"),
varEntry("Uint16Array"),
varEntry("Uint32Array"),
varEntry("Uint8Array"),
varEntry("Uint8ClampedArray"),
deprecatedFunctionEntry("unescape"),
varEntry("URIError"),
];
const globalKeywordsInsideFunction: readonly ExpectedCompletionEntryObject[] = [
"as",
"async",
"await",
"break",
"case",
"catch",
@@ -1390,11 +1451,15 @@ namespace FourSlashInterface {
"for",
"function",
"if",
"implements",
"import",
"in",
"instanceof",
"interface",
"let",
"new",
"null",
"package",
"return",
"super",
"switch",
@@ -1407,45 +1472,54 @@ namespace FourSlashInterface {
"void",
"while",
"with",
"implements",
"interface",
"let",
"package",
"yield",
"as",
"async",
"await",
].map(keywordEntry);
function compareExpectedCompletionEntries(a: ExpectedCompletionEntry, b: ExpectedCompletionEntry) {
const aSortText = typeof a !== "string" && a.sortText || ts.Completions.SortText.LocationPriority;
const bSortText = typeof b !== "string" && b.sortText || ts.Completions.SortText.LocationPriority;
const bySortText = ts.compareStringsCaseSensitiveUI(aSortText, bSortText);
if (bySortText !== ts.Comparison.EqualTo) return bySortText;
return ts.compareStringsCaseSensitiveUI(typeof a === "string" ? a : a.name, typeof b === "string" ? b : b.name);
}
export const undefinedVarEntry: ExpectedCompletionEntryObject = {
name: "undefined",
kind: "var",
sortText: SortText.GlobalsOrKeywords
};
// TODO: many of these are inappropriate to always provide
export const globalsInsideFunction = (plus: readonly ExpectedCompletionEntry[]): readonly ExpectedCompletionEntry[] => [
export const globalsInsideFunction = (plus: readonly ExpectedCompletionEntry[], options?: { noLib?: boolean }): readonly ExpectedCompletionEntry[] => [
{ name: "arguments", kind: "local var" },
...plus,
globalThisEntry,
...globalsVars,
...options?.noLib ? [] : globalsVars,
undefinedVarEntry,
...globalKeywordsInsideFunction,
];
].sort(compareExpectedCompletionEntries);
const globalInJsKeywordsInsideFunction = getInJsKeywords(globalKeywordsInsideFunction);
// TODO: many of these are inappropriate to always provide
export const globalsInJsInsideFunction = (plus: readonly ExpectedCompletionEntry[]): readonly ExpectedCompletionEntry[] => [
export const globalsInJsInsideFunction = (plus: readonly ExpectedCompletionEntry[], options?: { noLib?: boolean }): readonly ExpectedCompletionEntry[] => [
{ name: "arguments", kind: "local var" },
globalThisEntry,
...globalsVars,
...options?.noLib ? [] : globalsVars,
...plus,
undefinedVarEntry,
...globalInJsKeywordsInsideFunction,
];
].sort(compareExpectedCompletionEntries);
// TODO: many of these are inappropriate to always provide
export const globalKeywords: readonly ExpectedCompletionEntryObject[] = [
"abstract",
"any",
"as",
"asserts",
"async",
"await",
"bigint",
"boolean",
"break",
"case",
"catch",
@@ -1453,6 +1527,7 @@ namespace FourSlashInterface {
"const",
"continue",
"debugger",
"declare",
"default",
"delete",
"do",
@@ -1465,55 +1540,49 @@ namespace FourSlashInterface {
"for",
"function",
"if",
"implements",
"import",
"in",
"infer",
"instanceof",
"interface",
"keyof",
"let",
"module",
"namespace",
"never",
"new",
"null",
"number",
"object",
"package",
"readonly",
"return",
"string",
"super",
"switch",
"symbol",
"this",
"throw",
"true",
"try",
"type",
"typeof",
"unique",
"unknown",
"var",
"void",
"while",
"with",
"implements",
"interface",
"let",
"package",
"yield",
"abstract",
"as",
"asserts",
"any",
"async",
"await",
"boolean",
"declare",
"infer",
"keyof",
"module",
"namespace",
"never",
"readonly",
"number",
"object",
"string",
"symbol",
"type",
"unique",
"unknown",
"bigint",
].map(keywordEntry);
export const globalInJsKeywords = getInJsKeywords(globalKeywords);
export const insideMethodKeywords: readonly ExpectedCompletionEntryObject[] = [
"as",
"async",
"await",
"break",
"case",
"catch",
@@ -1533,11 +1602,15 @@ namespace FourSlashInterface {
"for",
"function",
"if",
"implements",
"import",
"in",
"instanceof",
"interface",
"let",
"new",
"null",
"package",
"return",
"super",
"switch",
@@ -1550,14 +1623,7 @@ namespace FourSlashInterface {
"void",
"while",
"with",
"implements",
"interface",
"let",
"package",
"yield",
"as",
"async",
"await",
].map(keywordEntry);
export const insideMethodInJsKeywords = getInJsKeywords(insideMethodKeywords);
@@ -1567,34 +1633,31 @@ namespace FourSlashInterface {
...globalsVars,
undefinedVarEntry,
...globalKeywords
];
].sort(compareExpectedCompletionEntries);
export const globalsInJs: readonly ExpectedCompletionEntryObject[] = [
globalThisEntry,
...globalsVars,
undefinedVarEntry,
...globalInJsKeywords
];
].sort(compareExpectedCompletionEntries);
export function globalsPlus(plus: readonly ExpectedCompletionEntry[]): readonly ExpectedCompletionEntry[] {
const firstEntry = plus[0];
const afterUndefined = typeof firstEntry !== "string" && firstEntry.sortText! > undefinedVarEntry.sortText!;
return [
export function globalsPlus(plus: readonly ExpectedCompletionEntry[], options?: { noLib?: boolean }) {
return combineExpectedCompletionEntries("globalsPlus", [
globalThisEntry,
...globalsVars,
...afterUndefined ? ts.emptyArray : plus,
...options?.noLib ? [] : globalsVars,
undefinedVarEntry,
...afterUndefined ? plus : ts.emptyArray,
...globalKeywords];
...globalKeywords,
], plus);
}
export function globalsInJsPlus(plus: readonly ExpectedCompletionEntry[]): readonly ExpectedCompletionEntry[] {
return [
export function globalsInJsPlus(plus: readonly ExpectedCompletionEntry[], options?: { noLib?: boolean }) {
return combineExpectedCompletionEntries("globalsInJsPlus", [
globalThisEntry,
...globalsVars,
...plus,
...options?.noLib ? [] : globalsVars,
undefinedVarEntry,
...globalInJsKeywords];
...globalInJsKeywords,
], plus);
}
}
@@ -1633,12 +1696,18 @@ namespace FourSlashInterface {
readonly sortText?: ts.Completions.SortText;
}
export type ExpectedExactCompletionsPlus = readonly ExpectedCompletionEntry[] & {
plusFunctionName: string,
plusArgument: readonly ExpectedCompletionEntry[]
};
export interface VerifyCompletionsOptions {
readonly marker?: ArrayOrSingle<string | FourSlash.Marker>;
readonly isNewIdentifierLocation?: boolean; // Always tested
readonly isGlobalCompletion?: boolean; // Only tested if set
readonly optionalReplacementSpan?: FourSlash.Range; // Only tested if set
readonly exact?: ArrayOrSingle<ExpectedCompletionEntry>;
readonly exact?: ArrayOrSingle<ExpectedCompletionEntry> | ExpectedExactCompletionsPlus;
readonly unsorted?: readonly ExpectedCompletionEntry[];
readonly includes?: ArrayOrSingle<ExpectedCompletionEntry>;
readonly excludes?: ArrayOrSingle<string>;
readonly preferences?: ts.UserPreferences;
+2 -2
View File
@@ -1854,14 +1854,14 @@ namespace ts.server {
if (kind === protocol.CommandTypes.CompletionsFull) return completions;
const prefix = args.prefix || "";
const entries = stableSort(mapDefined<CompletionEntry, protocol.CompletionEntry>(completions.entries, entry => {
const entries = mapDefined<CompletionEntry, protocol.CompletionEntry>(completions.entries, entry => {
if (completions.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) {
const { name, kind, kindModifiers, sortText, insertText, replacementSpan, hasAction, source, sourceDisplay, isSnippet, isRecommended, isPackageJsonImport, isImportStatementCompletion, data } = entry;
const convertedSpan = replacementSpan ? toProtocolTextSpan(replacementSpan, scriptInfo) : undefined;
// Use `hasAction || undefined` to avoid serializing `false`.
return { name, kind, kindModifiers, sortText, insertText, replacementSpan: convertedSpan, isSnippet, hasAction: hasAction || undefined, source, sourceDisplay, isRecommended, isPackageJsonImport, isImportStatementCompletion, data };
}
}), (a, b) => compareStringsCaseSensitiveUI(a.name, b.name));
});
if (kind === protocol.CommandTypes.Completions) {
if (completions.metadata) (entries as WithMetadata<readonly protocol.CompletionEntry[]>).metadata = completions.metadata;
+35 -9
View File
@@ -295,6 +295,32 @@ namespace ts.Completions {
}
}
// Editors will use the `sortText` and then fall back to `name` for sorting, but leave ties in response order.
// So, it's important that we sort those ties in the order we want them displayed if it matters. We don't
// strictly need to sort by name or SortText here since clients are going to do it anyway, but we have to
// do the work of comparing them so we can sort those ties appropriately; plus, it makes the order returned
// by the language service consistent with what TS Server does and what editors typically do. This also makes
// completions tests make more sense. We used to sort only alphabetically and only in the server layer, but
// this made tests really weird, since most fourslash tests don't use the server.
function compareCompletionEntries(entryInArray: CompletionEntry, entryToInsert: CompletionEntry): Comparison {
let result = compareStringsCaseSensitiveUI(entryInArray.sortText, entryToInsert.sortText);
if (result === Comparison.EqualTo) {
result = compareStringsCaseSensitiveUI(entryInArray.name, entryToInsert.name);
}
if (result === Comparison.EqualTo && entryInArray.data?.moduleSpecifier && entryToInsert.data?.moduleSpecifier) {
// Sort same-named auto-imports by module specifier
result = compareNumberOfDirectorySeparators(
(entryInArray.data as CompletionEntryDataResolved).moduleSpecifier,
(entryToInsert.data as CompletionEntryDataResolved).moduleSpecifier,
);
}
if (result === Comparison.EqualTo) {
// Fall back to symbol order - if we return `EqualTo`, `insertSorted` will put later symbols first.
return Comparison.LessThan;
}
return result;
}
function completionEntryDataIsResolved(data: CompletionEntryDataAutoImport | undefined): data is CompletionEntryDataResolved {
return !!data?.moduleSpecifier;
}
@@ -442,7 +468,7 @@ namespace ts.Completions {
}
}
const entries: CompletionEntry[] = [];
const entries = createSortedArray<CompletionEntry>();
if (isUncheckedFile(sourceFile, compilerOptions)) {
const uniqueNames = getCompletionEntriesFromSymbols(
@@ -504,13 +530,13 @@ namespace ts.Completions {
const entryNames = new Set(entries.map(e => e.name));
for (const keywordEntry of getKeywordCompletions(keywordFilters, !insideJsDocTagTypeExpression && isSourceFileJS(sourceFile))) {
if (!entryNames.has(keywordEntry.name)) {
entries.push(keywordEntry);
insertSorted(entries, keywordEntry, compareCompletionEntries, /*allowDuplicates*/ true);
}
}
}
for (const literal of literals) {
entries.push(createCompletionEntryForLiteral(sourceFile, preferences, literal));
insertSorted(entries, createCompletionEntryForLiteral(sourceFile, preferences, literal), compareCompletionEntries, /*allowDuplicates*/ true);
}
return {
@@ -589,7 +615,7 @@ namespace ts.Completions {
position: number,
uniqueNames: UniqueNameSet,
target: ScriptTarget,
entries: Push<CompletionEntry>): void {
entries: SortedArray<CompletionEntry>): void {
getNameTable(sourceFile).forEach((pos, name) => {
// Skip identifiers produced only from the current location
if (pos === position) {
@@ -598,13 +624,13 @@ namespace ts.Completions {
const realName = unescapeLeadingUnderscores(name);
if (!uniqueNames.has(realName) && isIdentifierText(realName, target)) {
uniqueNames.add(realName);
entries.push({
insertSorted(entries, {
name: realName,
kind: ScriptElementKind.warning,
kindModifiers: "",
sortText: SortText.JavascriptIdentifiers,
isFromUncheckedFile: true
});
}, compareCompletionEntries);
}
});
}
@@ -1105,7 +1131,7 @@ namespace ts.Completions {
export function getCompletionEntriesFromSymbols(
symbols: readonly Symbol[],
entries: Push<CompletionEntry>,
entries: SortedArray<CompletionEntry>,
replacementToken: Node | undefined,
contextToken: Node | undefined,
location: Node,
@@ -1174,7 +1200,7 @@ namespace ts.Completions {
/** True for locals; false for globals, module exports from other files, `this.` completions. */
const shouldShadowLaterSymbols = !origin && !(symbol.parent === undefined && !some(symbol.declarations, d => d.getSourceFile() === location.getSourceFile()));
uniques.set(name, shouldShadowLaterSymbols);
entries.push(entry);
insertSorted(entries, entry, compareCompletionEntries, /*allowDuplicates*/ true);
}
log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (timestamp() - start));
@@ -1831,7 +1857,7 @@ namespace ts.Completions {
// For `<div className="x" [||] ></div>`, `parent` will be JsxAttribute and `previousToken` will be its initializer
if ((parent as JsxAttribute).initializer === previousToken &&
previousToken.end < position) {
isJsxIdentifierExpected = true;
isJsxIdentifierExpected = true;
break;
}
switch (previousToken.kind) {
+1 -1
View File
@@ -39,7 +39,7 @@ namespace ts.Completions.StringCompletions {
case StringLiteralCompletionKind.Paths:
return convertPathCompletions(completion.paths);
case StringLiteralCompletionKind.Properties: {
const entries: CompletionEntry[] = [];
const entries = createSortedArray<CompletionEntry>();
getCompletionEntriesFromSymbols(
completion.symbols,
entries,
@@ -703,8 +703,7 @@ namespace ts.projectSystem {
// Check identifiers defined in HTML content are available in .ts file
const project = configuredProjectAt(projectService, 0);
let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1, emptyOptions);
assert(completions && completions.entries[1].name === "hello", `expected entry hello to be in completion list`);
assert(completions && completions.entries[0].name === "globalThis", `first entry should be globalThis (not strictly relevant for this test).`);
assert(completions && some(completions.entries, e => e.name === "hello"), `expected entry hello to be in completion list`);
// Close HTML file
projectService.applyChangesInOpenFiles(
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -76,141 +76,6 @@
}
]
},
{
"name": "property1",
"kind": "property",
"kindModifiers": "",
"sortText": "11",
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "property",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "Foo",
"kind": "className"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "property1",
"kind": "propertyName"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "string",
"kind": "keyword"
}
],
"documentation": [],
"tags": [
{
"name": "mytag",
"text": [
{
"text": "comment1 comment2",
"kind": "text"
}
]
}
]
},
{
"name": "property2",
"kind": "property",
"kindModifiers": "",
"sortText": "11",
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "property",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "Foo",
"kind": "className"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "property2",
"kind": "propertyName"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "number",
"kind": "keyword"
}
],
"documentation": [],
"tags": [
{
"name": "mytag1",
"text": [
{
"text": "some comments\nsome more comments about mytag1",
"kind": "text"
}
]
},
{
"name": "mytag2",
"text": [
{
"text": "here all the comments are on a new line",
"kind": "text"
}
]
},
{
"name": "mytag3"
},
{
"name": "mytag"
}
]
},
{
"name": "method3",
"kind": "method",
@@ -517,6 +382,141 @@
]
}
]
},
{
"name": "property1",
"kind": "property",
"kindModifiers": "",
"sortText": "11",
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "property",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "Foo",
"kind": "className"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "property1",
"kind": "propertyName"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "string",
"kind": "keyword"
}
],
"documentation": [],
"tags": [
{
"name": "mytag",
"text": [
{
"text": "comment1 comment2",
"kind": "text"
}
]
}
]
},
{
"name": "property2",
"kind": "property",
"kindModifiers": "",
"sortText": "11",
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "property",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "Foo",
"kind": "className"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "property2",
"kind": "propertyName"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "number",
"kind": "keyword"
}
],
"documentation": [],
"tags": [
{
"name": "mytag1",
"text": [
{
"text": "some comments\nsome more comments about mytag1",
"kind": "text"
}
]
},
{
"name": "mytag2",
"text": [
{
"text": "here all the comments are on a new line",
"kind": "text"
}
]
},
{
"name": "mytag3"
},
{
"name": "mytag"
}
]
}
]
}
@@ -123,6 +123,13 @@
}
]
},
{
"name": "a",
"kind": "warning",
"kindModifiers": "",
"sortText": "17",
"isFromUncheckedFile": true
},
{
"name": "C",
"kind": "warning",
@@ -137,13 +144,6 @@
"sortText": "17",
"isFromUncheckedFile": true
},
{
"name": "a",
"kind": "warning",
"kindModifiers": "",
"sortText": "17",
"isFromUncheckedFile": true
},
{
"name": "prototype",
"kind": "warning",
@@ -10,68 +10,6 @@
"isMemberCompletion": true,
"isNewIdentifierLocation": false,
"entries": [
{
"name": "toString",
"kind": "method",
"kindModifiers": "declare",
"sortText": "11",
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "method",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "String",
"kind": "localName"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "toString",
"kind": "methodName"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "string",
"kind": "keyword"
}
],
"documentation": [
{
"text": "Returns a string representation of a string.",
"kind": "text"
}
]
},
{
"name": "charAt",
"kind": "method",
@@ -659,6 +597,60 @@
}
]
},
{
"name": "length",
"kind": "property",
"kindModifiers": "declare",
"sortText": "11",
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "property",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "String",
"kind": "localName"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "length",
"kind": "propertyName"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "number",
"kind": "keyword"
}
],
"documentation": [
{
"text": "Returns the length of a String object.",
"kind": "text"
}
]
},
{
"name": "localeCompare",
"kind": "method",
@@ -1646,68 +1638,6 @@
}
]
},
{
"name": "toLowerCase",
"kind": "method",
"kindModifiers": "declare",
"sortText": "11",
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "method",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "String",
"kind": "localName"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "toLowerCase",
"kind": "methodName"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "string",
"kind": "keyword"
}
],
"documentation": [
{
"text": "Converts all the alphabetic characters in a string to lowercase.",
"kind": "text"
}
]
},
{
"name": "toLocaleLowerCase",
"kind": "method",
@@ -1814,68 +1744,6 @@
}
]
},
{
"name": "toUpperCase",
"kind": "method",
"kindModifiers": "declare",
"sortText": "11",
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "method",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "String",
"kind": "localName"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "toUpperCase",
"kind": "methodName"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "string",
"kind": "keyword"
}
],
"documentation": [
{
"text": "Converts all the alphabetic characters in a string to uppercase.",
"kind": "text"
}
]
},
{
"name": "toLocaleUpperCase",
"kind": "method",
@@ -1982,6 +1850,192 @@
}
]
},
{
"name": "toLowerCase",
"kind": "method",
"kindModifiers": "declare",
"sortText": "11",
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "method",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "String",
"kind": "localName"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "toLowerCase",
"kind": "methodName"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "string",
"kind": "keyword"
}
],
"documentation": [
{
"text": "Converts all the alphabetic characters in a string to lowercase.",
"kind": "text"
}
]
},
{
"name": "toString",
"kind": "method",
"kindModifiers": "declare",
"sortText": "11",
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "method",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "String",
"kind": "localName"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "toString",
"kind": "methodName"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "string",
"kind": "keyword"
}
],
"documentation": [
{
"text": "Returns a string representation of a string.",
"kind": "text"
}
]
},
{
"name": "toUpperCase",
"kind": "method",
"kindModifiers": "declare",
"sortText": "11",
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "method",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "String",
"kind": "localName"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "toUpperCase",
"kind": "methodName"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "string",
"kind": "keyword"
}
],
"documentation": [
{
"text": "Converts all the alphabetic characters in a string to uppercase.",
"kind": "text"
}
]
},
{
"name": "trim",
"kind": "method",
@@ -2045,8 +2099,8 @@
]
},
{
"name": "length",
"kind": "property",
"name": "valueOf",
"kind": "method",
"kindModifiers": "declare",
"sortText": "11",
"displayParts": [
@@ -2055,7 +2109,7 @@
"kind": "punctuation"
},
{
"text": "property",
"text": "method",
"kind": "text"
},
{
@@ -2075,8 +2129,16 @@
"kind": "punctuation"
},
{
"text": "length",
"kind": "propertyName"
"text": "valueOf",
"kind": "methodName"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": ":",
@@ -2087,13 +2149,13 @@
"kind": "space"
},
{
"text": "number",
"text": "string",
"kind": "keyword"
}
],
"documentation": [
{
"text": "Returns the length of a String object.",
"text": "Returns the primitive value of the specified object.",
"kind": "text"
}
]
@@ -2248,68 +2310,6 @@
]
}
]
},
{
"name": "valueOf",
"kind": "method",
"kindModifiers": "declare",
"sortText": "11",
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "method",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "String",
"kind": "localName"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "valueOf",
"kind": "methodName"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "string",
"kind": "keyword"
}
],
"documentation": [
{
"text": "Returns the primitive value of the specified object.",
"kind": "text"
}
]
}
]
}
+5 -6
View File
@@ -23,18 +23,17 @@
////d./*1*/
////D./*2*/
verify.completions({ marker: "1", exact: ["foo2", "foo"] });
verify.completions({ marker: "1", exact: ["foo", "foo2"] });
edit.insert('foo()');
verify.completions({
marker: "2",
exact: [
{ name: "prototype", sortText: completion.SortText.LocationPriority },
{ name: "bar2", sortText: completion.SortText.LocalDeclarationPriority },
exact: completion.functionMembersPlus([
{ name: "bar", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "bar2", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "baz", sortText: completion.SortText.LocationPriority },
{ name: "prototype", sortText: completion.SortText.LocationPriority },
{ name: "x", sortText: completion.SortText.LocationPriority },
...completion.functionMembers
]
])
});
edit.insert('bar()');
verify.noErrors();
+1 -1
View File
@@ -28,7 +28,7 @@
////d./*1*/
////D./*2*/
verify.completions({ marker: "1", exact: ["foo2", "foo"] });
verify.completions({ marker: "1", exact: ["foo", "foo2"] });
edit.insert('foo()');
verify.completions({
@@ -34,8 +34,8 @@ verify.completions({ marker: "6", exact: [{ name: "m1", text: "namespace extMod.
verify.completions({
marker: "7",
exact: [
{ name: "fooExport", text: "function extMod.m1.fooExport(): number", documentation: "exported function" },
{ name: "b", text: "var extMod.m1.b: number", documentation: "b's comment" },
{ name: "fooExport", text: "function extMod.m1.fooExport(): number", documentation: "exported function" },
{ name: "m2", text: "namespace extMod.m1.m2", documentation: "m2 comments" },
]
})
@@ -4,7 +4,7 @@
verify.completions({
marker: "",
exact: [
unsorted: [
completion.globalThisEntry,
...completion.globalsVars,
completion.undefinedVarEntry
@@ -27,8 +27,8 @@ verify.completions({
verify.completions({
marker: "2",
exact: [
{ name: "address" },
{ name: "bar" },
{ name: "address" }
],
preferences: { includeInsertTextCompletions: true },
});
@@ -36,8 +36,8 @@ verify.completions({
verify.completions({
marker: "3",
exact: [
{ name: "address" },
{ name: "bar" },
{ name: "address" }
],
preferences: { includeInsertTextCompletions: true },
});
@@ -128,7 +128,7 @@ verify.completions(
{
// Not a class element declaration location
marker: "InsideMethod",
exact: [
unsorted: [
"arguments",
completion.globalThisEntry,
"B", "C", "D", "D1", "D2", "D3", "D4", "D5", "D6", "E", "F", "F2", "G", "G2", "H", "I", "J", "K", "L", "L2", "M", "N", "O",
@@ -146,7 +146,7 @@ verify.completions(
"classThatStartedWritingIdentifierAfterPrivateModifier",
"classThatStartedWritingIdentifierAfterPrivateStaticModifier",
],
exact: ["private", "protected", "public", "static", "abstract", "async", "constructor", "declare", "get", "readonly", "set", "override"].map(
unsorted: ["private", "protected", "public", "static", "abstract", "async", "constructor", "declare", "get", "readonly", "set", "override"].map(
name => ({ name, sortText: completion.SortText.GlobalsOrKeywords })
),
isNewIdentifierLocation: true,
@@ -176,13 +176,13 @@ verify.completions(
"classThatHasWrittenAsyncKeyword",
"classElementAfterConstructorSeparatedByComma",
],
exact: [protectedMethod, getValue, ...completion.classElementKeywords],
unsorted: [protectedMethod, getValue, ...completion.classElementKeywords],
isNewIdentifierLocation: true,
},
{
// Static Base members and class member keywords allowed
marker: ["classElementContainingStatic", "classThatStartedWritingIdentifierAfterStaticModifier"],
exact: [staticMethod, ...completion.classElementKeywords],
unsorted: [staticMethod, ...completion.classElementKeywords],
isNewIdentifierLocation: true,
},
{
@@ -190,7 +190,7 @@ verify.completions(
"classThatHasAlreadyImplementedAnotherClassMethod",
"classThatHasAlreadyImplementedAnotherClassMethodAfterMethod",
],
exact: [protectedMethod, ...completion.classElementKeywords],
unsorted: [protectedMethod, ...completion.classElementKeywords],
isNewIdentifierLocation: true,
},
{
@@ -198,19 +198,19 @@ verify.completions(
"classThatHasAlreadyImplementedAnotherClassProtectedMethod",
"classThatHasDifferentMethodThanBaseAfterProtectedMethod",
],
exact: [getValue, ...completion.classElementKeywords],
unsorted: [getValue, ...completion.classElementKeywords],
isNewIdentifierLocation: true,
},
{
// instance memebers in D1 and base class are shown
marker: "classThatExtendsClassExtendingAnotherClass",
exact: ["getValue1", "protectedMethod", "getValue", ...completion.classElementKeywords],
unsorted: ["getValue1", "protectedMethod", "getValue", ...completion.classElementKeywords],
isNewIdentifierLocation: true,
},
{
// instance memebers in D2 and base class are shown
marker: "classThatExtendsClassExtendingAnotherClassWithOverridingMember",
exact: [
unsorted: [
{ name: "protectedMethod", text: "(method) D2.protectedMethod(): void" },
getValue,
...completion.classElementKeywords,
@@ -223,7 +223,7 @@ verify.completions(
"classThatExtendsClassExtendingAnotherClassAndTypesStatic",
"classThatExtendsClassExtendingAnotherClassWithOverridingMemberAndTypesStatic"
],
exact: [staticMethod, ...completion.classElementKeywords],
unsorted: [staticMethod, ...completion.classElementKeywords],
isNewIdentifierLocation: true,
},
);
@@ -398,6 +398,6 @@ const tests: ReadonlyArray<{ readonly marker: string | ReadonlyArray<string>, re
verify.completions(...tests.map(({ marker, members }): FourSlashInterface.CompletionsOptions => ({
marker,
exact: [...members.map(m => ({ ...m, kind: "method" })), ...completion.classElementKeywords],
unsorted: [...members.map(m => ({ ...m, kind: "method" })), ...completion.classElementKeywords],
isNewIdentifierLocation: true,
})));
@@ -18,7 +18,7 @@
function verifyHasBar() {
verify.completions({
exact: [
unsorted: [
{ name: "bar", text: "(method) IFoo.bar(): void", kind: "method" },
...completion.classElementKeywords,
],
@@ -17,7 +17,7 @@
verify.completions({
marker: "",
exact: [
{ name: "commonProperty", text: "(property) commonProperty: string | number" },
{ name: "commonFunction", text: "(method) commonFunction(): number" },
{ name: "commonProperty", text: "(property) commonProperty: string | number" },
],
});
@@ -20,9 +20,9 @@
verify.completions({
marker: "1",
exact: [
{ name: "toLocaleString", text: "(method) toLocaleString(): string (+1 overload)", documentation: "Returns a date converted to a string using the current locale." },
{ name: "toString", text: "(method) toString(): string (+1 overload)", documentation: "Returns a string representation of a string." },
{ name: "valueOf", text: "(method) valueOf(): string | number", documentation: "Returns the primitive value of the specified object." },
{ name: "toLocaleString", text: "(method) toLocaleString(): string (+1 overload)", documentation: "Returns a date converted to a string using the current locale." },
],
});
@@ -14,17 +14,17 @@
////}
const warnings = [
{ name: "classA", sortText: completion.SortText.JavascriptIdentifiers },
{ name: "foo", sortText: completion.SortText.JavascriptIdentifiers },
{ name: "Test7", sortText: completion.SortText.JavascriptIdentifiers },
{ name: "foo", sortText: completion.SortText.JavascriptIdentifiers }
];
verify.completions(
{ marker: "global", exact: completion.globalsInJsPlus(["foo", "classA", "Test7"]) },
{ marker: "global", exact: completion.globalsInJsPlus(["classA", "foo", "Test7"]) },
{
marker: "class",
isNewIdentifierLocation: true,
exact: [
...completion.classElementInJsKeywords,
...warnings,
...completion.classElementInJsKeywords
]
},
{
@@ -32,5 +32,5 @@ verify.completions(
isNewIdentifierLocation: true,
exact: warnings
},
{ marker: "insideFunction", exact: completion.globalsInJsInsideFunction(["foo", "classA", "Test7"]) },
{ marker: "insideFunction", exact: completion.globalsInJsInsideFunction(["classA", "foo", "Test7"]) },
);
@@ -13,7 +13,7 @@
const replacementSpan = test.ranges()[0]
verify.completions(
{ marker: "0", exact: ["jspm", '"jspm:browser"'] },
{ marker: "0", exact: ['"jspm:browser"', "jspm"] },
{ marker: "1", exact: [
{ name: "jspm", replacementSpan },
{ name: "jspm:browser", replacementSpan }
@@ -19,7 +19,7 @@
const replacementSpan = test.ranges()[0]
verify.completions(
{ marker: "0", exact: ["jspm", '"jspm:browser"'] },
{ marker: "0", exact: ['"jspm:browser"', "jspm"] },
{ marker: "1", exact: [
{ name: "jspm", replacementSpan },
{ name: "jspm:browser", replacementSpan }
@@ -17,7 +17,7 @@
const replacementSpan = test.ranges()[0]
verify.completions(
{ marker: "0", exact: ["jspm", '"jspm:browser"'] },
{ marker: "0", exact: ['"jspm:browser"', "jspm"] },
{ marker: "1", exact: [
{ name: "jspm", replacementSpan },
{ name: "jspm:browser", replacementSpan }
@@ -13,7 +13,7 @@
const replacementSpan = test.ranges()[0]
verify.completions(
{ marker: "0", exact: ["jspm", '"jspm:browser"'] },
{ marker: "0", exact: ['"jspm:browser"', "jspm"] },
{ marker: "1", exact: [
{ name: "jspm", replacementSpan },
{ name: "jspm:browser", replacementSpan }
@@ -15,11 +15,11 @@ const replacementSpan0 = test.ranges()[0]
verify.completions(
{ marker: "1", exact: [
{ name: "foo", replacementSpan: replacementSpan0 },
{ name: "bar", replacementSpan: replacementSpan0 },
{ name: "foo", replacementSpan: replacementSpan0 },
{ name: "some other name", replacementSpan: replacementSpan0 }
] },
{ marker: "2", exact: [ "foo", "bar", "some other name" ] },
{ marker: "2", exact: [ "bar", "foo", "some other name" ] },
{ marker: "3", exact: {
name: "a",
replacementSpan: test.ranges()[1]
@@ -9,6 +9,6 @@
const replacementSpan = test.ranges()[0]
verify.completions({ marker: "1", exact: [
{ name: "bar", replacementSpan },
{ name: "foo", replacementSpan },
{ name: "bar", replacementSpan }
] });
@@ -23,8 +23,8 @@ verify.completions(
{
marker: "prop",
exact: [
{ name: "x", text: "(property) I.x: number", documentation: "Prop doc", kind: "property", replacementSpan: test.ranges()[1] },
{ name: "m", text: "(method) I.m(): void", documentation: "Method doc", kind: "method", replacementSpan: test.ranges()[1] },
{ name: "x", text: "(property) I.x: number", documentation: "Prop doc", kind: "property", replacementSpan: test.ranges()[1] },
],
},
);
@@ -18,13 +18,14 @@ verify.completions(
exact: [
{ name: "x", text: "var x: number" },
{ name: "y", text: "var y: number" },
{ name: "type", sortText: completion.SortText.GlobalsOrKeywords }
{ name: "type", sortText: completion.SortText.GlobalsOrKeywords },
]
},
{
marker: "2",
exact: [
{ name: "y", text: "var y: number" },
{ name: "type", sortText: completion.SortText.GlobalsOrKeywords }
] },
{ name: "type", sortText: completion.SortText.GlobalsOrKeywords },
]
},
);
@@ -2,4 +2,11 @@
////5../**/
verify.completions({ marker: "", exact: ["toString", "toFixed", "toExponential", "toPrecision", "valueOf", "toLocaleString"] });
verify.completions({ marker: "", exact: [
"toExponential",
"toFixed",
"toLocaleString",
"toPrecision",
"toString",
"valueOf",
] });
@@ -3,4 +3,4 @@
////let v = 100;
/////a/./**/
verify.completions({ marker: "", exact: ["exec", "test", "source", "global", "ignoreCase", "multiline", "lastIndex", { name: "compile", sortText: completion.SortText.DeprecatedLocationPriority }] });
verify.completions({ marker: "", unsorted: ["exec", "test", "source", "global", "ignoreCase", "multiline", "lastIndex", { name: "compile", sortText: completion.SortText.DeprecatedLocationPriority }] });
@@ -2,4 +2,4 @@
/////a/./**/
verify.completions({ marker: "", exact: ["exec", "test", "source", "global", "ignoreCase", "multiline", "lastIndex", { name: "compile", sortText: completion.SortText.DeprecatedLocationPriority }] });
verify.completions({ marker: "", unsorted: ["exec", "test", "source", "global", "ignoreCase", "multiline", "lastIndex", { name: "compile", sortText: completion.SortText.DeprecatedLocationPriority }] });
@@ -4,7 +4,7 @@
verify.completions({
marker: "",
exact: [
unsorted: [
"toString", "charAt", "charCodeAt", "concat", "indexOf", "lastIndexOf", "localeCompare", "match", "replace", "search", "slice",
"split", "substring", "toLowerCase", "toLocaleLowerCase", "toUpperCase", "toLocaleUpperCase", "trim", "length", { name: "substr", sortText: completion.SortText.DeprecatedLocationPriority }, "valueOf",
],
@@ -29,12 +29,12 @@
// first declaration
verify.completions({
marker: ["var1"],
exact: completion.globalsPlus(["y", "C"]),
exact: completion.globalsPlus(["C", "y"]),
isNewIdentifierLocation: true
});
verify.completions({
marker: ["var2", "var3", "var4", "var5", "var6", "var7", "var8", "var9", "var10", "var11", "var12"],
exact: completion.globalsPlus(["x", "y", "C"]),
exact: completion.globalsPlus(["C", "x", "y"]),
isNewIdentifierLocation: true
});
@@ -26,27 +26,25 @@
verify.completions(
{
marker: "staticsInsideClassScope",
exact: [
{ name: "prototype", sortText: completion.SortText.LocationPriority },
{ name: "privateStaticProperty", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "publicStaticProperty", sortText: completion.SortText.LocalDeclarationPriority },
exact: completion.functionMembersPlus([
{ name: "privateStaticMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "privateStaticProperty", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "publicStaticMethod", sortText: completion.SortText.LocalDeclarationPriority },
...completion.functionMembers
],
{ name: "publicStaticProperty", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "prototype", sortText: completion.SortText.LocationPriority },
]),
},
{
marker: "instanceMembersInsideClassScope",
exact: ["privateInstanceMethod", "publicInstanceMethod", "privateProperty", "publicProperty"],
unsorted: ["privateInstanceMethod", "publicInstanceMethod", "privateProperty", "publicProperty"],
},
{
marker: "staticsOutsideClassScope",
exact: [
{ name: "prototype", sortText: completion.SortText.LocationPriority },
{ name: "publicStaticProperty", sortText: completion.SortText.LocalDeclarationPriority },
exact: completion.functionMembersPlus([
{ name: "publicStaticMethod", sortText: completion.SortText.LocalDeclarationPriority },
...completion.functionMembers
],
{ name: "publicStaticProperty", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "prototype", sortText: completion.SortText.LocationPriority },
]),
},
{
marker: "instanceMembersOutsideClassScope",
@@ -13,9 +13,9 @@
verify.completions({
marker: "",
exact: [
...completion.classElementInJsKeywords,
{ name: "A", sortText: completion.SortText.JavascriptIdentifiers },
{ name: "B", sortText: completion.SortText.JavascriptIdentifiers },
...completion.classElementInJsKeywords
],
isNewIdentifierLocation: true
});
@@ -11,5 +11,5 @@
verify.completions(
{ marker: ["valueReference", "typeReference"], exact: ["bar", "baz"] },
{ marker: "enumValueReference", exact: ["toString", "toFixed", "toExponential", "toPrecision", "valueOf", "toLocaleString"] },
{ marker: "enumValueReference", unsorted: ["toString", "toFixed", "toExponential", "toPrecision", "valueOf", "toLocaleString"] },
);
@@ -15,7 +15,14 @@
verify.completions(
// Should only have the enum's own members, and nothing else
{ marker: "enumVariable", exact: ["Red", "Green"] },
{ marker: "enumVariable", exact: ["Green", "Red"] },
// Should have number members, and not enum members
{ marker: ["variableOfEnumType", "callOfEnumReturnType"], exact: ["toString", "toFixed", "toExponential", "toPrecision", "valueOf", "toLocaleString"] },
{ marker: ["variableOfEnumType", "callOfEnumReturnType"], exact: [
"toExponential",
"toFixed",
"toLocaleString",
"toPrecision",
"toString",
"valueOf",
] }
);
@@ -15,6 +15,9 @@ verify.completions(
{ marker: "1", exact: [{ name: "bar", text: "(method) IFoo.bar(): IFoo" }] },
{
marker: "2",
exact: [{ name: "bar2", text: "(method) IFoo2.bar2(): IFoo2" }, { name: "bar", text: "(method) IFoo.bar(): IFoo" }]
exact: [
{ name: "bar", text: "(method) IFoo.bar(): IFoo" },
{ name: "bar2", text: "(method) IFoo2.bar2(): IFoo2" },
]
},
);
@@ -13,4 +13,8 @@
// @Filename: /a.ts
////import { /**/ } from "foo";
verify.completions({ marker: "", exact: ["Static", "foo", { name: "type", sortText: completion.SortText.GlobalsOrKeywords }] });
verify.completions({ marker: "", exact: [
"foo",
"Static",
{ name: "type", sortText: completion.SortText.GlobalsOrKeywords }
] });
@@ -10,5 +10,8 @@
verify.completions({
marker: "1",
exact: [{ name: "parent", text: "(property) Gen.parent: Gen" }, { name: "millenial", text: "(property) Gen.millenial: string" }],
exact: [
{ name: "millenial", text: "(property) Gen.millenial: string" },
{ name: "parent", text: "(property) Gen.parent: Gen" },
],
});
@@ -2,4 +2,4 @@
//// var person: {name:string; id: number} = { n/**/
verify.completions({ marker: "", exact: ["name", "id"] });
verify.completions({ marker: "", exact: ["id", "name"] });
@@ -2,4 +2,4 @@
//// var person: {name:string; id: number} = { n/**/
verify.completions({ marker: "", exact: ["name", "id"] });
verify.completions({ marker: "", exact: ["id", "name"] });
@@ -31,4 +31,4 @@
////import * as c from "./C";
////var x = c./**/
verify.completions({ marker: "", exact: ["cVar", "C1", "Inner", "bVar"] });
verify.completions({ marker: "", exact: ["bVar", "C1", "cVar", "Inner"] });
@@ -32,4 +32,4 @@
////import * as c from "./C";
////var x = c.Inner./**/
verify.completions({ marker: "", exact: ["varVar", "letVar", "constVar"] });
verify.completions({ marker: "", exact: ["constVar", "letVar", "varVar"] });
@@ -52,8 +52,8 @@
////}
verify.completions(
{ marker: "objectMembers", exact: ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable"] },
{ marker: "interfaceMembers", exact: ["bar21", "bar22", "bar11", "bar12"] },
{ marker: "callableMembers", exact: ["name", ...completion.functionMembersWithPrototype] },
{ marker: "publicOnlyMembers", exact: ["publicProperty", "publicMethod"] },
{ marker: "objectMembers", unsorted: ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable"] },
{ marker: "interfaceMembers", unsorted: ["bar21", "bar22", "bar11", "bar12"] },
{ marker: "callableMembers", unsorted: ["name", ...completion.functionMembersWithPrototype] },
{ marker: "publicOnlyMembers", unsorted: ["publicProperty", "publicMethod"] },
);
@@ -8,4 +8,7 @@
//// export { /**/ } from "M1"
////}
verify.completions({ marker: "", exact: ["V", { name: "type", sortText: completion.SortText.GlobalsOrKeywords }] });
verify.completions({ marker: "", exact: [
"V",
{ name: "type", sortText: completion.SortText.GlobalsOrKeywords },
] });
@@ -17,11 +17,10 @@
verify.completions(
{
marker: "1",
exact: [
{ name: "prototype", sortText: completion.SortText.LocationPriority },
exact: completion.functionMembersPlus([
{ name: "staticMethod", sortText: completion.SortText.LocalDeclarationPriority },
...completion.functionMembers
]
{ name: "prototype", sortText: completion.SortText.LocationPriority },
])
},
{ marker: ["2", "3", "4"], exact: undefined },
);
@@ -8,4 +8,7 @@
//// import { /**/ } from "M1"
////}
verify.completions({ marker: "", exact: ["V", { name: "type", sortText: completion.SortText.GlobalsOrKeywords }] });
verify.completions({ marker: "", exact: [
"V",
{ name: "type", sortText: completion.SortText.GlobalsOrKeywords },
] });
@@ -11,7 +11,7 @@
// @Filename: app.ts
////import {/*1*/} from './foo';
verify.completions({ marker: "1", exact: ["prototype", "prop1", "prop2", { name: "type", sortText: completion.SortText.GlobalsOrKeywords }] });
verify.completions({ marker: "1", unsorted: ["prototype", "prop1", "prop2", { name: "type", sortText: completion.SortText.GlobalsOrKeywords }] });
verify.noErrors();
goTo.marker('2');
verify.noErrors();
@@ -17,6 +17,6 @@
const exact = completion.globalsPlus(["C"]);
verify.completions(
{ marker: ["1", "2", "3", "6"], exact, isNewIdentifierLocation: true },
{ marker: "4", exact: ["str", ...exact], isNewIdentifierLocation: true },
{ marker: "5", exact: ["xyz", ...exact], isNewIdentifierLocation: true },
{ marker: "4", unsorted: ["str", ...exact], isNewIdentifierLocation: true },
{ marker: "5", unsorted: ["xyz", ...exact], isNewIdentifierLocation: true },
);
@@ -15,6 +15,6 @@
const exact = completion.globalTypesPlus(["I", "C"]);
verify.completions(
{ marker: ["1", "2"], exact: ["T", ...exact] },
{ marker: ["3", "4", "5"], exact: completion.globalTypesPlus(["I", "C", "T"]) },
{ marker: ["1", "2"], unsorted: ["T", ...exact] },
{ marker: ["3", "4", "5"], exact: completion.globalTypesPlus(["C", "I", "T"]) },
);
@@ -11,7 +11,20 @@ verify.completions(
{ marker: "0", includes: { name: "myClass", text: "(local class) myClass", kind: "local class" } },
{
marker: "1",
exact: ["private", "protected", "public", "static", "abstract", "async", "constructor", "declare", "get", "readonly", "set", "override"].map(
exact: [
"abstract",
"async",
"constructor",
"declare",
"get",
"override",
"private",
"protected",
"public",
"readonly",
"set",
"static",
].map(
name => ({ name, sortText: completion.SortText.GlobalsOrKeywords })
),
isNewIdentifierLocation: true,
@@ -16,7 +16,7 @@
////const { /*3*/ } = new Foo();
////const { /*4*/ } = Foo;
verify.completions({ marker: "1", exact: ["xxx1", "xxx2", "xxx3", "foo"] });
verify.completions({ marker: "2", exact: ["prototype", "xxx4", "xxx5", "xxx6"] });
verify.completions({ marker: "3", exact: ["xxx3", "foo"] });
verify.completions({ marker: "4", exact: ["prototype", "xxx6"] });
verify.completions({ marker: "1", unsorted: ["xxx1", "xxx2", "xxx3", "foo"] });
verify.completions({ marker: "2", unsorted: ["prototype", "xxx4", "xxx5", "xxx6"] });
verify.completions({ marker: "3", unsorted: ["xxx3", "foo"] });
verify.completions({ marker: "4", unsorted: ["prototype", "xxx6"] });
@@ -23,4 +23,4 @@
//// }
////}
verify.completions({ marker: test.markers(), exact: ["count", "isEmpty", "fileCount"] });
verify.completions({ marker: test.markers(), exact: ["count", "fileCount", "isEmpty"] });
@@ -8,4 +8,4 @@
//// /**/
////}
verify.completions({ marker: "", exact: ["name", "children"] });
verify.completions({ marker: "", exact: ["children", "name"] });
@@ -18,6 +18,6 @@
verify.completions({
marker: "",
exact: ["one", "two", "\"333\"", "\"4four\"", "\"5 five\"", "number", "Object"],
unsorted: ["one", "two", "\"333\"", "\"4four\"", "\"5 five\"", "number", "Object"],
isNewIdentifierLocation: true
});
@@ -7,4 +7,4 @@
////var C4 = class D<T extends /*4*/>{}
verify.completions({ marker: ["0", "1", "2", "3"], exact: undefined });
verify.completions({ marker: "4", exact: ["D", "T", ...completion.globalTypes] });
verify.completions({ marker: "4", exact: completion.globalTypesPlus(["D", "T"]) });
@@ -37,7 +37,7 @@
////}
verify.completions(
{ marker: "1", exact: ["m1", "m2", "m3", ...completion.classElementKeywords], isNewIdentifierLocation: true },
{ marker: "2", exact: ["m1", "m2", "m3", ...completion.classElementKeywords], isNewIdentifierLocation: true },
{ marker: "3", exact: ["m1", "m3", ...completion.classElementKeywords], isNewIdentifierLocation: true }
{ marker: "1", unsorted: ["m1", "m2", "m3", ...completion.classElementKeywords], isNewIdentifierLocation: true },
{ marker: "2", unsorted: ["m1", "m2", "m3", ...completion.classElementKeywords], isNewIdentifierLocation: true },
{ marker: "3", unsorted: ["m1", "m3", ...completion.classElementKeywords], isNewIdentifierLocation: true }
);
@@ -32,11 +32,11 @@
verify.completions(
{
marker: ["1", "2"],
exact: ["privateMethod", "privateProperty", "protectedMethod", "protectedProperty", "publicMethod", "publicProperty", "protectedOverriddenMethod", "protectedOverriddenProperty", "test"],
unsorted: ["privateMethod", "privateProperty", "protectedMethod", "protectedProperty", "publicMethod", "publicProperty", "protectedOverriddenMethod", "protectedOverriddenProperty", "test"],
},
{
marker: "3",
// Can not access protected properties overridden in subclass
exact: ["privateMethod", "privateProperty", "protectedMethod", "protectedProperty", "publicMethod", "publicProperty", "test"],
unsorted: ["privateMethod", "privateProperty", "protectedMethod", "protectedProperty", "publicMethod", "publicProperty", "test"],
},
);
@@ -17,7 +17,7 @@
const replacementSpan = test.ranges()[0];
const replacementSpan1 = test.ranges()[1];
verify.completions(
{ marker: "b", exact: [
{ marker: "b", unsorted: [
{ name: "foo ", replacementSpan: replacementSpan1 },
{ name: "bar", replacementSpan: replacementSpan1 },
{ name: "break", replacementSpan: replacementSpan1 },
@@ -29,7 +29,7 @@ verify.completions(
] },
{
marker: "a",
exact: [
unsorted: [
{ name: "foo ", insertText: '["foo "]', replacementSpan },
"bar",
"break",
@@ -36,7 +36,7 @@
////var user = </*16*/User name=/*17*/{ /*18*/window.isLoggedIn ? window.name : '/*19*/'} />; // globals only in JSX expression (but not in JSX expression strings)
const x = ["test", "A", "B", "C", "y", "z", "x", "user"];
const globals: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry> = [...x, ...completion.globals]
const globals = completion.sorted([...x, ...completion.globals])
verify.completions(
{ marker: ["1", "3"], exact: [{ name: "type", sortText: completion.SortText.GlobalsOrKeywords }], isNewIdentifierLocation: true, isGlobalCompletion: false },
{ marker: ["6", "8", "12", "14"], exact: undefined, isGlobalCompletion: false },
@@ -49,6 +49,6 @@ verify.completions(
{ marker: "10", exact: completion.classElementKeywords, isGlobalCompletion: false, isNewIdentifierLocation: true },
{ marker: "13", exact: globals.filter(name => name !== 'z'), isGlobalCompletion: false },
{ marker: "15", exact: globals.filter(name => name !== 'x'), isGlobalCompletion: true, isNewIdentifierLocation: true },
{ marker: "16", exact: [...x, completion.globalThisEntry, ...completion.globalsVars, completion.undefinedVarEntry].filter(name => name !== 'user'), isGlobalCompletion: false },
{ marker: "16", unsorted: [...x, completion.globalThisEntry, ...completion.globalsVars, completion.undefinedVarEntry].filter(name => name !== 'user'), isGlobalCompletion: false },
{ marker: "17", exact: completion.globalKeywords, isGlobalCompletion: false },
);
@@ -6,9 +6,5 @@
verify.completions({
marker: "",
exact: [
completion.globalThisEntry,
completion.undefinedVarEntry,
...completion.statementKeywordsWithTypes
]
exact: completion.globalsPlus([], { noLib: true }),
});
@@ -24,10 +24,10 @@
verify.completions(
{
marker: ["ValueReference", "TypeReferenceInExtendsList"],
exact: ["exportedFunction", "exportedVariable", "exportedClass", "exportedModule"],
unsorted: ["exportedFunction", "exportedVariable", "exportedClass", "exportedModule"],
},
{
marker: ["TypeReference", "TypeReferenceInImplementsList"],
exact: ["exportedClass", "exportedInterface"],
unsorted: ["exportedClass", "exportedInterface"],
},
);
@@ -33,6 +33,6 @@
////ci1./*2*/b;
verify.completions(
{ marker: "1", exact: ["i1", "i2", "i3", "a", "b", "c"] },
{ marker: "2", exact: ["i11", "i12", "a", "b", "b1"] },
{ marker: "1", unsorted: ["i1", "i2", "i3", "a", "b", "c"] },
{ marker: "2", unsorted: ["i11", "i12", "a", "b", "b1"] },
);
@@ -36,16 +36,15 @@
verify.completions(
// Module m / alias a
{ marker: ["1", "7"], exact: ["F", "C", "E", "N", "V", "A"] },
{ marker: ["1Type", "7Type"], exact: ["I", "C", "E", "A"] },
{ marker: ["1", "7"], unsorted: ["F", "C", "E", "N", "V", "A"] },
{ marker: ["1Type", "7Type"], unsorted: ["I", "C", "E", "A"] },
// Class C
{
marker: "2",
exact: [
{ name: "prototype", sortText: completion.SortText.LocationPriority },
exact: completion.functionMembersPlus([
{ name: "property", sortText: completion.SortText.LocalDeclarationPriority },
...completion.functionMembers
]
{ name: "prototype", sortText: completion.SortText.LocationPriority },
])
},
// Enum E
{ marker: "3", exact: "value" },
@@ -16,4 +16,4 @@
//// }
////}
verify.completions({ marker: "", exact: ["foo", "bar"] });
verify.completions({ marker: "", exact: ["bar", "foo"] });
@@ -11,4 +11,4 @@
//// }
////}
verify.completions({ marker: "", exact: ["y", "foo"] });
verify.completions({ marker: "", exact: ["foo", "y"] });
@@ -9,6 +9,6 @@
////f./*2*/
verify.completions(
{ marker: "1", exact: ["y", "x", "method"] },
{ marker: "1", exact: ["method", "x", "y"] },
{ marker: "2", exact: "method" },
);
@@ -26,7 +26,7 @@
verify.completions({ marker: "1", exact: ["#z", "t", "y"] });
verify.completions({ marker: "2", exact: ["#z", "#u", "v"] });
verify.completions({ marker: "3", exact: ["#z", "t", "y"] });
verify.completions({ marker: "1", unsorted: ["#z", "t", "y"] });
verify.completions({ marker: "2", unsorted: ["#z", "#u", "v"] });
verify.completions({ marker: "3", unsorted: ["#z", "t", "y"] });
verify.completions({ marker: "4", exact: ["y"] });
@@ -31,7 +31,7 @@
verify.completions({ marker: "1", exact: ["#z", "t", "l", "y"] });
verify.completions({ marker: "2", exact: ["#z", "#u", "v", "k"] });
verify.completions({ marker: "3", exact: ["#z", "t", "l", "y"] });
verify.completions({ marker: "1", unsorted: ["#z", "t", "l", "y"] });
verify.completions({ marker: "2", unsorted: ["#z", "#u", "v", "k"] });
verify.completions({ marker: "3", unsorted: ["#z", "t", "l", "y"] });
verify.completions({ marker: "4", exact: ["y"] });
@@ -25,7 +25,7 @@
verify.completions({ marker: "1", exact: ["#z", "t", "y"] });
verify.completions({ marker: "2", exact: ["#z", "#u", "v"] });
verify.completions({ marker: "3", exact: ["#z", "t", "y"] });
verify.completions({ marker: "1", unsorted: ["#z", "t", "y"] });
verify.completions({ marker: "2", unsorted: ["#z", "#u", "v"] });
verify.completions({ marker: "3", unsorted: ["#z", "t", "y"] });
verify.completions({ marker: "4", exact: ["y"] });
@@ -19,9 +19,9 @@
////f./*5*/
verify.completions(
{ marker: "1", exact: ["y", "x", "method"] },
{ marker: "2", exact: ["z", "method1", "y", "x", "method"] },
{ marker: "3", exact: ["method2", "y", "x", "method"] },
{ marker: "4", exact: ["method2", "z", "method1", "y", "x", "method"] },
{ marker: "1", unsorted: ["y", "x", "method"] },
{ marker: "2", unsorted: ["z", "method1", "y", "x", "method"] },
{ marker: "3", unsorted: ["method2", "y", "x", "method"] },
{ marker: "4", unsorted: ["method2", "z", "method1", "y", "x", "method"] },
{ marker: "5", exact: undefined },
);
@@ -8,10 +8,9 @@
verify.completions({
marker: "",
exact: [
{ name: "prototype", sortText: completion.SortText.LocationPriority },
exact: completion.functionMembersPlus([
{ name: "a", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "b", sortText: completion.SortText.LocalDeclarationPriority },
...completion.functionMembers
]
{ name: "prototype", sortText: completion.SortText.LocationPriority },
]),
});
@@ -30,41 +30,39 @@ verify.completions(
{
// Same class, everything is visible
marker: ["1"],
exact: [
{ name: "prototype", sortText: completion.SortText.LocationPriority },
exact: completion.functionMembersPlus([
{ name: "protectedMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "protectedOverriddenMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "protectedOverriddenProperty", sortText: completion.SortText.LocalDeclarationPriority},
{ name: "protectedProperty", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "publicMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "publicProperty", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "protectedOverriddenMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "protectedOverriddenProperty", sortText: completion.SortText.LocalDeclarationPriority},
...completion.functionMembers,
],
{ name: "prototype", sortText: completion.SortText.LocationPriority },
]),
},
{
marker: ["2", "3"],
exact: [
{ name: "prototype", sortText: completion.SortText.LocationPriority },
exact: completion.functionMembersPlus([
{ name: "protectedMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "protectedOverriddenMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "protectedOverriddenProperty", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "test", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "protectedMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "protectedProperty", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "publicMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "publicProperty", sortText: completion.SortText.LocalDeclarationPriority },
...completion.functionMembers,
],
{ name: "test", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "prototype", sortText: completion.SortText.LocationPriority },
]),
},
{
// only public and protected methods of the base class are accessible through super
marker: "4",
exact: [
{ name: "protectedMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "publicMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "protectedOverriddenMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "publicMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "apply", sortText: completion.SortText.LocationPriority },
{ name: "call", sortText: completion.SortText.LocationPriority },
{ name: "bind", sortText: completion.SortText.LocationPriority },
{ name: "call", sortText: completion.SortText.LocationPriority },
{ name: "toString", sortText: completion.SortText.LocationPriority },
],
},
@@ -25,10 +25,9 @@
// Only public properties are visible outside the class
verify.completions({
marker: ["1", "2"],
exact: [
{ name: "prototype", sortText: completion.SortText.LocationPriority },
exact: completion.functionMembersPlus([
{ name: "publicMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "publicProperty", sortText: completion.SortText.LocalDeclarationPriority },
...completion.functionMembers
],
{ name: "prototype", sortText: completion.SortText.LocationPriority },
]),
});
@@ -26,17 +26,16 @@
////}
//// Derived./*2*/
const publicCompletions: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry> = [
const publicCompletions: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry> = completion.functionMembersPlus([
{ name: "publicMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "publicProperty", sortText: completion.SortText.LocalDeclarationPriority },
...completion.functionMembers
];
]);
verify.completions(
{
// Sub class, everything but private is visible
marker: "1",
exact: [
unsorted: [
{ name: "prototype", sortText: completion.SortText.LocationPriority },
{ name: "protectedOverriddenMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "protectedOverriddenProperty", sortText: completion.SortText.LocalDeclarationPriority },
@@ -48,7 +47,7 @@ verify.completions(
{
// Can see protected methods elevated to public
marker: "2",
exact: [
unsorted: [
{ name: "prototype", sortText: completion.SortText.LocationPriority },
{ name: "protectedOverriddenMethod", sortText: completion.SortText.LocalDeclarationPriority },
{ name: "protectedOverriddenProperty", sortText: completion.SortText.LocalDeclarationPriority },
@@ -15,8 +15,7 @@
////var kk: m3.point3/*membertypeExpr*/ = m3.zz2/*membervalueExpr*/;
////var zz = </*typeExpr2*/point>{ x: 4, y: 3 };
const values: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry> = [
completion.globalThisEntry,
const values: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry> = completion.globalsPlus([
{ name: "m2", text: "namespace m2" }, // With no type side, allowed only in value
{ name: "m3", text: "namespace m3" },
{ name: "xx", text: "var xx: number" },
@@ -24,17 +23,15 @@ const values: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry> = [
{ name: "yy", text: "var yy: point" },
{ name: "kk", text: "var kk: m3.point3" },
{ name: "zz", text: "var zz: point" },
completion.undefinedVarEntry,
...completion.statementKeywordsWithTypes,
];
], { noLib: true });
const types: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry> = [
const types: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry> = completion.sorted([
completion.globalThisEntry,
{ name: "m", text: "namespace m" },
{ name: "m3", text: "namespace m3" },
{ name: "point", text: "interface point" },
...completion.typeKeywords,
];
]);
const filterValuesByName = (name: string) => {
return values.filter(entry => {
@@ -258,51 +258,43 @@ const commonTypes: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry> =
verify.completions(
{
marker: ["shadowNamespaceWithNoExport", "shadowNamespaceWithExport"],
exact: [
unsorted: completion.globalsPlus([
...commonValues,
{ name: "shwfn", text: "function shwfn(shadow: any): void" },
{ name: "shwvar", text: "var shwvar: string" },
{ name: "shwcls", text: "class shwcls" },
"tmp",
completion.globalThisEntry,
...commonValues,
completion.undefinedVarEntry,
...completion.statementKeywordsWithTypes,
],
], { noLib: true }),
}, {
marker: ["shadowNamespaceWithNoExportType", "shadowNamespaceWithExportType"],
exact: [
unsorted: completion.typeKeywordsPlus([
completion.globalThisEntry,
{ name: "shwcls", text: "class shwcls" },
{ name: "shwint", text: "interface shwint" },
completion.globalThisEntry,
...commonTypes,
...completion.typeKeywords,
]
]),
},
{
marker: "namespaceWithImport",
exact: [
unsorted: completion.globalsPlus([
"Mod1",
"iMod1",
"tmp",
completion.globalThisEntry,
{ name: "shwfn", text: "function shwfn(): void" },
...commonValues,
{ name: "shwcls", text: "class shwcls" },
{ name: "shwvar", text: "var shwvar: number" },
completion.undefinedVarEntry,
...completion.statementKeywordsWithTypes,
],
], { noLib: true }),
},
{
marker: "namespaceWithImportType",
exact: [
unsorted: completion.typeKeywordsPlus([
completion.globalThisEntry,
"Mod1",
"iMod1",
completion.globalThisEntry,
...commonTypes,
{ name: "shwcls", text: "class shwcls" },
{ name: "shwint", text: "interface shwint" },
...completion.typeKeywords,
],
]),
}
);
@@ -234,7 +234,7 @@
verify.completions(
{
marker: "extendedClass",
exact: ["scpfn", "scpvar", ...completion.classElementKeywords],
unsorted: ["scpfn", "scpvar", ...completion.classElementKeywords],
isNewIdentifierLocation: true,
},
{
@@ -13,8 +13,8 @@ verify.completions({
marker: "",
exact: [
{ name: "city", text: "(property) Address.city: string", insertText: undefined },
{ name: "method" },
{ name: "postal code", text: "(property) Address[\"postal code\"]: string", insertText: "[\"postal code\"]", replacementSpan: test.ranges()[0] },
{ name: "method" }
],
preferences: { includeInsertTextCompletions: true },
});
@@ -8,8 +8,8 @@ const replacementSpan = test.ranges()[0]
verify.completions({
marker: "",
exact: [
"catch",
"then",
"catch"
],
preferences: {
includeInsertTextCompletions: false,
@@ -58,7 +58,7 @@ const locals = [
];
verify.completions(
// Non-contextual, any, unknown, object, Record<string, ..>, [key: string]: .., Type parameter, etc..
{ marker: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"], exact: completion.globalsPlus(locals), isNewIdentifierLocation: true },
{ marker: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"], unsorted: completion.globalsPlus(locals), isNewIdentifierLocation: true },
// Has named property
{ marker: ["12", "13"], exact: "typed", isNewIdentifierLocation: false },
// Has both StringIndexType and named property
@@ -66,5 +66,5 @@ verify.completions(
// NumberIndexType
{ marker: ["15", "16"], exact: [], isNewIdentifierLocation: true },
// After comma
{ marker: ["17"], exact: completion.globalsPlus(locals), isNewIdentifierLocation: true },
{ marker: ["17"], unsorted: completion.globalsPlus(locals), isNewIdentifierLocation: true },
);
@@ -13,10 +13,10 @@
verify.completions({
marker: ["1"],
exact: completion.globalsPlus(["foo", "bar", "obj2"]),
exact: completion.globalsPlus(["bar", "foo", "obj2"]),
});
verify.completions({
marker: ["2"],
exact: completion.globalsPlus(["foo", "bar", "obj1"]),
exact: completion.globalsPlus(["bar", "foo", "obj1"]),
});
@@ -7,5 +7,5 @@
verify.completions({
marker: ["1"],
exact: completion.globalsPlus(["foo", "bar"]),
exact: completion.globalsPlus(["bar", "foo"]),
});
@@ -7,5 +7,5 @@
verify.completions({
marker: ["1"],
exact: completion.globalsPlus(["foo", "bar"]),
exact: completion.globalsPlus(["bar", "foo"]),
});
@@ -19,7 +19,7 @@
//// [prop] = /*6*/
////}
const exact = completion.globalsPlus(["Class1", "Class2", "Class3", "prop", "Class4"]);
const exact = completion.globalsPlus(["Class1", "Class2", "Class3", "Class4", "prop"]);
const markers = ["1", "2", "3", "4", "5", "6"];
verify.completions({ marker: "0", exact: ['a', 'b', 'c', 'd'], isGlobalCompletion: false });
@@ -10,8 +10,8 @@
verify.completions({
marker: "",
exact: [
exact: completion.globalsPlus([
{ name: "foo", kind: "alias", kindModifiers: "export,declare", text: "(alias) const foo: number\nimport foo = N.foo" },
...completion.globalsPlus([{ name: "N", kind: "module", kindModifiers: "declare", text: "namespace N" }]),
],
{ name: "N", kind: "module", kindModifiers: "declare", text: "namespace N" },
]),
});
@@ -11,4 +11,4 @@
//// }
//// }
verify.completions({ marker: "", exact: ["publicMethod", "privateMethod", "protectedMethod", "test"] });
verify.completions({ marker: "", exact: ["privateMethod", "protectedMethod", "publicMethod", "test"] });
@@ -16,7 +16,7 @@ verify.completions({
marker: "",
exact: [
{ name: "family", text: "(property) iScope<number>.family: number" },
{ name: "watch", text: "(property) iBaseScope.watch: () => void" },
{ name: "moveUp", text: "(property) iMover.moveUp: () => void" },
{ name: "watch", text: "(property) iBaseScope.watch: () => void" },
],
});
@@ -19,14 +19,11 @@
verify.completions({
marker: "",
exact: [
completion.globalThisEntry,
...completion.globalsVars,
exact: completion.globalsPlus([
{
name: "foo",
sortText: completion.SortText.GlobalsOrKeywords
},
completion.undefinedVarEntry,
{
name: "Bar",
source: "path1",
@@ -39,8 +36,7 @@ verify.completions({
hasAction: true,
sortText: completion.SortText.AutoImportSuggestions
},
...completion.statementKeywordsWithTypes
],
]),
preferences: {
includeCompletionsForModuleExports: true
}
@@ -11,9 +11,7 @@
verify.completions({
marker: "",
exact: [
completion.globalThisEntry,
completion.undefinedVarEntry,
exact: completion.globalsPlus([
{
name: "someModule",
source: "/someModule",
@@ -34,8 +32,7 @@ verify.completions({
hasAction: true,
sortText: completion.SortText.AutoImportSuggestions
},
...completion.statementKeywordsWithTypes
],
], { noLib: true }),
preferences: {
includeCompletionsForModuleExports: true
}
@@ -16,11 +16,7 @@ const preferences: FourSlashInterface.UserPreferences = { includeCompletionsForM
verify.completions(
{
marker: "0",
exact: [
completion.globalThisEntry,
completion.undefinedVarEntry,
...completion.statementKeywordsWithTypes
],
exact: completion.globalsPlus([], { noLib: true }),
preferences
},
{
@@ -25,21 +25,12 @@ const exportEntry: FourSlashInterface.ExpectedCompletionEntryObject = {
verify.completions(
{
marker: "0",
exact: [
completion.globalThisEntry,
completion.undefinedVarEntry,
...completion.statementKeywordsWithTypes
],
exact: completion.globalsPlus([], { noLib: true }),
preferences
},
{
marker: "1",
exact: [
completion.globalThisEntry,
completion.undefinedVarEntry,
exportEntry,
...completion.statementKeywordsWithTypes
],
exact: completion.globalsPlus([exportEntry], { noLib: true }),
preferences
}
);

Some files were not shown because too many files have changed in this diff Show More