From 8fc3fd9a20fb30e8602d20c68c799449497a7870 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 9 Jun 2017 18:02:42 -0700 Subject: [PATCH] request returns span --- src/harness/fourslash.ts | 14 +++++++++----- src/harness/harnessLanguageService.ts | 4 ++-- src/server/client.ts | 2 +- src/server/protocol.ts | 16 ++++++++++++---- src/server/session.ts | 9 +++++---- src/services/formatting/formatting.ts | 6 +++--- src/services/services.ts | 7 ++++--- src/services/shims.ts | 11 +++++------ src/services/types.ts | 2 +- 9 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 080614fc623..3feb5c0b19d 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2500,13 +2500,17 @@ namespace FourSlash { } } - public verifyIsInMultiLineCommentAtPosition(negative: boolean) { + public verifySpanOfEnclosingComment(negative: boolean, onlyMultiLine: boolean) { const expected = !negative; const position = this.currentCaretPosition; const fileName = this.activeFile.fileName; - const actual = this.languageService.isInMultiLineCommentAtPosition(fileName, position); + const actual = !!this.languageService.getSpanOfEnclosingComment(fileName, position, /*onlyMultiLine*/ onlyMultiLine); if (expected !== actual) { - this.raiseError(`verifyIsInMultiLineCommentAtPosition failed: at position '${position}' in '${fileName}', expected '${expected}'.`); + this.raiseError(`verifySpanOfEnclosingComment failed: + position: '${position}' + fileName: '${fileName}' + onlyMultiLine: '${onlyMultiLine}' + expected: '${expected}'.`); } } @@ -3583,8 +3587,8 @@ namespace FourSlashInterface { this.state.verifyBraceCompletionAtPosition(this.negative, openingBrace); } - public isInMultiLineCommentAtPosition() { - this.state.verifyIsInMultiLineCommentAtPosition(this.negative); + public isInCommentAtPosition(onlyMultiLine: boolean) { + this.state.verifySpanOfEnclosingComment(this.negative, onlyMultiLine); } public codeFixAvailable() { diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 962f9a0df5d..6d7eee5757f 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -486,8 +486,8 @@ namespace Harness.LanguageService { isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean { return unwrapJSONCallResult(this.shim.isValidBraceCompletionAtPosition(fileName, position, openingBrace)); } - isInMultiLineCommentAtPosition(fileName: string, position: number): boolean { - return unwrapJSONCallResult(this.shim.getisInMultiLineCommentAtPosition(fileName, position)); + getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): ts.TextSpan { + return unwrapJSONCallResult(this.shim.getSpanOfEnclosingComment(fileName, position, onlyMultiLine)); } getCodeFixesAtPosition(): ts.CodeAction[] { throw new Error("Not supported on the shim."); diff --git a/src/server/client.ts b/src/server/client.ts index 0e66516da40..5e5a6fcfcd5 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -676,7 +676,7 @@ namespace ts.server { return notImplemented(); } - isInMultiLineCommentAtPosition(_fileName: string, _position: number): boolean { + getSpanOfEnclosingComment(_fileName: string, _position: number, _onlyMultiLine: boolean): TextSpan { return notImplemented(); } diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 299ba4fceed..0dc510c4f6e 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -8,7 +8,7 @@ namespace ts.server.protocol { /* @internal */ BraceFull = "brace-full", BraceCompletion = "braceCompletion", - isInMultiLineComment = "isInMultiLineComment", + GetSpanOfEnclosingComment = "getSpanOfEnclosingComment", Change = "change", Close = "close", Completions = "completions", @@ -240,10 +240,18 @@ namespace ts.server.protocol { } /** - * A request to determine if the caret is inside a multi-line comment. + * A request to determine if the caret is inside a comment. */ - export interface IsInMultiLineCommentAtPositionRequest extends FileLocationRequest { - command: CommandTypes.isInMultiLineComment; + export interface SpanOfEnclosingCommentRequest extends FileLocationRequest { + command: CommandTypes.GetSpanOfEnclosingComment; + arguments: SpanOfEnclosingCommentRequestArgs; + } + + export interface SpanOfEnclosingCommentRequestArgs extends FileLocationRequestArgs { + /** + * Requires that the enclosing span be a multi-line comment, or else the request returns undefined. + */ + onlyMultiLine: boolean; } /** diff --git a/src/server/session.ts b/src/server/session.ts index 9657c666238..2be7cade587 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -961,11 +961,12 @@ namespace ts.server { return project.getLanguageService(/*ensureSynchronized*/ false).getDocCommentTemplateAtPosition(file, position); } - private getisInMultiLineCommentAtPosition(args: protocol.FileLocationRequestArgs) { + private getSpanOfEnclosingComment(args: protocol.SpanOfEnclosingCommentRequestArgs) { const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args); const scriptInfo = project.getScriptInfoForNormalizedPath(file); + const onlyMultiLine = args.onlyMultiLine; const position = this.getPosition(args, scriptInfo); - return project.getLanguageService(/*ensureSynchronized*/ false).isInMultiLineCommentAtPosition(file, position); + return project.getLanguageService(/*ensureSynchronized*/ false).getSpanOfEnclosingComment(file, position, onlyMultiLine); } private getIndentation(args: protocol.IndentationRequestArgs) { @@ -1701,8 +1702,8 @@ namespace ts.server { [CommandNames.DocCommentTemplate]: (request: protocol.DocCommentTemplateRequest) => { return this.requiredResponse(this.getDocCommentTemplate(request.arguments)); }, - [CommandNames.isInMultiLineComment]: (request: protocol.IsInMultiLineCommentAtPositionRequest) => { - return this.requiredResponse(this.getisInMultiLineCommentAtPosition(request.arguments)); + [CommandNames.GetSpanOfEnclosingComment]: (request: protocol.SpanOfEnclosingCommentRequest) => { + return this.requiredResponse(this.getSpanOfEnclosingComment(request.arguments)); }, [CommandNames.Format]: (request: protocol.FormatRequest) => { return this.requiredResponse(this.getFormattingEditsForRange(request.arguments)); diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 7feba4b7dd2..08d2bd83616 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -1122,7 +1122,7 @@ namespace ts.formatting { * and a negative value if the position is not in a multi-line comment. */ export function getIndentationOfEnclosingMultiLineComment(sourceFile: SourceFile, position: number, options: EditorSettings): number { - const range = getRangeOfEnclosingComment(sourceFile, position, SyntaxKind.MultiLineCommentTrivia); + const range = getRangeOfEnclosingComment(sourceFile, position, /*onlyMultiLine*/ true); if (range) { const commentStart = range.pos; const commentLineStart = getLineStartPositionForPosition(commentStart, sourceFile); @@ -1132,7 +1132,7 @@ namespace ts.formatting { return undefined; } - export function getRangeOfEnclosingComment(sourceFile: SourceFile, position: number, kind: CommentKind): CommentRange | undefined { + export function getRangeOfEnclosingComment(sourceFile: SourceFile, position: number, onlyMultiLine: boolean): CommentRange | undefined { const precedingToken = findPrecedingToken(position, sourceFile); const trailingRangesOfPreviousToken = precedingToken && getTrailingCommentRanges(sourceFile.text, precedingToken.end); const leadingCommentRangesOfNextToken = getLeadingCommentRangesOfNode(getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false), sourceFile); @@ -1143,7 +1143,7 @@ namespace ts.formatting { for (const range of commentRanges) { // We need to extend the range when in an unclosed multi-line comment. if (range.pos < position && (position < range.end || position === range.end && position === sourceFile.getFullWidth())) { - return range.kind === kind ? range : undefined; + return onlyMultiLine && range.kind !== SyntaxKind.MultiLineCommentTrivia ? undefined : range; } } } diff --git a/src/services/services.ts b/src/services/services.ts index 294afec6029..8234a100522 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1818,9 +1818,10 @@ namespace ts { return true; } - function isInMultiLineCommentAtPosition(fileName: string, position: number): boolean { + function getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean) { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); - return !!ts.formatting.getRangeOfEnclosingComment(sourceFile, position, SyntaxKind.MultiLineCommentTrivia); + const range = ts.formatting.getRangeOfEnclosingComment(sourceFile, position, onlyMultiLine); + return range && createTextSpanFromRange(range); } function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] { @@ -2045,7 +2046,7 @@ namespace ts { getFormattingEditsAfterKeystroke, getDocCommentTemplateAtPosition, isValidBraceCompletionAtPosition, - isInMultiLineCommentAtPosition, + getSpanOfEnclosingComment, getCodeFixesAtPosition, getEmitOutput, getNonBoundSourceFile, diff --git a/src/services/shims.ts b/src/services/shims.ts index fd2ba1cca72..2e9825e1457 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -255,9 +255,9 @@ namespace ts { isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): string; /** - * Returns JSON-encoded boolean to indicate whether the caret at the current position is in a multi-line comment. + * Returns a JSON-encoded TextSpan | undefined indicating the range of the enclosing comment, if it exists. */ - getisInMultiLineCommentAtPosition(fileName: string, position: number): string; + getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): string; getEmitOutput(fileName: string): string; getEmitOutputObject(fileName: string): EmitOutput; @@ -840,11 +840,10 @@ namespace ts { ); } - /// GET IS IN MULTI-LINE COMMENT - public getisInMultiLineCommentAtPosition(fileName: string, position: number): string { + public getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): string { return this.forwardJSONCall( - `getisInMultiLineCommentAtPosition('${fileName}', ${position})`, - () => this.languageService.isInMultiLineCommentAtPosition(fileName, position) + `getSpanOfEnclosingComment('${fileName}', ${position})`, + () => this.languageService.getSpanOfEnclosingComment(fileName, position, onlyMultiLine) ); } diff --git a/src/services/types.ts b/src/services/types.ts index bbd9fa9986c..73bf75b5508 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -260,7 +260,7 @@ namespace ts { isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; - isInMultiLineCommentAtPosition(fileName: string, position: number): boolean; + getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];