mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-30 01:04:49 -05:00
Expose document highlighting to server.
This commit is contained in:
@@ -2132,7 +2132,7 @@ module FourSlash {
|
||||
let occurance = occurances[i];
|
||||
if (occurance && occurance.fileName === fileName && occurance.textSpan.start === start && ts.textSpanEnd(occurance.textSpan) === end) {
|
||||
if (typeof isWriteAccess !== "undefined" && occurance.isWriteAccess !== isWriteAccess) {
|
||||
this.raiseError('verifyOccurancesAtPositionListContains failed - item isWriteAccess value doe not match, actual: ' + occurance.isWriteAccess + ', expected: ' + isWriteAccess + '.');
|
||||
this.raiseError('verifyOccurancesAtPositionListContains failed - item isWriteAccess value does not match, actual: ' + occurance.isWriteAccess + ', expected: ' + isWriteAccess + '.');
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -2152,6 +2152,51 @@ module FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
private getDocumentHighlightsAtCurrentPosition(fileNamesToSearch: string[]) {
|
||||
let filesToSearch = fileNamesToSearch.map(name => this.basePath + "/" + name);
|
||||
return this.languageService.getDocumentHighlights(this.activeFile.fileName, this.currentCaretPosition, filesToSearch);
|
||||
}
|
||||
|
||||
public verifyDocumentHighlightsAtPositionListContains(fileName: string, start: number, end: number, fileNamesToSearch: string[], kind?: string) {
|
||||
this.taoInvalidReason = 'verifyDocumentHighlightsAtPositionListContains NYI';
|
||||
|
||||
let documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNamesToSearch);
|
||||
|
||||
if (!documentHighlights || documentHighlights.length === 0) {
|
||||
this.raiseError('verifyDocumentHighlightsAtPositionListContains failed - found 0 highlights, expected at least one.');
|
||||
}
|
||||
|
||||
for (let i = 0; i < documentHighlights.length; i++) if (documentHighlights[i].fileName === fileName) {
|
||||
let { highlightSpans } = documentHighlights[i];
|
||||
|
||||
for (let highlight of highlightSpans) {
|
||||
if (highlight && highlight.textSpan.start === start && ts.textSpanEnd(highlight.textSpan) === end) {
|
||||
if (typeof kind !== "undefined" && highlight.kind !== kind) {
|
||||
this.raiseError('verifyDocumentHighlightsAtPositionListContains failed - item "kind" value does not match, actual: ' + highlight.kind + ', expected: ' + kind + '.');
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let missingItem = { fileName: fileName, start: start, end: end, kind: kind };
|
||||
this.raiseError('verifyOccurancesAtPositionListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(documentHighlights) + ')');
|
||||
}
|
||||
|
||||
public verifyDocumentHighlightsAtPositionListCount(expectedCount: number, fileNamesToSearch: string[]) {
|
||||
this.taoInvalidReason = 'verifyDocumentHighlightsAtPositionListCount NYI';
|
||||
|
||||
let documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNamesToSearch);
|
||||
let actualCount = documentHighlights
|
||||
? documentHighlights.reduce((currentCount, currentDocumentHighlights) => {
|
||||
return currentCount + currentDocumentHighlights.highlightSpans.length}, 0)
|
||||
: 0;
|
||||
|
||||
if (expectedCount !== actualCount) {
|
||||
this.raiseError('verifyDocumentHighlightsAtPositionListCount failed - actual: ' + actualCount + ', expected:' + expectedCount);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the text of the entire line the caret is currently at
|
||||
private getCurrentLineContent() {
|
||||
let text = this.getFileContent(this.activeFile.fileName);
|
||||
|
||||
@@ -528,7 +528,29 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
getDocumentHighlights(fileName: string, position: number): DocumentHighlights[] {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
var lineOffset = this.positionToOneBasedLineOffset(fileName, position);
|
||||
var args: protocol.FileLocationRequestArgs = {
|
||||
file: fileName,
|
||||
line: lineOffset.line,
|
||||
offset: lineOffset.offset,
|
||||
};
|
||||
|
||||
var request = this.processRequest<protocol.DocumentHighlightsRequest>(CommandNames.DocumentHighlights, args);
|
||||
var response = this.processResponse<protocol.DocumentHighlightsResponse>(request);
|
||||
|
||||
return response.body.map(entry => { // convert ts.server.protocol.DocumentHighlightsItem to ts.DocumentHighlights
|
||||
return {
|
||||
fileName: entry.file,
|
||||
highlightSpans: entry.highlightSpans.map(span => { // convert ts.server.protocol.HighlightSpan to ts.HighlighSpan
|
||||
var start = this.lineOffsetToPosition(entry.file, span.start);
|
||||
var end = this.lineOffsetToPosition(entry.file, span.end);
|
||||
return {
|
||||
textSpan: ts.createTextSpanFromBounds(start, end),
|
||||
kind: span.kind
|
||||
};
|
||||
})
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getOutliningSpans(fileName: string): OutliningSpan[] {
|
||||
|
||||
22
src/server/protocol.d.ts
vendored
22
src/server/protocol.d.ts
vendored
@@ -238,6 +238,28 @@ declare namespace ts.server.protocol {
|
||||
body?: OccurrencesResponseItem[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get document highlights request; value of command field is
|
||||
* "documentHighlights". Return response giving spans that are relevant
|
||||
* in the file at a given line and column.
|
||||
*/
|
||||
export interface DocumentHighlightsRequest extends FileLocationRequest {
|
||||
}
|
||||
|
||||
export interface HighLightSpan extends TextSpan {
|
||||
kind: string
|
||||
}
|
||||
|
||||
export interface DocumentHighlightsItem {
|
||||
file: string,
|
||||
highlightSpans: HighLightSpan[];
|
||||
}
|
||||
|
||||
export interface DocumentHighlightsResponse extends Response {
|
||||
body?: DocumentHighlightsItem[];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find references request; value of command field is
|
||||
* "references". Return response giving the file locations that
|
||||
|
||||
@@ -89,6 +89,7 @@ namespace ts.server {
|
||||
export const NavBar = "navbar";
|
||||
export const Navto = "navto";
|
||||
export const Occurrences = "occurrences";
|
||||
export const DocumentHighlights = "documentHighlights";
|
||||
export const Open = "open";
|
||||
export const Quickinfo = "quickinfo";
|
||||
export const References = "references";
|
||||
@@ -313,7 +314,7 @@ namespace ts.server {
|
||||
}));
|
||||
}
|
||||
|
||||
private getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[]{
|
||||
private getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[] {
|
||||
fileName = ts.normalizePath(fileName);
|
||||
let project = this.projectService.getProjectForFile(fileName);
|
||||
|
||||
@@ -343,6 +344,42 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
private getDocumentHighlights(line: number, offset: number, fileName: string): protocol.DocumentHighlightsItem[] {
|
||||
fileName = ts.normalizePath(fileName);
|
||||
let project = this.projectService.getProjectForFile(fileName);
|
||||
|
||||
if (!project) {
|
||||
throw Errors.NoProject;
|
||||
}
|
||||
|
||||
let { compilerService } = project;
|
||||
let position = compilerService.host.lineOffsetToPosition(fileName, line, offset);
|
||||
let filesToSearch = [fileName]; // only search for highlights inside the current file
|
||||
|
||||
let documentHighlights = compilerService.languageService.getDocumentHighlights(fileName, position, filesToSearch);
|
||||
|
||||
if (!documentHighlights) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return documentHighlights.map(documentHighlight => { // convert ts.DocumentHighlights to ts.server.protocol.DocumentHighlightsItem
|
||||
var file = documentHighlight.fileName;
|
||||
return {
|
||||
file: file,
|
||||
highlightSpans: documentHighlight.highlightSpans.map(highlightSpan => { // convert to ts.HighlightSpan to ts.server.protocol.HighlightSpan
|
||||
let { textSpan, kind } = highlightSpan;
|
||||
let start = compilerService.host.positionToLineOffset(file, textSpan.start);
|
||||
let end = compilerService.host.positionToLineOffset(file, ts.textSpanEnd(textSpan));
|
||||
return {
|
||||
start: start,
|
||||
end: end,
|
||||
kind: kind
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo {
|
||||
fileName = ts.normalizePath(fileName)
|
||||
let project = this.projectService.getProjectForFile(fileName)
|
||||
@@ -937,6 +974,10 @@ namespace ts.server {
|
||||
var { line, offset, file: fileName } = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
return {response: this.getOccurrences(line, offset, fileName), responseRequired: true};
|
||||
},
|
||||
[CommandNames.DocumentHighlights]: (request: protocol.Request) => {
|
||||
var { line, offset, file: fileName } = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
return {response: this.getDocumentHighlights(line, offset, fileName), responseRequired: true};
|
||||
},
|
||||
[CommandNames.ProjectInfo]: (request: protocol.Request) => {
|
||||
var { file, needFileNameList } = <protocol.ProjectInfoRequestArgs>request.arguments;
|
||||
return {response: this.getProjectInfo(file, needFileNameList), responseRequired: true};
|
||||
|
||||
Reference in New Issue
Block a user