Skip to content

Commit

Permalink
Merge pull request #37029 from armanio123/AddToggleCommentFeature
Browse files Browse the repository at this point in the history
Add ToggleLineComment and ToggleMultilineComment service
  • Loading branch information
armanio123 authored Jul 14, 2020
2 parents 3c91133 635ee24 commit 6279f98
Show file tree
Hide file tree
Showing 39 changed files with 1,262 additions and 33 deletions.
16 changes: 16 additions & 0 deletions src/harness/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 825,22 @@ namespace ts.server {
return notImplemented();
}

toggleLineComment(): TextChange[] {
return notImplemented();
}

toggleMultilineComment(): TextChange[] {
return notImplemented();
}

commentSelection(): TextChange[] {
return notImplemented();
}

uncommentSelection(): TextChange[] {
return notImplemented();
}

dispose(): void {
throw new Error("dispose is not available through the server layer.");
}
Expand Down
62 changes: 53 additions & 9 deletions src/harness/fourslashImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3226,7 3226,7 @@ namespace FourSlash {

this.raiseError(
`Expected to find a fix with the name '${fixName}', but none exists.`
availableFixes.length
availableFixes.length
? ` Available fixes: ${availableFixes.map(fix => `${fix.fixName} (${fix.fixId ? "with" : "without"} fix-all)`).join(", ")}`
: ""
);
Expand Down Expand Up @@ -3465,13 3465,13 @@ namespace FourSlash {

const incomingCalls =
direction === CallHierarchyItemDirection.Outgoing ? { result: "skip" } as const :
alreadySeen ? { result: "seen" } as const :
{ result: "show", values: this.languageService.provideCallHierarchyIncomingCalls(callHierarchyItem.file, callHierarchyItem.selectionSpan.start) } as const;
alreadySeen ? { result: "seen" } as const :
{ result: "show", values: this.languageService.provideCallHierarchyIncomingCalls(callHierarchyItem.file, callHierarchyItem.selectionSpan.start) } as const;

const outgoingCalls =
direction === CallHierarchyItemDirection.Incoming ? { result: "skip" } as const :
alreadySeen ? { result: "seen" } as const :
{ result: "show", values: this.languageService.provideCallHierarchyOutgoingCalls(callHierarchyItem.file, callHierarchyItem.selectionSpan.start) } as const;
alreadySeen ? { result: "seen" } as const :
{ result: "show", values: this.languageService.provideCallHierarchyOutgoingCalls(callHierarchyItem.file, callHierarchyItem.selectionSpan.start) } as const;

let text = "";
text = `${prefix}╭ name: ${callHierarchyItem.name}\n`;
Expand All @@ -3485,7 3485,7 @@ namespace FourSlash {
text = `${prefix}├ selectionSpan:\n`;
text = this.formatCallHierarchyItemSpan(file, callHierarchyItem.selectionSpan, `${prefix}│ `,
incomingCalls.result !== "skip" || outgoingCalls.result !== "skip" ? `${prefix}│ ` :
`${trailingPrefix}╰ `);
`${trailingPrefix}╰ `);

if (incomingCalls.result === "seen") {
if (outgoingCalls.result === "skip") {
Expand Down Expand Up @@ -3514,8 3514,8 @@ namespace FourSlash {
text = `${prefix}│ ├ fromSpans:\n`;
text = this.formatCallHierarchyItemSpans(file, incomingCall.fromSpans, `${prefix}│ │ `,
i < incomingCalls.values.length - 1 ? `${prefix}│ ╰ ` :
outgoingCalls.result !== "skip" ? `${prefix}│ ╰ ` :
`${trailingPrefix}╰ ╰ `);
outgoingCalls.result !== "skip" ? `${prefix}│ ╰ ` :
`${trailingPrefix}╰ ╰ `);
}
}
}
Expand All @@ -3536,7 3536,7 @@ namespace FourSlash {
text = `${prefix}│ ├ fromSpans:\n`;
text = this.formatCallHierarchyItemSpans(file, outgoingCall.fromSpans, `${prefix}│ │ `,
i < outgoingCalls.values.length - 1 ? `${prefix}│ ╰ ` :
`${trailingPrefix}╰ ╰ `);
`${trailingPrefix}╰ ╰ `);
}
}
}
Expand Down Expand Up @@ -3696,6 3696,50 @@ namespace FourSlash {
public configurePlugin(pluginName: string, configuration: any): void {
(<ts.server.SessionClient>this.languageService).configurePlugin(pluginName, configuration);
}

public toggleLineComment(newFileContent: string): void {
const changes: ts.TextChange[] = [];
for (const range of this.getRanges()) {
changes.push.apply(changes, this.languageService.toggleLineComment(this.activeFile.fileName, range));
}

this.applyEdits(this.activeFile.fileName, changes);

this.verifyCurrentFileContent(newFileContent);
}

public toggleMultilineComment(newFileContent: string): void {
const changes: ts.TextChange[] = [];
for (const range of this.getRanges()) {
changes.push.apply(changes, this.languageService.toggleMultilineComment(this.activeFile.fileName, range));
}

this.applyEdits(this.activeFile.fileName, changes);

this.verifyCurrentFileContent(newFileContent);
}

public commentSelection(newFileContent: string): void {
const changes: ts.TextChange[] = [];
for (const range of this.getRanges()) {
changes.push.apply(changes, this.languageService.commentSelection(this.activeFile.fileName, range));
}

this.applyEdits(this.activeFile.fileName, changes);

this.verifyCurrentFileContent(newFileContent);
}

public uncommentSelection(newFileContent: string): void {
const changes: ts.TextChange[] = [];
for (const range of this.getRanges()) {
changes.push.apply(changes, this.languageService.uncommentSelection(this.activeFile.fileName, range));
}

this.applyEdits(this.activeFile.fileName, changes);

this.verifyCurrentFileContent(newFileContent);
}
}

