Skip to content

Commit 3e08af4

Browse files
Merge pull request #746 from Microsoft/classifiedSigHelp
Switch signature help over to using display parts.
2 parents def57fe + b91dfc2 commit 3e08af4

File tree

5 files changed

+149
-76
lines changed

5 files changed

+149
-76
lines changed

src/compiler/checker.ts

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -925,38 +925,17 @@ module ts {
925925
var displayPartWriters: DisplayPartsSymbolWriter[] = [];
926926
var stringWriters: StringSymbolWriter[] = [];
927927

928-
function displayPartKind(symbol: Symbol): SymbolDisplayPartKind {
929-
var flags = symbol.flags;
930-
931-
if (flags & SymbolFlags.Variable) {
932-
return symbol.declarations && symbol.declarations.length > 0 && symbol.declarations[0].kind === SyntaxKind.Parameter
933-
? SymbolDisplayPartKind.parameterName
934-
: SymbolDisplayPartKind.localName;
935-
}
936-
else if (flags & SymbolFlags.Property) { return SymbolDisplayPartKind.propertyName; }
937-
else if (flags & SymbolFlags.EnumMember) { return SymbolDisplayPartKind.enumMemberName; }
938-
else if (flags & SymbolFlags.Function) { return SymbolDisplayPartKind.functionName; }
939-
else if (flags & SymbolFlags.Class) { return SymbolDisplayPartKind.className; }
940-
else if (flags & SymbolFlags.Interface) { return SymbolDisplayPartKind.interfaceName; }
941-
else if (flags & SymbolFlags.Enum) { return SymbolDisplayPartKind.enumName; }
942-
else if (flags & SymbolFlags.Module) { return SymbolDisplayPartKind.moduleName; }
943-
else if (flags & SymbolFlags.Method) { return SymbolDisplayPartKind.methodName; }
944-
else if (flags & SymbolFlags.TypeParameter) { return SymbolDisplayPartKind.typeParameterName; }
945-
946-
return SymbolDisplayPartKind.text;
947-
}
948-
949928
function getDisplayPartWriter(): DisplayPartsSymbolWriter {
950929
if (displayPartWriters.length == 0) {
951930
var displayParts: SymbolDisplayPart[] = [];
952931
return {
953932
displayParts: () => displayParts,
954933
writeKind: (text, kind) => displayParts.push(new SymbolDisplayPart(text, kind, undefined)),
955-
writeSymbol: (text, symbol) => displayParts.push(new SymbolDisplayPart(text, displayPartKind(symbol), symbol)),
934+
writeSymbol: (text, symbol) => displayParts.push(symbolPart(text, symbol)),
956935

957936
// Completely ignore indentation for display part writers. And map newlines to
958937
// a single space.
959-
writeLine: () => displayParts.push(new SymbolDisplayPart(" ", SymbolDisplayPartKind.space, undefined)),
938+
writeLine: () => displayParts.push(spacePart()),
960939
increaseIndent: () => { },
961940
decreaseIndent: () => { },
962941
clear: () => displayParts = [],
@@ -7693,4 +7672,49 @@ module ts {
76937672

76947673
return checker;
76957674
}
7675+
7676+
export function spacePart() {
7677+
return new SymbolDisplayPart(" ", SymbolDisplayPartKind.space, undefined);
7678+
}
7679+
7680+
export function keywordPart(kind: SyntaxKind) {
7681+
return new SymbolDisplayPart(tokenToString(kind), SymbolDisplayPartKind.keyword, undefined);
7682+
}
7683+
7684+
export function punctuationPart(kind: SyntaxKind) {
7685+
return new SymbolDisplayPart(tokenToString(kind), SymbolDisplayPartKind.punctuation, undefined);
7686+
}
7687+
7688+
export function operatorPart(kind: SyntaxKind) {
7689+
return new SymbolDisplayPart(tokenToString(kind), SymbolDisplayPartKind.operator, undefined);
7690+
}
7691+
7692+
export function textPart(text: string) {
7693+
return new SymbolDisplayPart(text, SymbolDisplayPartKind.text, undefined);
7694+
}
7695+
7696+
export function symbolPart(text: string, symbol: Symbol) {
7697+
return new SymbolDisplayPart(text, displayPartKind(symbol), symbol)
7698+
}
7699+
7700+
function displayPartKind(symbol: Symbol): SymbolDisplayPartKind {
7701+
var flags = symbol.flags;
7702+
7703+
if (flags & SymbolFlags.Variable) {
7704+
return symbol.declarations && symbol.declarations.length > 0 && symbol.declarations[0].kind === SyntaxKind.Parameter
7705+
? SymbolDisplayPartKind.parameterName
7706+
: SymbolDisplayPartKind.localName;
7707+
}
7708+
else if (flags & SymbolFlags.Property) { return SymbolDisplayPartKind.propertyName; }
7709+
else if (flags & SymbolFlags.EnumMember) { return SymbolDisplayPartKind.enumMemberName; }
7710+
else if (flags & SymbolFlags.Function) { return SymbolDisplayPartKind.functionName; }
7711+
else if (flags & SymbolFlags.Class) { return SymbolDisplayPartKind.className; }
7712+
else if (flags & SymbolFlags.Interface) { return SymbolDisplayPartKind.interfaceName; }
7713+
else if (flags & SymbolFlags.Enum) { return SymbolDisplayPartKind.enumName; }
7714+
else if (flags & SymbolFlags.Module) { return SymbolDisplayPartKind.moduleName; }
7715+
else if (flags & SymbolFlags.Method) { return SymbolDisplayPartKind.methodName; }
7716+
else if (flags & SymbolFlags.TypeParameter) { return SymbolDisplayPartKind.typeParameterName; }
7717+
7718+
return SymbolDisplayPartKind.text;
7719+
}
76967720
}

src/compiler/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,6 +1199,10 @@ module ts {
11991199
kind: SymbolDisplayPartKind[this.kind]
12001200
};
12011201
}
1202+
1203+
public static toString(parts: SymbolDisplayPart[]) {
1204+
return parts.map(p => p.text).join("");
1205+
}
12021206
}
12031207

12041208
export enum SymbolDisplayPartKind {

src/harness/fourslash.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,10 @@ module FourSlash {
820820
this.taoInvalidReason = 'verifyCurrentSignatureHelpIs NYI';
821821

822822
var help = this.getActiveSignatureHelpItem();
823-
assert.equal(help.prefix + help.parameters.map(p => p.display).join(help.separator) + help.suffix, expected);
823+
assert.equal(
824+
ts.SymbolDisplayPart.toString(help.prefixDisplayParts) +
825+
help.parameters.map(p => ts.SymbolDisplayPart.toString(p.displayParts)).join(ts.SymbolDisplayPart.toString(help.separatorDisplayParts)) +
826+
ts.SymbolDisplayPart.toString(help.suffixDisplayParts), expected);
824827
}
825828

826829
public verifyCurrentParameterIsVariable(isVariable: boolean) {
@@ -844,7 +847,7 @@ module FourSlash {
844847

845848
var activeSignature = this.getActiveSignatureHelpItem();
846849
var activeParameter = this.getActiveParameter();
847-
assert.equal(activeParameter.display, parameter);
850+
assert.equal(ts.SymbolDisplayPart.toString(activeParameter.displayParts), parameter);
848851
}
849852

850853
public verifyCurrentParameterHelpDocComment(docComment: string) {

src/services/services.ts

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ module ts {
722722
currentParameterIsTypeParameter: boolean; // current parameter is a type argument or a normal argument
723723
currentParameter: number; // Index of active parameter in "parameters" or "typeParamters" array
724724
}
725-
725+
726726
export interface ClassifiedSpan {
727727
textSpan: TypeScript.TextSpan;
728728
classificationType: string; // ClassificationTypeNames
@@ -833,8 +833,8 @@ module ts {
833833

834834
export interface SignatureHelpParameter {
835835
name: string;
836-
documentation: string;
837-
display: string;
836+
documentation: SymbolDisplayPart[];
837+
displayParts: SymbolDisplayPart[];
838838
isOptional: boolean;
839839
}
840840

@@ -847,11 +847,11 @@ module ts {
847847
*/
848848
export interface SignatureHelpItem {
849849
isVariadic: boolean;
850-
prefix: string;
851-
suffix: string;
852-
separator: string;
850+
prefixDisplayParts: SymbolDisplayPart[];
851+
suffixDisplayParts: SymbolDisplayPart[];
852+
separatorDisplayParts: SymbolDisplayPart[];
853853
parameters: SignatureHelpParameter[];
854-
documentation: string;
854+
documentation: SymbolDisplayPart[];
855855
}
856856

857857
/**
@@ -1622,6 +1622,11 @@ module ts {
16221622
});
16231623
}
16241624

1625+
export function getSymbolDocumentationDisplayParts(symbol: Symbol): SymbolDisplayPart[] {
1626+
var documentation = symbol.getDocumentationComment();
1627+
return documentation === "" ? [] : [new SymbolDisplayPart(documentation, SymbolDisplayPartKind.text, /*symbol:*/ null)];
1628+
}
1629+
16251630
export function createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry): LanguageService {
16261631
var syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host);
16271632
var formattingRulesProvider: TypeScript.Services.Formatting.RulesProvider;
@@ -2372,42 +2377,41 @@ module ts {
23722377
return undefined;
23732378
}
23742379

2375-
var documentation = symbol.getDocumentationComment();
2376-
var documentationParts = documentation === "" ? [] : [new SymbolDisplayPart(documentation, SymbolDisplayPartKind.text, /*symbol:*/ null)];
2380+
var documentationParts = getSymbolDocumentationDisplayParts(symbol);
23772381

23782382
// Having all this logic here is pretty unclean. Consider moving to the roslyn model
23792383
// where all symbol display logic is encapsulated into visitors and options.
23802384
var totalParts: SymbolDisplayPart[] = [];
23812385

23822386
if (symbol.flags & SymbolFlags.Class) {
2383-
totalParts.push(new SymbolDisplayPart("class", SymbolDisplayPartKind.keyword, undefined));
2384-
totalParts.push(new SymbolDisplayPart(" ", SymbolDisplayPartKind.space, undefined));
2387+
totalParts.push(keywordPart(SyntaxKind.ClassKeyword));
2388+
totalParts.push(spacePart());
23852389
totalParts.push.apply(totalParts, typeInfoResolver.symbolToDisplayParts(symbol, sourceFile));
23862390
}
23872391
else if (symbol.flags & SymbolFlags.Interface) {
2388-
totalParts.push(new SymbolDisplayPart("interface", SymbolDisplayPartKind.keyword, undefined));
2389-
totalParts.push(new SymbolDisplayPart(" ", SymbolDisplayPartKind.space, undefined));
2392+
totalParts.push(keywordPart(SyntaxKind.InterfaceKeyword));
2393+
totalParts.push(spacePart());
23902394
totalParts.push.apply(totalParts, typeInfoResolver.symbolToDisplayParts(symbol, sourceFile));
23912395
}
23922396
else if (symbol.flags & SymbolFlags.Enum) {
2393-
totalParts.push(new SymbolDisplayPart("enum", SymbolDisplayPartKind.keyword, undefined));
2394-
totalParts.push(new SymbolDisplayPart(" ", SymbolDisplayPartKind.space, undefined));
2397+
totalParts.push(keywordPart(SyntaxKind.EnumKeyword));
2398+
totalParts.push(spacePart());
23952399
totalParts.push.apply(totalParts, typeInfoResolver.symbolToDisplayParts(symbol, sourceFile));
23962400
}
23972401
else if (symbol.flags & SymbolFlags.Module) {
2398-
totalParts.push(new SymbolDisplayPart("module", SymbolDisplayPartKind.keyword, undefined));
2399-
totalParts.push(new SymbolDisplayPart(" ", SymbolDisplayPartKind.space, undefined));
2402+
totalParts.push(keywordPart(SyntaxKind.ModuleKeyword));
2403+
totalParts.push(spacePart());
24002404
totalParts.push.apply(totalParts, typeInfoResolver.symbolToDisplayParts(symbol, sourceFile));
24012405
}
24022406
else if (symbol.flags & SymbolFlags.TypeParameter) {
2403-
totalParts.push(new SymbolDisplayPart("(", SymbolDisplayPartKind.punctuation, undefined));
2407+
totalParts.push(punctuationPart(SyntaxKind.OpenParenToken));
24042408
totalParts.push(new SymbolDisplayPart("type parameter", SymbolDisplayPartKind.text, undefined));
2405-
totalParts.push(new SymbolDisplayPart(")", SymbolDisplayPartKind.punctuation, undefined));
2406-
totalParts.push(new SymbolDisplayPart(" ", SymbolDisplayPartKind.space, undefined));
2409+
totalParts.push(punctuationPart(SyntaxKind.CloseParenToken));
2410+
totalParts.push(spacePart());
24072411
totalParts.push.apply(totalParts, typeInfoResolver.symbolToDisplayParts(symbol));
24082412
}
24092413
else {
2410-
totalParts.push(new SymbolDisplayPart("(", SymbolDisplayPartKind.punctuation, undefined));
2414+
totalParts.push(punctuationPart(SyntaxKind.OpenParenToken));
24112415
var text: string;
24122416

24132417
if (symbol.flags & SymbolFlags.Property) { text = "property" }
@@ -2421,8 +2425,8 @@ module ts {
24212425
}
24222426

24232427
totalParts.push(new SymbolDisplayPart(text, SymbolDisplayPartKind.text, undefined));
2424-
totalParts.push(new SymbolDisplayPart(")", SymbolDisplayPartKind.punctuation, undefined));
2425-
totalParts.push(new SymbolDisplayPart(" ", SymbolDisplayPartKind.space, undefined));
2428+
totalParts.push(punctuationPart(SyntaxKind.CloseParenToken));
2429+
totalParts.push(spacePart());
24262430

24272431
totalParts.push.apply(totalParts, typeInfoResolver.symbolToDisplayParts(symbol, getContainerNode(node)));
24282432

@@ -2432,8 +2436,8 @@ module ts {
24322436
symbol.flags & SymbolFlags.Variable) {
24332437

24342438
if (type) {
2435-
totalParts.push(new SymbolDisplayPart(":", SymbolDisplayPartKind.punctuation, undefined));
2436-
totalParts.push(new SymbolDisplayPart(" ", SymbolDisplayPartKind.space, undefined));
2439+
totalParts.push(punctuationPart(SyntaxKind.ColonToken));
2440+
totalParts.push(spacePart());
24372441
totalParts.push.apply(totalParts, typeInfoResolver.typeToDisplayParts(type, getContainerNode(node)));
24382442
}
24392443
}
@@ -2448,9 +2452,9 @@ module ts {
24482452
if (declaration.kind === SyntaxKind.EnumMember) {
24492453
var constantValue = typeInfoResolver.getEnumMemberValue(<EnumMember>declaration);
24502454
if (constantValue !== undefined) {
2451-
totalParts.push(new SymbolDisplayPart(" ", SymbolDisplayPartKind.space, undefined));
2452-
totalParts.push(new SymbolDisplayPart("=", SymbolDisplayPartKind.operator, undefined));
2453-
totalParts.push(new SymbolDisplayPart(" ", SymbolDisplayPartKind.space, undefined));
2455+
totalParts.push(spacePart());
2456+
totalParts.push(operatorPart(SyntaxKind.EqualsToken));
2457+
totalParts.push(spacePart());
24542458
totalParts.push(new SymbolDisplayPart(constantValue.toString(), SymbolDisplayPartKind.numericLiteral, undefined));
24552459
}
24562460
}
@@ -3782,7 +3786,7 @@ module ts {
37823786

37833787
var formalSignatures: FormalSignatureItemInfo[] = [];
37843788
forEach(signatureHelpItems.items, signature => {
3785-
var signatureInfoString = signature.prefix;
3789+
var signatureInfoString = ts.SymbolDisplayPart.toString(signature.prefixDisplayParts);
37863790

37873791
var parameters: FormalParameterInfo[] = [];
37883792
if (signature.parameters) {
@@ -3791,32 +3795,31 @@ module ts {
37913795

37923796
// add the parameter to the string
37933797
if (i) {
3794-
signatureInfoString += signature.separator;
3798+
signatureInfoString += ts.SymbolDisplayPart.toString(signature.separatorDisplayParts);
37953799
}
37963800

37973801
var start = signatureInfoString.length;
3798-
signatureInfoString += parameter.display;
3802+
signatureInfoString += ts.SymbolDisplayPart.toString(parameter.displayParts);
37993803
var end = signatureInfoString.length - 1;
38003804

38013805
// add the parameter to the list
38023806
parameters.push({
38033807
name: parameter.name,
38043808
isVariable: i == n - 1 && signature.isVariadic,
3805-
docComment: parameter.documentation,
3809+
docComment: ts.SymbolDisplayPart.toString(parameter.documentation),
38063810
minChar: start,
38073811
limChar: end
38083812
});
38093813
}
38103814
}
38113815

3812-
signatureInfoString += signature.suffix;
3816+
signatureInfoString += ts.SymbolDisplayPart.toString(signature.suffixDisplayParts);
38133817

38143818
formalSignatures.push({
38153819
signatureInfo: signatureInfoString,
3816-
docComment: signature.documentation,
3820+
docComment: ts.SymbolDisplayPart.toString(signature.documentation),
38173821
parameters: parameters,
38183822
typeParameters: [],
3819-
docComments: signature.documentation
38203823
});
38213824
});
38223825

0 commit comments

Comments
 (0)