// 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/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:linter/src/analyzer.dart';

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

const _details = r'''

**AVOID** using unnecessary statements.

Statements which have no clear effect are usually unnecessary, or should be
broken up.

For example,

**BAD:**
```
myvar;
1 + 2;
some.getter;
methodOne() + methodTwo();
foo ? bar : baz;
```

While the getter may trigger a side-effect, it is not usually obvious.  Though
the added methods have a clear effect, the addition itself does not unless there
is some magical overload of the + operator.

Usually code like this indicates an incomplete thought, and is a bug.  For
instance, the getter was likely supposed to be a function call.

**GOOD:**
```
some.method();
new SomeClass();
methodOne();
methodTwo();
foo ? bar() : baz();
return myvar;
```

''';

class UnnecessaryStatements extends LintRule {
  UnnecessaryStatements()
      : super(
            name: 'unnecessary_statements',
            description: _desc,
            details: _details,
            group: Group.errors);

  @override
  AstVisitor getVisitor() =>
      new _Visitor(new _ReportNoClearEffectVisitor(this));
}

class _Visitor extends SimpleAstVisitor {
  final _ReportNoClearEffectVisitor reportNoClearEffect;
  _Visitor(this.reportNoClearEffect);

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

  @override
  visitForStatement(ForStatement node) {
    node.initialization?.accept(reportNoClearEffect);
    node.updaters?.forEach((u) {
      u.accept(reportNoClearEffect);
    });
  }
}

class _ReportNoClearEffectVisitor extends UnifyingAstVisitor {
  final LintRule rule;
  _ReportNoClearEffectVisitor(this.rule);

  @override
  visitMethodInvocation(MethodInvocation node) {
    // Has a clear effect
  }

  @override
  visitSuperConstructorInvocation(SuperConstructorInvocation node) {
    // Has a clear effect
  }

  @override
  visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
    // Has a clear effect
  }

  @override
  visitAssignmentExpression(AssignmentExpression node) {
    // Has a clear effect
  }

  @override
  visitAwaitExpression(AwaitExpression node) {
    // Has a clear effect
  }

  @override
  visitCascadeExpression(CascadeExpression node) {
    // Has a clear effect
  }

  @override
  visitPostfixExpression(PostfixExpression node) {
    // Has a clear effect
  }

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

  @override
  visitRethrowExpression(RethrowExpression node) {
    // Has a clear effect
  }

  @override
  visitThrowExpression(ThrowExpression node) {
    // Has a clear effect
  }

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

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

  @override
  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
  visitNode(AstNode expression) {
    rule.reportLint(expression);
  }
}
