Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1066)

Side by Side Diff: pkg/analysis_server/lib/src/analysis_server.dart

Issue 569743003: update error handling to send response with stack trace (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: merge Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/analysis_server/doc/api.html ('k') | pkg/analysis_server/lib/src/constants.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analysis.server; 5 library analysis.server;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:analyzer/file_system/file_system.dart'; 10 import 'package:analyzer/file_system/file_system.dart';
(...skipping 19 matching lines...) Expand all
30 30
31 31
32 class ServerContextManager extends ContextManager { 32 class ServerContextManager extends ContextManager {
33 final AnalysisServer analysisServer; 33 final AnalysisServer analysisServer;
34 34
35 /** 35 /**
36 * The default options used to create new analysis contexts. 36 * The default options used to create new analysis contexts.
37 */ 37 */
38 AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl(); 38 AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
39 39
40 ServerContextManager( 40 ServerContextManager(this.analysisServer, ResourceProvider resourceProvider,
41 this.analysisServer, ResourceProvider resourceProvider,
42 PackageMapProvider packageMapProvider) 41 PackageMapProvider packageMapProvider)
43 : super(resourceProvider, packageMapProvider); 42 : super(resourceProvider, packageMapProvider);
44 43
45 @override 44 @override
46 void addContext(Folder folder, Map<String, List<Folder>> packageMap) { 45 void addContext(Folder folder, Map<String, List<Folder>> packageMap) {
47 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext(); 46 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
48 analysisServer.folderMap[folder] = context; 47 analysisServer.folderMap[folder] = context;
49 context.sourceFactory = _createSourceFactory(packageMap); 48 context.sourceFactory = _createSourceFactory(packageMap);
50 context.analysisOptions = new AnalysisOptionsImpl.con1(defaultOptions); 49 context.analysisOptions = new AnalysisOptionsImpl.con1(defaultOptions);
51 analysisServer.schedulePerformAnalysisOperation(context); 50 analysisServer.schedulePerformAnalysisOperation(context);
(...skipping 13 matching lines...) Expand all
65 AnalysisContext context = analysisServer.folderMap.remove(folder); 64 AnalysisContext context = analysisServer.folderMap.remove(folder);
66 if (analysisServer.index != null) { 65 if (analysisServer.index != null) {
67 analysisServer.index.removeContext(context); 66 analysisServer.index.removeContext(context);
68 } 67 }
69 analysisServer.sendContextAnalysisDoneNotifications( 68 analysisServer.sendContextAnalysisDoneNotifications(
70 context, 69 context,
71 AnalysisDoneReason.CONTEXT_REMOVED); 70 AnalysisDoneReason.CONTEXT_REMOVED);
72 } 71 }
73 72
74 @override 73 @override
75 void updateContextPackageMap(Folder contextFolder, 74 void updateContextPackageMap(Folder contextFolder, Map<String,
76 Map<String, List<Folder>> packageMap) { 75 List<Folder>> packageMap) {
77 AnalysisContext context = analysisServer.folderMap[contextFolder]; 76 AnalysisContext context = analysisServer.folderMap[contextFolder];
78 context.sourceFactory = _createSourceFactory(packageMap); 77 context.sourceFactory = _createSourceFactory(packageMap);
79 analysisServer.schedulePerformAnalysisOperation(context); 78 analysisServer.schedulePerformAnalysisOperation(context);
80 } 79 }
81 80
82 /** 81 /**
83 * Set up a [SourceFactory] that resolves packages using the given 82 * Set up a [SourceFactory] that resolves packages using the given
84 * [packageMap]. 83 * [packageMap].
85 */ 84 */
86 SourceFactory _createSourceFactory(Map<String, List<Folder>> packageMap) { 85 SourceFactory _createSourceFactory(Map<String, List<Folder>> packageMap) {
87 List<UriResolver> resolvers = <UriResolver>[ 86 List<UriResolver> resolvers = <UriResolver>[
88 new DartUriResolver(analysisServer.defaultSdk), 87 new DartUriResolver(analysisServer.defaultSdk),
89 new ResourceUriResolver(resourceProvider), 88 new ResourceUriResolver(resourceProvider),
90 new PackageMapUriResolver(resourceProvider, packageMap) 89 new PackageMapUriResolver(resourceProvider, packageMap)];
91 ];
92 return new SourceFactory(resolvers); 90 return new SourceFactory(resolvers);
93 } 91 }
94 } 92 }
95 93
96 94
97 /** 95 /**
98 * Enum representing reasons why analysis might be done for a given file. 96 * Enum representing reasons why analysis might be done for a given file.
99 */ 97 */
100 class AnalysisDoneReason { 98 class AnalysisDoneReason {
101 /** 99 /**
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 * If [rethrowExceptions] is true, then any exceptions thrown by analysis are 225 * If [rethrowExceptions] is true, then any exceptions thrown by analysis are
228 * propagated up the call stack. The default is true to allow analysis 226 * propagated up the call stack. The default is true to allow analysis
229 * exceptions to show up in unit tests, but it should be set to false when 227 * exceptions to show up in unit tests, but it should be set to false when
230 * running a full analysis server. 228 * running a full analysis server.
231 */ 229 */
232 AnalysisServer(this.channel, this.resourceProvider, 230 AnalysisServer(this.channel, this.resourceProvider,
233 PackageMapProvider packageMapProvider, this.index, this.defaultSdk, 231 PackageMapProvider packageMapProvider, this.index, this.defaultSdk,
234 {this.rethrowExceptions: true}) { 232 {this.rethrowExceptions: true}) {
235 searchEngine = createSearchEngine(index); 233 searchEngine = createSearchEngine(index);
236 operationQueue = new ServerOperationQueue(this); 234 operationQueue = new ServerOperationQueue(this);
237 contextDirectoryManager = new ServerContextManager( 235 contextDirectoryManager =
238 this, resourceProvider, packageMapProvider); 236 new ServerContextManager(this, resourceProvider, packageMapProvider);
239 AnalysisEngine.instance.logger = new AnalysisLogger(); 237 AnalysisEngine.instance.logger = new AnalysisLogger();
240 running = true; 238 running = true;
241 Notification notification = new ServerConnectedParams().toNotification(); 239 Notification notification = new ServerConnectedParams().toNotification();
242 channel.sendNotification(notification); 240 channel.sendNotification(notification);
243 channel.listen(handleRequest, onDone: done, onError: error); 241 channel.listen(handleRequest, onDone: done, onError: error);
244 } 242 }
245 243
246 /** 244 /**
247 * Schedules execution of the given [ServerOperation]. 245 * Schedules execution of the given [ServerOperation].
248 */ 246 */
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 if (sourceList == null) { 289 if (sourceList == null) {
292 sourceList = <Source>[]; 290 sourceList = <Source>[];
293 sourceMap[analysisContext] = sourceList; 291 sourceMap[analysisContext] = sourceList;
294 } 292 }
295 sourceList.add(getSource(file)); 293 sourceList.add(getSource(file));
296 } 294 }
297 }); 295 });
298 if (unanalyzed.isNotEmpty) { 296 if (unanalyzed.isNotEmpty) {
299 StringBuffer buffer = new StringBuffer(); 297 StringBuffer buffer = new StringBuffer();
300 buffer.writeAll(unanalyzed, ', '); 298 buffer.writeAll(unanalyzed, ', ');
301 throw new RequestFailure(new Response.unanalyzedPriorityFiles(request, 299 throw new RequestFailure(
302 buffer.toString())); 300 new Response.unanalyzedPriorityFiles(request, buffer.toString()));
303 } 301 }
304 folderMap.forEach((Folder folder, AnalysisContext context) { 302 folderMap.forEach((Folder folder, AnalysisContext context) {
305 List<Source> sourceList = sourceMap[context]; 303 List<Source> sourceList = sourceMap[context];
306 if (sourceList == null) { 304 if (sourceList == null) {
307 sourceList = Source.EMPTY_ARRAY; 305 sourceList = Source.EMPTY_ARRAY;
308 } 306 }
309 context.analysisPriorityOrder = sourceList; 307 context.analysisPriorityOrder = sourceList;
310 }); 308 });
311 } 309 }
312 310
313 /** 311 /**
314 * Use the given updaters to update the values of the options in every 312 * Use the given updaters to update the values of the options in every
315 * existing analysis context. 313 * existing analysis context.
316 */ 314 */
317 void updateOptions(List<OptionUpdater> optionUpdaters) { 315 void updateOptions(List<OptionUpdater> optionUpdaters) {
318 // 316 //
319 // Update existing contexts. 317 // Update existing contexts.
320 // 318 //
321 folderMap.forEach((Folder folder, AnalysisContext context) { 319 folderMap.forEach((Folder folder, AnalysisContext context) {
322 AnalysisOptionsImpl options = new AnalysisOptionsImpl.con1(context.analysi sOptions); 320 AnalysisOptionsImpl options =
321 new AnalysisOptionsImpl.con1(context.analysisOptions);
323 optionUpdaters.forEach((OptionUpdater optionUpdater) { 322 optionUpdaters.forEach((OptionUpdater optionUpdater) {
324 optionUpdater(options); 323 optionUpdater(options);
325 }); 324 });
326 context.analysisOptions = options; 325 context.analysisOptions = options;
327 }); 326 });
328 // 327 //
329 // Update the defaults used to create new contexts. 328 // Update the defaults used to create new contexts.
330 // 329 //
331 AnalysisOptionsImpl options = contextDirectoryManager.defaultOptions; 330 AnalysisOptionsImpl options = contextDirectoryManager.defaultOptions;
332 optionUpdaters.forEach((OptionUpdater optionUpdater) { 331 optionUpdaters.forEach((OptionUpdater optionUpdater) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 return; 397 return;
399 } 398 }
400 if (response != null) { 399 if (response != null) {
401 channel.sendResponse(response); 400 channel.sendResponse(response);
402 return; 401 return;
403 } 402 }
404 } on RequestFailure catch (exception) { 403 } on RequestFailure catch (exception) {
405 channel.sendResponse(exception.response); 404 channel.sendResponse(exception.response);
406 return; 405 return;
407 } catch (exception, stackTrace) { 406 } catch (exception, stackTrace) {
408 _sendServerErrorNotification(exception, stackTrace); 407 RequestError error = new RequestError(
409 RequestError error = 408 RequestErrorCode.SERVER_ERROR,
410 new RequestError(RequestErrorCode.SERVER_ERROR, 'Server Error'); 409 exception);
410 if (stackTrace != null) {
411 error.stackTrace = stackTrace.toString();
412 }
411 Response response = new Response(request.id, error: error); 413 Response response = new Response(request.id, error: error);
412 channel.sendResponse(response); 414 channel.sendResponse(response);
413 return; 415 return;
414 } 416 }
415 } 417 }
416 channel.sendResponse(new Response.unknownRequest(request)); 418 channel.sendResponse(new Response.unknownRequest(request));
417 }, onError: _sendServerErrorNotification); 419 }, onError: _sendServerErrorNotification);
418 } 420 }
419 421
420 /** 422 /**
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 if (!serverServices.contains(ServerService.STATUS)) { 515 if (!serverServices.contains(ServerService.STATUS)) {
514 return; 516 return;
515 } 517 }
516 // Only send status when it changes 518 // Only send status when it changes
517 bool isAnalyzing = operation != null; 519 bool isAnalyzing = operation != null;
518 if (statusAnalyzing == isAnalyzing) { 520 if (statusAnalyzing == isAnalyzing) {
519 return; 521 return;
520 } 522 }
521 statusAnalyzing = isAnalyzing; 523 statusAnalyzing = isAnalyzing;
522 AnalysisStatus analysis = new AnalysisStatus(isAnalyzing); 524 AnalysisStatus analysis = new AnalysisStatus(isAnalyzing);
523 channel.sendNotification(new ServerStatusParams( 525 channel.sendNotification(
524 analysis: analysis).toNotification()); 526 new ServerStatusParams(analysis: analysis).toNotification());
525 } 527 }
526 528
527 /** 529 /**
528 * Implementation for `analysis.setAnalysisRoots`. 530 * Implementation for `analysis.setAnalysisRoots`.
529 * 531 *
530 * TODO(scheglov) implement complete projects/contexts semantics. 532 * TODO(scheglov) implement complete projects/contexts semantics.
531 * 533 *
532 * The current implementation is intentionally simplified and expected 534 * The current implementation is intentionally simplified and expected
533 * that only folders are given each given folder corresponds to the exactly 535 * that only folders are given each given folder corresponds to the exactly
534 * one context. 536 * one context.
535 * 537 *
536 * So, we can start working in parallel on adding services and improving 538 * So, we can start working in parallel on adding services and improving
537 * projects/contexts support. 539 * projects/contexts support.
538 */ 540 */
539 void setAnalysisRoots(String requestId, 541 void setAnalysisRoots(String requestId, List<String> includedPaths,
540 List<String> includedPaths, 542 List<String> excludedPaths) {
541 List<String> excludedPaths) {
542 try { 543 try {
543 contextDirectoryManager.setRoots(includedPaths, excludedPaths); 544 contextDirectoryManager.setRoots(includedPaths, excludedPaths);
544 } on UnimplementedError catch (e) { 545 } on UnimplementedError catch (e) {
545 throw new RequestFailure( 546 throw new RequestFailure(
546 new Response.unsupportedFeature( 547 new Response.unsupportedFeature(requestId, e.message));
547 requestId, e.message));
548 } 548 }
549 } 549 }
550 550
551 /** 551 /**
552 * Implementation for `analysis.updateContent`. 552 * Implementation for `analysis.updateContent`.
553 */ 553 */
554 void updateContent(String id, Map<String, dynamic> changes) { 554 void updateContent(String id, Map<String, dynamic> changes) {
555 changes.forEach((file, change) { 555 changes.forEach((file, change) {
556 AnalysisContext analysisContext = getAnalysisContext(file); 556 AnalysisContext analysisContext = getAnalysisContext(file);
557 // TODO(paulberry): handle the case where a file is referred to by more 557 // TODO(paulberry): handle the case where a file is referred to by more
558 // than one context (e.g package A depends on package B using a local 558 // than one context (e.g package A depends on package B using a local
559 // path, user has both packages open for editing in separate contexts, 559 // path, user has both packages open for editing in separate contexts,
560 // and user modifies a file in package B). 560 // and user modifies a file in package B).
561 if (analysisContext != null) { 561 if (analysisContext != null) {
562 Source source = getSource(file); 562 Source source = getSource(file);
563 if (change is AddContentOverlay) { 563 if (change is AddContentOverlay) {
564 analysisContext.setContents(source, change.content); 564 analysisContext.setContents(source, change.content);
565 } else if (change is ChangeContentOverlay) { 565 } else if (change is ChangeContentOverlay) {
566 // TODO(paulberry): an error should be generated if source is not 566 // TODO(paulberry): an error should be generated if source is not
567 // currently in the content cache. 567 // currently in the content cache.
568 TimestampedData<String> oldContents = analysisContext.getContents( 568 TimestampedData<String> oldContents =
569 source); 569 analysisContext.getContents(source);
570 String newContents; 570 String newContents;
571 try { 571 try {
572 newContents = SourceEdit.applySequence(oldContents.data, 572 newContents =
573 change.edits); 573 SourceEdit.applySequence(oldContents.data, change.edits);
574 } on RangeError { 574 } on RangeError {
575 throw new RequestFailure(new Response(id, error: new RequestError( 575 throw new RequestFailure(
576 RequestErrorCode.INVALID_OVERLAY_CHANGE, 576 new Response(
577 'Invalid overlay change'))); 577 id,
578 error: new RequestError(
579 RequestErrorCode.INVALID_OVERLAY_CHANGE,
580 'Invalid overlay change')));
578 } 581 }
579 // TODO(paulberry): to aid in incremental processing it would be 582 // TODO(paulberry): to aid in incremental processing it would be
580 // better to use setChangedContents. 583 // better to use setChangedContents.
581 analysisContext.setContents(source, newContents); 584 analysisContext.setContents(source, newContents);
582 } else if (change is RemoveContentOverlay) { 585 } else if (change is RemoveContentOverlay) {
583 analysisContext.setContents(source, null); 586 analysisContext.setContents(source, null);
584 } else { 587 } else {
585 // Protocol parsing should have ensured that we never get here. 588 // Protocol parsing should have ensured that we never get here.
586 throw new AnalysisException('Illegal change type'); 589 throw new AnalysisException('Illegal change type');
587 } 590 }
588 schedulePerformAnalysisOperation(analysisContext); 591 schedulePerformAnalysisOperation(analysisContext);
589 } 592 }
590 }); 593 });
591 } 594 }
592 595
593 /** 596 /**
594 * Implementation for `analysis.setSubscriptions`. 597 * Implementation for `analysis.setSubscriptions`.
595 */ 598 */
596 void setAnalysisSubscriptions(Map<AnalysisService, Set<String>> subscriptions) { 599 void setAnalysisSubscriptions(Map<AnalysisService,
600 Set<String>> subscriptions) {
597 // send notifications for already analyzed sources 601 // send notifications for already analyzed sources
598 subscriptions.forEach((service, Set<String> newFiles) { 602 subscriptions.forEach((service, Set<String> newFiles) {
599 Set<String> oldFiles = analysisServices[service]; 603 Set<String> oldFiles = analysisServices[service];
600 Set<String> todoFiles = oldFiles != null ? newFiles.difference(oldFiles) : newFiles; 604 Set<String> todoFiles =
605 oldFiles != null ? newFiles.difference(oldFiles) : newFiles;
601 for (String file in todoFiles) { 606 for (String file in todoFiles) {
602 Source source = getSource(file); 607 Source source = getSource(file);
603 // prepare context 608 // prepare context
604 AnalysisContext context = getAnalysisContext(file); 609 AnalysisContext context = getAnalysisContext(file);
605 if (context == null) { 610 if (context == null) {
606 continue; 611 continue;
607 } 612 }
608 // Dart unit notifications. 613 // Dart unit notifications.
609 if (AnalysisEngine.isDartFileName(file)) { 614 if (AnalysisEngine.isDartFileName(file)) {
610 CompilationUnit dartUnit = getResolvedCompilationUnitToResendNotificat ion(file); 615 CompilationUnit dartUnit =
616 getResolvedCompilationUnitToResendNotification(file);
611 if (dartUnit != null) { 617 if (dartUnit != null) {
612 switch (service) { 618 switch (service) {
613 case AnalysisService.HIGHLIGHTS: 619 case AnalysisService.HIGHLIGHTS:
614 sendAnalysisNotificationHighlights(this, file, dartUnit); 620 sendAnalysisNotificationHighlights(this, file, dartUnit);
615 break; 621 break;
616 case AnalysisService.NAVIGATION: 622 case AnalysisService.NAVIGATION:
617 // TODO(scheglov) consider support for one unit in 2+ libraries 623 // TODO(scheglov) consider support for one unit in 2+ libraries
618 sendAnalysisNotificationNavigation(this, file, dartUnit); 624 sendAnalysisNotificationNavigation(this, file, dartUnit);
619 break; 625 break;
620 case AnalysisService.OCCURRENCES: 626 case AnalysisService.OCCURRENCES:
621 sendAnalysisNotificationOccurrences(this, file, dartUnit); 627 sendAnalysisNotificationOccurrences(this, file, dartUnit);
622 break; 628 break;
623 case AnalysisService.OUTLINE: 629 case AnalysisService.OUTLINE:
624 sendAnalysisNotificationOutline(this, context, source, dartUnit) ; 630 sendAnalysisNotificationOutline(
631 this,
632 context,
633 source,
634 dartUnit);
625 break; 635 break;
626 case AnalysisService.OVERRIDES: 636 case AnalysisService.OVERRIDES:
627 sendAnalysisNotificationOverrides(this, file, dartUnit); 637 sendAnalysisNotificationOverrides(this, file, dartUnit);
628 break; 638 break;
629 } 639 }
630 } 640 }
631 } 641 }
632 } 642 }
633 }); 643 });
634 // remember new subscriptions 644 // remember new subscriptions
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 List<CompilationUnit> units = <CompilationUnit>[]; 756 List<CompilationUnit> units = <CompilationUnit>[];
747 // prepare AnalysisContext 757 // prepare AnalysisContext
748 AnalysisContext context = getAnalysisContext(path); 758 AnalysisContext context = getAnalysisContext(path);
749 if (context == null) { 759 if (context == null) {
750 return units; 760 return units;
751 } 761 }
752 // add a unit for each unit/library combination 762 // add a unit for each unit/library combination
753 Source unitSource = getSource(path); 763 Source unitSource = getSource(path);
754 List<Source> librarySources = context.getLibrariesContaining(unitSource); 764 List<Source> librarySources = context.getLibrariesContaining(unitSource);
755 for (Source librarySource in librarySources) { 765 for (Source librarySource in librarySources) {
756 CompilationUnit unit = context.getResolvedCompilationUnit2(unitSource, lib rarySource); 766 CompilationUnit unit =
767 context.getResolvedCompilationUnit2(unitSource, librarySource);
757 if (unit != null) { 768 if (unit != null) {
758 units.add(unit); 769 units.add(unit);
759 } 770 }
760 } 771 }
761 // done 772 // done
762 return units; 773 return units;
763 } 774 }
764 775
765 /** 776 /**
766 * Returns [AstNode]s at the given [offset] of the given [file]. 777 * Returns [AstNode]s at the given [offset] of the given [file].
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 contextAnalysisDoneCompleters[context] = completer; 850 contextAnalysisDoneCompleters[context] = completer;
840 } 851 }
841 return completer.future; 852 return completer.future;
842 } 853 }
843 854
844 /** 855 /**
845 * This method is called when analysis of the given [AnalysisContext] is 856 * This method is called when analysis of the given [AnalysisContext] is
846 * done. 857 * done.
847 */ 858 */
848 void sendContextAnalysisDoneNotifications(AnalysisContext context, 859 void sendContextAnalysisDoneNotifications(AnalysisContext context,
849 AnalysisDoneReason reason) { 860 AnalysisDoneReason reason) {
850 Completer<AnalysisDoneReason> completer = 861 Completer<AnalysisDoneReason> completer =
851 contextAnalysisDoneCompleters.remove(context); 862 contextAnalysisDoneCompleters.remove(context);
852 if (completer != null) { 863 if (completer != null) {
853 completer.complete(reason); 864 completer.complete(reason);
854 } 865 }
855 } 866 }
856 867
857 void shutdown() { 868 void shutdown() {
858 running = false; 869 running = false;
859 if (index != null) { 870 if (index != null) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 exceptionString = 'null exception'; 930 exceptionString = 'null exception';
920 } 931 }
921 // prepare stackTrace.toString() 932 // prepare stackTrace.toString()
922 String stackTraceString; 933 String stackTraceString;
923 if (stackTrace != null) { 934 if (stackTrace != null) {
924 stackTraceString = stackTrace.toString(); 935 stackTraceString = stackTrace.toString();
925 } else { 936 } else {
926 stackTraceString = 'null stackTrace'; 937 stackTraceString = 'null stackTrace';
927 } 938 }
928 // send the notification 939 // send the notification
929 channel.sendNotification(new ServerErrorParams(true, exceptionString, 940 channel.sendNotification(
930 stackTraceString).toNotification()); 941 new ServerErrorParams(
942 true,
943 exceptionString,
944 stackTraceString).toNotification());
931 } 945 }
932 } 946 }
933 947
934 /** 948 /**
935 * An object that is listening for lifecycle events from an analysis server. 949 * An object that is listening for lifecycle events from an analysis server.
936 */ 950 */
937 abstract class AnalysisServerListener { 951 abstract class AnalysisServerListener {
938 /** 952 /**
939 * Analysis is complete. 953 * Analysis is complete.
940 */ 954 */
941 void analysisComplete(); 955 void analysisComplete();
942 } 956 }
943 957
944 typedef void OptionUpdater(AnalysisOptionsImpl options); 958 typedef void OptionUpdater(AnalysisOptionsImpl options);
OLDNEW
« no previous file with comments | « pkg/analysis_server/doc/api.html ('k') | pkg/analysis_server/lib/src/constants.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698