Skip to content

Commit

Permalink
Add kindModifier to mark if a completion item is for an optional field (
Browse files Browse the repository at this point in the history
#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
  • Loading branch information
mjbvz authored and mhegazy committed Jan 5, 2018
1 parent b36d614 commit 12d5063
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 8 deletions.
24 changes: 18 additions & 6 deletions src/harness/fourslash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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 };
}
Expand Down
7 changes: 6 additions & 1 deletion src/services/symbolDisplay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions src/services/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,7 @@ namespace ts {
ambientModifier = "declare",
staticModifier = "static",
abstractModifier = "abstract",
optionalModifier = "optional"
}

export const enum ClassificationTypeNames {
Expand Down
1 change: 1 addition & 0 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4505,6 +4505,7 @@ declare namespace ts {
ambientModifier = "declare",
staticModifier = "static",
abstractModifier = "abstract",
optionalModifier = "optional",
}
enum ClassificationTypeNames {
comment = "comment",
Expand Down
1 change: 1 addition & 0 deletions tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4505,6 +4505,7 @@ declare namespace ts {
ambientModifier = "declare",
staticModifier = "static",
abstractModifier = "abstract",
optionalModifier = "optional",
}
enum ClassificationTypeNames {
comment = "comment",
Expand Down
10 changes: 10 additions & 0 deletions tests/cases/fourslash/completionsOptionalKindModifier.ts
Original file line number Diff line number Diff line change
@@ -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" });
2 changes: 1 addition & 1 deletion tests/cases/fourslash/fourslash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down

0 comments on commit 12d5063

Please sign in to comment.