mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-22 02:35:48 -05:00
Merge pull request #2106 from Microsoft/addNavtoLimit
Add maxResultCount optional field to NavtoRequestArgs. Change
This commit is contained in:
@@ -208,9 +208,9 @@ module ts.server {
|
||||
return response.body[0];
|
||||
}
|
||||
|
||||
getNavigateToItems(searchTerm: string): NavigateToItem[] {
|
||||
getNavigateToItems(searchValue: string): NavigateToItem[] {
|
||||
var args: protocol.NavtoRequestArgs = {
|
||||
searchTerm,
|
||||
searchValue,
|
||||
file: this.host.getScriptFileNames()[0]
|
||||
};
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ module ts.server {
|
||||
ls: ts.LanguageService = null;
|
||||
compilationSettings: ts.CompilerOptions;
|
||||
filenameToScript: ts.Map<ScriptInfo> = {};
|
||||
roots: ScriptInfo[] = [];
|
||||
|
||||
constructor(public host: ServerHost, public project: Project) {
|
||||
}
|
||||
@@ -144,7 +145,7 @@ module ts.server {
|
||||
var scriptInfo = ts.lookUp(this.filenameToScript, info.fileName);
|
||||
if (!scriptInfo) {
|
||||
this.filenameToScript[info.fileName] = info;
|
||||
return info;
|
||||
this.roots.push(info);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,10 +287,12 @@ module ts.server {
|
||||
return this.filenameToSourceFile[info.fileName];
|
||||
}
|
||||
|
||||
getSourceFileFromName(filename: string) {
|
||||
getSourceFileFromName(filename: string, requireOpen?: boolean) {
|
||||
var info = this.projectService.getScriptInfo(filename);
|
||||
if (info) {
|
||||
return this.getSourceFile(info);
|
||||
if ((!requireOpen) || info.isOpen) {
|
||||
return this.getSourceFile(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,7 +327,7 @@ module ts.server {
|
||||
// add a root file to project
|
||||
addRoot(info: ScriptInfo) {
|
||||
info.defaultProject = this;
|
||||
return this.compilerService.host.addRoot(info);
|
||||
this.compilerService.host.addRoot(info);
|
||||
}
|
||||
|
||||
filesToString() {
|
||||
@@ -360,7 +363,7 @@ module ts.server {
|
||||
}
|
||||
|
||||
interface ProjectServiceEventHandler {
|
||||
(eventName: string, project: Project): void;
|
||||
(eventName: string, project: Project, fileName: string): void;
|
||||
}
|
||||
|
||||
export class ProjectService {
|
||||
@@ -392,7 +395,6 @@ module ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
log(msg: string, type = "Err") {
|
||||
this.psLogger.msg(msg, type);
|
||||
}
|
||||
@@ -423,7 +425,20 @@ module ts.server {
|
||||
for (var i = 0, len = referencingProjects.length; i < len; i++) {
|
||||
referencingProjects[i].removeReferencedFile(info);
|
||||
}
|
||||
for (var j = 0, flen = this.openFileRoots.length; j < flen; j++) {
|
||||
var openFile = this.openFileRoots[j];
|
||||
if (this.eventHandler) {
|
||||
this.eventHandler("context", openFile.defaultProject, openFile.fileName);
|
||||
}
|
||||
}
|
||||
for (var j = 0, flen = this.openFilesReferenced.length; j < flen; j++) {
|
||||
var openFile = this.openFilesReferenced[j];
|
||||
if (this.eventHandler) {
|
||||
this.eventHandler("context", openFile.defaultProject, openFile.fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.printProjects();
|
||||
}
|
||||
|
||||
@@ -503,19 +518,52 @@ module ts.server {
|
||||
info.close();
|
||||
}
|
||||
|
||||
findReferencingProjects(info: ScriptInfo) {
|
||||
findReferencingProjects(info: ScriptInfo, excludedProject?: Project) {
|
||||
var referencingProjects: Project[] = [];
|
||||
info.defaultProject = undefined;
|
||||
for (var i = 0, len = this.inferredProjects.length; i < len; i++) {
|
||||
this.inferredProjects[i].updateGraph();
|
||||
if (this.inferredProjects[i].getSourceFile(info)) {
|
||||
info.defaultProject = this.inferredProjects[i];
|
||||
referencingProjects.push(this.inferredProjects[i]);
|
||||
if (this.inferredProjects[i] != excludedProject) {
|
||||
if (this.inferredProjects[i].getSourceFile(info)) {
|
||||
info.defaultProject = this.inferredProjects[i];
|
||||
referencingProjects.push(this.inferredProjects[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return referencingProjects;
|
||||
}
|
||||
|
||||
updateProjectStructure() {
|
||||
this.log("updating project structure from ...", "Info");
|
||||
this.printProjects();
|
||||
for (var i = 0, len = this.openFilesReferenced.length; i < len; i++) {
|
||||
var refdFile = this.openFilesReferenced[i];
|
||||
refdFile.defaultProject.updateGraph();
|
||||
var sourceFile = refdFile.defaultProject.getSourceFile(refdFile);
|
||||
if (!sourceFile) {
|
||||
this.openFilesReferenced = copyListRemovingItem(refdFile, this.openFilesReferenced);
|
||||
this.addOpenFile(refdFile);
|
||||
}
|
||||
}
|
||||
var openFileRoots: ScriptInfo[] = [];
|
||||
for (var i = 0, len = this.openFileRoots.length; i < len; i++) {
|
||||
var rootFile = this.openFileRoots[i];
|
||||
var rootedProject = rootFile.defaultProject;
|
||||
var referencingProjects = this.findReferencingProjects(rootFile, rootedProject);
|
||||
if (referencingProjects.length == 0) {
|
||||
rootFile.defaultProject = rootedProject;
|
||||
openFileRoots.push(rootFile);
|
||||
}
|
||||
else {
|
||||
// remove project from inferred projects list
|
||||
this.inferredProjects = copyListRemovingItem(rootedProject, this.inferredProjects);
|
||||
this.openFilesReferenced.push(rootFile);
|
||||
}
|
||||
}
|
||||
this.openFileRoots = openFileRoots;
|
||||
this.printProjects();
|
||||
}
|
||||
|
||||
getScriptInfo(filename: string) {
|
||||
filename = ts.normalizePath(filename);
|
||||
return ts.lookUp(this.filenameToScriptInfo, filename);
|
||||
@@ -621,6 +669,7 @@ module ts.server {
|
||||
this.psLogger.startGroup();
|
||||
for (var i = 0, len = this.inferredProjects.length; i < len; i++) {
|
||||
var project = this.inferredProjects[i];
|
||||
project.updateGraph();
|
||||
this.psLogger.info("Project " + i.toString());
|
||||
this.psLogger.info(project.filesToString());
|
||||
this.psLogger.info("-----------------------------------------------");
|
||||
|
||||
6
src/server/protocol.d.ts
vendored
6
src/server/protocol.d.ts
vendored
@@ -676,7 +676,11 @@ declare module ts.server.protocol {
|
||||
* Search term to navigate to from current location; term can
|
||||
* be '.*' or an identifier prefix.
|
||||
*/
|
||||
searchTerm: string;
|
||||
searchValue: string;
|
||||
/**
|
||||
* Optional limit on the number of items to return.
|
||||
*/
|
||||
maxResultCount?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -82,7 +82,6 @@ module ts.server {
|
||||
private watchedFiles: WatchedFile[] = [];
|
||||
private nextFileToCheck = 0;
|
||||
private watchTimer: NodeJS.Timer;
|
||||
private static fileDeleted = 34;
|
||||
|
||||
// average async stat takes about 30 microseconds
|
||||
// set chunk size to do 30 files in < 1 millisecond
|
||||
@@ -111,13 +110,7 @@ module ts.server {
|
||||
|
||||
fs.stat(watchedFile.fileName,(err, stats) => {
|
||||
if (err) {
|
||||
var msg = err.message;
|
||||
if (err.errno) {
|
||||
msg += " errno: " + err.errno.toString();
|
||||
}
|
||||
if (err.errno == WatchedFileSet.fileDeleted) {
|
||||
watchedFile.callback(watchedFile.fileName);
|
||||
}
|
||||
watchedFile.callback(watchedFile.fileName);
|
||||
}
|
||||
else if (watchedFile.mtime.getTime() != stats.mtime.getTime()) {
|
||||
watchedFile.mtime = WatchedFileSet.getModifiedTime(watchedFile.fileName);
|
||||
|
||||
@@ -52,30 +52,6 @@ module ts.server {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
function sortNavItems(items: ts.NavigateToItem[]) {
|
||||
return items.sort((a, b) => {
|
||||
if (a.matchKind < b.matchKind) {
|
||||
return -1;
|
||||
}
|
||||
else if (a.matchKind == b.matchKind) {
|
||||
var lowa = a.name.toLowerCase();
|
||||
var lowb = b.name.toLowerCase();
|
||||
if (lowa < lowb) {
|
||||
return -1;
|
||||
}
|
||||
else if (lowa == lowb) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function formatDiag(fileName: string, project: Project, diag: ts.Diagnostic) {
|
||||
return {
|
||||
@@ -138,7 +114,18 @@ module ts.server {
|
||||
changeSeq = 0;
|
||||
|
||||
constructor(private host: ServerHost, private logger: Logger) {
|
||||
this.projectService = new ProjectService(host, logger);
|
||||
this.projectService =
|
||||
new ProjectService(host, logger, (eventName,project,fileName) => {
|
||||
this.handleEvent(eventName, project, fileName);
|
||||
});
|
||||
}
|
||||
|
||||
handleEvent(eventName: string, project: Project, fileName: string) {
|
||||
if (eventName == "context") {
|
||||
this.projectService.log("got context event, updating diagnostics for" + fileName, "Info");
|
||||
this.updateErrorCheck([{ fileName, project }], this.changeSeq,
|
||||
(n) => n == this.changeSeq, 100);
|
||||
}
|
||||
}
|
||||
|
||||
logError(err: Error, cmd: string) {
|
||||
@@ -215,6 +202,14 @@ module ts.server {
|
||||
this.semanticCheck(file, project);
|
||||
}
|
||||
|
||||
updateProjectStructure(seq: number, matchSeq: (seq: number) => boolean, ms = 1500) {
|
||||
setTimeout(() => {
|
||||
if (matchSeq(seq)) {
|
||||
this.projectService.updateProjectStructure();
|
||||
}
|
||||
}, ms);
|
||||
}
|
||||
|
||||
updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
|
||||
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200) {
|
||||
if (followMs > ms) {
|
||||
@@ -231,7 +226,7 @@ module ts.server {
|
||||
var checkOne = () => {
|
||||
if (matchSeq(seq)) {
|
||||
var checkSpec = checkList[index++];
|
||||
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName)) {
|
||||
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName, true)) {
|
||||
this.syntacticCheck(checkSpec.fileName, checkSpec.project);
|
||||
this.immediateId = setImmediate(() => {
|
||||
this.semanticCheck(checkSpec.fileName, checkSpec.project);
|
||||
@@ -404,7 +399,7 @@ module ts.server {
|
||||
var position = compilerService.host.lineColToPosition(file, line, col);
|
||||
var quickInfo = compilerService.languageService.getQuickInfoAtPosition(file, position);
|
||||
if (!quickInfo) {
|
||||
throw Errors.NoContent;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var displayString = ts.displayPartsToString(quickInfo.displayParts);
|
||||
@@ -494,7 +489,7 @@ module ts.server {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
throw Errors.NoProject;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var compilerService = project.compilerService;
|
||||
@@ -559,6 +554,10 @@ module ts.server {
|
||||
compilerService.host.editScript(file, start, end, insertString);
|
||||
this.changeSeq++;
|
||||
}
|
||||
// update project structure on idle commented out
|
||||
// until we can have the host return only the root files
|
||||
// from getScriptFileNames()
|
||||
//this.updateProjectStructure(this.changeSeq, (n) => n == this.changeSeq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -625,7 +624,7 @@ module ts.server {
|
||||
return this.decorateNavigationBarItem(project, fileName, items);
|
||||
}
|
||||
|
||||
getNavigateToItems(searchTerm: string, fileName: string): protocol.NavtoItem[] {
|
||||
getNavigateToItems(searchValue: string, fileName: string, maxResultCount?: number): protocol.NavtoItem[] {
|
||||
var file = ts.normalizePath(fileName);
|
||||
var project = this.projectService.getProjectForFile(file);
|
||||
if (!project) {
|
||||
@@ -633,7 +632,7 @@ module ts.server {
|
||||
}
|
||||
|
||||
var compilerService = project.compilerService;
|
||||
var navItems = sortNavItems(compilerService.languageService.getNavigateToItems(searchTerm));
|
||||
var navItems = compilerService.languageService.getNavigateToItems(searchValue, maxResultCount);
|
||||
if (!navItems) {
|
||||
throw Errors.NoContent;
|
||||
}
|
||||
@@ -690,6 +689,7 @@ module ts.server {
|
||||
try {
|
||||
var request = <protocol.Request>JSON.parse(message);
|
||||
var response: any;
|
||||
var errorMessage: string;
|
||||
switch (request.command) {
|
||||
case CommandNames.Definition: {
|
||||
var defArgs = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
@@ -714,6 +714,9 @@ module ts.server {
|
||||
case CommandNames.Quickinfo: {
|
||||
var quickinfoArgs = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
response = this.getQuickInfo(quickinfoArgs.line, quickinfoArgs.col, quickinfoArgs.file);
|
||||
if (!response) {
|
||||
errorMessage = "No info at this location";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CommandNames.Format: {
|
||||
@@ -729,6 +732,9 @@ module ts.server {
|
||||
case CommandNames.Completions: {
|
||||
var completionsArgs = <protocol.CompletionsRequestArgs>request.arguments;
|
||||
response = this.getCompletions(request.arguments.line, request.arguments.col, completionsArgs.prefix, request.arguments.file);
|
||||
if (!response) {
|
||||
errorMessage = "No completions at this location";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CommandNames.CompletionDetails: {
|
||||
@@ -765,7 +771,7 @@ module ts.server {
|
||||
}
|
||||
case CommandNames.Navto: {
|
||||
var navtoArgs = <protocol.NavtoRequestArgs>request.arguments;
|
||||
response = this.getNavigateToItems(navtoArgs.searchTerm, navtoArgs.file);
|
||||
response = this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount);
|
||||
break;
|
||||
}
|
||||
case CommandNames.Brace: {
|
||||
@@ -788,6 +794,9 @@ module ts.server {
|
||||
if (response) {
|
||||
this.output(response, request.command, request.seq);
|
||||
}
|
||||
else if (errorMessage) {
|
||||
this.output(undefined, request.command, request.seq, errorMessage);
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
if (err instanceof OperationCanceledException) {
|
||||
|
||||
Reference in New Issue
Block a user