Chromium Code Reviews| Index: pkg/analyzer_cli/lib/src/driver.dart |
| diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart |
| index d8aacada4fbe24c7b9aa927a07db9906ae6e2511..407b970244722806047dfb514bdb33ecc46ead46 100644 |
| --- a/pkg/analyzer_cli/lib/src/driver.dart |
| +++ b/pkg/analyzer_cli/lib/src/driver.dart |
| @@ -49,6 +49,8 @@ import 'package:package_config/src/packages_impl.dart' show MapPackages; |
| import 'package:path/path.dart' as path; |
| import 'package:plugin/manager.dart'; |
| import 'package:plugin/plugin.dart'; |
| +import 'package:telemetry/crash_reporting.dart'; |
| +import 'package:telemetry/telemetry.dart' as telemetry; |
| import 'package:yaml/yaml.dart'; |
| /// Shared IO sink for standard error reporting. |
| @@ -67,6 +69,27 @@ bool containsLintRuleEntry(Map<String, YamlNode> options) { |
| return linterNode is YamlMap && linterNode.containsKey('rules'); |
| } |
| +telemetry.Analytics _analytics; |
| + |
| +// TODO(devoncarew): Replace with the real tracking ID. |
| +const _analyticsID = 'UA-001'; |
| + |
| +/// The analytics instance for analyzer-cli. |
| +telemetry.Analytics get analytics => (_analytics ??= |
| + telemetry.createAnalyticsInstance(_analyticsID, 'analyzer-cli')); |
| + |
| +/// Make sure that we create an analytics instance that doesn't send for this |
| +/// session. |
| +void disableAnalyticsForSession() { |
| + _analytics = telemetry.createAnalyticsInstance(_analyticsID, 'analyzer-cli', |
| + disableForSession: true); |
| +} |
| + |
| +/// Public for testing. |
|
Brian Wilkerson
2017/06/30 18:51:22
Please use the annotation `visibleForTesting` (fro
devoncarew
2017/06/30 21:58:13
Updated!
|
| +void setAnalyticsMock(telemetry.Analytics replacementAnalytics) { |
| + _analytics = replacementAnalytics; |
| +} |
| + |
| class Driver implements CommandLineStarter { |
| static final PerformanceTag _analyzeAllTag = |
| new PerformanceTag("Driver._analyzeAll"); |
| @@ -109,6 +132,22 @@ class Driver implements CommandLineStarter { |
| /// Collected analysis statistics. |
| final AnalysisStats stats = new AnalysisStats(); |
| + CrashReportSender _crashReportSender; |
| + |
| + // TODO(devoncarew): Replace with the real crash product ID. |
| + /// The crash reporting instance for analyzer-cli. |
| + CrashReportSender get crashReportSender => (_crashReportSender ??= |
| + new CrashReportSender('Dart-analyzer-cli', analytics)); |
| + |
| + /// Create a new Driver instance. |
| + /// |
| + /// [isTesting] is true is we're running in a test environment. |
|
Brian Wilkerson
2017/06/30 18:51:22
"true is" --> "true if"
devoncarew
2017/06/30 21:58:13
Done.
|
| + Driver({bool isTesting: false}) { |
| + if (isTesting) { |
| + disableAnalyticsForSession(); |
| + } |
| + } |
| + |
| /// This Driver's current analysis context. |
| /// |
| /// *Visible for testing.* |
| @@ -133,6 +172,15 @@ class Driver implements CommandLineStarter { |
| // Parse commandline options. |
| CommandLineOptions options = CommandLineOptions.parse(args); |
| + if (options.batchMode || options.buildMode) { |
| + disableAnalyticsForSession(); |
| + } |
| + |
| + // Ping analytics with our initial call. |
| + analytics.sendScreenView('home'); |
| + |
| + var timer = analytics.startTimer('analyze'); |
| + |
| // Do analysis. |
| if (options.buildMode) { |
| ErrorSeverity severity = _buildModeAnalyze(options); |
| @@ -140,7 +188,7 @@ class Driver implements CommandLineStarter { |
| if (_shouldBeFatal(severity, options)) { |
| io.exitCode = severity.ordinal; |
| } |
| - } else if (options.shouldBatch) { |
| + } else if (options.batchMode) { |
| BatchRunner batchRunner = new BatchRunner(outSink, errorSink); |
| batchRunner.runAsBatch(args, (List<String> args) async { |
| CommandLineOptions options = CommandLineOptions.parse(args); |
| @@ -158,17 +206,29 @@ class Driver implements CommandLineStarter { |
| _analyzedFileCount += _context.sources.length; |
| } |
| + // Send how long analysis took. |
| + timer.finish(); |
| + |
| + // Send how many files were analyzed. |
| + analytics.sendEvent('analyze', 'analyzedFiles', value: _analyzedFileCount); |
| + |
| if (options.perfReport != null) { |
| String json = makePerfReport( |
| startTime, currentTimeMillis, options, _analyzedFileCount, stats); |
| new io.File(options.perfReport).writeAsStringSync(json); |
| } |
| + |
| + // Wait a brief time for any analytics calls to finish. |
| + await analytics.waitForLastPing(timeout: new Duration(milliseconds: 200)); |
| } |
| Future<ErrorSeverity> _analyzeAll(CommandLineOptions options) async { |
| PerformanceTag previous = _analyzeAllTag.makeCurrent(); |
| try { |
| return await _analyzeAllImpl(options); |
| + } catch (e, st) { |
| + crashReportSender.sendReport(e, stackTrace: st); |
| + rethrow; |
| } finally { |
| previous.makeCurrent(); |
| } |
| @@ -321,7 +381,7 @@ class Driver implements CommandLineStarter { |
| /// [AnalyzeFunctionBodiesPredicate] that implements this policy. |
| AnalyzeFunctionBodiesPredicate _chooseDietParsingPolicy( |
| CommandLineOptions options) { |
| - if (options.shouldBatch) { |
| + if (options.batchMode) { |
| // As analyzer is currently implemented, once a file has been diet |
| // parsed, it can't easily be un-diet parsed without creating a brand new |
| // context and losing caching. In batch mode, we can't predict which |