OLD | NEW |
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 import 'dart:core' hide Resource; | 9 import 'dart:core' hide Resource; |
10 import 'dart:math' show max; | 10 import 'dart:math' show max; |
(...skipping 21 matching lines...) Expand all Loading... |
32 import 'package:analyzer/src/generated/ast.dart'; | 32 import 'package:analyzer/src/generated/ast.dart'; |
33 import 'package:analyzer/src/generated/engine.dart'; | 33 import 'package:analyzer/src/generated/engine.dart'; |
34 import 'package:analyzer/src/generated/java_engine.dart'; | 34 import 'package:analyzer/src/generated/java_engine.dart'; |
35 import 'package:analyzer/src/generated/java_io.dart'; | 35 import 'package:analyzer/src/generated/java_io.dart'; |
36 import 'package:analyzer/src/generated/sdk.dart'; | 36 import 'package:analyzer/src/generated/sdk.dart'; |
37 import 'package:analyzer/src/generated/source.dart'; | 37 import 'package:analyzer/src/generated/source.dart'; |
38 import 'package:analyzer/src/generated/source_io.dart'; | 38 import 'package:analyzer/src/generated/source_io.dart'; |
39 import 'package:analyzer/src/generated/utilities_general.dart'; | 39 import 'package:analyzer/src/generated/utilities_general.dart'; |
40 import 'package:analyzer/src/task/dart.dart'; | 40 import 'package:analyzer/src/task/dart.dart'; |
41 import 'package:analyzer/src/util/glob.dart'; | 41 import 'package:analyzer/src/util/glob.dart'; |
| 42 import 'package:analyzer/task/dart.dart'; |
42 import 'package:plugin/plugin.dart'; | 43 import 'package:plugin/plugin.dart'; |
43 | 44 |
44 typedef void OptionUpdater(AnalysisOptionsImpl options); | 45 typedef void OptionUpdater(AnalysisOptionsImpl options); |
45 | 46 |
46 /** | 47 /** |
47 * Enum representing reasons why analysis might be done for a given file. | 48 * Enum representing reasons why analysis might be done for a given file. |
48 */ | 49 */ |
49 class AnalysisDoneReason { | 50 class AnalysisDoneReason { |
50 /** | 51 /** |
51 * Analysis of the file completed successfully. | 52 * Analysis of the file completed successfully. |
(...skipping 24 matching lines...) Expand all Loading... |
76 * The version of the analysis server. The value should be replaced | 77 * The version of the analysis server. The value should be replaced |
77 * automatically during the build. | 78 * automatically during the build. |
78 */ | 79 */ |
79 static final String VERSION = '1.15.0'; | 80 static final String VERSION = '1.15.0'; |
80 | 81 |
81 /** | 82 /** |
82 * The number of milliseconds to perform operations before inserting | 83 * The number of milliseconds to perform operations before inserting |
83 * a 1 millisecond delay so that the VM and dart:io can deliver content | 84 * a 1 millisecond delay so that the VM and dart:io can deliver content |
84 * to stdin. This should be removed once the underlying problem is fixed. | 85 * to stdin. This should be removed once the underlying problem is fixed. |
85 */ | 86 */ |
86 static int performOperationDelayFreqency = 25; | 87 static int performOperationDelayFrequency = 25; |
87 | 88 |
88 /** | 89 /** |
89 * The options of this server instance. | 90 * The options of this server instance. |
90 */ | 91 */ |
91 AnalysisServerOptions options; | 92 AnalysisServerOptions options; |
92 | 93 |
93 /** | 94 /** |
94 * The channel from which requests are received and to which responses should | 95 * The channel from which requests are received and to which responses should |
95 * be sent. | 96 * be sent. |
96 */ | 97 */ |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 _onFileAnalyzedController = new StreamController.broadcast(); | 348 _onFileAnalyzedController = new StreamController.broadcast(); |
348 _onPriorityChangeController = | 349 _onPriorityChangeController = |
349 new StreamController<PriorityChangeEvent>.broadcast(); | 350 new StreamController<PriorityChangeEvent>.broadcast(); |
350 running = true; | 351 running = true; |
351 onAnalysisStarted.first.then((_) { | 352 onAnalysisStarted.first.then((_) { |
352 onAnalysisComplete.then((_) { | 353 onAnalysisComplete.then((_) { |
353 performanceAfterStartup = new ServerPerformance(); | 354 performanceAfterStartup = new ServerPerformance(); |
354 _performance = performanceAfterStartup; | 355 _performance = performanceAfterStartup; |
355 }); | 356 }); |
356 }); | 357 }); |
| 358 _setupIndexInvalidation(); |
357 Notification notification = | 359 Notification notification = |
358 new ServerConnectedParams(VERSION).toNotification(); | 360 new ServerConnectedParams(VERSION).toNotification(); |
359 channel.sendNotification(notification); | 361 channel.sendNotification(notification); |
360 channel.listen(handleRequest, onDone: done, onError: error); | 362 channel.listen(handleRequest, onDone: done, onError: error); |
361 handlers = serverPlugin.createDomains(this); | 363 handlers = serverPlugin.createDomains(this); |
362 sdkManager = new DartSdkManager(defaultSdkCreator); | 364 sdkManager = new DartSdkManager(defaultSdkCreator); |
363 } | 365 } |
364 | 366 |
365 /** | 367 /** |
366 * Return the [AnalysisContext]s that are being used to analyze the analysis | 368 * Return the [AnalysisContext]s that are being used to analyze the analysis |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 Source source = contextSource.source; | 670 Source source = contextSource.source; |
669 if (context == null) { | 671 if (context == null) { |
670 return null; | 672 return null; |
671 } | 673 } |
672 if (!context.exists(source)) { | 674 if (!context.exists(source)) { |
673 return null; | 675 return null; |
674 } | 676 } |
675 return context.getErrors(source); | 677 return context.getErrors(source); |
676 } | 678 } |
677 | 679 |
678 // TODO(brianwilkerson) Add the following method after 'prioritySources' has | |
679 // been added to InternalAnalysisContext. | |
680 // /** | |
681 // * Return a list containing the full names of all of the sources that are | |
682 // * priority sources. | |
683 // */ | |
684 // List<String> getPriorityFiles() { | |
685 // List<String> priorityFiles = new List<String>(); | |
686 // folderMap.values.forEach((ContextDirectory directory) { | |
687 // InternalAnalysisContext context = directory.context; | |
688 // context.prioritySources.forEach((Source source) { | |
689 // priorityFiles.add(source.fullName); | |
690 // }); | |
691 // }); | |
692 // return priorityFiles; | |
693 // } | |
694 | |
695 /** | 680 /** |
696 * Returns resolved [AstNode]s at the given [offset] of the given [file]. | 681 * Returns resolved [AstNode]s at the given [offset] of the given [file]. |
697 * | 682 * |
698 * May be empty, but not `null`. | 683 * May be empty, but not `null`. |
699 */ | 684 */ |
700 List<AstNode> getNodesAtOffset(String file, int offset) { | 685 List<AstNode> getNodesAtOffset(String file, int offset) { |
701 List<CompilationUnit> units = getResolvedCompilationUnits(file); | 686 List<CompilationUnit> units = getResolvedCompilationUnits(file); |
702 List<AstNode> nodes = <AstNode>[]; | 687 List<AstNode> nodes = <AstNode>[]; |
703 for (CompilationUnit unit in units) { | 688 for (CompilationUnit unit in units) { |
704 AstNode node = new NodeLocator(offset).searchWithin(unit); | 689 AstNode node = new NodeLocator(offset).searchWithin(unit); |
705 if (node != null) { | 690 if (node != null) { |
706 nodes.add(node); | 691 nodes.add(node); |
707 } | 692 } |
708 } | 693 } |
709 return nodes; | 694 return nodes; |
710 } | 695 } |
711 | 696 |
| 697 // TODO(brianwilkerson) Add the following method after 'prioritySources' has |
| 698 // been added to InternalAnalysisContext. |
| 699 // /** |
| 700 // * Return a list containing the full names of all of the sources that are |
| 701 // * priority sources. |
| 702 // */ |
| 703 // List<String> getPriorityFiles() { |
| 704 // List<String> priorityFiles = new List<String>(); |
| 705 // folderMap.values.forEach((ContextDirectory directory) { |
| 706 // InternalAnalysisContext context = directory.context; |
| 707 // context.prioritySources.forEach((Source source) { |
| 708 // priorityFiles.add(source.fullName); |
| 709 // }); |
| 710 // }); |
| 711 // return priorityFiles; |
| 712 // } |
| 713 |
712 /** | 714 /** |
713 * Returns resolved [CompilationUnit]s of the Dart file with the given [path]. | 715 * Returns resolved [CompilationUnit]s of the Dart file with the given [path]. |
714 * | 716 * |
715 * May be empty, but not `null`. | 717 * May be empty, but not `null`. |
716 */ | 718 */ |
717 List<CompilationUnit> getResolvedCompilationUnits(String path) { | 719 List<CompilationUnit> getResolvedCompilationUnits(String path) { |
718 List<CompilationUnit> units = <CompilationUnit>[]; | 720 List<CompilationUnit> units = <CompilationUnit>[]; |
719 ContextSourcePair contextSource = getContextSourcePair(path); | 721 ContextSourcePair contextSource = getContextSourcePair(path); |
720 // prepare AnalysisContext | 722 // prepare AnalysisContext |
721 AnalysisContext context = contextSource.context; | 723 AnalysisContext context = contextSource.context; |
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1445 * is fixed. Currently, the VM and dart:io do not deliver content | 1447 * is fixed. Currently, the VM and dart:io do not deliver content |
1446 * on stdin in a timely manner if the event loop is busy. | 1448 * on stdin in a timely manner if the event loop is busy. |
1447 * To work around this problem, we delay for 1 millisecond | 1449 * To work around this problem, we delay for 1 millisecond |
1448 * every 25 milliseconds. | 1450 * every 25 milliseconds. |
1449 * | 1451 * |
1450 * To disable this workaround and see the underlying problem, | 1452 * To disable this workaround and see the underlying problem, |
1451 * set performOperationDelayFreqency to zero | 1453 * set performOperationDelayFreqency to zero |
1452 */ | 1454 */ |
1453 int now = new DateTime.now().millisecondsSinceEpoch; | 1455 int now = new DateTime.now().millisecondsSinceEpoch; |
1454 if (now > _nextPerformOperationDelayTime && | 1456 if (now > _nextPerformOperationDelayTime && |
1455 performOperationDelayFreqency > 0) { | 1457 performOperationDelayFrequency > 0) { |
1456 _nextPerformOperationDelayTime = now + performOperationDelayFreqency; | 1458 _nextPerformOperationDelayTime = now + performOperationDelayFrequency; |
1457 new Future.delayed(new Duration(milliseconds: 1), performOperation); | 1459 new Future.delayed(new Duration(milliseconds: 1), performOperation); |
1458 } else { | 1460 } else { |
1459 new Future(performOperation); | 1461 new Future(performOperation); |
1460 } | 1462 } |
1461 performOperationPending = true; | 1463 performOperationPending = true; |
1462 } | 1464 } |
| 1465 |
| 1466 /** |
| 1467 * Listen for context events and invalidate index. |
| 1468 * |
| 1469 * It is possible that this method will do more in the future, e.g. listening |
| 1470 * for summary information and linking pre-indexed packages into the index, |
| 1471 * but for now we only invalidate project specific index information. |
| 1472 */ |
| 1473 void _setupIndexInvalidation() { |
| 1474 if (index2 == null) { |
| 1475 return; |
| 1476 } |
| 1477 onContextsChanged.listen((ContextsChangedEvent event) { |
| 1478 for (AnalysisContext context in event.added) { |
| 1479 context |
| 1480 .onResultChanged(RESOLVED_UNIT) |
| 1481 .listen((ResultChangedEvent event) { |
| 1482 if (event.wasInvalidated) { |
| 1483 LibrarySpecificUnit target = event.target; |
| 1484 index2.removeUnit(event.context, target.library, target.unit); |
| 1485 } |
| 1486 }); |
| 1487 } |
| 1488 for (AnalysisContext context in event.removed) { |
| 1489 index2.removeContext(context); |
| 1490 } |
| 1491 }); |
| 1492 } |
1463 } | 1493 } |
1464 | 1494 |
1465 class AnalysisServerOptions { | 1495 class AnalysisServerOptions { |
1466 bool enableIncrementalResolutionApi = false; | 1496 bool enableIncrementalResolutionApi = false; |
1467 bool enableIncrementalResolutionValidation = false; | 1497 bool enableIncrementalResolutionValidation = false; |
1468 bool noErrorNotification = false; | 1498 bool noErrorNotification = false; |
1469 bool noIndex = false; | 1499 bool noIndex = false; |
1470 bool useAnalysisHighlight2 = false; | 1500 bool useAnalysisHighlight2 = false; |
1471 String fileReadMode = 'as-is'; | 1501 String fileReadMode = 'as-is'; |
1472 } | 1502 } |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1655 * The maximum latency (milliseconds) for all recorded requests. | 1685 * The maximum latency (milliseconds) for all recorded requests. |
1656 */ | 1686 */ |
1657 int maxLatency = 0; | 1687 int maxLatency = 0; |
1658 | 1688 |
1659 /** | 1689 /** |
1660 * The number of requests with latency > 150 milliseconds. | 1690 * The number of requests with latency > 150 milliseconds. |
1661 */ | 1691 */ |
1662 int slowRequestCount = 0; | 1692 int slowRequestCount = 0; |
1663 | 1693 |
1664 /** | 1694 /** |
1665 * Log performation information about the given request. | 1695 * Log performance information about the given request. |
1666 */ | 1696 */ |
1667 void logRequest(Request request) { | 1697 void logRequest(Request request) { |
1668 ++requestCount; | 1698 ++requestCount; |
1669 if (request.clientRequestTime != null) { | 1699 if (request.clientRequestTime != null) { |
1670 int latency = | 1700 int latency = |
1671 new DateTime.now().millisecondsSinceEpoch - request.clientRequestTime; | 1701 new DateTime.now().millisecondsSinceEpoch - request.clientRequestTime; |
1672 requestLatency += latency; | 1702 requestLatency += latency; |
1673 maxLatency = max(maxLatency, latency); | 1703 maxLatency = max(maxLatency, latency); |
1674 if (latency > 150) { | 1704 if (latency > 150) { |
1675 ++slowRequestCount; | 1705 ++slowRequestCount; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1724 /** | 1754 /** |
1725 * The [PerformanceTag] for time spent in server request handlers. | 1755 * The [PerformanceTag] for time spent in server request handlers. |
1726 */ | 1756 */ |
1727 static PerformanceTag serverRequests = new PerformanceTag('serverRequests'); | 1757 static PerformanceTag serverRequests = new PerformanceTag('serverRequests'); |
1728 | 1758 |
1729 /** | 1759 /** |
1730 * The [PerformanceTag] for time spent in split store microtasks. | 1760 * The [PerformanceTag] for time spent in split store microtasks. |
1731 */ | 1761 */ |
1732 static PerformanceTag splitStore = new PerformanceTag('splitStore'); | 1762 static PerformanceTag splitStore = new PerformanceTag('splitStore'); |
1733 } | 1763 } |
OLD | NEW |