Migrate the completion metrics tool

Change-Id: I6d66ebd2d5cbb32147252927819f9d6533cb4012
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/194882
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/tool/code_completion/completion_metrics.dart b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
index d5b2d61..f9c0503 100644
--- a/pkg/analysis_server/tool/code_completion/completion_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:convert';
 import 'dart:io' as io;
 import 'dart:math' as math;
@@ -53,7 +51,6 @@
 import 'package:analyzer/src/util/performance/operation_performance.dart';
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
 import 'package:args/args.dart';
-import 'package:meta/meta.dart';
 
 import 'metrics_util.dart';
 import 'output_utilities.dart';
@@ -65,7 +62,7 @@
   var result = parser.parse(args);
 
   if (!validArguments(parser, result)) {
-    return io.exit(1);
+    io.exit(1);
   }
 
   var options = CompletionMetricsOptions(result);
@@ -116,7 +113,7 @@
   } else {
     computer.printResults();
   }
-  return io.exit(code);
+  io.exit(code);
 }
 
 /// A [Counter] to track the performance of each of the completion strategies
@@ -203,7 +200,7 @@
 }
 
 /// Print usage information for this tool.
-void printUsage(ArgParser parser, {String error}) {
+void printUsage(ArgParser parser, {String? error}) {
   if (error != null) {
     print(error);
     print('');
@@ -286,10 +283,10 @@
   final String name;
 
   /// The function to be executed when this metrics collector is enabled.
-  final void Function() enableFunction;
+  final void Function()? enableFunction;
 
   /// The function to be executed when this metrics collector is disabled.
-  final void Function() disableFunction;
+  final void Function()? disableFunction;
 
   final Counter completionCounter = Counter('all completions');
 
@@ -441,6 +438,7 @@
   /// Perform any operations required in order to revert computing the kind of
   /// completions represented by this metrics collector.
   void disable() {
+    var disableFunction = this.disableFunction;
     if (disableFunction != null) {
       disableFunction();
     }
@@ -449,6 +447,7 @@
   /// Perform any initialization required in order to compute the kind of
   /// completions represented by this metrics collector.
   void enable() {
+    var enableFunction = this.enableFunction;
     if (enableFunction != null) {
       enableFunction();
     }
@@ -497,11 +496,11 @@
   /// If the completion location was requested but missing when computing the
   /// [result], then record where that happened.
   void _recordMissingInformation(MetricsSuggestionListener listener) {
-    var location = listener?.missingCompletionLocation;
+    var location = listener.missingCompletionLocation;
     if (location != null) {
       missingCompletionLocations.add(location);
     } else {
-      location = listener?.missingCompletionLocationTable;
+      location = listener.missingCompletionLocationTable;
       if (location != null) {
         missingCompletionLocationTables.add(location);
       }
@@ -568,10 +567,10 @@
 
   final CompletionMetricsOptions options;
 
-  ResolvedUnitResult _resolvedUnitResult;
+  late ResolvedUnitResult _resolvedUnitResult;
 
   /// The int to be returned from the [computeMetrics] call.
-  int resultCode;
+  int resultCode = 0;
 
   /// A list of the metrics to be computed.
   final List<CompletionMetrics> targetMetrics = [];
@@ -642,12 +641,10 @@
       CompletionRequestImpl request,
       MetricsSuggestionListener listener,
       ExpectedCompletion expectedCompletion,
-      String completionLocation,
+      String? completionLocation,
       List<protocol.CompletionSuggestion> suggestions,
       CompletionMetrics metrics,
       int elapsedMS) {
-    assert(suggestions != null);
-
     var place = placementInSuggestionList(suggestions, expectedCompletion);
 
     metrics.mrrComputer.addRank(place.rank);
@@ -658,14 +655,14 @@
       var rank = place.rank;
       var suggestion = suggestions[rank - 1];
       var actualSuggestion =
-          SuggestionData(suggestion, listener.featureMap[suggestion]);
-      List<SuggestionData> topSuggestions;
-      Map<int, int> precedingRelevanceCounts;
+          SuggestionData(suggestion, listener.featureMap[suggestion]!);
+      List<SuggestionData>? topSuggestions;
+      Map<int, int>? precedingRelevanceCounts;
       if (options.printWorstResults) {
         topSuggestions = suggestions
             .sublist(0, math.min(10, suggestions.length))
             .map((suggestion) =>
-                SuggestionData(suggestion, listener.featureMap[suggestion]))
+                SuggestionData(suggestion, listener.featureMap[suggestion]!))
             .toList();
         precedingRelevanceCounts = <int, int>{};
         for (var i = 0; i < rank - 1; i++) {
@@ -704,7 +701,7 @@
           .count(expectedCompletion.elementKind.toString());
 
       if (options.printMissedCompletionDetails) {
-        protocol.CompletionSuggestion closeMatchSuggestion;
+        protocol.CompletionSuggestion? closeMatchSuggestion;
         for (var suggestion in suggestions) {
           if (suggestion.completion == expectedCompletion.completion) {
             closeMatchSuggestion = suggestion;
@@ -790,14 +787,14 @@
       ];
     }
 
-    var groups = metrics.groupMrrComputers.keys.toList();
-    groups.sort((first, second) => first.name.compareTo(second.name));
+    var entries = metrics.groupMrrComputers.entries.toList();
+    entries.sort((first, second) => first.key.name.compareTo(second.key.name));
     var table = [
       ['', 'mrr', 'inverse mrr', 'mrr_5', 'inverse mrr_5', 'count'],
       toRow(metrics.mrrComputer),
       toRow(metrics.successfulMrrComputer),
       ['', '', '', '', '', ''],
-      for (var group in groups) toRow(metrics.groupMrrComputers[group]),
+      for (var entry in entries) toRow(entry.value),
     ];
     rightJustifyColumns(table, [2, 4, 5]);
 
@@ -890,7 +887,7 @@
     elementKinds.sort((first, second) => first.name.compareTo(second.name));
     for (var kind in elementKinds) {
       table.add(toRow(
-          targetMetrics.map((metrics) => metrics.groupMrrComputers[kind])));
+          targetMetrics.map((metrics) => metrics.groupMrrComputers[kind]!)));
     }
     if (options.printMrrByLocation) {
       table.add(blankRow);
@@ -901,7 +898,7 @@
       locations.sort();
       for (var location in locations) {
         table.add(toRow(targetMetrics
-            .map((metrics) => metrics.locationMrrComputers[location])));
+            .map((metrics) => metrics.locationMrrComputers[location]!)));
       }
     }
     rightJustifyColumns(table, range(1, table[0].length));
@@ -963,23 +960,23 @@
 
   void printSlowestResults(CompletionMetrics metrics) {
     var slowestResults = metrics.slowestResults;
-    var groups = slowestResults.keys.toList();
-    groups.sort((first, second) => first.name.compareTo(second.name));
+    var entries = slowestResults.entries.toList();
+    entries.sort((first, second) => first.key.name.compareTo(second.key.name));
     print('');
     printHeading(2, 'The slowest completion results to compute');
-    for (var group in groups) {
-      _printSlowestResults('In ${group.name}', slowestResults[group]);
+    for (var entry in entries) {
+      _printSlowestResults('In ${entry.key.name}', entry.value);
     }
   }
 
   void printWorstResults(CompletionMetrics metrics) {
     var worstResults = metrics.worstResults;
-    var groups = worstResults.keys.toList();
-    groups.sort((first, second) => first.name.compareTo(second.name));
+    var entries = worstResults.entries.toList();
+    entries.sort((first, second) => first.key.name.compareTo(second.key.name));
     print('');
     printHeading(2, 'The worst completion results');
-    for (var group in groups) {
-      _printWorstResults('In ${group.name}', worstResults[group]);
+    for (var entry in entries) {
+      _printWorstResults('In ${entry.key.name}', entry.value);
     }
   }
 
@@ -1006,8 +1003,8 @@
       MetricsSuggestionListener listener,
       OperationPerformanceImpl performance,
       CompletionRequestImpl request,
-      [DeclarationsTracker declarationsTracker,
-      protocol.CompletionAvailableSuggestionsParams
+      [DeclarationsTracker? declarationsTracker,
+      protocol.CompletionAvailableSuggestionsParams?
           availableSuggestionsParams]) async {
     List<protocol.CompletionSuggestion> suggestions;
 
@@ -1048,25 +1045,24 @@
       };
 
       for (var availableSuggestionSet
-          in availableSuggestionsParams.changedLibraries) {
+          in availableSuggestionsParams!.changedLibraries!) {
         var id = availableSuggestionSet.id;
         for (var availableSuggestion in availableSuggestionSet.items) {
           // Exclude available suggestions where this element kind doesn't match
           // an element kind in includedElementKinds.
-          var elementKind = availableSuggestion.element?.kind;
-          if (elementKind != null &&
-              includedElementKinds.contains(elementKind)) {
+          var elementKind = availableSuggestion.element.kind;
+          if (includedElementKinds.contains(elementKind)) {
             if (includedSuggestionSetMap.containsKey(id)) {
-              var relevance = includedSuggestionSetMap[id].relevance;
+              var relevance = includedSuggestionSetMap[id]!.relevance;
 
               // Search for any matching relevance tags to apply any boosts
               if (includedSuggestionRelevanceTagList.isNotEmpty &&
                   availableSuggestion.relevanceTags != null &&
-                  availableSuggestion.relevanceTags.isNotEmpty) {
-                for (var tag in availableSuggestion.relevanceTags) {
+                  availableSuggestion.relevanceTags!.isNotEmpty) {
+                for (var tag in availableSuggestion.relevanceTags!) {
                   if (includedSuggestionRelevanceTagMap.containsKey(tag)) {
                     // apply the boost
-                    relevance += includedSuggestionRelevanceTagMap[tag];
+                    relevance += includedSuggestionRelevanceTagMap[tag]!;
                   }
                 }
               }
@@ -1097,8 +1093,8 @@
 
     // Set the DeclarationsTracker, only call doWork to build up the available
     // suggestions if doComputeCompletionsFromAnalysisServer is true.
-    DeclarationsTracker declarationsTracker;
-    protocol.CompletionAvailableSuggestionsParams availableSuggestionsParams;
+    DeclarationsTracker? declarationsTracker;
+    protocol.CompletionAvailableSuggestionsParams? availableSuggestionsParams;
     if (options.availableSuggestions) {
       declarationsTracker = DeclarationsTracker(
           MemoryByteStore(), PhysicalResourceProvider.INSTANCE);
@@ -1110,11 +1106,6 @@
       // Have the AvailableDeclarationsSet computed to use later.
       availableSuggestionsParams = createCompletionAvailableSuggestions(
           declarationsTracker.allLibraries.toList(), []);
-
-      // assert that this object is not null, throw if it is.
-      if (availableSuggestionsParams == null) {
-        throw Exception('availableSuggestionsParam not computable.');
-      }
     }
 
     // Loop through each file, resolve the file and call
@@ -1138,7 +1129,7 @@
           // Use the ExpectedCompletionsVisitor to compute the set of expected
           // completions for this CompilationUnit.
           final visitor = ExpectedCompletionsVisitor(filePath);
-          _resolvedUnitResult.unit.accept(visitor);
+          _resolvedUnitResult.unit!.accept(visitor);
 
           for (var expectedCompletion in visitor.expectedCompletions) {
             var resolvedUnitResult = _resolvedUnitResult;
@@ -1147,7 +1138,7 @@
             // have the context reanalyze the file
             if (options.overlay != CompletionMetricsOptions.OVERLAY_NONE) {
               var overlayContents = _getOverlayContents(
-                  _resolvedUnitResult.content, expectedCompletion);
+                  _resolvedUnitResult.content!, expectedCompletion);
 
               _provider.setOverlay(filePath,
                   content: overlayContents,
@@ -1162,8 +1153,8 @@
             // comparison:
 
             Future<int> handleExpectedCompletion(
-                {MetricsSuggestionListener listener,
-                @required CompletionMetrics metrics}) async {
+                {required MetricsSuggestionListener listener,
+                required CompletionMetrics metrics}) async {
               var stopwatch = Stopwatch()..start();
               var request = CompletionRequestImpl(
                 resolvedUnitResult,
@@ -1172,8 +1163,8 @@
               );
               var directiveInfo = DartdocDirectiveInfo();
 
-              OpType opType;
-              List<protocol.CompletionSuggestion> suggestions;
+              late OpType opType;
+              late List<protocol.CompletionSuggestion> suggestions;
               await request.performance.runRequestOperation(
                 (performance) async {
                   var dartRequest = await DartCompletionRequestImpl.from(
@@ -1314,10 +1305,10 @@
       var actualSuggestion = result.actualSuggestion;
       var expected = result.expectedCompletion;
 
-      var topSuggestions = result.topSuggestions;
+      var topSuggestions = result.topSuggestions!;
       var topSuggestionCount = topSuggestions.length;
 
-      var preceding = result.precedingRelevanceCounts;
+      var preceding = result.precedingRelevanceCounts!;
       var precedingRelevances = preceding.keys.toList();
       precedingRelevances.sort();
 
@@ -1372,7 +1363,7 @@
 
   /// Given some [ResolvedUnitResult] return the first error of high severity
   /// if such an error exists, `null` otherwise.
-  static err.AnalysisError getFirstErrorOrNull(
+  static err.AnalysisError? getFirstErrorOrNull(
       ResolvedUnitResult resolvedUnitResult) {
     for (var error in resolvedUnitResult.errors) {
       if (error.severity == Severity.error) {
@@ -1492,14 +1483,14 @@
   }
 
   CompletionMetricsOptions._(
-      {@required this.availableSuggestions,
-      @required this.overlay,
-      @required this.printMissedCompletionDetails,
-      @required this.printMissedCompletionSummary,
-      @required this.printMissingInformation,
-      @required this.printMrrByLocation,
-      @required this.printSlowestResults,
-      @required this.printWorstResults})
+      {required this.availableSuggestions,
+      required this.overlay,
+      required this.printMissedCompletionDetails,
+      required this.printMissedCompletionSummary,
+      required this.printMissingInformation,
+      required this.printMrrByLocation,
+      required this.printSlowestResults,
+      required this.printWorstResults})
       : assert(overlay == OVERLAY_NONE ||
             overlay == OVERLAY_REMOVE_TOKEN ||
             overlay == OVERLAY_REMOVE_REST_OF_FILE);
@@ -1509,19 +1500,19 @@
 class CompletionResult {
   final Place place;
 
-  final CompletionRequestImpl request;
+  final CompletionRequestImpl? request;
 
   final SuggestionData actualSuggestion;
 
-  final List<SuggestionData> topSuggestions;
+  final List<SuggestionData>? topSuggestions;
 
   final ExpectedCompletion expectedCompletion;
 
-  final String completionLocation;
+  final String? completionLocation;
 
   final int elapsedMS;
 
-  final Map<int, int> precedingRelevanceCounts;
+  final Map<int, int>? precedingRelevanceCounts;
 
   CompletionResult(
       this.place,
@@ -1539,11 +1530,11 @@
     var actualSuggestion = SuggestionData.fromJson(
         map['actualSuggestion'] as Map<String, dynamic>);
     var topSuggestions = (map['topSuggestions'] as List<dynamic>)
-        ?.map((map) => SuggestionData.fromJson(map as Map<String, dynamic>))
-        ?.toList();
+        .map((map) => SuggestionData.fromJson(map as Map<String, dynamic>))
+        .toList();
     var precedingRelevanceCounts =
         (map['precedingRelevanceCounts'] as Map<String, dynamic>)
-            ?.map((key, value) => MapEntry(int.parse(key), value as int));
+            .map((key, value) => MapEntry(int.parse(key), value as int));
     var expectedCompletion = ExpectedCompletion.fromJson(
         map['expectedCompletion'] as Map<String, dynamic>);
     var completionLocation = map['completionLocation'] as String;
@@ -1585,8 +1576,8 @@
         }
         if (entity is SimpleIdentifier &&
             entity.parent is TypeName &&
-            entity.parent.parent is ConstructorName &&
-            entity.parent.parent.parent is InstanceCreationExpression) {
+            entity.parent!.parent is ConstructorName &&
+            entity.parent!.parent!.parent is InstanceCreationExpression) {
           return CompletionGroup.constructorElement;
         }
         return CompletionGroup.classElement;
@@ -1622,9 +1613,9 @@
       'actualSuggestion': actualSuggestion.toJson(),
       if (topSuggestions != null)
         'topSuggestions':
-            topSuggestions.map((suggestion) => suggestion.toJson()).toList(),
+            topSuggestions!.map((suggestion) => suggestion.toJson()).toList(),
       if (precedingRelevanceCounts != null)
-        'precedingRelevanceCounts': precedingRelevanceCounts
+        'precedingRelevanceCounts': precedingRelevanceCounts!
             .map((key, value) => MapEntry(key.toString(), value)),
       'expectedCompletion': expectedCompletion.toJson(),
       'completionLocation': completionLocation,
@@ -1634,13 +1625,13 @@
 
   /// Return the element associated with the syntactic [entity], or `null` if
   /// there is no such element.
-  Element _getElement(SyntacticEntity entity) {
+  Element? _getElement(SyntacticEntity entity) {
     if (entity is SimpleIdentifier) {
       var element = entity.staticElement;
       if (element != null) {
         return element;
       }
-      AstNode node = entity;
+      AstNode? node = entity;
       while (node != null) {
         var parent = node.parent;
         if (parent is AssignmentExpression) {
@@ -1688,11 +1679,11 @@
   final double mrr_5;
 
   LocationTableLine(
-      {@required this.label,
-      @required this.product,
-      @required this.count,
-      @required this.mrr,
-      @required this.mrr_5});
+      {required this.label,
+      required this.product,
+      required this.count,
+      required this.mrr,
+      required this.mrr_5});
 }
 
 class MetricsSuggestionListener implements SuggestionListener {
@@ -1710,9 +1701,9 @@
     0.0
   ];
 
-  String missingCompletionLocation;
+  String? missingCompletionLocation;
 
-  String missingCompletionLocationTable;
+  String? missingCompletionLocationTable;
 
   @override
   void builtSuggestion(protocol.CompletionSuggestion suggestion) {
@@ -1854,7 +1845,6 @@
       case CompletionGroup.unknown:
         return 'unknown';
     }
-    return '<unknown>';
   }
 }
 
diff --git a/pkg/analysis_server/tool/code_completion/visitors.dart b/pkg/analysis_server/tool/code_completion/visitors.dart
index a4abe60..5e86cd3 100644
--- a/pkg/analysis_server/tool/code_completion/visitors.dart
+++ b/pkg/analysis_server/tool/code_completion/visitors.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/protocol/protocol_internal.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
@@ -21,15 +19,15 @@
   /// Some completions are special cased from the DAS "import" for instance is
   /// suggested as a completion "import '';", the completion string here in this
   /// instance would have the value "import '';".
-  final String _completionString;
+  final String? _completionString;
 
-  final protocol.CompletionSuggestionKind _kind;
+  final protocol.CompletionSuggestionKind? _kind;
 
   final int _lineNumber;
 
   final int _columnNumber;
 
-  final protocol.ElementKind _elementKind;
+  final protocol.ElementKind? _elementKind;
 
   ExpectedCompletion(this._filePath, this._entity, this._lineNumber,
       this._columnNumber, this._kind, this._elementKind)
@@ -74,11 +72,11 @@
 
   String get completion => _completionString ?? _entity.toString();
 
-  protocol.ElementKind get elementKind => _elementKind;
+  protocol.ElementKind? get elementKind => _elementKind;
 
   String get filePath => _filePath;
 
-  protocol.CompletionSuggestionKind get kind => _kind;
+  protocol.CompletionSuggestionKind? get kind => _kind;
 
   int get lineNumber => _lineNumber;
 
@@ -90,9 +88,7 @@
 
   bool matches(protocol.CompletionSuggestion completionSuggestion) {
     if (completionSuggestion.completion == completion) {
-      if (kind != null &&
-          completionSuggestion.kind != null &&
-          completionSuggestion.kind != kind) {
+      if (kind != null && completionSuggestion.kind != kind) {
         return false;
       }
       if (elementKind != null &&
@@ -107,14 +103,16 @@
 
   /// Return a map used to represent this expected completion in a JSON structure.
   Map<String, dynamic> toJson() {
+    var kind = _kind;
+    var elementKind = _elementKind;
     return {
       'filePath': _filePath,
       'offset': _entity.offset,
       'lineNumber': _lineNumber,
       'columnNumber': _columnNumber,
       'completionString': _completionString,
-      if (_kind != null) 'kind': _kind.toJson(),
-      if (_elementKind != null) 'elementKind': _elementKind.toJson(),
+      if (kind != null) 'kind': kind.toJson(),
+      if (elementKind != null) 'elementKind': elementKind.toJson(),
     };
   }
 
@@ -128,7 +126,7 @@
 
   final String filePath;
 
-  CompilationUnit _enclosingCompilationUnit;
+  late CompilationUnit _enclosingCompilationUnit;
 
   /// This boolean is set to enable whether or not we should assert that some
   /// found keyword in Dart syntax should be in the completion set returned from
@@ -144,20 +142,19 @@
   final bool _doExpectCommentRefs = false;
 
   ExpectedCompletionsVisitor(this.filePath)
-      : expectedCompletions = <ExpectedCompletion>[],
-        assert(filePath != null);
+      : expectedCompletions = <ExpectedCompletion>[];
 
-  void safelyRecordEntity(SyntacticEntity entity,
-      {protocol.CompletionSuggestionKind kind,
-      protocol.ElementKind elementKind}) {
+  void safelyRecordEntity(SyntacticEntity? entity,
+      {protocol.CompletionSuggestionKind? kind,
+      protocol.ElementKind? elementKind}) {
     // Only record if this entity is not null, has a length, etc.
     if (entity != null && entity.offset > 0 && entity.length > 0) {
       // Compute the line number at this offset
-      var lineNumber = _enclosingCompilationUnit.lineInfo
+      var lineNumber = _enclosingCompilationUnit.lineInfo!
           .getLocation(entity.offset)
           .lineNumber;
 
-      var columnNumber = _enclosingCompilationUnit.lineInfo
+      var columnNumber = _enclosingCompilationUnit.lineInfo!
           .getLocation(entity.offset)
           .columnNumber;
 
@@ -242,7 +239,7 @@
     }
   }
 
-  void safelyRecordKeywordCompletion(SyntacticEntity entity) {
+  void safelyRecordKeywordCompletion(SyntacticEntity? entity) {
     if (_doExpectKeywordCompletions) {
       safelyRecordEntity(entity,
           kind: protocol.CompletionSuggestionKind.KEYWORD);
@@ -617,9 +614,10 @@
   @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
     if (_doIncludeSimpleIdentifier(node)) {
-      protocol.ElementKind elementKind;
-      if (node.staticElement?.kind != null) {
-        elementKind = protocol.convertElementKind(node.staticElement.kind);
+      protocol.ElementKind? elementKind;
+      var kind = node.staticElement?.kind;
+      if (kind != null) {
+        elementKind = protocol.convertElementKind(kind);
 
         // If the completed element kind is a getter or setter set the element
         // kind to null as the exact kind from the DAS is unknown at this
@@ -651,8 +649,8 @@
         //      constructor invocation in which case the "Foo" above is
         //      considered a constructor still
         if (elementKind == protocol.ElementKind.CLASS) {
-          if (node.parent?.parent is ConstructorName) {
-            var constructorName = node.parent.parent as ConstructorName;
+          var constructorName = node.parent?.parent;
+          if (constructorName is ConstructorName) {
             var instanceCreationExpression = constructorName.parent;
             if (instanceCreationExpression is InstanceCreationExpression &&
                 constructorName.type.name == node) {
@@ -759,12 +757,13 @@
   bool _doIncludeSimpleIdentifier(SimpleIdentifier node) {
     // Do not continue if this node is synthetic, or if the node is in a
     // declaration context
-    if (node == null || node.isSynthetic || node.inDeclarationContext()) {
+    if (node.isSynthetic || node.inDeclarationContext()) {
       return false;
     }
 
     // If the type of the SimpleIdentifier is dynamic, don't include.
-    if (node.staticType != null && node.staticType.isDynamic) {
+    var staticType = node.staticType;
+    if (staticType != null && staticType.isDynamic) {
       return false;
     }