diff --git a/pkg/compiler/analysis_options.yaml b/pkg/compiler/analysis_options.yaml index 22a29b365f5..2ab9f2f796f 100644 --- a/pkg/compiler/analysis_options.yaml +++ b/pkg/compiler/analysis_options.yaml @@ -15,3 +15,5 @@ linter: 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 25a1041b88f..e8b8488a71d 100644 --- a/pkg/compiler/lib/src/common/codegen.dart +++ b/pkg/compiler/lib/src/common/codegen.dart @@ -218,9 +218,8 @@ class _CodegenImpact extends WorldImpactBuilderImpl implements CodegenImpact { @override Iterable> get typeVariableBoundsSubtypeChecks { - return _typeVariableBoundsSubtypeChecks != null - ? _typeVariableBoundsSubtypeChecks - : const >[]; + return _typeVariableBoundsSubtypeChecks ?? + const >[]; } void registerConstSymbol(String name) { @@ -230,7 +229,7 @@ class _CodegenImpact extends WorldImpactBuilderImpl implements CodegenImpact { @override Iterable get constSymbols { - return _constSymbols != null ? _constSymbols : const []; + return _constSymbols ?? const []; } void registerSpecializedGetInterceptor(Set classes) { @@ -240,9 +239,7 @@ class _CodegenImpact extends WorldImpactBuilderImpl implements CodegenImpact { @override Iterable> get specializedGetInterceptors { - return _specializedGetInterceptors != null - ? _specializedGetInterceptors - : const >[]; + return _specializedGetInterceptors ?? const >[]; } void registerUseInterceptor() { diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart index be3a777bbfd..09b4aeabee2 100644 --- a/pkg/compiler/lib/src/compiler.dart +++ b/pkg/compiler/lib/src/compiler.dart @@ -962,7 +962,7 @@ class CompilerDiagnosticReporter extends DiagnosticReporter { } 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 7c220bb132b..aff7306c0fc 100644 --- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart +++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart @@ -1109,9 +1109,7 @@ class InferrerEngine { } 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 b313818ab6e..b4f6789431b 100644 --- a/pkg/compiler/lib/src/inferrer/powersets/powersets.dart +++ b/pkg/compiler/lib/src/inferrer/powersets/powersets.dart @@ -45,7 +45,7 @@ class PowersetValue implements AbstractValue { } 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 aa3679c2592..7e21d25a275 100644 --- a/pkg/compiler/lib/src/inferrer/powersets/wrapped.dart +++ b/pkg/compiler/lib/src/inferrer/powersets/wrapped.dart @@ -37,7 +37,7 @@ class WrappedAbstractValue implements AbstractValue { } 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 52572670739..334c9cf63fb 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 @@ abstract class TypeInformation { final MemberTypeInformation context; /// The element this [TypeInformation] node belongs to. - MemberEntity get contextMember => context == null ? null : context.member; + MemberEntity get contextMember => context?.member; Iterable get inputs => _inputs; diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart index a0ccdf205a5..75aa83d51f0 100644 --- a/pkg/compiler/lib/src/io/position_information.dart +++ b/pkg/compiler/lib/src/io/position_information.dart @@ -77,8 +77,7 @@ class PositionSourceInformation extends SourceInformation { @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 4bb75d58287..a95894c2fb7 100644 --- a/pkg/compiler/lib/src/ir/scope_visitor.dart +++ b/pkg/compiler/lib/src/ir/scope_visitor.dart @@ -402,7 +402,7 @@ class ScopeModelBuilder extends ir.Visitor // 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 f5b28da616c..ffbad60e4dc 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 @@ class TypeCheckMapping implements TypeChecks { @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 1e469ff8602..d379248f1c6 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 @@ class JsClosedWorld implements JClosedWorld { } } Iterable uses = _liveMixinUses[cls]; - return uses != null ? uses : const []; + return uses ?? const []; } @override diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart index add4b9a89a9..744a46b9ef8 100644 --- a/pkg/compiler/lib/src/ssa/builder_kernel.dart +++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart @@ -6426,15 +6426,13 @@ class TryCatchFinallyBuilder { // 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 501d09f7adb..7fc8c53583a 100644 --- a/pkg/compiler/lib/src/ssa/optimize.dart +++ b/pkg/compiler/lib/src/ssa/optimize.dart @@ -565,7 +565,7 @@ class SsaInstructionSimplifier extends HBaseVisitor @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 @@ class SsaInstructionSimplifier extends HBaseVisitor @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 f4024bdef56..2bf062d94a1 100644 --- a/pkg/compiler/lib/src/ssa/variable_allocator.dart +++ b/pkg/compiler/lib/src/ssa/variable_allocator.dart @@ -101,7 +101,7 @@ class LiveEnvironment { 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 a7188d986b5..5dc762929ab 100644 --- a/pkg/compiler/lib/src/universe/class_set.dart +++ b/pkg/compiler/lib/src/universe/class_set.dart @@ -906,7 +906,7 @@ class ClassHierarchyNodeIterator implements Iterator { @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 ca57e09b791..7926857cadc 100644 --- a/pkg/compiler/test/analysis_options.yaml +++ b/pkg/compiler/test/analysis_options.yaml @@ -16,3 +16,5 @@ analyzer: 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 cab50ac3864..d434a2ac256 100644 --- a/pkg/compiler/test/helpers/text_helpers.dart +++ b/pkg/compiler/test/helpers/text_helpers.dart @@ -17,8 +17,8 @@ int checkEqualContentAndShowDiff(String text1, String text2, 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 ? '' : line1; - String newText = line2 == null ? '' : line2; + String text = line1 ?? ''; + String newText = line2 ?? ''; print('(skipped) - $i ${text}'); print('(skipped) + $i ${newText}'); } else { @@ -41,8 +41,8 @@ int checkEqualContentAndShowDiff(String text1, String text2, print(' $j $line1'); } } else { - String text = line1 == null ? '' : line1; - String newText = line2 == null ? '' : line2; + String text = line1 ?? ''; + String newText = line2 ?? ''; 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 8332491691c..ad274e5caf6 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 @@ void testWithSideEffects(DartTypes dartTypes, String specString, 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 4d9cb2a53ba..0e8b004c8ff 100644 --- a/pkg/compiler/test/jsinterop/declaration_test.dart +++ b/pkg/compiler/test/jsinterop/declaration_test.dart @@ -386,7 +386,7 @@ class Test { this.warnings: const []}) : _source = null; - String get source => _source != null ? _source : _sources['main.dart']; + String get source => _source ?? _sources['main.dart']; Map 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 d8843448def..fd8526e3208 100644 --- a/pkg/compiler/test/model/class_set_test.dart +++ b/pkg/compiler/test/model/class_set_test.dart @@ -96,7 +96,7 @@ testIterators() async { void checkState(ClassEntity root, {ClassEntity currentNode, List stack}) { ClassEntity classOf(ClassHierarchyNode node) { - return node != null ? node.cls : null; + return node?.cls; } List classesOf(Iterable list) { diff --git a/pkg/compiler/test/sourcemaps/helpers/diff.dart b/pkg/compiler/test/sourcemaps/helpers/diff.dart index c00709b7d4c..0b2e9c33fd9 100644 --- a/pkg/compiler/test/sourcemaps/helpers/diff.dart +++ b/pkg/compiler/test/sourcemaps/helpers/diff.dart @@ -37,7 +37,7 @@ class DiffColumn { } @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 be586f6f153..f2f33b81f92 100644 --- a/pkg/compiler/test/sourcemaps/helpers/output_structure.dart +++ b/pkg/compiler/test/sourcemaps/helpers/output_structure.dart @@ -282,7 +282,7 @@ abstract class AbstractEntity extends OutputEntity { 'from': from, 'to': to, 'children': children.map((child) => child.toJson(strategy)).toList(), - 'codeSource': codeSource != null ? codeSource.toJson() : null, + 'codeSource': codeSource?.toJson(), }; }