Add kindModifier to mark if a completion item is for an optional field (#20839)
* Add kindModifier to mark if a completion item is for an optional field For #12458 Adds a new KindModifier for completion items to mark when a property is optional. This can be used by editors to either change the item icon or add a `?` to the item text * Add method test * Baseline-accept
This commit is contained in:
parent
b36d614b56
commit
12d5063e4c
|
@ -872,7 +872,7 @@ namespace FourSlash {
|
|||
});
|
||||
}
|
||||
|
||||
public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean, options?: FourSlashInterface.VerifyCompletionListContainsOptions) {
|
||||
public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, hasAction?: boolean, options?: FourSlashInterface.VerifyCompletionListContainsOptions) {
|
||||
const completions = this.getCompletionListAtCaret(options);
|
||||
if (completions) {
|
||||
this.assertItemInCompletionList(completions.entries, entryId, text, documentation, kind, spanIndex, hasAction, options);
|
||||
|
@ -893,7 +893,7 @@ namespace FourSlash {
|
|||
* @param expectedKind the kind of symbol (see ScriptElementKind)
|
||||
* @param spanIndex the index of the range that the completion item's replacement text span should match
|
||||
*/
|
||||
public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string, spanIndex?: number, options?: FourSlashInterface.CompletionsAtOptions) {
|
||||
public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, options?: FourSlashInterface.CompletionsAtOptions) {
|
||||
let replacementSpan: ts.TextSpan;
|
||||
if (spanIndex !== undefined) {
|
||||
replacementSpan = this.getTextSpanForRangeAtIndex(spanIndex);
|
||||
|
@ -902,7 +902,7 @@ namespace FourSlash {
|
|||
const completions = this.getCompletionListAtCaret(options);
|
||||
if (completions) {
|
||||
let filterCompletions = completions.entries.filter(e => e.name === entryId.name && e.source === entryId.source);
|
||||
filterCompletions = expectedKind ? filterCompletions.filter(e => e.kind === expectedKind) : filterCompletions;
|
||||
filterCompletions = expectedKind ? filterCompletions.filter(e => e.kind === expectedKind || (typeof expectedKind === "object" && e.kind === expectedKind.kind)) : filterCompletions;
|
||||
filterCompletions = filterCompletions.filter(entry => {
|
||||
const details = this.getCompletionEntryDetails(entry.name);
|
||||
const documentation = details && ts.displayPartsToString(details.documentation);
|
||||
|
@ -3089,7 +3089,7 @@ Actual: ${stringify(fullActual)}`);
|
|||
entryId: ts.Completions.CompletionEntryIdentifier,
|
||||
text: string | undefined,
|
||||
documentation: string | undefined,
|
||||
kind: string | undefined,
|
||||
kind: string | undefined | { kind?: string, kindModifiers?: string },
|
||||
spanIndex: number | undefined,
|
||||
hasAction: boolean | undefined,
|
||||
options: FourSlashInterface.VerifyCompletionListContainsOptions | undefined,
|
||||
|
@ -3123,9 +3123,21 @@ Actual: ${stringify(fullActual)}`);
|
|||
}
|
||||
|
||||
if (kind !== undefined) {
|
||||
assert.equal(item.kind, kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + entryId));
|
||||
if (typeof kind === "string") {
|
||||
assert.equal(item.kind, kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + entryId));
|
||||
}
|
||||
else {
|
||||
if (kind.kind) {
|
||||
assert.equal(item.kind, kind.kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + entryId));
|
||||
}
|
||||
if (kind.kindModifiers !== undefined) {
|
||||
assert.equal(item.kindModifiers, kind.kindModifiers, this.assertionMessageAtLastKnownMarker("completion item kindModifiers for " + entryId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (spanIndex !== undefined) {
|
||||
const span = this.getTextSpanForRangeAtIndex(spanIndex);
|
||||
assert.isTrue(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + entryId));
|
||||
|
@ -3842,7 +3854,7 @@ namespace FourSlashInterface {
|
|||
|
||||
// Verifies the completion list contains the specified symbol. The
|
||||
// completion list is brought up if necessary
|
||||
public completionListContains(entryId: string | ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean, options?: VerifyCompletionListContainsOptions) {
|
||||
public completionListContains(entryId: string | ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, hasAction?: boolean, options?: VerifyCompletionListContainsOptions) {
|
||||
if (typeof entryId === "string") {
|
||||
entryId = { name: entryId, source: undefined };
|
||||
}
|
||||
|
|
|
@ -91,9 +91,14 @@ namespace ts.SymbolDisplay {
|
|||
}
|
||||
|
||||
export function getSymbolModifiers(symbol: Symbol): string {
|
||||
return symbol && symbol.declarations && symbol.declarations.length > 0
|
||||
const nodeModifiers = symbol && symbol.declarations && symbol.declarations.length > 0
|
||||
? getNodeModifiers(symbol.declarations[0])
|
||||
: ScriptElementKindModifier.none;
|
||||
|
||||
const symbolModifiers = symbol && symbol.flags & SymbolFlags.Optional ?
|
||||
ScriptElementKindModifier.optionalModifier
|
||||
: ScriptElementKindModifier.none;
|
||||
return nodeModifiers && symbolModifiers ? nodeModifiers + "," + symbolModifiers : nodeModifiers || symbolModifiers;
|
||||
}
|
||||
|
||||
interface SymbolDisplayPartsDocumentationAndSymbolKind {
|
||||
|
|
|
@ -954,6 +954,7 @@ namespace ts {
|
|||
ambientModifier = "declare",
|
||||
staticModifier = "static",
|
||||
abstractModifier = "abstract",
|
||||
optionalModifier = "optional"
|
||||
}
|
||||
|
||||
export const enum ClassificationTypeNames {
|
||||
|
|
|
@ -4505,6 +4505,7 @@ declare namespace ts {
|
|||
ambientModifier = "declare",
|
||||
staticModifier = "static",
|
||||
abstractModifier = "abstract",
|
||||
optionalModifier = "optional",
|
||||
}
|
||||
enum ClassificationTypeNames {
|
||||
comment = "comment",
|
||||
|
|
|
@ -4505,6 +4505,7 @@ declare namespace ts {
|
|||
ambientModifier = "declare",
|
||||
staticModifier = "static",
|
||||
abstractModifier = "abstract",
|
||||
optionalModifier = "optional",
|
||||
}
|
||||
enum ClassificationTypeNames {
|
||||
comment = "comment",
|
||||
|
|
10
tests/cases/fourslash/completionsOptionalKindModifier.ts
Normal file
10
tests/cases/fourslash/completionsOptionalKindModifier.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////interface A { a?: number; method?(): number; };
|
||||
////function f(x: A) {
|
||||
////x./*a*/;
|
||||
////}
|
||||
|
||||
goTo.marker("a");
|
||||
verify.completionListContains("a", /* text */ undefined, /* documentation */ undefined, { kindModifiers: "optional" });
|
||||
verify.completionListContains("method", /* text */ undefined, /* documentation */ undefined, { kindModifiers: "optional" });
|
|
@ -146,7 +146,7 @@ declare namespace FourSlashInterface {
|
|||
entryId: string | { name: string, source?: string },
|
||||
text?: string,
|
||||
documentation?: string,
|
||||
kind?: string,
|
||||
kind?: string | { kind?: string, kindModifiers?: string },
|
||||
spanIndex?: number,
|
||||
hasAction?: boolean,
|
||||
options?: { includeExternalModuleExports?: boolean, sourceDisplay?: string, isRecommended?: true },
|
||||
|
|
Loading…
Reference in a new issue