diff --git a/lib/src/ast.dart b/lib/src/ast.dart index a72533b45..bb42509e1 100644 --- a/lib/src/ast.dart +++ b/lib/src/ast.dart @@ -99,8 +99,10 @@ bool inPrivateMember(AstNode node) { } /// Returns `true` if the given [declaration] is annotated `@deprecated`. -bool isDeprecated(Declaration declaration) => - declaration.declaredElement!.hasDeprecated; +bool isDeprecated(Declaration declaration) { + var declaredElement = declaration.declaredElement; + return declaredElement != null && declaredElement.hasDeprecated; +} /// Returns `true` if this element is the `==` method declaration. bool isEquals(ClassMember element) => @@ -121,7 +123,8 @@ bool isHashCode(ClassMember element) => /// [package]'s `lib/` directory tree. bool isInLibDir(CompilationUnit node, WorkspacePackage? package) { if (package == null) return false; - final cuPath = node.declaredElement!.library.source.fullName; + final cuPath = node.declaredElement?.library.source.fullName; + if (cuPath == null) return false; final libDir = path.join(package.root, 'lib'); return path.isWithin(libDir, cuPath); } @@ -146,8 +149,10 @@ bool isProtected(Declaration declaration) => declaration.metadata.any((Annotation a) => a.name.name == 'protected'); /// Returns `true` if the given [ClassMember] is a public method. -bool isPublicMethod(ClassMember m) => - isMethod(m) && m.declaredElement!.isPublic; +bool isPublicMethod(ClassMember m) { + var declaredElement = m.declaredElement; + return declaredElement != null && isMethod(m) && declaredElement.isPublic; +} /// Returns `true` if the given method [declaration] is a "simple getter". /// @@ -287,8 +292,8 @@ bool _checkForSimpleSetter(MethodDeclaration setter, Expression expression) { return false; } - var parameters = setter.parameters!.parameters; - if (parameters.length == 1) { + var parameters = setter.parameters?.parameters; + if (parameters != null && parameters.length == 1) { return rightElement == parameters[0].declaredElement; } } diff --git a/lib/src/formatter.dart b/lib/src/formatter.dart index 137865ab5..fde572c6f 100644 --- a/lib/src/formatter.dart +++ b/lib/src/formatter.dart @@ -60,7 +60,7 @@ Future writeBenchmarks( final pedanticRuleset = await pedanticRules; final stats = timings.keys.map((t) { final details = pedanticRuleset.contains(t) ? ' [pedantic]' : ''; - return _Stat('$t$details', timings[t]); + return _Stat('$t$details', timings[t] ?? 0); }).toList(); _writeTimings(out, stats, 0); } @@ -95,7 +95,7 @@ void _writeTimings(IOSink out, List<_Stat> timings, int summaryLength) { timings.sort(); for (var stat in timings) { - totalTime += stat.elapsed!; + totalTime += stat.elapsed; // TODO: Shame timings slower than 100ms? // TODO: Present both total times and time per count? out.writeln( @@ -266,8 +266,9 @@ class SimpleFormatter implements ReportFormatter { } void writeLints() { + var filter = this.filter; errors.forEach((info) => (info.errors.toList()..sort(compare)).forEach((e) { - if (filter != null && filter!.filter(e)) { + if (filter != null && filter.filter(e)) { filteredLintCount++; } else { ++errorCount; @@ -299,7 +300,7 @@ class SimpleFormatter implements ReportFormatter { void writeTimings() { final timers = lintRegistry.timers; final timings = timers.keys - .map((t) => _Stat(t, timers[t]!.elapsedMilliseconds)) + .map((t) => _Stat(t, timers[t]?.elapsedMilliseconds ?? 0)) .toList(); _writeTimings(out, timings, _summaryLength); } @@ -322,10 +323,10 @@ class SimpleFormatter implements ReportFormatter { class _Stat implements Comparable<_Stat> { final String name; - final int? elapsed; + final int elapsed; _Stat(this.name, this.elapsed); @override - int compareTo(_Stat other) => other.elapsed! - elapsed!; + int compareTo(_Stat other) => other.elapsed - elapsed; } diff --git a/lib/src/rules/always_put_required_named_parameters_first.dart b/lib/src/rules/always_put_required_named_parameters_first.dart index f87b32863..f8d9d6606 100644 --- a/lib/src/rules/always_put_required_named_parameters_first.dart +++ b/lib/src/rules/always_put_required_named_parameters_first.dart @@ -51,8 +51,8 @@ class _Visitor extends SimpleAstVisitor { void visitFormalParameterList(FormalParameterList node) { var nonRequiredSeen = false; for (var param in node.parameters.where((p) => p.isNamed)) { - var element = param.declaredElement!; - if (element.hasRequired || element.isRequiredNamed) { + var element = param.declaredElement; + if (element != null && (element.hasRequired || element.isRequiredNamed)) { if (nonRequiredSeen) { var identifier = param.identifier; if (identifier != null) { diff --git a/lib/src/rules/always_require_non_null_named_parameters.dart b/lib/src/rules/always_require_non_null_named_parameters.dart index 17de2e7aa..80baf2312 100644 --- a/lib/src/rules/always_require_non_null_named_parameters.dart +++ b/lib/src/rules/always_require_non_null_named_parameters.dart @@ -73,10 +73,12 @@ class _Visitor extends SimpleAstVisitor { // Only named parameters if (p.isNamed) { final parameter = p as DefaultFormalParameter; - // Without a default value or marked @required - if (parameter.defaultValue == null && - !parameter.declaredElement!.hasRequired) { - params.add(parameter); + // Without a default value or marked required + if (parameter.defaultValue == null) { + var declaredElement = parameter.declaredElement; + if (declaredElement != null && !declaredElement.hasRequired) { + params.add(parameter); + } } } } @@ -97,8 +99,10 @@ class _Visitor extends SimpleAstVisitor { void _checkAssert( Expression assertExpression, List params) { for (final param in params) { - if (_hasAssertNotNull(assertExpression, param.identifier!.name)) { - rule.reportLintForToken(param.identifier!.beginToken); + var identifier = param.identifier; + if (identifier != null && + _hasAssertNotNull(assertExpression, identifier.name)) { + rule.reportLintForToken(identifier.beginToken); params.remove(param); return; } diff --git a/lib/src/rules/avoid_unnecessary_containers.dart b/lib/src/rules/avoid_unnecessary_containers.dart index 8dfd0ea71..84007b6b7 100644 --- a/lib/src/rules/avoid_unnecessary_containers.dart +++ b/lib/src/rules/avoid_unnecessary_containers.dart @@ -75,8 +75,8 @@ class _Visitor extends SimpleAstVisitor { } final parent = node.parent; if (parent is NamedExpression && parent.name.label.name == 'child') { - final args = parent.thisOrAncestorOfType()!; - if (args.arguments.length == 1) { + final args = parent.thisOrAncestorOfType(); + if (args?.arguments.length == 1) { final parentCreation = parent.thisOrAncestorOfType(); if (parentCreation != null) { diff --git a/lib/src/rules/cast_nullable_to_non_nullable.dart b/lib/src/rules/cast_nullable_to_non_nullable.dart index 9ee1409b2..5f24296c9 100644 --- a/lib/src/rules/cast_nullable_to_non_nullable.dart +++ b/lib/src/rules/cast_nullable_to_non_nullable.dart @@ -67,9 +67,10 @@ class _Visitor extends SimpleAstVisitor { @override void visitAsExpression(AsExpression node) { - final expressionType = node.expression.staticType!; + final expressionType = node.expression.staticType; final type = node.type.type; - if (!expressionType.isDynamic && + if (expressionType != null && + !expressionType.isDynamic && context.typeSystem.isNullable(expressionType) && context.typeSystem.isNonNullable(type!)) { rule.reportLint(node); diff --git a/lib/src/rules/deprecated_consistency.dart b/lib/src/rules/deprecated_consistency.dart index 83c34bdc4..91a94ac38 100644 --- a/lib/src/rules/deprecated_consistency.dart +++ b/lib/src/rules/deprecated_consistency.dart @@ -74,8 +74,9 @@ class _Visitor extends SimpleAstVisitor { @override void visitConstructorDeclaration(ConstructorDeclaration node) { - var constructorElement = node.declaredElement!; - if (constructorElement.enclosingElement.hasDeprecated && + var constructorElement = node.declaredElement; + if (constructorElement != null && + constructorElement.enclosingElement.hasDeprecated && !constructorElement.hasDeprecated) { rule.reportLint(node); } diff --git a/lib/src/rules/invariant_booleans.dart b/lib/src/rules/invariant_booleans.dart index 0234f1cbf..c39aa21ab 100644 --- a/lib/src/rules/invariant_booleans.dart +++ b/lib/src/rules/invariant_booleans.dart @@ -141,12 +141,12 @@ class _InvariantBooleansVisitor extends ConditionScopeVisitor { @override void visitCondition(Expression? node) { // Right part discards reporting a subexpression already reported. - if (node?.staticType?.isDartCoreBool != true) { + if (node == null || node.staticType?.isDartCoreBool != true) { return; } - final testedNodes = _findPreviousTestedExpressions(node!); - testedNodes.evaluateInvariant()!.forEach((ContradictoryComparisons e) { + final testedNodes = _findPreviousTestedExpressions(node); + testedNodes?.evaluateInvariant()?.forEach((ContradictoryComparisons e) { final reportRule = _ContradictionReportRule(e); reportRule ..reporter = rule.reporter @@ -166,10 +166,13 @@ class _InvariantBooleansVisitor extends ConditionScopeVisitor { } } - TestedExpressions _findPreviousTestedExpressions(Expression node) { + TestedExpressions? _findPreviousTestedExpressions(Expression node) { final elements = _getElementsInExpression(node); - final conjunctions = getTrueExpressions(elements).toSet(); - final negations = getFalseExpressions(elements).toSet(); + final conjunctions = getTrueExpressions(elements)?.toSet(); + final negations = getFalseExpressions(elements)?.toSet(); + if (conjunctions == null || negations == null) { + return null; + } return TestedExpressions(node, conjunctions, negations); } } diff --git a/lib/src/rules/lines_longer_than_80_chars.dart b/lib/src/rules/lines_longer_than_80_chars.dart index 089ba95eb..f3bea2d53 100644 --- a/lib/src/rules/lines_longer_than_80_chars.dart +++ b/lib/src/rules/lines_longer_than_80_chars.dart @@ -159,11 +159,11 @@ class _AllowedLongLineVisitor extends RecursiveAstVisitor { } class _LineInfo { - final int? index; - final int? offset; - final int? end; - _LineInfo({this.index, this.offset, this.end}); - int get length => end! - offset!; + final int index; + final int offset; + final int end; + _LineInfo({required this.index, required this.offset, required this.end}); + int get length => end - offset; } class _Visitor extends SimpleAstVisitor { @@ -175,7 +175,10 @@ class _Visitor extends SimpleAstVisitor { @override void visitCompilationUnit(CompilationUnit node) { - final lineInfo = node.lineInfo!; + final lineInfo = node.lineInfo; + if (lineInfo == null) { + return; + } final lineCount = lineInfo.lineCount; final longLines = <_LineInfo>[]; for (var i = 0; i < lineCount; i++) { @@ -213,9 +216,9 @@ class _Visitor extends SimpleAstVisitor { ]; for (final line in longLines) { - if (allowedLines.contains(line.index! + 1)) continue; + if (allowedLines.contains(line.index + 1)) continue; rule.reporter - .reportErrorForOffset(rule.lintCode, line.offset!, line.length); + .reportErrorForOffset(rule.lintCode, line.offset, line.length); } } } diff --git a/lib/src/rules/prefer_asserts_in_initializer_lists.dart b/lib/src/rules/prefer_asserts_in_initializer_lists.dart index 1a32f67e4..e52a84730 100644 --- a/lib/src/rules/prefer_asserts_in_initializer_lists.dart +++ b/lib/src/rules/prefer_asserts_in_initializer_lists.dart @@ -51,7 +51,7 @@ class PreferAssertsInInitializerLists extends LintRule implements NodeLintRule { } class _AssertVisitor extends RecursiveAstVisitor { - final ConstructorElement? constructorElement; + final ConstructorElement constructorElement; final _ClassAndSuperClasses? classAndSuperClasses; bool needInstance = false; @@ -71,7 +71,7 @@ class _AssertVisitor extends RecursiveAstVisitor { element is PropertyAccessorElement && !element.isStatic && _hasAccessor(element) && - !constructorElement!.parameters + !constructorElement.parameters .whereType() .any((p) => p.field?.getter == element); } @@ -81,11 +81,15 @@ class _AssertVisitor extends RecursiveAstVisitor { needInstance = true; } - bool _hasAccessor(PropertyAccessorElement element) => - classAndSuperClasses!.classes.contains(element.enclosingElement); + bool _hasAccessor(PropertyAccessorElement element) { + var classes = classAndSuperClasses?.classes; + return classes != null && classes.contains(element.enclosingElement); + } - bool _hasMethod(MethodElement element) => - classAndSuperClasses!.classes.contains(element.enclosingElement); + bool _hasMethod(MethodElement element) { + var classes = classAndSuperClasses?.classes; + return classes != null && classes.contains(element.enclosingElement); + } } /// Lazy cache of elements. @@ -126,7 +130,8 @@ class _Visitor extends SimpleAstVisitor { @override void visitConstructorDeclaration(ConstructorDeclaration node) { - if (node.declaredElement!.isFactory) return; + var declaredElement = node.declaredElement; + if (declaredElement == null || declaredElement.isFactory) return; final body = node.body; if (body is BlockFunctionBody) { @@ -134,7 +139,7 @@ class _Visitor extends SimpleAstVisitor { if (statement is! AssertStatement) break; final assertVisitor = - _AssertVisitor(node.declaredElement, _classAndSuperClasses); + _AssertVisitor(declaredElement, _classAndSuperClasses); statement.visitChildren(assertVisitor); if (!assertVisitor.needInstance) { rule.reportLintForToken(statement.beginToken); diff --git a/lib/src/rules/prefer_bool_in_asserts.dart b/lib/src/rules/prefer_bool_in_asserts.dart index cfb02b5d4..9ca371553 100644 --- a/lib/src/rules/prefer_bool_in_asserts.dart +++ b/lib/src/rules/prefer_bool_in_asserts.dart @@ -70,8 +70,9 @@ class _Visitor extends SimpleAstVisitor { @override void visitAssertStatement(AssertStatement node) { - var conditionType = _unbound(node.condition.staticType)!; - if (!typeSystem.isAssignableTo(conditionType, boolType)) { + var conditionType = _unbound(node.condition.staticType); + if (conditionType != null && + !typeSystem.isAssignableTo(conditionType, boolType)) { rule.reportLint(node.condition); } } diff --git a/lib/src/rules/prefer_const_constructors_in_immutables.dart b/lib/src/rules/prefer_const_constructors_in_immutables.dart index 9e587b117..873a47ae4 100644 --- a/lib/src/rules/prefer_const_constructors_in_immutables.dart +++ b/lib/src/rules/prefer_const_constructors_in_immutables.dart @@ -75,14 +75,17 @@ class _Visitor extends SimpleAstVisitor { @override void visitConstructorDeclaration(ConstructorDeclaration node) { - final element = node.declaredElement!; + final element = node.declaredElement; + if (element == null) { + return; + } final isRedirected = element.isFactory && element.redirectedConstructor != null; if (node.body is EmptyFunctionBody && !element.isConst && !_hasMixin(element.enclosingElement) && _hasImmutableAnnotation(element.enclosingElement) && - (isRedirected && element.redirectedConstructor!.isConst || + (isRedirected && element.redirectedConstructor?.isConst == true || (!isRedirected && _hasConstConstructorInvocation(node) && context.canBeConstConstructor(node)))) { @@ -91,23 +94,29 @@ class _Visitor extends SimpleAstVisitor { } bool _hasConstConstructorInvocation(ConstructorDeclaration node) { - final clazz = node.declaredElement!.enclosingElement; + var declaredElement = node.declaredElement; + if (declaredElement == null) { + return false; + } + final clazz = declaredElement.enclosingElement; // construct with super final superInvocation = node.initializers .firstWhereOrNull((e) => e is SuperConstructorInvocation) as SuperConstructorInvocation?; - if (superInvocation != null) return superInvocation.staticElement!.isConst; + if (superInvocation != null) { + return superInvocation.staticElement?.isConst == true; + } // construct with this final redirectInvocation = node.initializers .firstWhereOrNull((e) => e is RedirectingConstructorInvocation) as RedirectingConstructorInvocation?; if (redirectInvocation != null) { - return redirectInvocation.staticElement!.isConst; + return redirectInvocation.staticElement?.isConst == true; } // construct with implicit super() - return clazz.supertype!.constructors - .firstWhere((e) => e.name.isEmpty) - .isConst; + var supertype = clazz.supertype; + return supertype != null && + supertype.constructors.firstWhere((e) => e.name.isEmpty).isConst; } bool _hasImmutableAnnotation(ClassElement clazz) { diff --git a/lib/src/rules/prefer_const_literals_to_create_immutables.dart b/lib/src/rules/prefer_const_literals_to_create_immutables.dart index 3e4df4e5b..3c65e0c62 100644 --- a/lib/src/rules/prefer_const_literals_to_create_immutables.dart +++ b/lib/src/rules/prefer_const_literals_to_create_immutables.dart @@ -119,7 +119,7 @@ class _Visitor extends SimpleAstVisitor { node is SetOrMapLiteral || node is MapLiteralEntry || node is NamedExpression)) { - node = node!.parent; + node = node?.parent; } if (!(node is InstanceCreationExpression && _hasImmutableAnnotation(node.staticType))) { diff --git a/lib/src/rules/prefer_contains.dart b/lib/src/rules/prefer_contains.dart index 7ed71aa73..e39ba0627 100644 --- a/lib/src/rules/prefer_contains.dart +++ b/lib/src/rules/prefer_contains.dart @@ -136,17 +136,17 @@ class _Visitor extends SimpleAstVisitor { final rightOperand = binaryExpression.rightOperand; final rightValue = context.evaluateConstant(rightOperand).value; - if (rightValue?.type?.isDartCoreInt == true) { + if (rightValue != null && rightValue.type?.isDartCoreInt == true) { // Constant is on right side of comparison operator - _checkConstant(binaryExpression, rightValue!.toIntValue(), operator.type); + _checkConstant(binaryExpression, rightValue.toIntValue(), operator.type); return; } final leftOperand = binaryExpression.leftOperand; final leftValue = context.evaluateConstant(leftOperand).value; - if (leftValue?.type?.isDartCoreInt == true) { + if (leftValue != null && leftValue.type?.isDartCoreInt == true) { // Constants is on left side of comparison operator - _checkConstant(binaryExpression, leftValue!.toIntValue(), + _checkConstant(binaryExpression, leftValue.toIntValue(), _invertedTokenType(operator.type)); } } diff --git a/lib/src/rules/prefer_for_elements_to_map_fromIterable.dart b/lib/src/rules/prefer_for_elements_to_map_fromIterable.dart index 34959efaf..a27eec7c0 100644 --- a/lib/src/rules/prefer_for_elements_to_map_fromIterable.dart +++ b/lib/src/rules/prefer_for_elements_to_map_fromIterable.dart @@ -58,8 +58,9 @@ class _Visitor extends SimpleAstVisitor { @override void visitInstanceCreationExpression(InstanceCreationExpression creation) { final element = creation.constructorName.staticElement; - if (element?.name != 'fromIterable' || - element!.enclosingElement != context.typeProvider.mapElement) { + if (element == null || + element.name != 'fromIterable' || + element.enclosingElement != context.typeProvider.mapElement) { return; } @@ -94,8 +95,10 @@ class _Visitor extends SimpleAstVisitor { if (argument is NamedExpression && argument.name.label.name == name) { final expression = argument.expression.unParenthesized; if (expression is FunctionExpression) { - final parameters = expression.parameters!.parameters; - if (parameters.length == 1 && parameters[0].isRequired) { + final parameters = expression.parameters?.parameters; + if (parameters != null && + parameters.length == 1 && + parameters[0].isRequired) { if (extractBody(expression) != null) { return expression; } diff --git a/lib/src/rules/prefer_initializing_formals.dart b/lib/src/rules/prefer_initializing_formals.dart index edb97f810..ce1f507e6 100644 --- a/lib/src/rules/prefer_initializing_formals.dart +++ b/lib/src/rules/prefer_initializing_formals.dart @@ -93,7 +93,7 @@ Element? _getLeftElement(AssignmentExpression assignment) => DartTypeUtilities.getCanonicalElement(assignment.writeElement); Iterable _getParameters(ConstructorDeclaration node) => - node.parameters.parameters.map((e) => e.identifier!.staticElement); + node.parameters.parameters.map((e) => e.identifier?.staticElement); Element? _getRightElement(AssignmentExpression assignment) => DartTypeUtilities.getCanonicalElementFromIdentifier( @@ -135,7 +135,7 @@ class _Visitor extends SimpleAstVisitor { leftElement is FieldElement && !leftElement.isSynthetic && leftElement.enclosingElement == - node.declaredElement!.enclosingElement && + node.declaredElement?.enclosingElement && parameters.contains(rightElement) && (!parametersUsedMoreThanOnce.contains(rightElement) && !(rightElement as ParameterElement).isNamed || @@ -152,7 +152,7 @@ class _Visitor extends SimpleAstVisitor { (!parametersUsedMoreThanOnce.contains(expression.staticElement) && !(expression.staticElement as ParameterElement).isNamed || (constructorFieldInitializer.fieldName.staticElement?.name == - expression.staticElement!.name)); + expression.staticElement?.name)); } void processElement(Element? element) { @@ -162,7 +162,7 @@ class _Visitor extends SimpleAstVisitor { } node.parameters.parameterElements - .where((p) => p!.isInitializingFormal) + .where((p) => p != null && p.isInitializingFormal) .forEach(processElement); _getAssignmentExpressionsInConstructorBody(node) diff --git a/lib/src/rules/prefer_inlined_adds.dart b/lib/src/rules/prefer_inlined_adds.dart index c40b04ad3..7161c456a 100644 --- a/lib/src/rules/prefer_inlined_adds.dart +++ b/lib/src/rules/prefer_inlined_adds.dart @@ -57,10 +57,11 @@ class _Visitor extends SimpleAstVisitor { return; } - final cascade = invocation.thisOrAncestorOfType()!; - final sections = cascade.cascadeSections; - final target = cascade.target; - if (target is! ListLiteral || sections[0] != invocation) { + final cascade = invocation.thisOrAncestorOfType(); + final sections = cascade?.cascadeSections; + final target = cascade?.target; + if (target is! ListLiteral || + (sections != null && sections[0] != invocation)) { // todo (pq): consider extending to handle set literals. return; } diff --git a/lib/src/rules/prefer_int_literals.dart b/lib/src/rules/prefer_int_literals.dart index eac87fde4..79dc3cb45 100644 --- a/lib/src/rules/prefer_int_literals.dart +++ b/lib/src/rules/prefer_int_literals.dart @@ -96,8 +96,8 @@ class _Visitor extends SimpleAstVisitor { } else if (parent is ExpressionFunctionBody) { return hasReturnTypeDouble(parent.parent); } else if (parent is ReturnStatement) { - final body = parent.thisOrAncestorOfType()!; - return hasReturnTypeDouble(body.parent); + final body = parent.thisOrAncestorOfType(); + return body != null && hasReturnTypeDouble(body.parent); } else if (parent is VariableDeclaration) { final varList = parent.parent; if (varList is VariableDeclarationList) { diff --git a/lib/src/rules/prefer_is_empty.dart b/lib/src/rules/prefer_is_empty.dart index b4b795a52..aed42fab3 100644 --- a/lib/src/rules/prefer_is_empty.dart +++ b/lib/src/rules/prefer_is_empty.dart @@ -240,7 +240,10 @@ class _Visitor extends SimpleAstVisitor { var operand = expressions.operand; if (expressions.operator.type == TokenType.MINUS && operand is IntegerLiteral) { - return -operand.value!; + var value = operand.value; + if (value != null) { + return -value; + } } } // ignore: avoid_returning_null diff --git a/lib/src/rules/prefer_is_not_operator.dart b/lib/src/rules/prefer_is_not_operator.dart index e5be29b09..9b3153cfe 100644 --- a/lib/src/rules/prefer_is_not_operator.dart +++ b/lib/src/rules/prefer_is_not_operator.dart @@ -57,14 +57,14 @@ class _Visitor extends SimpleAstVisitor { return; } + var parent = node.parent; // Check whether is expression is inside parenthesis - if (node.parent is ParenthesizedExpression) { - final parenthesizedExpression = node.parent!; - final prefixExpression = parenthesizedExpression.parent; + if (parent is ParenthesizedExpression) { + final prefixExpression = parent.parent; // Check for NOT (!) operator if (prefixExpression is PrefixExpression && prefixExpression.operator.type == TokenType.BANG) { - rule.reportLint(parenthesizedExpression.parent); + rule.reportLint(prefixExpression); } } } diff --git a/lib/src/rules/prefer_relative_imports.dart b/lib/src/rules/prefer_relative_imports.dart index d174d00c9..e468ad0cc 100644 --- a/lib/src/rules/prefer_relative_imports.dart +++ b/lib/src/rules/prefer_relative_imports.dart @@ -72,7 +72,8 @@ class _Visitor extends SimpleAstVisitor { if (!samePackage(importUri, sourceUri)) return false; // todo (pq): context.package.contains(source) should work (but does not) - return path.isWithin(context.package!.root, source.fullName); + var packageRoot = context.package?.root; + return packageRoot != null && path.isWithin(packageRoot, source.fullName); } @override diff --git a/lib/src/rules/prefer_spread_collections.dart b/lib/src/rules/prefer_spread_collections.dart index 2b91bba5a..ae4ee0fc9 100644 --- a/lib/src/rules/prefer_spread_collections.dart +++ b/lib/src/rules/prefer_spread_collections.dart @@ -98,13 +98,13 @@ class _Visitor extends SimpleAstVisitor { return; } - final cascade = invocation.thisOrAncestorOfType()!; - final sections = cascade.cascadeSections; - final target = cascade.target; + final cascade = invocation.thisOrAncestorOfType(); + final sections = cascade?.cascadeSections; + final target = cascade?.target; // todo (pq): add support for Set literals. if (target is! ListLiteral || (target is ListLiteralImpl && target.inConstantContext) || - sections[0] != invocation) { + (sections != null && sections[0] != invocation)) { return; } diff --git a/lib/src/rules/prefer_void_to_null.dart b/lib/src/rules/prefer_void_to_null.dart index 428578902..e5671d1d9 100644 --- a/lib/src/rules/prefer_void_to_null.dart +++ b/lib/src/rules/prefer_void_to_null.dart @@ -69,7 +69,8 @@ class _Visitor extends SimpleAstVisitor { @override void visitTypeName(TypeName node) { - if (!node.type!.isDartCoreNull) { + var nodeType = node.type; + if (nodeType == null || !nodeType.isDartCoreNull) { return; } @@ -83,7 +84,7 @@ class _Visitor extends SimpleAstVisitor { // Function(Null) if (parent is SimpleFormalParameter && parent.parent is FormalParameterList && - parent.parent!.parent is GenericFunctionType) { + parent.parent?.parent is GenericFunctionType) { return; } diff --git a/lib/src/rules/pub/sort_pub_dependencies.dart b/lib/src/rules/pub/sort_pub_dependencies.dart index 1edc65a56..208ac2587 100644 --- a/lib/src/rules/pub/sort_pub_dependencies.dart +++ b/lib/src/rules/pub/sort_pub_dependencies.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/lint/pub.dart'; // ignore: implementation_imports +import 'package:source_span/source_span.dart'; import '../../analyzer.dart'; @@ -47,16 +48,28 @@ class Visitor extends PubspecVisitor { } void _visitDeps(PSDependencyList dependencies) { + int compare(SourceLocation? lc1, SourceLocation? lc2) { + if (lc1 == null || lc2 == null) { + return 0; + } + return lc1.compareTo(lc2); + } + final depsByLocation = dependencies.toList() - ..sort((d1, d2) => d1.name!.span.start.compareTo(d2.name!.span.start)); + ..sort((d1, d2) => compare(d1.name?.span.start, d2.name?.span.start)); var previousName = ''; for (final dep in depsByLocation) { - final name = dep.name!.text!; - if (name.compareTo(previousName) < 0) { - rule.reportPubLint(dep.name!); - return; + final name = dep.name; + if (name != null) { + final text = name.text; + if (text != null) { + if (text.compareTo(previousName) < 0) { + rule.reportPubLint(name); + return; + } + previousName = text; + } } - previousName = name; } } } diff --git a/lib/src/rules/public_member_api_docs.dart b/lib/src/rules/public_member_api_docs.dart index b4c4831ac..8377ef801 100644 --- a/lib/src/rules/public_member_api_docs.dart +++ b/lib/src/rules/public_member_api_docs.dart @@ -334,14 +334,19 @@ class _Visitor extends SimpleAstVisitor { } } + var declaredElement = node.declaredElement; + if (declaredElement == null) { + return; + } + // But only setters whose getter is missing a doc. for (var setter in setters) { final getter = getters[setter.name.name]; if (getter == null) { - final libraryUri = node.declaredElement!.library.source.uri; + final libraryUri = declaredElement.library.source.uri; // Look for an inherited getter. Element? getter = context.inheritanceManager.getMember( - node.declaredElement!.thisType, + declaredElement.thisType, Name(libraryUri, setter.name.name), ); if (getter is PropertyAccessorElement) { diff --git a/lib/src/rules/recursive_getters.dart b/lib/src/rules/recursive_getters.dart index ee4a6011f..0ccf3c5c1 100644 --- a/lib/src/rules/recursive_getters.dart +++ b/lib/src/rules/recursive_getters.dart @@ -62,15 +62,16 @@ class _RecursiveGetterParentVisitor extends SimpleAstVisitor { @override bool? visitSimpleIdentifier(SimpleIdentifier node) { - if (node.parent is ArgumentList || - node.parent is ConditionalExpression || - node.parent is ExpressionFunctionBody || - node.parent is ReturnStatement) { + var parent = node.parent; + if (parent is ArgumentList || + parent is ConditionalExpression || + parent is ExpressionFunctionBody || + parent is ReturnStatement) { return true; } - if (node.parent is PropertyAccess) { - return node.parent!.accept(this); + if (parent is PropertyAccess) { + return parent.accept(this); } return false; diff --git a/lib/src/rules/test_types_in_equals.dart b/lib/src/rules/test_types_in_equals.dart index c72c23ec0..edfbfab08 100644 --- a/lib/src/rules/test_types_in_equals.dart +++ b/lib/src/rules/test_types_in_equals.dart @@ -98,7 +98,7 @@ class _Visitor extends SimpleAstVisitor { } final identifier = node.expression as SimpleIdentifier; - var parameters = declaration!.parameters; + var parameters = declaration?.parameters; final parameterName = parameters?.parameterElements.first?.name; if (identifier.name == parameterName) { rule.reportLint(node); diff --git a/lib/src/rules/tighten_type_of_initializing_formals.dart b/lib/src/rules/tighten_type_of_initializing_formals.dart index c22b077d0..5c500addb 100644 --- a/lib/src/rules/tighten_type_of_initializing_formals.dart +++ b/lib/src/rules/tighten_type_of_initializing_formals.dart @@ -77,14 +77,17 @@ class _Visitor extends SimpleAstVisitor { : e.leftOperand is NullLiteral ? e.rightOperand : null) - .where((e) => e != null) - .where((e) => context.typeSystem.isNullable(e!.staticType!)) .whereType() + .where((e) { + var staticType = e.staticType; + return staticType != null && + context.typeSystem.isNullable(staticType); + }) .map((e) => e.staticElement) .whereType() .forEach((e) { - rule.reportLint( - node.parameters.parameters.firstWhere((p) => p.declaredElement == e)); - }); + rule.reportLint(node.parameters.parameters + .firstWhere((p) => p.declaredElement == e)); + }); } } diff --git a/lib/src/rules/type_annotate_public_apis.dart b/lib/src/rules/type_annotate_public_apis.dart index befd6525f..b3f3d91f0 100644 --- a/lib/src/rules/type_annotate_public_apis.dart +++ b/lib/src/rules/type_annotate_public_apis.dart @@ -139,8 +139,11 @@ class _VisitorHelper extends RecursiveAstVisitor { @override void visitSimpleFormalParameter(SimpleFormalParameter param) { - if (param.type == null && !isJustUnderscores(param.identifier!.name)) { - rule.reportLint(param); + if (param.type == null) { + var paramName = param.identifier?.name; + if (paramName != null && !isJustUnderscores(paramName)) { + rule.reportLint(param); + } } } diff --git a/lib/src/rules/type_init_formals.dart b/lib/src/rules/type_init_formals.dart index d88afaa9a..172e84d36 100644 --- a/lib/src/rules/type_init_formals.dart +++ b/lib/src/rules/type_init_formals.dart @@ -61,7 +61,7 @@ class _Visitor extends SimpleAstVisitor { void visitFieldFormalParameter(FieldFormalParameter node) { var nodeType = node.type; if (nodeType != null) { - var cls = node.thisOrAncestorOfType()?.declaredElement!; + var cls = node.thisOrAncestorOfType()?.declaredElement; if (cls != null) { var field = cls.getField(node.identifier.name); // If no such field exists, the code is invalid; do not report lint. diff --git a/lib/src/rules/unnecessary_await_in_return.dart b/lib/src/rules/unnecessary_await_in_return.dart index 852f65156..a41d21975 100644 --- a/lib/src/rules/unnecessary_await_in_return.dart +++ b/lib/src/rules/unnecessary_await_in_return.dart @@ -66,8 +66,9 @@ class _Visitor extends SimpleAstVisitor { @override void visitReturnStatement(ReturnStatement node) { - if (node.expression != null) { - _visit(node, node.expression!.unParenthesized); + var expression = node.expression; + if (expression != null) { + _visit(node, expression.unParenthesized); } } diff --git a/lib/src/rules/unnecessary_const.dart b/lib/src/rules/unnecessary_const.dart index d3d6ca9b6..91cfcb521 100644 --- a/lib/src/rules/unnecessary_const.dart +++ b/lib/src/rules/unnecessary_const.dart @@ -66,7 +66,7 @@ class _Visitor extends SimpleAstVisitor { final isConstWithoutKeyword = node.isConst; node.keyword = oldKeyword; - if (isConstWithoutKeyword && node.keyword!.type == Keyword.CONST) { + if (isConstWithoutKeyword && node.keyword?.type == Keyword.CONST) { rule.reportLint(node); } } @@ -88,7 +88,7 @@ class _Visitor extends SimpleAstVisitor { final isConstWithoutKeyword = node.isConst; node.constKeyword = oldKeyword; - if (isConstWithoutKeyword && node.constKeyword!.type == Keyword.CONST) { + if (isConstWithoutKeyword && node.constKeyword?.type == Keyword.CONST) { rule.reportLint(node); } } diff --git a/lib/src/rules/unnecessary_lambdas.dart b/lib/src/rules/unnecessary_lambdas.dart index 47312eb69..1a3f08c44 100644 --- a/lib/src/rules/unnecessary_lambdas.dart +++ b/lib/src/rules/unnecessary_lambdas.dart @@ -118,7 +118,7 @@ class _Visitor extends SimpleAstVisitor { @override void visitFunctionExpression(FunctionExpression node) { - if (node.declaredElement!.name != '' || node.body!.keyword != null) { + if (node.declaredElement?.name != '' || node.body?.keyword != null) { return; } final body = node.body; @@ -143,23 +143,25 @@ class _Visitor extends SimpleAstVisitor { void _visitInvocationExpression( InvocationExpression node, FunctionExpression nodeToLint) { - if (!DartTypeUtilities.matchesArgumentsWithParameters( - node.argumentList.arguments, nodeToLint.parameters!.parameters)) { + var nodeToLintParams = nodeToLint.parameters?.parameters; + if (nodeToLintParams == null || + !DartTypeUtilities.matchesArgumentsWithParameters( + node.argumentList.arguments, nodeToLintParams)) { return; } bool isTearoffAssignable(DartType? assignedType) { if (assignedType != null) { - var tearoffType = node.staticInvokeType!; - if (!context.typeSystem.isSubtypeOf(tearoffType, assignedType)) { + var tearoffType = node.staticInvokeType; + if (tearoffType == null || + !context.typeSystem.isSubtypeOf(tearoffType, assignedType)) { return false; } } return true; } - final parameters = - nodeToLint.parameters!.parameters.map((e) => e.declaredElement).toSet(); + final parameters = nodeToLintParams.map((e) => e.declaredElement).toSet(); if (node is FunctionExpressionInvocation) { // todo (pq): consider checking for assignability // see: https://github.com/dart-lang/linter/issues/1561 diff --git a/lib/src/rules/unnecessary_null_checks.dart b/lib/src/rules/unnecessary_null_checks.dart index 7148a5526..78cd81701 100644 --- a/lib/src/rules/unnecessary_null_checks.dart +++ b/lib/src/rules/unnecessary_null_checks.dart @@ -38,12 +38,12 @@ m() { DartType? getExpectedType(PostfixExpression node) { var realNode = - node.thisOrAncestorMatching((e) => e.parent is! ParenthesizedExpression)!; - var parent = realNode.parent; + node.thisOrAncestorMatching((e) => e.parent is! ParenthesizedExpression); + var parent = realNode?.parent; // in return value if (parent is ReturnStatement || parent is ExpressionFunctionBody) { - var parentExpression = parent!.thisOrAncestorOfType(); + var parentExpression = parent?.thisOrAncestorOfType(); if (parentExpression == null) { return null; } @@ -60,7 +60,7 @@ DartType? getExpectedType(PostfixExpression node) { } // in variable declaration if (parent is VariableDeclaration) { - return parent.declaredElement!.type; + return parent.declaredElement?.type; } // as right member of binary operator if (parent is BinaryExpression && parent.rightOperand == realNode) { diff --git a/lib/src/rules/unnecessary_nullable_for_final_variable_declarations.dart b/lib/src/rules/unnecessary_nullable_for_final_variable_declarations.dart index 91f37e58c..17951cfdb 100644 --- a/lib/src/rules/unnecessary_nullable_for_final_variable_declarations.dart +++ b/lib/src/rules/unnecessary_nullable_for_final_variable_declarations.dart @@ -85,14 +85,17 @@ class _Visitor extends SimpleAstVisitor { if (variable.isSynthetic) { return; } - if (variable.initializer == null) { + var initializerType = variable.initializer?.staticType; + if (initializerType == null) { return; } - if (variable.declaredElement!.type.isDynamic) { + var declaredElement = variable.declaredElement; + if (declaredElement == null || declaredElement.type.isDynamic) { return; } - if (context.typeSystem.isNullable(variable.declaredElement!.type) && - context.typeSystem.isNonNullable(variable.initializer!.staticType!)) { + + if (context.typeSystem.isNullable(declaredElement.type) && + context.typeSystem.isNonNullable(initializerType)) { rule.reportLint(variable); } } diff --git a/lib/src/rules/unnecessary_overrides.dart b/lib/src/rules/unnecessary_overrides.dart index f6b86301b..536f61789 100644 --- a/lib/src/rules/unnecessary_overrides.dart +++ b/lib/src/rules/unnecessary_overrides.dart @@ -128,26 +128,36 @@ abstract class _AbstractUnnecessaryOverrideVisitor extends SimpleAstVisitor { } bool _addsMetadata() { - for (var annotation in declaration.declaredElement!.metadata) { - if (!annotation.isOverride) { - return true; + var metadata = declaration.declaredElement?.metadata; + if (metadata != null) { + for (var annotation in metadata) { + if (!annotation.isOverride) { + return true; + } } } return false; } bool _haveSameDeclaration() { - if (declaration.declaredElement!.returnType != - inheritedMethod!.returnType) { + var declaredElement = declaration.declaredElement; + if (declaredElement == null) { + return false; + } + var inheritedMethod = this.inheritedMethod; + if (inheritedMethod == null) { return false; } - if (declaration.declaredElement!.parameters.length != - inheritedMethod!.parameters.length) { + if (declaredElement.returnType != inheritedMethod.returnType) { return false; } - for (var i = 0; i < inheritedMethod!.parameters.length; i++) { - final superParam = inheritedMethod!.parameters[i]; - final param = declaration.declaredElement!.parameters[i]; + if (declaredElement.parameters.length != + inheritedMethod.parameters.length) { + return false; + } + for (var i = 0; i < inheritedMethod.parameters.length; i++) { + final superParam = inheritedMethod.parameters[i]; + final param = declaredElement.parameters[i]; if (param.type != superParam.type) return false; if (param.name != superParam.name) return false; if (param.isCovariant != superParam.isCovariant) return false; @@ -195,9 +205,11 @@ class _UnnecessaryMethodOverrideVisitor @override void visitMethodInvocation(MethodInvocation node) { - if (node.methodName.staticElement == inheritedMethod && + var declarationParameters = declaration.parameters; + if (declarationParameters != null && + node.methodName.staticElement == inheritedMethod && DartTypeUtilities.matchesArgumentsWithParameters( - node.argumentList.arguments, declaration.parameters!.parameters)) { + node.argumentList.arguments, declarationParameters.parameters)) { node.target?.accept(this); } } @@ -213,10 +225,11 @@ class _UnnecessaryOperatorOverrideVisitor @override void visitBinaryExpression(BinaryExpression node) { - final parameters = declaration.parameters!.parameters; + final parameters = declaration.parameters?.parameters; if (node.operator.type == declaration.name.token.type && + parameters != null && parameters.length == 1 && - parameters.first.identifier!.staticElement == + parameters.first.identifier?.staticElement == DartTypeUtilities.getCanonicalElementFromIdentifier( node.rightOperand)) { final leftPart = node.leftOperand.unParenthesized; @@ -228,8 +241,9 @@ class _UnnecessaryOperatorOverrideVisitor @override void visitPrefixExpression(PrefixExpression node) { - final parameters = declaration.parameters!.parameters; - if (node.operator.type == declaration.name.token.type && + final parameters = declaration.parameters?.parameters; + if (parameters != null && + node.operator.type == declaration.name.token.type && parameters.isEmpty) { final operand = node.operand.unParenthesized; if (operand is SuperExpression) { @@ -249,9 +263,10 @@ class _UnnecessarySetterOverrideVisitor @override void visitAssignmentExpression(AssignmentExpression node) { - final parameters = declaration.parameters!.parameters; - if (parameters.length == 1 && - parameters.first.identifier!.staticElement == + final parameters = declaration.parameters?.parameters; + if (parameters != null && + parameters.length == 1 && + parameters.first.identifier?.staticElement == DartTypeUtilities.getCanonicalElementFromIdentifier( node.rightHandSide)) { final leftPart = node.leftHandSide.unParenthesized; diff --git a/lib/src/rules/use_is_even_rather_than_modulo.dart b/lib/src/rules/use_is_even_rather_than_modulo.dart index 01a0c72f0..65d37c0b9 100644 --- a/lib/src/rules/use_is_even_rather_than_modulo.dart +++ b/lib/src/rules/use_is_even_rather_than_modulo.dart @@ -61,8 +61,8 @@ class _Visitor extends SimpleAstVisitor { var rightType = right.staticType; // Both sides have to have static type of int if (!(right is IntegerLiteral && - leftType!.isDartCoreInt == true && - rightType!.isDartCoreInt == true)) { + leftType?.isDartCoreInt == true && + rightType?.isDartCoreInt == true)) { return; } // The left side expression has to be modulo by 2 type. @@ -72,7 +72,7 @@ class _Visitor extends SimpleAstVisitor { if (left.operator.type == TokenType.PERCENT && rightChild is IntegerLiteral && rightChild.value == 2 && - rightChildType!.isDartCoreInt == true) { + rightChildType?.isDartCoreInt == true) { rule.reportLint(node); } } diff --git a/lib/src/rules/use_key_in_widget_constructors.dart b/lib/src/rules/use_key_in_widget_constructors.dart index 705ae1ba3..dbf21a756 100644 --- a/lib/src/rules/use_key_in_widget_constructors.dart +++ b/lib/src/rules/use_key_in_widget_constructors.dart @@ -57,8 +57,9 @@ class _Visitor extends SimpleAstVisitor { @override void visitClassDeclaration(ClassDeclaration node) { - var classElement = node.declaredElement!; - if (classElement.isPublic && + var classElement = node.declaredElement; + if (classElement != null && + classElement.isPublic && hasWidgetAsAscendant(classElement) && classElement.constructors.where((e) => !e.isSynthetic).isEmpty) { rule.reportLint(node.name); @@ -68,7 +69,10 @@ class _Visitor extends SimpleAstVisitor { @override void visitConstructorDeclaration(ConstructorDeclaration node) { - var constructorElement = node.declaredElement!; + var constructorElement = node.declaredElement; + if (constructorElement == null) { + return; + } var classElement = constructorElement.enclosingElement; if (constructorElement.isPublic && !constructorElement.isFactory && @@ -91,7 +95,7 @@ class _Visitor extends SimpleAstVisitor { element.parameters.any((e) => e.name == 'key' && _isKeyType(e.type)); bool _defineKeyArgument(ArgumentList argumentList) => argumentList.arguments - .any((a) => a.staticParameterElement!.name == 'key'); + .any((a) => a.staticParameterElement?.name == 'key'); bool _isKeyType(DartType type) => DartTypeUtilities.implementsInterface(type, 'Key', ''); diff --git a/lib/src/rules/use_late_for_private_fields_and_variables.dart b/lib/src/rules/use_late_for_private_fields_and_variables.dart index 36f0f5b92..591a0b85b 100644 --- a/lib/src/rules/use_late_for_private_fields_and_variables.dart +++ b/lib/src/rules/use_late_for_private_fields_and_variables.dart @@ -72,7 +72,11 @@ class _Visitor extends UnifyingAstVisitor { @override void visitCompilationUnit(CompilationUnit node) { if (node.featureSet.isEnabled(Feature.non_nullable)) { - currentUnit = node.declaredElement; + var declaredElement = node.declaredElement; + if (declaredElement == null) { + return; + } + currentUnit = declaredElement; lateables.putIfAbsent(currentUnit, () => []); nullableAccess.putIfAbsent(currentUnit, () => {}); @@ -80,9 +84,8 @@ class _Visitor extends UnifyingAstVisitor { final unitsInContext = context.allUnits.map((e) => e.unit.declaredElement).toSet(); - final libraryUnitsInContext = node.declaredElement!.library.units - .where(unitsInContext.contains) - .toSet(); + final libraryUnitsInContext = + declaredElement.library.units.where(unitsInContext.contains).toSet(); final areAllLibraryUnitsVisited = libraryUnitsInContext.every(lateables.containsKey); if (areAllLibraryUnitsVisited) { @@ -123,7 +126,7 @@ class _Visitor extends UnifyingAstVisitor { context.typeSystem.isNonNullable(parent.rightHandSide.staticType!)) { // ok non-null access } else { - nullableAccess[currentUnit]!.add(element); + nullableAccess[currentUnit]?.add(element); } } super.visitNode(node); @@ -138,8 +141,9 @@ class _Visitor extends UnifyingAstVisitor { // we'd need to ensure that there are no instances of either the // enclosing class or any subclass of the enclosing class that are ever // accessible outside this library. - if (Identifier.isPrivateName(variable.name.name) || - _isPrivateExtension(parent)) { + if (parent != null && + (Identifier.isPrivateName(variable.name.name) || + _isPrivateExtension(parent))) { _visit(variable); } } @@ -163,10 +167,12 @@ class _Visitor extends UnifyingAstVisitor { if (variable.isSynthetic) { return; } - if (context.typeSystem.isNonNullable(variable.declaredElement!.type)) { + var declaredElement = variable.declaredElement; + if (declaredElement == null || + context.typeSystem.isNonNullable(declaredElement.type)) { return; } - lateables[currentUnit]!.add(variable); + lateables[currentUnit]?.add(variable); } void _checkAccess(Iterable units) { @@ -183,6 +189,10 @@ class _Visitor extends UnifyingAstVisitor { } } -bool _isPrivateExtension(AstNode? parent) => - parent is ExtensionDeclaration && - (parent.name == null || Identifier.isPrivateName(parent.name!.name)); +bool _isPrivateExtension(AstNode parent) { + if (parent is! ExtensionDeclaration) { + return false; + } + var parentName = parent.name?.name; + return parentName == null || Identifier.isPrivateName(parentName); +} diff --git a/lib/src/rules/use_named_constants.dart b/lib/src/rules/use_named_constants.dart index cf17b07b9..fdb2b60bd 100644 --- a/lib/src/rules/use_named_constants.dart +++ b/lib/src/rules/use_named_constants.dart @@ -53,7 +53,7 @@ class _Visitor extends SimpleAstVisitor { @override void visitInstanceCreationExpression(InstanceCreationExpression node) { if (node.isConst) { - final element = node.staticType!.element; + final element = node.staticType?.element; if (element is ClassElement) { final nodeField = node.thisOrAncestorOfType()?.declaredElement; @@ -66,7 +66,7 @@ class _Visitor extends SimpleAstVisitor { // } if (nodeField?.enclosingElement == element) return; - final library = (node.root as CompilationUnit).declaredElement!.library; + final library = (node.root as CompilationUnit).declaredElement?.library; final value = context.evaluateConstant(node).value; for (final field in element.fields.where((e) => e.isStatic && e.isConst)) { diff --git a/lib/src/rules/use_setters_to_change_properties.dart b/lib/src/rules/use_setters_to_change_properties.dart index 28b6a1eba..be9171d9c 100644 --- a/lib/src/rules/use_setters_to_change_properties.dart +++ b/lib/src/rules/use_setters_to_change_properties.dart @@ -69,7 +69,7 @@ class _Visitor extends SimpleAstVisitor { final rightOperand = DartTypeUtilities.getCanonicalElementFromIdentifier( expression.rightHandSide); - final parameterElement = node.declaredElement!.parameters.first; + final parameterElement = node.declaredElement?.parameters.first; if (rightOperand == parameterElement && leftOperand is FieldElement) { rule.reportLint(node); } diff --git a/lib/src/rules/use_to_and_as_if_applicable.dart b/lib/src/rules/use_to_and_as_if_applicable.dart index a5e4c746b..8680518ae 100644 --- a/lib/src/rules/use_to_and_as_if_applicable.dart +++ b/lib/src/rules/use_to_and_as_if_applicable.dart @@ -79,8 +79,10 @@ class _Visitor extends SimpleAstVisitor { @override void visitMethodDeclaration(MethodDeclaration node) { + var nodeParameters = node.parameters; if (!node.isGetter && - node.parameters!.parameters.isEmpty && + nodeParameters != null && + nodeParameters.parameters.isEmpty && !_isVoid(node.returnType) && !_beginsWithAsOrTo(node.name.name) && !DartTypeUtilities.hasInheritedMethod(node) && diff --git a/lib/src/rules/void_checks.dart b/lib/src/rules/void_checks.dart index c7486fc20..2edb55169 100644 --- a/lib/src/rules/void_checks.dart +++ b/lib/src/rules/void_checks.dart @@ -120,11 +120,11 @@ class _Visitor extends SimpleAstVisitor { } } else if (parent is MethodDeclaration) { _check( - parent.declaredElement!.returnType, node.expression?.staticType, node, + parent.declaredElement?.returnType, node.expression?.staticType, node, checkedNode: node.expression); } else if (parent is FunctionDeclaration) { _check( - parent.declaredElement!.returnType, node.expression?.staticType, node, + parent.declaredElement?.returnType, node.expression?.staticType, node, checkedNode: node.expression); } } diff --git a/lib/src/util/condition_scope_visitor.dart b/lib/src/util/condition_scope_visitor.dart index fb4f12375..d34c11d63 100644 --- a/lib/src/util/condition_scope_visitor.dart +++ b/lib/src/util/condition_scope_visitor.dart @@ -129,10 +129,11 @@ abstract class ConditionScopeVisitor extends RecursiveAstVisitor { ConditionScope? outerScope; final breakScope = BreakScope(); - Iterable getFalseExpressions(Iterable elements) => + /// todo (pq): here and w/ getTrueExpressions, consider an empty iterable + Iterable? getFalseExpressions(Iterable elements) => _getExpressions(elements, value: false); - Iterable getTrueExpressions(Iterable elements) => + Iterable? getTrueExpressions(Iterable elements) => _getExpressions(elements); @override @@ -213,9 +214,11 @@ abstract class ConditionScopeVisitor extends RecursiveAstVisitor { @override void visitIfStatement(IfStatement node) { - final elseScope = _visitElseStatement(node.elseStatement, node.condition)!; + final elseScope = _visitElseStatement(node.elseStatement, node.condition); _visitIfStatement(node); - _propagateUndefinedExpressions(elseScope); + if (elseScope != null) { + _propagateUndefinedExpressions(elseScope); + } final addFalseCondition = _isLastStatementAnExitStatement(node.thenStatement); final addTrueCondition = @@ -315,9 +318,9 @@ abstract class ConditionScopeVisitor extends RecursiveAstVisitor { }); } - Iterable _getExpressions(Iterable elements, + Iterable? _getExpressions(Iterable elements, {bool value = true}) => - outerScope!.getExpressions(elements, value: value); + outerScope?.getExpressions(elements, value: value); bool _isLastStatementAnExitStatement(Statement? statement) { if (statement is Block) { @@ -372,7 +375,7 @@ abstract class ConditionScopeVisitor extends RecursiveAstVisitor { ConditionScope? _removeLastScope() { final deletedScope = outerScope; - outerScope = outerScope!.outer; + outerScope = outerScope?.outer; return deletedScope; } diff --git a/lib/src/util/dart_type_utilities.dart b/lib/src/util/dart_type_utilities.dart index f485d470c..2bdccd990 100644 --- a/lib/src/util/dart_type_utilities.dart +++ b/lib/src/util/dart_type_utilities.dart @@ -51,13 +51,13 @@ class DartTypeUtilities { // And no subclasses in the defining library. var compilationUnit = classElement.library.definingCompilationUnit; for (var cls in compilationUnit.types) { - var classType = cls.thisType; + InterfaceType? classType = cls.thisType; do { - classType = classType.superclass!; + classType = classType?.superclass; if (classType == type) { return null; } - } while (!classType.isDartCoreObject); + } while (classType != null && !classType.isDartCoreObject); } return EnumLikeClassDescription(enumConstantNames); @@ -249,9 +249,13 @@ class DartTypeUtilities { expression?.unParenthesized is NullLiteral; static PropertyAccessorElement? lookUpGetter(MethodDeclaration node) { - final parent = node.declaredElement!.enclosingElement; + var declaredElement = node.declaredElement; + if (declaredElement == null) { + return null; + } + final parent = declaredElement.enclosingElement; if (parent is ClassElement) { - return parent.lookUpGetter(node.name.name, node.declaredElement!.library); + return parent.lookUpGetter(node.name.name, declaredElement.library); } if (parent is ExtensionElement) { return parent.getGetter(node.name.name); @@ -261,20 +265,27 @@ class DartTypeUtilities { static PropertyAccessorElement? lookUpInheritedConcreteGetter( MethodDeclaration node) { - final parent = node.declaredElement!.enclosingElement; + var declaredElement = node.declaredElement; + if (declaredElement == null) { + return null; + } + final parent = declaredElement.enclosingElement; if (parent is ClassElement) { return parent.lookUpInheritedConcreteGetter( - node.name.name, node.declaredElement!.library); + node.name.name, declaredElement.library); } // Extensions don't inherit. return null; } static MethodElement? lookUpInheritedConcreteMethod(MethodDeclaration node) { - final parent = node.declaredElement!.enclosingElement; - if (parent is ClassElement) { - return parent.lookUpInheritedConcreteMethod( - node.name.name, node.declaredElement!.library); + var declaredElement = node.declaredElement; + if (declaredElement != null) { + final parent = declaredElement.enclosingElement; + if (parent is ClassElement) { + return parent.lookUpInheritedConcreteMethod( + node.name.name, declaredElement.library); + } } // Extensions don't inherit. return null; @@ -282,30 +293,40 @@ class DartTypeUtilities { static PropertyAccessorElement? lookUpInheritedConcreteSetter( MethodDeclaration node) { - final parent = node.declaredElement!.enclosingElement; - if (parent is ClassElement) { - return parent.lookUpInheritedConcreteSetter( - node.name.name, node.declaredElement!.library); + var declaredElement = node.declaredElement; + if (declaredElement != null) { + final parent = declaredElement.enclosingElement; + if (parent is ClassElement) { + return parent.lookUpInheritedConcreteSetter( + node.name.name, declaredElement.library); + } } // Extensions don't inherit. return null; } static MethodElement? lookUpInheritedMethod(MethodDeclaration node) { - final parent = node.declaredElement!.enclosingElement; - return parent is ClassElement - ? parent.lookUpInheritedMethod( - node.name.name, node.declaredElement!.library) - : null; + var declaredElement = node.declaredElement; + if (declaredElement != null) { + final parent = declaredElement.enclosingElement; + if (parent is ClassElement) { + return parent.lookUpInheritedMethod( + node.name.name, declaredElement.library); + } + } + return null; } static PropertyAccessorElement? lookUpSetter(MethodDeclaration node) { - final parent = node.declaredElement!.enclosingElement; - if (parent is ClassElement) { - return parent.lookUpSetter(node.name.name, node.declaredElement!.library); - } - if (parent is ExtensionElement) { - return parent.getSetter(node.name.name); + var declaredElement = node.declaredElement; + if (declaredElement != null) { + final parent = declaredElement.enclosingElement; + if (parent is ClassElement) { + return parent.lookUpSetter(node.name.name, declaredElement.library); + } + if (parent is ExtensionElement) { + return parent.getSetter(node.name.name); + } } return null; } @@ -317,11 +338,13 @@ class DartTypeUtilities { final positionalParameters = []; final positionalArguments = []; for (final parameter in parameters) { - if (parameter.isNamed) { - namedParameters[parameter.identifier!.name] = - parameter.identifier!.staticElement; - } else { - positionalParameters.add(parameter.identifier!.staticElement); + var identifier = parameter.identifier; + if (identifier != null) { + if (parameter.isNamed) { + namedParameters[identifier.name] = identifier.staticElement; + } else { + positionalParameters.add(identifier.staticElement); + } } } for (final argument in arguments) { @@ -365,9 +388,15 @@ class DartTypeUtilities { if (parent is! ClassOrMixinDeclaration) { return false; } - final name = node.declaredElement!.name; + final name = node.declaredElement?.name; + if (name == null) { + return false; + } final clazz = parent; - final classElement = clazz.declaredElement!; + final classElement = clazz.declaredElement; + if (classElement == null) { + return false; + } final library = classElement.library; return classElement.allSupertypes .map(node.isGetter diff --git a/lib/src/util/leak_detector_visitor.dart b/lib/src/util/leak_detector_visitor.dart index b88658157..6f39f1acf 100644 --- a/lib/src/util/leak_detector_visitor.dart +++ b/lib/src/util/leak_detector_visitor.dart @@ -38,8 +38,10 @@ _VisitVariableDeclaration _buildVariableReporter( LintRule rule, Map predicates) => (VariableDeclaration variable) { - if (!predicates.keys - .any((DartTypePredicate p) => p(variable.declaredElement!.type))) { + if (!predicates.keys.any((DartTypePredicate p) { + var declaredElement = variable.declaredElement; + return declaredElement != null && p(declaredElement.type); + })) { return; } @@ -72,10 +74,12 @@ _VisitVariableDeclaration _buildVariableReporter( Iterable _findMethodCallbackNodes(Iterable containerNodes, VariableDeclaration variable, Map predicates) { final prefixedIdentifiers = containerNodes.whereType(); - return prefixedIdentifiers.where((n) => - n.prefix.staticElement == variable.name.staticElement && - _hasMatch(predicates, variable.declaredElement!.type, - n.identifier.token.lexeme)); + return prefixedIdentifiers.where((n) { + var declaredElement = variable.declaredElement; + return declaredElement != null && + n.prefix.staticElement == variable.name.staticElement && + _hasMatch(predicates, declaredElement.type, n.identifier.token.lexeme); + }); } Iterable _findMethodInvocationsWithVariableAsArgument( @@ -91,16 +95,18 @@ Iterable _findNodesInvokingMethodOnVariable( Iterable classNodes, VariableDeclaration variable, Map predicates) => - classNodes.where((AstNode n) => - n is MethodInvocation && - ((_hasMatch(predicates, variable.declaredElement!.type, - n.methodName.name) && - (_isSimpleIdentifierElementEqualToVariable( - n.realTarget, variable) || - _isPropertyAccessThroughThis(n.realTarget, variable) || - (n.thisOrAncestorMatching((a) => a == variable) != - null))) || - (_isInvocationThroughCascadeExpression(n, variable)))); + classNodes.where((AstNode n) { + var declaredElement = variable.declaredElement; + return declaredElement != null && + n is MethodInvocation && + ((_hasMatch(predicates, declaredElement.type, n.methodName.name) && + (_isSimpleIdentifierElementEqualToVariable( + n.realTarget, variable) || + _isPropertyAccessThroughThis(n.realTarget, variable) || + (n.thisOrAncestorMatching((a) => a == variable) != + null))) || + (_isInvocationThroughCascadeExpression(n, variable))); + }); Iterable _findVariableAssignments( Iterable containerNodes, VariableDeclaration variable) { diff --git a/lib/src/util/tested_expressions.dart b/lib/src/util/tested_expressions.dart index 256b71f73..bf0de5d49 100644 --- a/lib/src/util/tested_expressions.dart +++ b/lib/src/util/tested_expressions.dart @@ -100,7 +100,7 @@ class TestedExpressions { ? binaryExpression.operator.type : TokenType.AMPERSAND_AMPERSAND); - if (_contradictions!.isEmpty) { + if (_contradictions?.isEmpty == true) { final set = (binaryExpression != null ? _extractComparisons(testingExpression as BinaryExpression) : {testingExpression}) @@ -109,7 +109,7 @@ class TestedExpressions { // Here and in several places we proceed only for // TokenType.AMPERSAND_AMPERSAND because we then know that all comparisons // must be true. - _contradictions!.addAll( + _contradictions?.addAll( _findContradictoryComparisons(set, TokenType.AMPERSAND_AMPERSAND)); } diff --git a/lib/src/util/unrelated_types_visitor.dart b/lib/src/util/unrelated_types_visitor.dart index 28c0215aa..88bdd3a49 100644 --- a/lib/src/util/unrelated_types_visitor.dart +++ b/lib/src/util/unrelated_types_visitor.dart @@ -106,8 +106,9 @@ abstract class UnrelatedTypesProcessors extends SimpleAstVisitor { // [definition]. DartType? targetType; - if (node.target != null) { - targetType = node.target!.staticType; + var target = node.target; + if (target != null) { + targetType = target.staticType; } else { final classDeclaration = node.thisOrAncestorOfType();