function prefixMessage(message: string | undefined) {
Expand Down
16 changes: 16 additions & 0 deletions src/harness/fourslashInterfaceImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 214,22 @@ namespace FourSlashInterface {
public refactorAvailableForTriggerReason(triggerReason: ts.RefactorTriggerReason, name: string, actionName?: string) {
this.state.verifyRefactorAvailable(this.negative, triggerReason, name, actionName);
}

public toggleLineComment(newFileContent: string) {
this.state.toggleLineComment(newFileContent);
}

public toggleMultilineComment(newFileContent: string) {
this.state.toggleMultilineComment(newFileContent);
}

public commentSelection(newFileContent: string) {
this.state.commentSelection(newFileContent);
}

public uncommentSelection(newFileContent: string) {
this.state.uncommentSelection(newFileContent);
}
}

export class Verify extends VerifyNegatable {
Expand Down
12 changes: 12 additions & 0 deletions src/harness/harnessLanguageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 603,18 @@ namespace Harness.LanguageService {
clearSourceMapperCache(): never {
return ts.notImplemented();
}
toggleLineComment(fileName: string, textRange: ts.TextRange): ts.TextChange[] {
return unwrapJSONCallResult(this.shim.toggleLineComment(fileName, textRange));
}
toggleMultilineComment(fileName: string, textRange: ts.TextRange): ts.TextChange[] {
return unwrapJSONCallResult(this.shim.toggleMultilineComment(fileName, textRange));
}
commentSelection(fileName: string, textRange: ts.TextRange): ts.TextChange[] {
return unwrapJSONCallResult(this.shim.commentSelection(fileName, textRange));
}
uncommentSelection(fileName: string, textRange: ts.TextRange): ts.TextChange[] {
return unwrapJSONCallResult(this.shim.uncommentSelection(fileName, textRange));
}
dispose(): void { this.shim.dispose({}); }
}

Expand Down
33 changes: 32 additions & 1 deletion src/server/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 136,18 @@ namespace ts.server.protocol {
SelectionRange = "selectionRange",
/* @internal */
SelectionRangeFull = "selectionRange-full",

ToggleLineComment = "toggleLineComment",
/* @internal */
ToggleLineCommentFull = "toggleLineComment-full",
ToggleMultilineComment = "toggleMultilineComment",
/* @internal */
ToggleMultilineCommentFull = "toggleMultilineComment-full",
CommentSelection = "commentSelection",
/* @internal */
CommentSelectionFull = "commentSelection-full",
UncommentSelection = "uncommentSelection",
/* @internal */
UncommentSelectionFull = "uncommentSelection-full",
PrepareCallHierarchy = "prepareCallHierarchy",
ProvideCallHierarchyIncomingCalls = "provideCallHierarchyIncomingCalls",
ProvideCallHierarchyOutgoingCalls = "provideCallHierarchyOutgoingCalls",
Expand Down Expand Up @@ -1542,6 1553,26 @@ namespace ts.server.protocol {
parent?: SelectionRange;
}

export interface ToggleLineCommentRequest extends FileRequest {
command: CommandTypes.ToggleLineComment;
arguments: FileRangeRequestArgs;
}

export interface ToggleMultilineCommentRequest extends FileRequest {
command: CommandTypes.ToggleMultilineComment;
arguments: FileRangeRequestArgs;
}

export interface CommentSelectionRequest extends FileRequest {
command: CommandTypes.CommentSelection;
arguments: FileRangeRequestArgs;
}

export interface UncommentSelectionRequest extends FileRequest {
command: CommandTypes.UncommentSelection;
arguments: FileRangeRequestArgs;
}

/**
* Information found in an "open" request.
*/
Expand Down
97 changes: 95 additions & 2 deletions src/server/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2012,8 2012,7 @@ namespace ts.server {
position = getPosition(args);
}
else {
const { startPosition, endPosition } = this.getStartAndEndPosition(args, scriptInfo);
textRange = { pos: startPosition, end: endPosition };
textRange = this.getRange(args, scriptInfo);
}
return Debug.checkDefined(position === undefined ? textRange : position);

Expand All @@ -2022,6 2021,12 @@ namespace ts.server {
}
}

private getRange(args: protocol.FileRangeRequestArgs, scriptInfo: ScriptInfo): TextRange {
const { startPosition, endPosition } = this.getStartAndEndPosition(args, scriptInfo);

return { pos: startPosition, end: endPosition };
}

private getApplicableRefactors(args: protocol.GetApplicableRefactorsRequestArgs): protocol.ApplicableRefactorInfo[] {
const { file, project } = this.getFileAndProject(args);
const scriptInfo = project.getScriptInfoForNormalizedPath(file)!;
Expand Down Expand Up @@ -2251,6 2256,70 @@ namespace ts.server {
});
}

private toggleLineComment(args: protocol.FileRangeRequestArgs, simplifiedResult: boolean): TextChange[] | protocol.CodeEdit[] {
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
const scriptInfo = this.projectService.getScriptInfo(file)!;
const textRange = this.getRange(args, scriptInfo);

const textChanges = languageService.toggleLineComment(file, textRange);

if (simplifiedResult) {
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;

return textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo));
}

