mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-26 00:36:29 -05:00
Merge branch 'master' into JSDocCommentScaffolding
This commit is contained in:
@@ -183,7 +183,7 @@ namespace ts.server {
|
||||
|
||||
return {
|
||||
configFileName: response.body.configFileName,
|
||||
fileNameList: response.body.fileNameList
|
||||
fileNames: response.body.fileNames
|
||||
};
|
||||
}
|
||||
|
||||
@@ -527,8 +527,33 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
getDocumentHighlights(fileName: string, position: number): DocumentHighlights[] {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getDocumentHighlights(fileName: string, position: number, filesToSearch: string[]): DocumentHighlights[] {
|
||||
let { line, offset } = this.positionToOneBasedLineOffset(fileName, position);
|
||||
let args: protocol.DocumentHighlightsRequestArgs = { file: fileName, line, offset, filesToSearch };
|
||||
|
||||
let request = this.processRequest<protocol.DocumentHighlightsRequest>(CommandNames.DocumentHighlights, args);
|
||||
let response = this.processResponse<protocol.DocumentHighlightsResponse>(request);
|
||||
|
||||
let self = this;
|
||||
return response.body.map(convertToDocumentHighlights);
|
||||
|
||||
function convertToDocumentHighlights(item: ts.server.protocol.DocumentHighlightsItem): ts.DocumentHighlights {
|
||||
let { file, highlightSpans } = item;
|
||||
|
||||
return {
|
||||
fileName: file,
|
||||
highlightSpans: highlightSpans.map(convertHighlightSpan)
|
||||
};
|
||||
|
||||
function convertHighlightSpan(span: ts.server.protocol.HighlightSpan): ts.HighlightSpan {
|
||||
let start = self.lineOffsetToPosition(file, span.start);
|
||||
let end = self.lineOffsetToPosition(file, span.end);
|
||||
return {
|
||||
textSpan: ts.createTextSpanFromBounds(start, end),
|
||||
kind: span.kind
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getOutliningSpans(fileName: string): OutliningSpan[] {
|
||||
|
||||
@@ -304,7 +304,7 @@ namespace ts.server {
|
||||
return this.projectService.openFile(filename, false);
|
||||
}
|
||||
|
||||
getFileNameList() {
|
||||
getFileNames() {
|
||||
let sourceFiles = this.program.getSourceFiles();
|
||||
return sourceFiles.map(sourceFile => sourceFile.fileName);
|
||||
}
|
||||
|
||||
9
src/server/node.d.ts
vendored
9
src/server/node.d.ts
vendored
@@ -123,9 +123,14 @@ declare module NodeJS {
|
||||
|
||||
export interface ReadWriteStream extends ReadableStream, WritableStream { }
|
||||
|
||||
interface WindowSize {
|
||||
columns: number;
|
||||
rows: number;
|
||||
}
|
||||
|
||||
export interface Process extends EventEmitter {
|
||||
stdout: WritableStream;
|
||||
stderr: WritableStream;
|
||||
stdout: WritableStream & WindowSize;
|
||||
stderr: WritableStream & WindowSize;
|
||||
stdin: ReadableStream;
|
||||
argv: string[];
|
||||
execPath: string;
|
||||
|
||||
67
src/server/protocol.d.ts
vendored
67
src/server/protocol.d.ts
vendored
@@ -116,7 +116,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* The list of normalized file name in the project, including 'lib.d.ts'
|
||||
*/
|
||||
fileNameList?: string[];
|
||||
fileNames?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,6 +156,17 @@ declare namespace ts.server.protocol {
|
||||
arguments: FileLocationRequestArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Arguments in document highlight request; include: filesToSearch, file,
|
||||
* line, offset.
|
||||
*/
|
||||
export interface DocumentHighlightsRequestArgs extends FileLocationRequestArgs {
|
||||
/**
|
||||
* List of files to search for document highlights.
|
||||
*/
|
||||
filesToSearch: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to definition request; value of command field is
|
||||
* "definition". Return response giving the file locations that
|
||||
@@ -238,6 +249,35 @@ 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 {
|
||||
arguments: DocumentHighlightsRequestArgs
|
||||
}
|
||||
|
||||
export interface HighlightSpan extends TextSpan {
|
||||
kind: string
|
||||
}
|
||||
|
||||
export interface DocumentHighlightsItem {
|
||||
/**
|
||||
* File containing highlight spans.
|
||||
*/
|
||||
file: string,
|
||||
|
||||
/**
|
||||
* Spans to highlight in file.
|
||||
*/
|
||||
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
|
||||
@@ -854,6 +894,31 @@ declare namespace ts.server.protocol {
|
||||
export interface SignatureHelpResponse extends Response {
|
||||
body?: SignatureHelpItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Arguments for GeterrForProject request.
|
||||
*/
|
||||
export interface GeterrForProjectRequestArgs {
|
||||
/**
|
||||
* the file requesting project error list
|
||||
*/
|
||||
file: string;
|
||||
|
||||
/**
|
||||
* Delay in milliseconds to wait before starting to compute
|
||||
* errors for the files in the file list
|
||||
*/
|
||||
delay: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* GeterrForProjectRequest request; value of command field is
|
||||
* "geterrForProject". It works similarly with 'Geterr', only
|
||||
* it request for every file in this project.
|
||||
*/
|
||||
export interface GeterrForProjectRequest extends Request {
|
||||
arguments: GeterrForProjectRequestArgs
|
||||
}
|
||||
|
||||
/**
|
||||
* Arguments for geterr messages.
|
||||
|
||||
@@ -86,9 +86,11 @@ namespace ts.server {
|
||||
export const Format = "format";
|
||||
export const Formatonkey = "formatonkey";
|
||||
export const Geterr = "geterr";
|
||||
export const GeterrForProject = "geterrForProject";
|
||||
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";
|
||||
@@ -234,7 +236,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
|
||||
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200) {
|
||||
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200, requireOpen = true) {
|
||||
if (followMs > ms) {
|
||||
followMs = ms;
|
||||
}
|
||||
@@ -249,7 +251,7 @@ namespace ts.server {
|
||||
var checkOne = () => {
|
||||
if (matchSeq(seq)) {
|
||||
var checkSpec = checkList[index++];
|
||||
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName, true)) {
|
||||
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName, requireOpen)) {
|
||||
this.syntacticCheck(checkSpec.fileName, checkSpec.project);
|
||||
this.immediateId = setImmediate(() => {
|
||||
this.semanticCheck(checkSpec.fileName, checkSpec.project);
|
||||
@@ -313,7 +315,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 +345,42 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
private getDocumentHighlights(line: number, offset: number, fileName: string, filesToSearch: 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 documentHighlights = compilerService.languageService.getDocumentHighlights(fileName, position, filesToSearch);
|
||||
|
||||
if (!documentHighlights) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return documentHighlights.map(convertToDocumentHighlightsItem);
|
||||
|
||||
function convertToDocumentHighlightsItem(documentHighlights: ts.DocumentHighlights): ts.server.protocol.DocumentHighlightsItem {
|
||||
let { fileName, highlightSpans } = documentHighlights;
|
||||
|
||||
return {
|
||||
file: fileName,
|
||||
highlightSpans: highlightSpans.map(convertHighlightSpan)
|
||||
};
|
||||
|
||||
function convertHighlightSpan(highlightSpan: ts.HighlightSpan): ts.server.protocol.HighlightSpan {
|
||||
let { textSpan, kind } = highlightSpan;
|
||||
let start = compilerService.host.positionToLineOffset(fileName, textSpan.start);
|
||||
let end = compilerService.host.positionToLineOffset(fileName, ts.textSpanEnd(textSpan));
|
||||
return { start, end, kind };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo {
|
||||
fileName = ts.normalizePath(fileName)
|
||||
let project = this.projectService.getProjectForFile(fileName)
|
||||
@@ -352,7 +390,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
if (needFileNameList) {
|
||||
projectInfo.fileNameList = project.getFileNameList();
|
||||
projectInfo.fileNames = project.getFileNames();
|
||||
}
|
||||
|
||||
return projectInfo;
|
||||
@@ -836,7 +874,53 @@ namespace ts.server {
|
||||
}));
|
||||
}
|
||||
|
||||
public exit() {
|
||||
getDiagnosticsForProject(delay: number, fileName: string) {
|
||||
let { configFileName, fileNames: fileNamesInProject } = this.getProjectInfo(fileName, true);
|
||||
// No need to analyze lib.d.ts
|
||||
fileNamesInProject = fileNamesInProject.filter((value, index, array) => value.indexOf("lib.d.ts") < 0);
|
||||
|
||||
// Sort the file name list to make the recently touched files come first
|
||||
let highPriorityFiles: string[] = [];
|
||||
let mediumPriorityFiles: string[] = [];
|
||||
let lowPriorityFiles: string[] = [];
|
||||
let veryLowPriorityFiles: string[] = [];
|
||||
let normalizedFileName = ts.normalizePath(fileName);
|
||||
let project = this.projectService.getProjectForFile(normalizedFileName);
|
||||
for (let fileNameInProject of fileNamesInProject) {
|
||||
if (this.getCanonicalFileName(fileNameInProject) == this.getCanonicalFileName(fileName))
|
||||
highPriorityFiles.push(fileNameInProject);
|
||||
else {
|
||||
let info = this.projectService.getScriptInfo(fileNameInProject);
|
||||
if (!info.isOpen) {
|
||||
if (fileNameInProject.indexOf(".d.ts") > 0)
|
||||
veryLowPriorityFiles.push(fileNameInProject);
|
||||
else
|
||||
lowPriorityFiles.push(fileNameInProject);
|
||||
}
|
||||
else
|
||||
mediumPriorityFiles.push(fileNameInProject);
|
||||
}
|
||||
}
|
||||
|
||||
fileNamesInProject = highPriorityFiles.concat(mediumPriorityFiles).concat(lowPriorityFiles).concat(veryLowPriorityFiles);
|
||||
|
||||
if (fileNamesInProject.length > 0) {
|
||||
let checkList = fileNamesInProject.map<PendingErrorCheck>((fileName: string) => {
|
||||
let normalizedFileName = ts.normalizePath(fileName);
|
||||
return { fileName: normalizedFileName, project };
|
||||
});
|
||||
// Project level error analysis runs on background files too, therefore
|
||||
// doesn't require the file to be opened
|
||||
this.updateErrorCheck(checkList, this.changeSeq, (n) => n == this.changeSeq, delay, 200, /*requireOpen*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
getCanonicalFileName(fileName: string) {
|
||||
let name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
return ts.normalizePath(name);
|
||||
}
|
||||
|
||||
exit() {
|
||||
}
|
||||
|
||||
private handlers : Map<(request: protocol.Request) => {response?: any, responseRequired?: boolean}> = {
|
||||
@@ -894,6 +978,10 @@ namespace ts.server {
|
||||
var geterrArgs = <protocol.GeterrRequestArgs>request.arguments;
|
||||
return {response: this.getDiagnostics(geterrArgs.delay, geterrArgs.files), responseRequired: false};
|
||||
},
|
||||
[CommandNames.GeterrForProject]: (request: protocol.Request) => {
|
||||
let { file, delay } = <protocol.GeterrForProjectRequestArgs>request.arguments;
|
||||
return {response: this.getDiagnosticsForProject(delay, file), responseRequired: false};
|
||||
},
|
||||
[CommandNames.Change]: (request: protocol.Request) => {
|
||||
var changeArgs = <protocol.ChangeRequestArgs>request.arguments;
|
||||
this.change(changeArgs.line, changeArgs.offset, changeArgs.endLine, changeArgs.endOffset,
|
||||
@@ -937,6 +1025,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, filesToSearch } = <protocol.DocumentHighlightsRequestArgs>request.arguments;
|
||||
return {response: this.getDocumentHighlights(line, offset, fileName, filesToSearch), 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