| Index: pkg/analyzer/lib/src/generated/resolver.dart
|
| diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
|
| index 40a216228e023948cb8ea441a93abc05123bd76a..b5d6e1dff9f4204d4916ee9166274bd60a6c6528 100644
|
| --- a/pkg/analyzer/lib/src/generated/resolver.dart
|
| +++ b/pkg/analyzer/lib/src/generated/resolver.dart
|
| @@ -6,6 +6,8 @@ library engine.resolver;
|
|
|
| import 'dart:collection';
|
|
|
| +import 'package:analyzer/src/generated/scanner.dart';
|
| +
|
| import 'ast.dart';
|
| import 'constant.dart';
|
| import 'element.dart';
|
| @@ -104,6 +106,12 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
|
| }
|
|
|
| @override
|
| + Object visitAssertStatement(AssertStatement node) {
|
| + _checkForPossibleNullCondition(node.condition);
|
| + return super.visitAssertStatement(node);
|
| + }
|
| +
|
| + @override
|
| Object visitAssignmentExpression(AssignmentExpression node) {
|
| sc.TokenType operatorType = node.operator.type;
|
| if (operatorType == sc.TokenType.EQ) {
|
| @@ -136,18 +144,42 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
|
| }
|
|
|
| @override
|
| + Object visitConditionalExpression(ConditionalExpression node) {
|
| + _checkForPossibleNullCondition(node.condition);
|
| + return super.visitConditionalExpression(node);
|
| + }
|
| +
|
| + @override
|
| + Object visitDoStatement(DoStatement node) {
|
| + _checkForPossibleNullCondition(node.condition);
|
| + return super.visitDoStatement(node);
|
| + }
|
| +
|
| + @override
|
| Object visitExportDirective(ExportDirective node) {
|
| _checkForDeprecatedMemberUse(node.uriElement, node);
|
| return super.visitExportDirective(node);
|
| }
|
|
|
| @override
|
| + Object visitForStatement(ForStatement node) {
|
| + _checkForPossibleNullCondition(node.condition);
|
| + return super.visitForStatement(node);
|
| + }
|
| +
|
| + @override
|
| Object visitFunctionDeclaration(FunctionDeclaration node) {
|
| _checkForMissingReturn(node.returnType, node.functionExpression.body);
|
| return super.visitFunctionDeclaration(node);
|
| }
|
|
|
| @override
|
| + Object visitIfStatement(IfStatement node) {
|
| + _checkForPossibleNullCondition(node.condition);
|
| + return super.visitIfStatement(node);
|
| + }
|
| +
|
| + @override
|
| Object visitImportDirective(ImportDirective node) {
|
| _checkForDeprecatedMemberUse(node.uriElement, node);
|
| ImportElement importElement = node.element;
|
| @@ -223,6 +255,12 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
|
| return super.visitVariableDeclaration(node);
|
| }
|
|
|
| + @override
|
| + Object visitWhileStatement(WhileStatement node) {
|
| + _checkForPossibleNullCondition(node.condition);
|
| + return super.visitWhileStatement(node);
|
| + }
|
| +
|
| /**
|
| * Check for the passed is expression for the unnecessary type check hint codes as well as null
|
| * checks expressed using an is expression.
|
| @@ -619,6 +657,54 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
|
| }
|
|
|
| /**
|
| + * Produce a hint if the given [condition] could have a value of `null`.
|
| + */
|
| + void _checkForPossibleNullCondition(Expression condition) {
|
| + while (condition is ParenthesizedExpression) {
|
| + condition = (condition as ParenthesizedExpression).expression;
|
| + }
|
| + if (condition is BinaryExpression) {
|
| + _checkForPossibleNullConditionInBinaryExpression(condition);
|
| + } else {
|
| + _checkForPossibleNullConditionInSimpleExpression(condition);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Produce a hint if any of the parts of the given binary [condition] could
|
| + * have a value of `null`.
|
| + */
|
| + void _checkForPossibleNullConditionInBinaryExpression(
|
| + BinaryExpression condition) {
|
| + Token operator = condition.operator;
|
| + if (operator != null &&
|
| + (operator.type == TokenType.AMPERSAND_AMPERSAND ||
|
| + operator.type == TokenType.BAR_BAR)) {
|
| + _checkForPossibleNullCondition(condition.leftOperand);
|
| + _checkForPossibleNullCondition(condition.rightOperand);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Produce a hint if the given [condition] could have a value of `null`.
|
| + */
|
| + void _checkForPossibleNullConditionInSimpleExpression(Expression condition) {
|
| + if (condition is MethodInvocation) {
|
| + Token operator = condition.operator;
|
| + if (operator != null && operator.type == TokenType.QUESTION_PERIOD) {
|
| + _errorReporter.reportErrorForNode(
|
| + HintCode.NULL_AWARE_IN_CONDITION, condition);
|
| + }
|
| + } else if (condition is PropertyAccess) {
|
| + Token operator = condition.operator;
|
| + if (operator != null && operator.type == TokenType.QUESTION_PERIOD) {
|
| + _errorReporter.reportErrorForNode(
|
| + HintCode.NULL_AWARE_IN_CONDITION, condition);
|
| + }
|
| + }
|
| + }
|
| +
|
| + /**
|
| * Check for the passed class declaration for the
|
| * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
|
| *
|
| @@ -4824,7 +4910,7 @@ class HintGenerator {
|
| _usedImportedElementsVisitor =
|
| new GatherUsedImportedElementsVisitor(_library);
|
| _enableDart2JSHints = _context.analysisOptions.dart2jsHint;
|
| - _manager = new InheritanceManager(_compilationUnits[0].element.library);
|
| + _manager = new InheritanceManager(_library);
|
| _usedLocalElementsVisitor = new GatherUsedLocalElementsVisitor(_library);
|
| }
|
|
|
|
|