pkg:compiler - enable and fix null operator lints

Change-Id: I5aaef20fdd61fd6ac9dc69978111fb680c7f99e5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/211624
Auto-Submit: Kevin Moore <kevmoo@google.com>
Commit-Queue: Kevin Moore <kevmoo@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
diff --git a/pkg/compiler/analysis_options.yaml b/pkg/compiler/analysis_options.yaml
index 22a29b3..2ab9f2f 100644
--- a/pkg/compiler/analysis_options.yaml
+++ b/pkg/compiler/analysis_options.yaml
@@ -15,3 +15,5 @@
   rules:
     - annotate_overrides
     - prefer_final_fields
+    - prefer_if_null_operators
+    - prefer_null_aware_operators
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index 25a1041..e8b8488 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -218,9 +218,8 @@
 
   @override
   Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks {
-    return _typeVariableBoundsSubtypeChecks != null
-        ? _typeVariableBoundsSubtypeChecks
-        : const <Pair<DartType, DartType>>[];
+    return _typeVariableBoundsSubtypeChecks ??
+        const <Pair<DartType, DartType>>[];
   }
 
   void registerConstSymbol(String name) {
@@ -230,7 +229,7 @@
 
   @override
   Iterable<String> get constSymbols {
-    return _constSymbols != null ? _constSymbols : const <String>[];
+    return _constSymbols ?? const <String>[];
   }
 
   void registerSpecializedGetInterceptor(Set<ClassEntity> classes) {
@@ -240,9 +239,7 @@
 
   @override
   Iterable<Set<ClassEntity>> get specializedGetInterceptors {
-    return _specializedGetInterceptors != null
-        ? _specializedGetInterceptors
-        : const <Set<ClassEntity>>[];
+    return _specializedGetInterceptors ?? const <Set<ClassEntity>>[];
   }
 
   void registerUseInterceptor() {
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index be3a777..09b4aea 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -962,7 +962,7 @@
     } else if (node is HInstruction) {
       element = node.sourceElement;
     }
-    return element != null ? element : currentElement;
+    return element ?? currentElement;
   }
 
   @override
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index 7c220bb..aff7306 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -1109,9 +1109,7 @@
     } else if (selector.isGetter) {
       if (element.isFunction) {
         // [functionType] is null if the inferrer did not run.
-        return types.functionType == null
-            ? types.dynamicType
-            : types.functionType;
+        return types.functionType ?? types.dynamicType;
       } else if (element.isField) {
         return typeOfMember(element);
       } else if (element.isGetter) {
diff --git a/pkg/compiler/lib/src/inferrer/powersets/powersets.dart b/pkg/compiler/lib/src/inferrer/powersets/powersets.dart
index b313818..b4f6789 100644
--- a/pkg/compiler/lib/src/inferrer/powersets/powersets.dart
+++ b/pkg/compiler/lib/src/inferrer/powersets/powersets.dart
@@ -45,7 +45,7 @@
 }
 
 AbstractValue unwrapOrNull(PowersetValue powerset) {
-  return powerset == null ? null : powerset._abstractValue;
+  return powerset?._abstractValue;
 }
 
 PowersetValue wrapOrNull(AbstractValue abstractValue, int powersetBits) {
diff --git a/pkg/compiler/lib/src/inferrer/powersets/wrapped.dart b/pkg/compiler/lib/src/inferrer/powersets/wrapped.dart
index aa3679c..7e21d25 100644
--- a/pkg/compiler/lib/src/inferrer/powersets/wrapped.dart
+++ b/pkg/compiler/lib/src/inferrer/powersets/wrapped.dart
@@ -37,7 +37,7 @@
 }
 
 AbstractValue unwrapOrNull(WrappedAbstractValue wrapped) {
-  return wrapped == null ? null : wrapped._abstractValue;
+  return wrapped?._abstractValue;
 }
 
 WrappedAbstractValue wrapOrNull(AbstractValue abstractValue) {
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 5257267..334c9cf 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -47,7 +47,7 @@
   final MemberTypeInformation context;
 
   /// The element this [TypeInformation] node belongs to.
-  MemberEntity get contextMember => context == null ? null : context.member;
+  MemberEntity get contextMember => context?.member;
 
   Iterable<TypeInformation> get inputs => _inputs;
 
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index a0ccdf2..75aa83d 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -77,8 +77,7 @@
 
   @override
   SourceSpan get sourceSpan {
-    SourceLocation location =
-        startPosition != null ? startPosition : innerPosition;
+    SourceLocation location = startPosition ?? innerPosition;
     Uri uri = location.sourceUri;
     int offset = location.offset;
     return SourceSpan(uri, offset, offset);
diff --git a/pkg/compiler/lib/src/ir/scope_visitor.dart b/pkg/compiler/lib/src/ir/scope_visitor.dart
index 4bb75d5..a95894c 100644
--- a/pkg/compiler/lib/src/ir/scope_visitor.dart
+++ b/pkg/compiler/lib/src/ir/scope_visitor.dart
@@ -402,7 +402,7 @@
             // If this typeParameter is part of a typedef then its parent is
             // null because it has no context. Just pass in null for the
             // context in that case.
-            typeParameter.parent != null ? typeParameter.parent.parent : null);
+            typeParameter.parent?.parent);
 
     ir.TreeNode context = _executableContext;
     if (_isInsideClosure && context is ir.Procedure && context.isFactory) {
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index f5b28da..ffbad60 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -777,7 +777,7 @@
   @override
   ClassChecks operator [](ClassEntity element) {
     ClassChecks result = map[element];
-    return result != null ? result : const ClassChecks.empty();
+    return result ?? const ClassChecks.empty();
   }
 
   void operator []=(ClassEntity element, ClassChecks checks) {
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index 1e469ff..d379248 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -406,7 +406,7 @@
       }
     }
     Iterable<ClassEntity> uses = _liveMixinUses[cls];
-    return uses != null ? uses : const <ClassEntity>[];
+    return uses ?? const <ClassEntity>[];
   }
 
   @override
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index add4b9a..744a46b 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -6426,15 +6426,13 @@
     // The body has either the catch or the finally block as successor.
     if (endTryBlock != null) {
       assert(startCatchBlock != null || startFinallyBlock != null);
-      endTryBlock.addSuccessor(
-          startCatchBlock != null ? startCatchBlock : startFinallyBlock);
+      endTryBlock.addSuccessor(startCatchBlock ?? startFinallyBlock);
       endTryBlock.addSuccessor(exitBlock);
     }
 
     // The catch block has either the finally or the exit block as
     // successor.