return textChanges;
}

private toggleMultilineComment(args: protocol.FileRangeRequestArgs, simplifiedResult: boolean): TextChange[] | protocol.CodeEdit[] {
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
const textRange = this.getRange(args, scriptInfo);

const textChanges = languageService.toggleMultilineComment(file, textRange);

if (simplifiedResult) {
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;

return textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo));
}

return textChanges;
}

private commentSelection(args: protocol.FileRangeRequestArgs, simplifiedResult: boolean): TextChange[] | protocol.CodeEdit[] {
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
const textRange = this.getRange(args, scriptInfo);

const textChanges = languageService.commentSelection(file, textRange);

if (simplifiedResult) {
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;

return textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo));
}

return textChanges;
}

private uncommentSelection(args: protocol.FileRangeRequestArgs, simplifiedResult: boolean): TextChange[] | protocol.CodeEdit[] {
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
const textRange = this.getRange(args, scriptInfo);

const textChanges = languageService.uncommentSelection(file, textRange);

if (simplifiedResult) {
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;

return textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo));
}

return textChanges;
}

private mapSelectionRange(selectionRange: SelectionRange, scriptInfo: ScriptInfo): protocol.SelectionRange {
const result: protocol.SelectionRange = {
textSpan: toProtocolTextSpan(selectionRange.textSpan, scriptInfo),
Expand Down Expand Up @@ -2697,6 2766,30 @@ namespace ts.server {
[CommandNames.ProvideCallHierarchyOutgoingCalls]: (request: protocol.ProvideCallHierarchyOutgoingCallsRequest) => {
return this.requiredResponse(this.provideCallHierarchyOutgoingCalls(request.arguments));
},
[CommandNames.ToggleLineComment]: (request: protocol.ToggleLineCommentRequest) => {
return this.requiredResponse(this.toggleLineComment(request.arguments, /*simplifiedResult*/ true));
},
[CommandNames.ToggleLineCommentFull]: (request: protocol.ToggleLineCommentRequest) => {
return this.requiredResponse(this.toggleLineComment(request.arguments, /*simplifiedResult*/ false));
},
[CommandNames.ToggleMultilineComment]: (request: protocol.ToggleMultilineCommentRequest) => {
return this.requiredResponse(this.toggleMultilineComment(request.arguments, /*simplifiedResult*/ true));
},
[CommandNames.ToggleMultilineCommentFull]: (request: protocol.ToggleMultilineCommentRequest) => {
return this.requiredResponse(this.toggleMultilineComment(request.arguments, /*simplifiedResult*/ false));
},
[CommandNames.CommentSelection]: (request: protocol.CommentSelectionRequest) => {
return this.requiredResponse(this.commentSelection(request.arguments, /*simplifiedResult*/ true));
},
[CommandNames.CommentSelectionFull]: (request: protocol.CommentSelectionRequest) => {
return this.requiredResponse(this.commentSelection(request.arguments, /*simplifiedResult*/ false));
},
[CommandNames.UncommentSelection]: (request: protocol.UncommentSelectionRequest) => {
return this.requiredResponse(this.uncommentSelection(request.arguments, /*simplifiedResult*/ true));
},
[CommandNames.UncommentSelectionFull]: (request: protocol.UncommentSelectionRequest) => {
return this.requiredResponse(this.uncommentSelection(request.arguments, /*simplifiedResult*/ false));
},
}));

public addProtocolHandler(command: string, handler: (request: protocol.Request) => HandlerResponse) {
Expand Down
Loading

0 comments on commit 6279f98

Please sign in to comment.