Skip to content

Commit 7df14c1

Browse files
committed
Merge pull request #2106 from Microsoft/addNavtoLimit
Add maxResultCount optional field to NavtoRequestArgs. Change
2 parents 67f67dd + 47d265b commit 7df14c1

File tree

5 files changed

+107
-52
lines changed

5 files changed

+107
-52
lines changed

src/server/client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,9 @@ module ts.server {
208208
return response.body[0];
209209
}
210210

211-
getNavigateToItems(searchTerm: string): NavigateToItem[] {
211+
getNavigateToItems(searchValue: string): NavigateToItem[] {
212212
var args: protocol.NavtoRequestArgs = {
213-
searchTerm,
213+
searchValue,
214214
file: this.host.getScriptFileNames()[0]
215215
};
216216

src/server/editorServices.ts

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ module ts.server {
6565
ls: ts.LanguageService = null;
6666
compilationSettings: ts.CompilerOptions;
6767
filenameToScript: ts.Map<ScriptInfo> = {};
68+
roots: ScriptInfo[] = [];
6869

6970
constructor(public host: ServerHost, public project: Project) {
7071
}
@@ -144,7 +145,7 @@ module ts.server {
144145
var scriptInfo = ts.lookUp(this.filenameToScript, info.fileName);
145146
if (!scriptInfo) {
146147
this.filenameToScript[info.fileName] = info;
147-
return info;
148+
this.roots.push(info);
148149
}
149150
}
150151

@@ -286,10 +287,12 @@ module ts.server {
286287
return this.filenameToSourceFile[info.fileName];
287288
}
288289

289-
getSourceFileFromName(filename: string) {
290+
getSourceFileFromName(filename: string, requireOpen?: boolean) {
290291
var info = this.projectService.getScriptInfo(filename);
291292
if (info) {
292-
return this.getSourceFile(info);
293+
if ((!requireOpen) || info.isOpen) {
294+
return this.getSourceFile(info);
295+
}
293296
}
294297
}
295298

@@ -324,7 +327,7 @@ module ts.server {
324327
// add a root file to project
325328
addRoot(info: ScriptInfo) {
326329
info.defaultProject = this;
327-
return this.compilerService.host.addRoot(info);
330+
this.compilerService.host.addRoot(info);
328331
}
329332

330333
filesToString() {
@@ -360,7 +363,7 @@ module ts.server {
360363
}
361364

362365
interface ProjectServiceEventHandler {
363-
(eventName: string, project: Project): void;
366+
(eventName: string, project: Project, fileName: string): void;
364367
}
365368

366369
export class ProjectService {
@@ -392,7 +395,6 @@ module ts.server {
392395
}
393396
}
394397

395-
396398
log(msg: string, type = "Err") {
397399
this.psLogger.msg(msg, type);
398400
}
@@ -423,7 +425,20 @@ module ts.server {
423425
for (var i = 0, len = referencingProjects.length; i < len; i++) {
424426
referencingProjects[i].removeReferencedFile(info);
425427
}
428+
for (var j = 0, flen = this.openFileRoots.length; j < flen; j++) {
429+
var openFile = this.openFileRoots[j];
430+
if (this.eventHandler) {
431+
this.eventHandler("context", openFile.defaultProject, openFile.fileName);
432+
}
433+
}
434+
for (var j = 0, flen = this.openFilesReferenced.length; j < flen; j++) {
435+
var openFile = this.openFilesReferenced[j];
436+
if (this.eventHandler) {
437+
this.eventHandler("context", openFile.defaultProject, openFile.fileName);
438+
}
439+
}
426440
}
441+
427442
this.printProjects();
428443
}
429444

@@ -503,19 +518,52 @@ module ts.server {
503518
info.close();
504519
}
505520

506-
findReferencingProjects(info: ScriptInfo) {
521+
findReferencingProjects(info: ScriptInfo, excludedProject?: Project) {
507522
var referencingProjects: Project[] = [];
508523
info.defaultProject = undefined;
509524
for (var i = 0, len = this.inferredProjects.length; i < len; i++) {
510525
this.inferredProjects[i].updateGraph();
511-
if (this.inferredProjects[i].getSourceFile(info)) {
512-
info.defaultProject = this.inferredProjects[i];
513-
referencingProjects.push(this.inferredProjects[i]);
526+
if (this.inferredProjects[i] != excludedProject) {
527+
if (this.inferredProjects[i].getSourceFile(info)) {
528+
info.defaultProject = this.inferredProjects[i];
529+
referencingProjects.push(this.inferredProjects[i]);
530+
}
514531
}
515532
}
516533
return referencingProjects;
517534
}
518535

536+
updateProjectStructure() {
537+
this.log("updating project structure from ...", "Info");
538+
this.printProjects();
539+
for (var i = 0, len = this.openFilesReferenced.length; i < len; i++) {
540+
var refdFile = this.openFilesReferenced[i];
541+
refdFile.defaultProject.updateGraph();
542+
var sourceFile = refdFile.defaultProject.getSourceFile(refdFile);
543+
if (!sourceFile) {
544+
this.openFilesReferenced = copyListRemovingItem(refdFile, this.openFilesReferenced);
545+
this.addOpenFile(refdFile);
546+
}
547+
}
548+
var openFileRoots: ScriptInfo[] = [];
549+
for (var i = 0, len = this.openFileRoots.length; i < len; i++) {
550+
var rootFile = this.openFileRoots[i];
551+
var rootedProject = rootFile.defaultProject;
552+
var referencingProjects = this.findReferencingProjects(rootFile, rootedProject);
553+
if (referencingProjects.length == 0) {
554+
rootFile.defaultProject = rootedProject;
555+
openFileRoots.push(rootFile);
556+
}
557+
else {
558+
// remove project from inferred projects list
559+
this.inferredProjects = copyListRemovingItem(rootedProject, this.inferredProjects);
560+
this.openFilesReferenced.push(rootFile);
561+
}
562+
}
563+
this.openFileRoots = openFileRoots;
564+
this.printProjects();
565+
}
566+
519567
getScriptInfo(filename: string) {
520568
filename = ts.normalizePath(filename);
521569
return ts.lookUp(this.filenameToScriptInfo, filename);
@@ -621,6 +669,7 @@ module ts.server {
621669
this.psLogger.startGroup();
622670
for (var i = 0, len = this.inferredProjects.length; i < len; i++) {
623671
var project = this.inferredProjects[i];
672+
project.updateGraph();
624673
this.psLogger.info("Project " + i.toString());
625674
this.psLogger.info(project.filesToString());
626675
this.psLogger.info("-----------------------------------------------");

src/server/protocol.d.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,11 @@ declare module ts.server.protocol {
676676
* Search term to navigate to from current location; term can
677677
* be '.*' or an identifier prefix.
678678
*/
679-
searchTerm: string;
679+
searchValue: string;
680+
/**
681+
* Optional limit on the number of items to return.
682+
*/
683+
maxResultCount?: number;
680684
}
681685

682686
/**

src/server/server.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ module ts.server {
8282
private watchedFiles: WatchedFile[] = [];
8383
private nextFileToCheck = 0;
8484
private watchTimer: NodeJS.Timer;
85-
private static fileDeleted = 34;
8685

8786
// average async stat takes about 30 microseconds
8887
// set chunk size to do 30 files in < 1 millisecond
@@ -111,13 +110,7 @@ module ts.server {
111110

112111
fs.stat(watchedFile.fileName,(err, stats) => {
113112
if (err) {
114-
var msg = err.message;
115-
if (err.errno) {
116-
msg += " errno: " + err.errno.toString();
117-
}
118-
if (err.errno == WatchedFileSet.fileDeleted) {
119-
watchedFile.callback(watchedFile.fileName);
120-
}
113+
watchedFile.callback(watchedFile.fileName);
121114
}
122115
else if (watchedFile.mtime.getTime() != stats.mtime.getTime()) {
123116
watchedFile.mtime = WatchedFileSet.getModifiedTime(watchedFile.fileName);

src/server/session.ts

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -52,30 +52,6 @@ module ts.server {
5252
return 1;
5353
}
5454
}
55-
56-
function sortNavItems(items: ts.NavigateToItem[]) {
57-
return items.sort((a, b) => {
58-
if (a.matchKind < b.matchKind) {
59-
return -1;
60-
}
61-
else if (a.matchKind == b.matchKind) {
62-
var lowa = a.name.toLowerCase();
63-
var lowb = b.name.toLowerCase();
64-
if (lowa < lowb) {
65-
return -1;
66-
}
67-
else if (lowa == lowb) {
68-
return 0;
69-
}
70-
else {
71-
return 1;
72-
}
73-
}
74-
else {
75-
return 1;
76-
}
77-
})
78-
}
7955

8056
function formatDiag(fileName: string, project: Project, diag: ts.Diagnostic) {
8157
return {
@@ -138,7 +114,18 @@ module ts.server {
138114
changeSeq = 0;
139115

140116
constructor(private host: ServerHost, private logger: Logger) {
141-
this.projectService = new ProjectService(host, logger);
117+
this.projectService =
118+
new ProjectService(host, logger, (eventName,project,fileName) => {
119+
this.handleEvent(eventName, project, fileName);
120+
});
121+
}
122+
123+
handleEvent(eventName: string, project: Project, fileName: string) {
124+
if (eventName == "context") {
125+
this.projectService.log("got context event, updating diagnostics for" + fileName, "Info");
126+
this.updateErrorCheck([{ fileName, project }], this.changeSeq,
127+
(n) => n == this.changeSeq, 100);
128+
}
142129
}
143130

144131
logError(err: Error, cmd: string) {
@@ -215,6 +202,14 @@ module ts.server {
215202
this.semanticCheck(file, project);
216203
}
217204

205+
updateProjectStructure(seq: number, matchSeq: (seq: number) => boolean, ms = 1500) {
206+
setTimeout(() => {
207+
if (matchSeq(seq)) {
208+
this.projectService.updateProjectStructure();
209+
}
210+
}, ms);
211+
}
212+
218213
updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
219214
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200) {
220215
if (followMs > ms) {
@@ -231,7 +226,7 @@ module ts.server {
231226
var checkOne = () => {
232227
if (matchSeq(seq)) {
233228
var checkSpec = checkList[index++];
234-
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName)) {
229+
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName, true)) {
235230
this.syntacticCheck(checkSpec.fileName, checkSpec.project);
236231
this.immediateId = setImmediate(() => {
237232
this.semanticCheck(checkSpec.fileName, checkSpec.project);
@@ -404,7 +399,7 @@ module ts.server {
404399
var position = compilerService.host.lineColToPosition(file, line, col);
405400
var quickInfo = compilerService.languageService.getQuickInfoAtPosition(file, position);
406401
if (!quickInfo) {
407-
throw Errors.NoContent;
402+
return undefined;
408403
}
409404

410405
var displayString = ts.displayPartsToString(quickInfo.displayParts);
@@ -494,7 +489,7 @@ module ts.server {
494489
var file = ts.normalizePath(fileName);
495490
var project = this.projectService.getProjectForFile(file);
496491
if (!project) {
497-
throw Errors.NoProject;
492+
return undefined;
498493
}
499494

500495
var compilerService = project.compilerService;
@@ -559,6 +554,10 @@ module ts.server {
559554
compilerService.host.editScript(file, start, end, insertString);
560555
this.changeSeq++;
561556
}
557+
// update project structure on idle commented out
558+
// until we can have the host return only the root files
559+
// from getScriptFileNames()
560+
//this.updateProjectStructure(this.changeSeq, (n) => n == this.changeSeq);
562561
}
563562
}
564563

@@ -625,15 +624,15 @@ module ts.server {
625624
return this.decorateNavigationBarItem(project, fileName, items);
626625
}
627626

628-
getNavigateToItems(searchTerm: string, fileName: string): protocol.NavtoItem[] {
627+
getNavigateToItems(searchValue: string, fileName: string, maxResultCount?: number): protocol.NavtoItem[] {
629628
var file = ts.normalizePath(fileName);
630629
var project = this.projectService.getProjectForFile(file);
631630
if (!project) {
632631
throw Errors.NoProject;
633632
}
634633

635634
var compilerService = project.compilerService;
636-
var navItems = sortNavItems(compilerService.languageService.getNavigateToItems(searchTerm));
635+
var navItems = compilerService.languageService.getNavigateToItems(searchValue, maxResultCount);
637636
if (!navItems) {
638637
throw Errors.NoContent;
639638
}
@@ -690,6 +689,7 @@ module ts.server {
690689
try {
691690
var request = <protocol.Request>JSON.parse(message);
692691
var response: any;
692+
var errorMessage: string;
693693
switch (request.command) {
694694
case CommandNames.Definition: {
695695
var defArgs = <protocol.FileLocationRequestArgs>request.arguments;
@@ -714,6 +714,9 @@ module ts.server {
714714
case CommandNames.Quickinfo: {
715715
var quickinfoArgs = <protocol.FileLocationRequestArgs>request.arguments;
716716
response = this.getQuickInfo(quickinfoArgs.line, quickinfoArgs.col, quickinfoArgs.file);
717+
if (!response) {
718+
errorMessage = "No info at this location";
719+
}
717720
break;
718721
}
719722
case CommandNames.Format: {
@@ -729,6 +732,9 @@ module ts.server {
729732
case CommandNames.Completions: {
730733
var completionsArgs = <protocol.CompletionsRequestArgs>request.arguments;
731734
response = this.getCompletions(request.arguments.line, request.arguments.col, completionsArgs.prefix, request.arguments.file);
735+
if (!response) {
736+
errorMessage = "No completions at this location";
737+
}
732738
break;
733739
}
734740
case CommandNames.CompletionDetails: {
@@ -765,7 +771,7 @@ module ts.server {
765771
}
766772
case CommandNames.Navto: {
767773
var navtoArgs = <protocol.NavtoRequestArgs>request.arguments;
768-
response = this.getNavigateToItems(navtoArgs.searchTerm, navtoArgs.file);
774+
response = this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount);
769775
break;
770776
}
771777
case CommandNames.Brace: {
@@ -788,6 +794,9 @@ module ts.server {
788794
if (response) {
789795
this.output(response, request.command, request.seq);
790796
}
797+
else if (errorMessage) {
798+
this.output(undefined, request.command, request.seq, errorMessage);
799+
}
791800

792801
} catch (err) {
793802
if (err instanceof OperationCanceledException) {

0 commit comments

Comments
 (0)