-    endCatchBlock?.addSuccessor(
-        startFinallyBlock != null ? startFinallyBlock : exitBlock);
+    endCatchBlock?.addSuccessor(startFinallyBlock ?? exitBlock);
 
     // The finally block has the exit block as successor.
     endFinallyBlock?.addSuccessor(exitBlock);
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 501d09f..7fc8c53 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -565,7 +565,7 @@
   @override
   HInstruction visitInvokeUnary(HInvokeUnary node) {
     HInstruction folded = foldUnary(node.operation(), node.operand);
-    return folded != null ? folded : node;
+    return folded ?? node;
   }
 
   HInstruction foldUnary(
@@ -1161,7 +1161,7 @@
   @override
   HInstruction visitIdentity(HIdentity node) {
     HInstruction newInstruction = handleIdentityCheck(node);
-    return newInstruction == null ? super.visitIdentity(node) : newInstruction;
+    return newInstruction ?? super.visitIdentity(node);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/ssa/variable_allocator.dart b/pkg/compiler/lib/src/ssa/variable_allocator.dart
index f4024bd..2bf062d 100644
--- a/pkg/compiler/lib/src/ssa/variable_allocator.dart
+++ b/pkg/compiler/lib/src/ssa/variable_allocator.dart
@@ -101,7 +101,7 @@
         liveIntervals.putIfAbsent(instruction, () => LiveInterval());
     int lastId = liveInstructions[instruction];
     // If [lastId] is null, then this instruction is not being used.
-    interval.add(LiveRange(id, lastId == null ? id : lastId));
+    interval.add(LiveRange(id, lastId ?? id));
     // The instruction is defined at [id].
     interval.start = id;
     liveInstructions.remove(instruction);
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index a7188d9..5dc7629 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -906,7 +906,7 @@
 
   @override
   ClassEntity get current {
-    return currentNode != null ? currentNode.cls : null;
+    return currentNode?.cls;
   }
 
   @override
diff --git a/pkg/compiler/test/analysis_options.yaml b/pkg/compiler/test/analysis_options.yaml
index ca57e09..7926857 100644
--- a/pkg/compiler/test/analysis_options.yaml
+++ b/pkg/compiler/test/analysis_options.yaml
@@ -16,3 +16,5 @@
 linter:
   rules:
     - annotate_overrides
+    - prefer_if_null_operators
+    - prefer_null_aware_operators
diff --git a/pkg/compiler/test/helpers/text_helpers.dart b/pkg/compiler/test/helpers/text_helpers.dart
index cab50ac..d434a2a 100644
--- a/pkg/compiler/test/helpers/text_helpers.dart
+++ b/pkg/compiler/test/helpers/text_helpers.dart
@@ -17,8 +17,8 @@
       if (filter != null && filter(i, lines1, lines2)) {
         String line1 = 0 <= i && i < lines1.length ? lines1[i] : null;
         String line2 = 0 <= i && i < lines2.length ? lines2[i] : null;
-        String text = line1 == null ? '<eof>' : line1;
-        String newText = line2 == null ? '<eof>' : line2;
+        String text = line1 ?? '<eof>';
+        String newText = line2 ?? '<eof>';
         print('(skipped) - $i ${text}');
         print('(skipped) + $i ${newText}');
       } else {
@@ -41,8 +41,8 @@
               print('  $j $line1');
             }
           } else {
-            String text = line1 == null ? '<eof>' : line1;
-            String newText = line2 == null ? '<eof>' : line2;
+            String text = line1 ?? '<eof>';
+            String newText = line2 ?? '<eof>';
 
             if (text.length > 80 && newText.length > 80) {
               flushPendingLines();
diff --git a/pkg/compiler/test/js/js_spec_string_test.dart b/pkg/compiler/test/js/js_spec_string_test.dart
index 8332491..ad274e5 100644
--- a/pkg/compiler/test/js/js_spec_string_test.dart
+++ b/pkg/compiler/test/js/js_spec_string_test.dart
@@ -96,9 +96,7 @@
         returns: returns,
         creates: creates,
         expectedSideEffects: expectedSideEffects,
-        expectError: sideEffectsExpectError == null
-            ? expectError
-            : sideEffectsExpectError);
+        expectError: sideEffectsExpectError ?? expectError);
   }
 
   SideEffects emptySideEffects = new SideEffects.empty();
