// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analyzer/analysis_rule/rule_context.dart';
import 'package:analyzer/analysis_rule/rule_visitor_registry.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';

import '../analyzer.dart';

const _desc = r'Avoid using unnecessary statements.';

class UnnecessaryStatements extends LintRule {
  UnnecessaryStatements()
    : super(name: LintNames.unnecessary_statements, description: _desc);

  @override
  DiagnosticCode get diagnosticCode => LinterLintCode.unnecessaryStatements;

  @override
  void registerNodeProcessors(
    RuleVisitorRegistry registry,
    RuleContext context,
  ) {
    var visitor = _Visitor(_ReportNoClearEffectVisitor(this));
    registry.addExpressionStatement(this, visitor);
    registry.addForStatement(this, visitor);
    registry.addCascadeExpression(this, visitor);
  }
}

/// A visitor that reports expressions that have no clear effect.
///
/// This visitor works a little differently from most. It reports lint rule
/// violations in `visitNode`, a sort of "catch all" location. It also contains
/// many empty-bodied "visit" method overrides that serve to short-circuit a
/// traversal down the syntax tree. Each empty-bodied "visit" method represents
/// a case where an expression can validly act as a statement, as there are
/// common cases where the expression has a clear effect.
///
/// In this way the visitor's visitations are typically very shallow, starting
/// either with a method that just returns without visiting any children, or
/// starting with `visitNode`, which reports a violation and also does not
/// descend. We descend into only a few node types, like binary expressions and
/// conditional expressions.
class _ReportNoClearEffectVisitor extends UnifyingAstVisitor<void> {
  final LintRule rule;

  _ReportNoClearEffectVisitor(this.rule);

  @override
  void visitAsExpression(AsExpression node) {
    //  https://github.com/dart-lang/linter/issues/2163
  }

  @override
  void visitAssignmentExpression(AssignmentExpression node) {
    // Has a clear effect. Do not descend.
  }

  @override
  void visitAwaitExpression(AwaitExpression node) {
    // Has a clear effect. Do not descend.
  }

  @override
  void visitBinaryExpression(BinaryExpression node) {
    switch (node.operator.lexeme) {
      case '??':
      case '||':
      case '&&':
        // These are OK when used for control flow.
        node.rightOperand.accept(this);
        return;
    }

    super.visitBinaryExpression(node);
  }

  @override
  void visitCascadeExpression(CascadeExpression node) {
    // Has a clear effect. Do not descend.
  }

  @override
  void visitConditionalExpression(ConditionalExpression node) {
    node.thenExpression.accept(this);
    node.elseExpression.accept(this);
  }

  @override
  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
    // Has a clear effect. Do not descend.
  }

  @override
  void visitInstanceCreationExpression(InstanceCreationExpression node) {
    // A few APIs use this for side effects, like Timer. Also, constructors
    // that have side effects typically have tests will often include an
    // instantiation expression statement.
  }

  @override
  void visitMethodInvocation(MethodInvocation node) {
    // Has a clear effect. Do not descend.
  }

  @override
  void visitNode(AstNode expression) {
    rule.reportAtNode(expression);
  }

  @override
  void visitPatternAssignment(PatternAssignment node) {
    // Has a clear effect. Do not descend.
  }

  @override
  void visitPostfixExpression(PostfixExpression node) {
    // Has a clear effect. Do not descend.
  }

  @override
  void visitPrefixedIdentifier(PrefixedIdentifier node) {
    // Allow getters; getters with side effects were the main cause of false
    // positives.
    var element = node.identifier.element;
    if (element is GetterElement && !element.isSynthetic) {
      return;
    }

    super.visitPrefixedIdentifier(node);
  }

  @override
  void visitPrefixExpression(PrefixExpression node) {
    if (node.operator.lexeme == '--' || node.operator.lexeme == '++') {
      // Has a clear effect. Do not descend.
      return;
    }
    super.visitPrefixExpression(node);
  }

  @override
  void visitPropertyAccess(PropertyAccess node) {
    // Allow getters; previously getters with side effects were the main cause
    // of false positives.
    var element = node.propertyName.element;
    if (element is GetterElement && !element.isSynthetic) {
      return;
    }

    super.visitPropertyAccess(node);
  }

  @override
  void visitRethrowExpression(RethrowExpression node) {
    // Has a clear effect. Do not descend.
  }

  @override
  void visitSimpleIdentifier(SimpleIdentifier node) {
    // Allow getter (in this case with an implicit `this.`); previously, getters
    // with side effects were the main cause of false positives.
    var element = node.element;
    if (element is GetterElement && !element.isSynthetic) {
      return;
    }

    super.visitSimpleIdentifier(node);
  }

  @override
  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
    // Has a clear effect. Do not descend.
  }

  @override
  void visitThrowExpression(ThrowExpression node) {
    // Has a clear effect. Do not descend.
  }
}

class _Visitor extends SimpleAstVisitor<void> {
  final _ReportNoClearEffectVisitor reportNoClearEffect;

  _Visitor(this.reportNoClearEffect);
  @override
  void visitCascadeExpression(CascadeExpression node) {
    for (var section in node.cascadeSections) {
      if (section is PropertyAccess && section.staticType is FunctionType) {
        reportNoClearEffect.rule.reportAtNode(section);
      }
    }
  }

  @override
  void visitExpressionStatement(ExpressionStatement node) {
    if (node.parent is FunctionBody) {
      return;
    }
    node.expression.accept(reportNoClearEffect);
  }

  @override
  void visitForStatement(ForStatement node) {
    var loopParts = node.forLoopParts;
    if (loopParts is ForPartsWithExpression) {
      loopParts.initialization?.accept(reportNoClearEffect);
      for (var u in loopParts.updaters) {
        u.accept(reportNoClearEffect);
      }
    }
  }
}