diff --git a/pkg/compiler/test/jsinterop/declaration_test.dart b/pkg/compiler/test/jsinterop/declaration_test.dart
index 4d9cb2a..0e8b004 100644
--- a/pkg/compiler/test/jsinterop/declaration_test.dart
+++ b/pkg/compiler/test/jsinterop/declaration_test.dart
@@ -386,7 +386,7 @@
       this.warnings: const <MessageKind>[]})
       : _source = null;
 
-  String get source => _source != null ? _source : _sources['main.dart'];
+  String get source => _source ?? _sources['main.dart'];
 
   Map<String, String> get sources =>
       _source != null ? {'main.dart': _source} : _sources;
diff --git a/pkg/compiler/test/model/class_set_test.dart b/pkg/compiler/test/model/class_set_test.dart
index d884344..fd8526e 100644
--- a/pkg/compiler/test/model/class_set_test.dart
+++ b/pkg/compiler/test/model/class_set_test.dart
@@ -96,7 +96,7 @@
   void checkState(ClassEntity root,
       {ClassEntity currentNode, List<ClassEntity> stack}) {
     ClassEntity classOf(ClassHierarchyNode node) {
-      return node != null ? node.cls : null;
+      return node?.cls;
     }
 
     List<ClassEntity> classesOf(Iterable<ClassHierarchyNode> list) {
diff --git a/pkg/compiler/test/sourcemaps/helpers/diff.dart b/pkg/compiler/test/sourcemaps/helpers/diff.dart
index c00709b..0b2e9c3 100644
--- a/pkg/compiler/test/sourcemaps/helpers/diff.dart
+++ b/pkg/compiler/test/sourcemaps/helpers/diff.dart
@@ -37,7 +37,7 @@
   }
 
   @override
-  String toString() => '$type${index != null ? index : ''}';
+  String toString() => '$type${index ?? ''}';
 }
 
 /// A block of code in an output column.
diff --git a/pkg/compiler/test/sourcemaps/helpers/output_structure.dart b/pkg/compiler/test/sourcemaps/helpers/output_structure.dart
index be586f6..f2f33b8 100644
--- a/pkg/compiler/test/sourcemaps/helpers/output_structure.dart
+++ b/pkg/compiler/test/sourcemaps/helpers/output_structure.dart
@@ -282,7 +282,7 @@
       'from': from,
       'to': to,
       'children': children.map((child) => child.toJson(strategy)).toList(),
-      'codeSource': codeSource != null ? codeSource.toJson() : null,
+      'codeSource': codeSource?.toJson(),
     };
   }