// 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 'dart:async';
import 'dart:math';

import 'package:analysis_server/src/protocol_server.dart' hide Element;
import 'package:analysis_server/src/services/correction/source_buffer.dart';
import 'package:analysis_server/src/services/correction/util.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/error.dart' as engine;
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/error/hint_codes.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';

/**
 * An enumeration of possible statement completion kinds.
 */
class DartStatementCompletion {
  static const NO_COMPLETION =
      const StatementCompletionKind('No_COMPLETION', 'No completion available');
  static const SIMPLE_ENTER = const StatementCompletionKind(
      'SIMPLE_ENTER', "Insert a newline at the end of the current line");
  static const SIMPLE_SEMICOLON = const StatementCompletionKind(
      'SIMPLE_SEMICOLON', "Add a semicolon and newline");
  static const COMPLETE_CLASS_DECLARATION = const StatementCompletionKind(
      'COMPLETE_CLASS_DECLARATION', "Complete class declaration");
  static const COMPLETE_CONTROL_FLOW_BLOCK = const StatementCompletionKind(
      'COMPLETE_CONTROL_FLOW_BLOCK', "Complete control flow block");
  static const COMPLETE_DO_STMT = const StatementCompletionKind(
      'COMPLETE_DO_STMT', "Complete do-statement");
  static const COMPLETE_IF_STMT = const StatementCompletionKind(
      'COMPLETE_IF_STMT', "Complete if-statement");
  static const COMPLETE_FOR_STMT = const StatementCompletionKind(
      'COMPLETE_FOR_STMT', "Complete for-statement");
  static const COMPLETE_FOR_EACH_STMT = const StatementCompletionKind(
      'COMPLETE_FOR_EACH_STMT', "Complete for-each-statement");
  static const COMPLETE_FUNCTION_DECLARATION = const StatementCompletionKind(
      'COMPLETE_FUNCTION_DECLARATION', "Complete function declaration");
  static const COMPLETE_SWITCH_STMT = const StatementCompletionKind(
      'COMPLETE_SWITCH_STMT', "Complete switch-statement");
  static const COMPLETE_TRY_STMT = const StatementCompletionKind(
      'COMPLETE_TRY_STMT', "Complete try-statement");
  static const COMPLETE_VARIABLE_DECLARATION = const StatementCompletionKind(
      'COMPLETE_VARIABLE_DECLARATION', "Complete variable declaration");
  static const COMPLETE_WHILE_STMT = const StatementCompletionKind(
      'COMPLETE_WHILE_STMT', "Complete while-statement");
}

/**
 * A description of a statement completion.
 *
 * Clients may not extend, implement or mix-in this class.
 */
class StatementCompletion {
  /**
   * A description of the assist being proposed.
   */
  final StatementCompletionKind kind;

  /**
   * The change to be made in order to apply the assist.
   */
  final SourceChange change;

  /**
   * Initialize a newly created completion to have the given [kind] and [change].
   */
  StatementCompletion(this.kind, this.change);
}

/**
 * The context for computing a statement completion.
 */
class StatementCompletionContext {
  final ResolvedUnitResult resolveResult;
  final int selectionOffset;

  StatementCompletionContext(this.resolveResult, this.selectionOffset);
}

/**
 * A description of a class of statement completions. Instances are intended to
 * hold the information that is common across a number of completions and to be
 * shared by those completions.
 *
 * Clients may not extend, implement or mix-in this class.
 */
class StatementCompletionKind {
  /**
   * The name of this kind of statement completion, used for debugging.
   */
  final String name;

  /**
   * A human-readable description of the changes that will be applied by this
   * kind of statement completion.
   */
  final String message;

  /**
   * Initialize a newly created kind of statement completion to have the given
   * [name] and [message].
   */
  const StatementCompletionKind(this.name, this.message);

  @override
  String toString() => name;
}

/**
 * The computer for Dart statement completions.
 */
class StatementCompletionProcessor {
  static final NO_COMPLETION = new StatementCompletion(
      DartStatementCompletion.NO_COMPLETION, new SourceChange("", edits: []));

  final StatementCompletionContext statementContext;
  final CorrectionUtils utils;
  AstNode node;
  StatementCompletion completion;
  SourceChange change = new SourceChange('statement-completion');
  List<engine.AnalysisError> errors = [];
  final Map<String, LinkedEditGroup> linkedPositionGroups =
      <String, LinkedEditGroup>{};
  Position exitPosition = null;

  StatementCompletionProcessor(this.statementContext)
      : utils = new CorrectionUtils(statementContext.resolveResult);

  String get eol => utils.endOfLine;

  String get file => statementContext.resolveResult.path;

  LineInfo get lineInfo => statementContext.resolveResult.lineInfo;

  int get selectionOffset => statementContext.selectionOffset;

  Source get source => unitElement.source;

  CompilationUnit get unit => statementContext.resolveResult.unit;

  CompilationUnitElement get unitElement =>
      statementContext.resolveResult.unit.declaredElement;

  Future<StatementCompletion> compute() async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    node = _selectedNode();
    if (node == null) {
      return NO_COMPLETION;
    }
    node = node.thisOrAncestorMatching(
        (n) => n is Statement || _isNonStatementDeclaration(n));
    if (node == null) {
      return _complete_simpleEnter() ? completion : NO_COMPLETION;
    }
    if (node is Block) {
      Block blockNode = node;
      if (blockNode.statements.isNotEmpty) {
        node = blockNode.statements.last;
      }
    }
    if (_isEmptyStatementOrEmptyBlock(node)) {
      node = node.parent;
    }
    for (engine.AnalysisError error in statementContext.resolveResult.errors) {
      if (error.offset >= node.offset && error.offset <= node.end) {
        if (error.errorCode is! HintCode) {
          errors.add(error);
        }
      }
    }

    _checkExpressions();
    if (node is Statement) {
      if (errors.isEmpty) {
        if (_complete_ifStatement() ||
            _complete_forStatement2() ||
            _complete_whileStatement() ||
            _complete_controlFlowBlock()) {
          return completion;
        }
      } else {
        if (_complete_ifStatement() ||
            _complete_doStatement() ||
            _complete_forStatement2() ||
            _complete_functionDeclarationStatement() ||
            _complete_switchStatement() ||
            _complete_tryStatement() ||
            _complete_whileStatement() ||
            _complete_controlFlowBlock() ||
            _complete_simpleSemicolon() ||
            _complete_methodCall()) {
          return completion;
        }
      }
    } else if (node is Declaration) {
      if (errors.isNotEmpty) {
        if (_complete_classDeclaration() ||
            _complete_functionDeclaration() ||
            _complete_variableDeclaration()) {
          return completion;
        }
      }
    }
    if (_complete_simpleEnter()) {
      return completion;
    }
    return NO_COMPLETION;
  }

  void _addInsertEdit(int offset, String text) {
    SourceEdit edit = new SourceEdit(offset, 0, text);
    doSourceChange_addElementEdit(change, unitElement, edit);
  }

  void _addReplaceEdit(SourceRange range, String text) {
    SourceEdit edit = new SourceEdit(range.offset, range.length, text);
    doSourceChange_addElementEdit(change, unitElement, edit);
  }

  void _appendEmptyBraces(SourceBuilder sb, [bool needsExitMark = false]) {
    sb.append('{');
    sb.append(eol);
    String indent = utils.getLinePrefix(selectionOffset);
    sb.append(indent);
    sb.append(utils.getIndent(1));
    if (needsExitMark && sb.exitOffset == null) {
      sb.setExitOffset();
    }
    sb.append(eol);
    sb.append(indent);
    sb.append('}');
  }

  int _appendNewlinePlusIndent() {
    return _appendNewlinePlusIndentAt(selectionOffset);
  }

  int _appendNewlinePlusIndentAt(int offset) {
    // Append a newline plus proper indent and another newline.
    // Return the position before the second newline.
    String indent = utils.getLinePrefix(offset);
    int loc = utils.getLineNext(offset);
    _addInsertEdit(loc, indent + eol);
    return loc + indent.length;
  }

  String _baseNodeText(AstNode astNode) {
    String text = utils.getNodeText(astNode);
    if (text.endsWith(eol)) {
      text = text.substring(0, text.length - eol.length);
    }
    return text;
  }

  void _checkExpressions() {
    // Note: This may queue edits that have to be accounted for later.
    // See _lengthOfInsertions().
    AstNode errorMatching(errorCode, {partialMatch = null}) {
      var error = _findError(errorCode, partialMatch: partialMatch);
      if (error == null) {
        return null;
      }
      AstNode expr = _selectedNode();
      return (expr.thisOrAncestorOfType<StringInterpolation>() == null)
          ? expr
          : null;
    }

    var expr = errorMatching(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
    if (expr != null) {
      String source = utils.getNodeText(expr);
      String content = source;
      int char = content.codeUnitAt(0);
      if (char == 'r'.codeUnitAt(0)) {
        content = source.substring(1);
        char = content.codeUnitAt(0);
      }
      String delimiter;
      int loc;
      if (content.length >= 3 &&
          char == content.codeUnitAt(1) &&
          char == content.codeUnitAt(2)) {
        // multi-line string
        delimiter = content.substring(0, 3);
        int newlineLoc = source.indexOf(eol, selectionOffset - expr.offset);
        if (newlineLoc < 0) {
          newlineLoc = source.length;
        }
        loc = newlineLoc + expr.offset;
      } else {
        // add first char of src
        delimiter = content.substring(0, 1);
        loc = expr.offset + source.length;
      }
      _removeError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
      _addInsertEdit(loc, delimiter);
    }
    expr = errorMatching(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "']'") ??
        errorMatching(ScannerErrorCode.EXPECTED_TOKEN, partialMatch: "']'");
    if (expr != null) {
      expr = expr.thisOrAncestorOfType<ListLiteral>();
      if (expr != null) {
        ListLiteral lit = expr;
        if (lit.rightBracket.isSynthetic) {
          String src = utils.getNodeText(expr).trim();
          int loc = expr.offset + src.length;
          if (src.contains(eol)) {
            String indent = utils.getNodePrefix(node);
            _addInsertEdit(loc, ',' + eol + indent + ']');
          } else {
            _addInsertEdit(loc, ']');
          }
          _removeError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "']'");
          _removeError(ScannerErrorCode.EXPECTED_TOKEN, partialMatch: "']'");
          var ms =
              _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'");
          if (ms != null) {
            // Ensure the semicolon gets inserted in the correct location.
            ms.offset = loc - 1;
          }
        }
      }
    }
    // The following code is similar to the code for ']' but does not work well.
    // A closing brace is recognized as belong to the map even if it is intended
    // to close a block of code.
    /*
    expr = errorMatching(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "'}'");
    if (expr != null) {
      expr = expr.getAncestor((n) => n is MapLiteral);
      if (expr != null) {
        MapLiteral lit = expr;
        String src = utils.getNodeText(expr).trim();
        int loc = expr.offset + src.length;
        if (lit.entries.last.separator.isSynthetic) {
          _addInsertEdit(loc, ': ');
        }
        if (!src.endsWith('}')/*lit.rightBracket.isSynthetic*/) {
          _addInsertEdit(loc, '}');
        }
        _removeError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "'}'");
        var ms =
          _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'");
        if (ms != null) {
          // Ensure the semicolon gets inserted in the correct location.
          ms.offset = loc - 1;
        }
      }
    }
    */
  }

  bool _complete_classDeclaration() {
    if (node is! ClassDeclaration) {
      return false;
    }
    ClassDeclaration decl = node;
    if (decl.leftBracket.isSynthetic && errors.length == 1) {
      // The space before the left brace is assumed to exist, even if it does not.
      SourceBuilder sb = new SourceBuilder(file, decl.end - 1);
      sb.append(' ');
      _appendEmptyBraces(sb, true);
      _insertBuilder(sb);
      _setCompletion(DartStatementCompletion.COMPLETE_CLASS_DECLARATION);
      return true;
    }
    return false;
  }

  bool _complete_controlFlowBlock() {
    Expression expr = (node is ExpressionStatement)
        ? (node as ExpressionStatement).expression
        : (node is ReturnStatement
            ? (node as ReturnStatement).expression
            : null);
    if (!(node is ReturnStatement || expr is ThrowExpression)) {
      return false;
    }
    if (node.parent is! Block) {
      return false;
    }
    AstNode outer = node.parent.parent;
    if (!(outer is DoStatement ||
        outer is ForStatement2 ||
        outer is IfStatement ||
        outer is WhileStatement)) {
      return false;
    }
    int previousInsertions = _lengthOfInsertions();
    int delta = 0;
    if (errors.isNotEmpty) {
      var error =
          _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'");
      if (error != null) {
        int insertOffset;
        // Fasta scanner reports unterminated string literal errors
        // and generates a synthetic string token with non-zero length.
        // Because of this, check for length == 0 rather than isSynthetic.
        if (expr == null || expr.length == 0) {
          if (node is ReturnStatement) {
            insertOffset = (node as ReturnStatement).returnKeyword.end;
          } else if (node is ExpressionStatement) {
            insertOffset =
                ((node as ExpressionStatement).expression as ThrowExpression)
                    .throwKeyword
                    .end;
          } else {
            insertOffset = node.end; // Not reached.
          }
        } else {
          insertOffset = expr.end;
        }
        //TODO(messick) Uncomment the following line when error location is fixed.
        //insertOffset = error.offset + error.length;
        _addInsertEdit(insertOffset, ';');
        delta = 1;
      }
    }
    int offset = _appendNewlinePlusIndentAt(node.parent.end);
    exitPosition = new Position(file, offset + delta + previousInsertions);
    _setCompletion(DartStatementCompletion.COMPLETE_CONTROL_FLOW_BLOCK);
    return true;
  }

  bool _complete_doStatement() {
    if (node is! DoStatement) {
      return false;
    }
    DoStatement statement = node;
    SourceBuilder sb = _sourceBuilderAfterKeyword(statement.doKeyword);
    // I modified the code and ran the tests with both the old and new parser.
    // Apparently the old parser sometimes sticks something other than 'while'
    // into the whileKeyword field, which causes statement completion to throw
    // an exception further downstream.
    // TODO(danrubel): change `statement.whileKeyword?.lexeme == "while"`
    // to `statement.whileKeyword != null` once the fasta parser is the default.
    bool hasWhileKeyword = statement.whileKeyword?.lexeme == "while" &&
        !statement.whileKeyword.isSynthetic;
    int exitDelta = 0;
    if (!_statementHasValidBody(statement.doKeyword, statement.body)) {
      String text = utils.getNodeText(statement.body);
      int delta = 0;
      if (text.startsWith(';')) {
        delta = 1;
        _addReplaceEdit(range.startLength(statement.body, delta), '');
        if (hasWhileKeyword) {
          text = utils.getNodeText(statement);
          if (text.indexOf(new RegExp(r'do\s*;\s*while')) == 0) {
            int end = text.indexOf('while');
            int start = text.indexOf(';') + 1;
            delta += end - start - 1;
            _addReplaceEdit(
                new SourceRange(start + statement.offset, end - start), ' ');
          }
        }
        sb = new SourceBuilder(file, sb.offset + delta);
        sb.append(' ');
      }
      _appendEmptyBraces(sb,
          !(hasWhileKeyword && _isSyntheticExpression(statement.condition)));
      if (delta != 0) {
        exitDelta = sb.length - delta;
      }
    } else if (_isEmptyBlock(statement.body)) {
      sb = new SourceBuilder(sb.file, statement.body.end);
    }
    SourceBuilder sb2;
    if (hasWhileKeyword) {
      var stmt = new _KeywordConditionBlockStructure(
          statement.whileKeyword,
          statement.leftParenthesis,
          statement.condition,
          statement.rightParenthesis,
          null);
      sb2 = _complete_keywordCondition(stmt);
      if (sb2 == null) {
        return false;
      }
      if (sb2.length == 0) {
        // true if condition is '()'
        if (exitPosition != null) {
          if (statement.semicolon.isSynthetic) {
            _insertBuilder(sb);
            sb = new SourceBuilder(file, exitPosition.offset + 1);
            sb.append(';');
          }
        }
      } else {
        if (sb.exitOffset == null && sb2?.exitOffset != null) {
          _insertBuilder(sb);
          sb = sb2;
          sb.append(';');
        } else {
          sb.append(sb2.toString());
        }
      }
    } else {
      sb.append(" while (");
      sb.setExitOffset();
      sb.append(");");
    }
    _insertBuilder(sb);
    if (exitDelta != 0) {
      exitPosition =
          new Position(exitPosition.file, exitPosition.offset + exitDelta);
    }
    _setCompletion(DartStatementCompletion.COMPLETE_DO_STMT);
    return true;
  }

  bool _complete_forEachStatement(
      ForStatement2 forNode, ForEachParts forEachParts) {
    AstNode name;
    if (forEachParts is ForEachPartsWithIdentifier) {
      name = forEachParts.identifier;
    } else if (forEachParts is ForEachPartsWithDeclaration) {
      name = forEachParts.loopVariable;
    } else {
      throw new StateError('Unrecognized for loop parts');
    }
    return _complete_forEachStatementRest(
        forNode.forKeyword,
        forNode.leftParenthesis,
        name,
        forEachParts.inKeyword,
        forEachParts.iterable,
        forNode.rightParenthesis,
        forNode.body);
  }

  bool _complete_forEachStatementRest(
      Token forKeyword,
      Token leftParenthesis,
      AstNode name,
      Token inKeyword,
      Expression iterable,
      Token rightParenthesis,
      Statement body) {
    if (inKeyword.isSynthetic) {
      return false; // Can't happen -- would be parsed as a for-statement.
    }
    SourceBuilder sb = new SourceBuilder(file, rightParenthesis.offset + 1);
    String src = utils.getNodeText(node);
    if (name == null) {
      exitPosition = new Position(file, leftParenthesis.offset + 1);
      src = src.substring(leftParenthesis.offset - node.offset);
      if (src.startsWith(new RegExp(r'\(\s*in\s*\)'))) {
        _addReplaceEdit(
            range.startOffsetEndOffset(
                leftParenthesis.offset + 1, rightParenthesis.offset),
            ' in ');
      } else if (src.startsWith(new RegExp(r'\(\s*in'))) {
        _addReplaceEdit(
            range.startOffsetEndOffset(
                leftParenthesis.offset + 1, inKeyword.offset),
            ' ');
      }
    } else if (iterable != null && _isSyntheticExpression(iterable)) {
      exitPosition = new Position(file, rightParenthesis.offset + 1);
      src = src.substring(inKeyword.offset - node.offset);
      if (src.startsWith(new RegExp(r'in\s*\)'))) {
        _addReplaceEdit(
            range.startOffsetEndOffset(
                inKeyword.offset + inKeyword.length, rightParenthesis.offset),
            ' ');
      }
    }
    if (!_statementHasValidBody(forKeyword, body)) {
      sb.append(' ');
      _appendEmptyBraces(sb, exitPosition == null);
    }
    _insertBuilder(sb);
    _setCompletion(DartStatementCompletion.COMPLETE_FOR_EACH_STMT);
    return true;
  }

  bool _complete_forStatement(ForStatement2 forNode, ForParts forParts) {
    SourceBuilder sb;
    int replacementLength = 0;
    if (forNode.leftParenthesis.isSynthetic) {
      if (!forNode.rightParenthesis.isSynthetic) {
        return false;
      }
      // keywordOnly (unit test name suffix that exercises this branch)
      sb = _sourceBuilderAfterKeyword(forNode.forKeyword);
      sb.append('(');
      sb.setExitOffset();
      sb.append(')');
    } else {
      if (!forParts.rightSeparator.isSynthetic) {
        // Fully-defined init, cond, updaters so nothing more needed here.
        // emptyParts, noError
        sb = new SourceBuilder(file, forNode.rightParenthesis.offset + 1);
      } else if (!forParts.leftSeparator.isSynthetic) {
        if (_isSyntheticExpression(forParts.condition)) {
          String text = utils
              .getNodeText(forNode)
              .substring(forParts.leftSeparator.offset - forNode.offset);
          Match match =
              new RegExp(r';\s*(/\*.*\*/\s*)?\)[ \t]*').matchAsPrefix(text);
          if (match != null) {
            // emptyCondition, emptyInitializersEmptyCondition
            replacementLength = match.end - match.start;
            sb = new SourceBuilder(file, forParts.leftSeparator.offset);
            sb.append('; ${match.group(1) == null ? '' : match.group(1)}; )');
            String suffix = text.substring(match.end);
            if (suffix.trim().isNotEmpty) {
              sb.append(' ');
              sb.append(suffix.trim());
              replacementLength += suffix.length;
              if (suffix.endsWith(eol)) {
                // emptyCondition
                replacementLength -= eol.length;
              }
            }
            exitPosition = _newPosition(forParts.leftSeparator.offset + 2);
          } else {
            return false; // Line comment in condition
          }
        } else {
          // emptyUpdaters
          sb = new SourceBuilder(file, forNode.rightParenthesis.offset);
          replacementLength = 1;
          sb.append('; )');
          exitPosition = _newPosition(forParts.rightSeparator.offset + 2);
        }
      } else if (forParts is ForPartsWithExpression &&
          _isSyntheticExpression(forParts.initialization)) {
        // emptyInitializers
        exitPosition = _newPosition(forNode.rightParenthesis.offset);
        sb = new SourceBuilder(file, forNode.rightParenthesis.offset);
      } else if (forParts is ForPartsWithExpression &&
          forParts.initialization is SimpleIdentifier &&
          forParts.initialization.beginToken.lexeme == 'in') {
        // looks like a for/each statement missing the loop variable
        return _complete_forEachStatementRest(
            forNode.forKeyword,
            forNode.leftParenthesis,
            null,
            forParts.initialization.beginToken,
            null,
            forNode.rightParenthesis,
            forNode.body);
      } else {
        int start = forParts.condition.offset + forParts.condition.length;
        String text =
            utils.getNodeText(forNode).substring(start - forNode.offset);
        if (text.startsWith(new RegExp(r'\s*\)'))) {
          // missingLeftSeparator
          int end = text.indexOf(')');
          sb = new SourceBuilder(file, start);
          _addReplaceEdit(new SourceRange(start, end), '; ; ');
          exitPosition = new Position(file, start - (end - '; '.length));
        } else {
          // Not possible; any comment following init is attached to init.
          exitPosition = _newPosition(forNode.rightParenthesis.offset);
          sb = new SourceBuilder(file, forNode.rightParenthesis.offset);
        }
      }
    }
    if (!_statementHasValidBody(forNode.forKeyword, forNode.body)) {
      // keywordOnly, noError
      sb.append(' ');
      _appendEmptyBraces(sb, true /*exitPosition == null*/);
    } else if (forNode.body is Block) {
      Block body = forNode.body;
      if (body.rightBracket.end <= selectionOffset) {
        // emptyInitializersAfterBody
        errors = []; // Ignore errors; they are for previous statement.
        return false; // If cursor is after closing brace just add newline.
      }
    }
    _insertBuilder(sb, replacementLength);
    _setCompletion(DartStatementCompletion.COMPLETE_FOR_STMT);
    return true;
  }

  bool _complete_forStatement2() {
    var node = this.node;
    if (node is ForStatement2) {
      var forLoopParts = node.forLoopParts;
      if (forLoopParts is ForParts) {
        return _complete_forStatement(node, forLoopParts);
      } else if (forLoopParts is ForEachParts) {
        return _complete_forEachStatement(node, forLoopParts);
      }
    }
    return false;
  }

  bool _complete_functionDeclaration() {
    if (node is! MethodDeclaration && node is! FunctionDeclaration) {
      return false;
    }
    bool needsParen = false;
    int computeExitPos(FormalParameterList parameters) {
      if (needsParen = parameters.rightParenthesis.isSynthetic) {
        var error = _findError(ParserErrorCode.MISSING_CLOSING_PARENTHESIS);
        if (error != null) {
          return error.offset - 1;
        }
      }
      return node.end - 1;
    }

    int paramListEnd;
    if (node is FunctionDeclaration) {
      FunctionDeclaration func = node;
      paramListEnd = computeExitPos(func.functionExpression.parameters);
    } else {
      MethodDeclaration meth = node;
      paramListEnd = computeExitPos(meth.parameters);
    }
    SourceBuilder sb = new SourceBuilder(file, paramListEnd);
    if (needsParen) {
      sb.append(')');
    }
    sb.append(' ');
    _appendEmptyBraces(sb, true);
    _insertBuilder(sb);
    _setCompletion(DartStatementCompletion.COMPLETE_FUNCTION_DECLARATION);
    return true;
  }

  bool _complete_functionDeclarationStatement() {
    if (node is! FunctionDeclarationStatement) {
      return false;
    }
    var error = _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'");
    if (error != null) {
      FunctionDeclarationStatement stmt = node;
      String src = utils.getNodeText(stmt);
      int insertOffset = stmt.functionDeclaration.end - 1;
      if (stmt.functionDeclaration.functionExpression.body
          is ExpressionFunctionBody) {
        ExpressionFunctionBody fnb =
            stmt.functionDeclaration.functionExpression.body;
        int fnbOffset = fnb.functionDefinition.offset;
        String fnSrc = src.substring(fnbOffset - stmt.offset);
        if (!fnSrc.startsWith('=>')) {
          return false;
        }
        int delta = 0;
        if (fnb.expression.isSynthetic) {
          if (!fnSrc.startsWith('=> ')) {
            _addInsertEdit(insertOffset, ' ');
            delta = 1;
          }
          _addInsertEdit(insertOffset, ';');
          _appendNewlinePlusIndentAt(insertOffset);
        } else {
          delta = 1;
          _addInsertEdit(insertOffset, ';');
          insertOffset = _appendNewlinePlusIndent();
        }
        _setCompletionAt(
            DartStatementCompletion.SIMPLE_SEMICOLON, insertOffset + delta);
        return true;
      }
    }
    return false;
  }

  bool _complete_ifOrWhileStatement(
      _KeywordConditionBlockStructure statement, StatementCompletionKind kind) {
    if (_statementHasValidBody(statement.keyword, statement.block)) {
      return false;
    }
    SourceBuilder sb = _complete_keywordCondition(statement);
    if (sb == null) {
      return false;
    }
    int overshoot = _lengthOfDeletions();
    sb.append(' ');
    _appendEmptyBraces(sb, exitPosition == null);
    _insertBuilder(sb);
    if (overshoot != 0) {
      exitPosition = _newPosition(exitPosition.offset - overshoot);
    }
    _setCompletion(kind);
    return true;
  }

  bool _complete_ifStatement() {
    if (node is! IfStatement) {
      return false;
    }
    IfStatement ifNode = node;
    if (ifNode.elseKeyword != null) {
      if (selectionOffset >= ifNode.elseKeyword.end &&
          _isEmptyStatement(ifNode.elseStatement)) {
        SourceBuilder sb = new SourceBuilder(file, selectionOffset);
        String src = utils.getNodeText(ifNode);
        if (!src
            .substring(ifNode.elseKeyword.end - node.offset)
            .startsWith(new RegExp(r'[ \t]'))) {
          sb.append(' ');
        }
        _appendEmptyBraces(sb, true);
        _insertBuilder(sb);
        _setCompletion(DartStatementCompletion.COMPLETE_IF_STMT);
        return true;
      }
      return false;
    }
    var stmt = new _KeywordConditionBlockStructure(
        ifNode.ifKeyword,
        ifNode.leftParenthesis,
        ifNode.condition,
        ifNode.rightParenthesis,
        ifNode.thenStatement);
    return _complete_ifOrWhileStatement(
        stmt, DartStatementCompletion.COMPLETE_IF_STMT);
  }

  SourceBuilder _complete_keywordCondition(
      _KeywordConditionBlockStructure statement) {
    SourceBuilder sb;
    if (statement.leftParenthesis.isSynthetic) {
      if (!statement.rightParenthesis.isSynthetic) {
        // Quite unlikely to see this so don't try to fix it.
        return null;
      }
      sb = _sourceBuilderAfterKeyword(statement.keyword);
      sb.append('(');
      sb.setExitOffset();
      sb.append(')');
    } else {
      if (_isSyntheticExpression(statement.condition)) {
        exitPosition = _newPosition(statement.leftParenthesis.offset + 1);
        sb = new SourceBuilder(file, statement.rightParenthesis.offset + 1);
      } else if (statement.rightParenthesis.isSynthetic) {
        sb = new SourceBuilder(file, statement.condition.end);
        sb.append(')');
      } else {
        int afterParen = statement.rightParenthesis.offset + 1;
        if (utils
            .getNodeText(node)
            .substring(afterParen - node.offset)
            .startsWith(new RegExp(r'[ \t]'))) {
          _addReplaceEdit(new SourceRange(afterParen, 1), '');
          sb = new SourceBuilder(file, afterParen + 1);
        } else {
          sb = new SourceBuilder(file, afterParen);
        }
      }
    }
    return sb;
  }

  bool _complete_methodCall() {
    var parenError =
        _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "')'") ??
            _findError(ScannerErrorCode.EXPECTED_TOKEN, partialMatch: "')'");
    if (parenError == null) {
      return false;
    }
    AstNode argList =
        _selectedNode(at: selectionOffset).thisOrAncestorOfType<ArgumentList>();
    if (argList == null) {
      argList = _selectedNode(at: parenError.offset)
          .thisOrAncestorOfType<ArgumentList>();
    }
    if (argList?.thisOrAncestorMatching((n) => n == node) == null) {
      return false;
    }
    int previousInsertions = _lengthOfInsertions();
    int loc = min(selectionOffset, argList.end - 1);
    int delta = 1;
    var semicolonError =
        _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'");
    if (semicolonError == null) {
      loc += 1;
      delta = 0;
    }
    _addInsertEdit(loc, ')');
    if (semicolonError != null) {
      _addInsertEdit(loc, ';');
    }
    String indent = utils.getLinePrefix(selectionOffset);
    int exit = utils.getLineNext(selectionOffset);
    _addInsertEdit(exit, indent + eol);
    exit += indent.length + eol.length + previousInsertions;

    _setCompletionAt(DartStatementCompletion.SIMPLE_ENTER, exit + delta);
    return true;
  }

  bool _complete_simpleEnter() {
    int offset;
    if (!errors.isEmpty) {
      offset = selectionOffset;
    } else {
      String indent = utils.getLinePrefix(selectionOffset);
      int loc = utils.getLineNext(selectionOffset);
      _addInsertEdit(loc, indent + eol);
      offset = loc + indent.length;
    }
    _setCompletionAt(DartStatementCompletion.SIMPLE_ENTER, offset);
    return true;
  }

  bool _complete_simpleSemicolon() {
    if (errors.length != 1) {
      return false;
    }
    var error = _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'");
    if (error != null) {
      int previousInsertions = _lengthOfInsertions();
      // TODO(messick) Fix this to find the correct place in all cases.
      int insertOffset = error.offset + error.length;
      _addInsertEdit(insertOffset, ';');
      int offset = _appendNewlinePlusIndent() + 1 /*';'*/ + previousInsertions;
      _setCompletionAt(DartStatementCompletion.SIMPLE_SEMICOLON, offset);
      return true;
    }
    return false;
  }

  bool _complete_switchStatement() {
    if (node is! SwitchStatement) {
      return false;
    }
    SourceBuilder sb;
    SwitchStatement switchNode = node;
    if (switchNode.leftParenthesis.isSynthetic &&
        switchNode.rightParenthesis.isSynthetic) {
      exitPosition = new Position(file, switchNode.switchKeyword.end + 2);
      String src = utils.getNodeText(switchNode);
      if (src
          .substring(switchNode.switchKeyword.end - switchNode.offset)
          .startsWith(new RegExp(r'[ \t]+'))) {
        sb = new SourceBuilder(file, switchNode.switchKeyword.end + 1);
      } else {
        sb = new SourceBuilder(file, switchNode.switchKeyword.end);
        sb.append(' ');
      }
      sb.append('()');
    } else if (switchNode.leftParenthesis.isSynthetic ||
        switchNode.rightParenthesis.isSynthetic) {
      return false;
    } else {
      sb = new SourceBuilder(file, switchNode.rightParenthesis.offset + 1);
      if (_isSyntheticExpression(switchNode.expression)) {
        exitPosition =
            new Position(file, switchNode.leftParenthesis.offset + 1);
      }
    }
    if (switchNode
        .leftBracket.isSynthetic /*&& switchNode.rightBracket.isSynthetic*/) {
      // See https://github.com/dart-lang/sdk/issues/29391
      sb.append(' ');
      _appendEmptyBraces(sb, exitPosition == null);
    } else {
      SwitchMember member = _findInvalidElement(switchNode.members);
      if (member != null) {
        if (member.colon.isSynthetic) {
          int loc =
              member is SwitchCase ? member.expression.end : member.keyword.end;
          sb = new SourceBuilder(file, loc);
          sb.append(': ');
          exitPosition = new Position(file, loc + 2);
        }
      }
    }
    _insertBuilder(sb);
    _setCompletion(DartStatementCompletion.COMPLETE_SWITCH_STMT);
    return true;
  }

  bool _complete_tryStatement() {
    if (node is! TryStatement) {
      return false;
    }
    TryStatement tryNode = node;
    SourceBuilder sb;
    CatchClause catchNode;
    bool addSpace = true;
    if (tryNode.body.leftBracket.isSynthetic) {
      String src = utils.getNodeText(tryNode);
      if (src
          .substring(tryNode.tryKeyword.end - tryNode.offset)
          .startsWith(new RegExp(r'[ \t]+'))) {
        // keywordSpace
        sb = new SourceBuilder(file, tryNode.tryKeyword.end + 1);
      } else {
        // keywordOnly
        sb = new SourceBuilder(file, tryNode.tryKeyword.end);
        sb.append(' ');
      }
      _appendEmptyBraces(sb, true);
      _insertBuilder(sb);
      sb = null;
    } else if ((catchNode = _findInvalidElement(tryNode.catchClauses)) !=
        null) {
      if (catchNode.onKeyword != null) {
        if (catchNode.exceptionType.length == 0 ||
            null !=
                _findError(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE,
                    partialMatch: "name 'catch")) {
          String src = utils.getNodeText(catchNode);
          if (src.startsWith(new RegExp(r'on[ \t]+'))) {
            if (src.startsWith(new RegExp(r'on[ \t][ \t]+'))) {
              // onSpaces
              exitPosition = new Position(file, catchNode.onKeyword.end + 1);
              sb = new SourceBuilder(file, catchNode.onKeyword.end + 2);
              addSpace = false;
            } else {
              // onSpace
              sb = new SourceBuilder(file, catchNode.onKeyword.end + 1);
              sb.setExitOffset();
            }
          } else {
            // onOnly
            sb = new SourceBuilder(file, catchNode.onKeyword.end);
            sb.append(' ');
            sb.setExitOffset();
          }
        } else {
          // onType
          sb = new SourceBuilder(file, catchNode.exceptionType.end);
        }
      }
      if (catchNode.catchKeyword != null) {
        // catchOnly
        var struct = new _KeywordConditionBlockStructure(
            catchNode.catchKeyword,
            catchNode.leftParenthesis,
            catchNode.exceptionParameter,
            catchNode.rightParenthesis,
            catchNode.body);
        if (sb != null) {
          // onCatch
          _insertBuilder(sb);
        }
        sb = _complete_keywordCondition(struct);
        if (sb == null) {
          return false;
        }
      }
      if (catchNode.body.leftBracket.isSynthetic) {
        // onOnly and others
        if (addSpace) {
          sb.append(' ');
        }
        _appendEmptyBraces(sb, exitPosition == null);
      }
      _insertBuilder(sb);
    } else if (tryNode.finallyKeyword != null) {
      if (tryNode.finallyBlock.leftBracket.isSynthetic) {
        // finallyOnly
        sb = new SourceBuilder(file, tryNode.finallyKeyword.end);
        sb.append(' ');
        _appendEmptyBraces(sb, true);
        _insertBuilder(sb);
      }
    }
    _setCompletion(DartStatementCompletion.COMPLETE_TRY_STMT);
    return true;
  }

  bool _complete_variableDeclaration() {
    if (node is! VariableDeclaration) {
      return false;
    }
    _addInsertEdit(node.end, ';');
    exitPosition = new Position(file, _appendNewlinePlusIndentAt(node.end) + 1);
    _setCompletion(DartStatementCompletion.COMPLETE_VARIABLE_DECLARATION);
    return true;
  }

  bool _complete_whileStatement() {
    if (node is! WhileStatement) {
      return false;
    }
    WhileStatement whileNode = node;
    if (whileNode != null) {
      var stmt = new _KeywordConditionBlockStructure(
          whileNode.whileKeyword,
          whileNode.leftParenthesis,
          whileNode.condition,
          whileNode.rightParenthesis,
          whileNode.body);
      return _complete_ifOrWhileStatement(
          stmt, DartStatementCompletion.COMPLETE_WHILE_STMT);
    }
    return false;
  }

  engine.AnalysisError _findError(ErrorCode code, {partialMatch: null}) {
    return errors.firstWhere(
        (err) =>
            err.errorCode == code &&
            (partialMatch == null ? true : err.message.contains(partialMatch)),
        orElse: () => null);
  }

  T _findInvalidElement<T extends AstNode>(NodeList<T> list) {
    return list.firstWhere(
        (item) => selectionOffset >= item.offset && selectionOffset <= item.end,
        orElse: () => null);
  }

  void _insertBuilder(SourceBuilder builder, [int length = 0]) {
    {
      SourceRange range = new SourceRange(builder.offset, length);
      String text = builder.toString();
      _addReplaceEdit(range, text);
    }
    // add exit position
    {
      int exitOffset = builder.exitOffset;
      if (exitOffset != null) {
        exitPosition = _newPosition(exitOffset);
      }
    }
  }

  bool _isEmptyBlock(AstNode stmt) {
    return stmt is Block && stmt.statements.isEmpty;
  }

  bool _isEmptyStatement(AstNode stmt) {
    if (stmt is ExpressionStatement) {
      Expression expression = stmt.expression;
      if (expression is SimpleIdentifier) {
        return expression.token.isSynthetic;
      }
    }
    return stmt is EmptyStatement;
  }

  bool _isEmptyStatementOrEmptyBlock(AstNode stmt) {
    return _isEmptyStatement(stmt) || _isEmptyBlock(stmt);
  }

  bool _isNonStatementDeclaration(AstNode n) {
    if (n is! Declaration) {
      return false;
    }
    if (n is! VariableDeclaration && n is! FunctionDeclaration) {
      return true;
    }
    AstNode p = n.parent;
    return p is! Statement &&
        p?.parent is! Statement &&
        p?.parent?.parent is! Statement;
  }

  bool _isSyntheticExpression(Expression expr) {
    return expr is SimpleIdentifier && expr.isSynthetic;
  }

  int _lengthOfDeletions() {
    if (change.edits.isEmpty) {
      return 0;
    }
    int length = 0;
    for (SourceFileEdit edit in change.edits) {
      for (SourceEdit srcEdit in edit.edits) {
        if (srcEdit.length > 0) {
          length += srcEdit.length - srcEdit.replacement.length;
        }
      }
    }
    return length;
  }

  int _lengthOfInsertions() {
    // Any _complete_*() that may follow changes made by _checkExpressions()
    // must cache the result of this method and add that value to its
    // exit position. That's assuming all edits are done in increasing position.
    // There are currently no editing sequences that produce both insertions and
    // deletions, but if there were this approach would have to be generalized.
    if (change.edits.isEmpty) {
      return 0;
    }
    int length = 0;
    for (SourceFileEdit edit in change.edits) {
      for (SourceEdit srcEdit in edit.edits) {
        if (srcEdit.length == 0) {
          length += srcEdit.replacement.length;
        }
      }
    }
    return length;
  }

  Position _newPosition(int offset) {
    return new Position(file, offset);
  }

  void _removeError(errorCode, {partialMatch = null}) {
    var error = _findError(errorCode, partialMatch: partialMatch);
    if (error != null) {
      errors.remove(error);
    }
  }

  AstNode _selectedNode({int at: null}) =>
      new NodeLocator(at == null ? selectionOffset : at).searchWithin(unit);

  void _setCompletion(StatementCompletionKind kind, [List args]) {
    assert(exitPosition != null);
    change.selection = exitPosition;
    change.message = formatList(kind.message, args);
    linkedPositionGroups.values
        .forEach((group) => change.addLinkedEditGroup(group));
    completion = new StatementCompletion(kind, change);
  }

  void _setCompletionAt(StatementCompletionKind kind, int offset, [List args]) {
    exitPosition = _newPosition(offset);
    _setCompletion(kind, args);
  }

  SourceBuilder _sourceBuilderAfterKeyword(Token keyword) {
    SourceBuilder sb;
    String text = _baseNodeText(node);
    text = text.substring(keyword.offset - node.offset);
    int len = keyword.length;
    if (text.length == len || // onCatchComment
        !text.substring(len, len + 1).contains(new RegExp(r'[ \t]'))) {
      sb = new SourceBuilder(file, keyword.offset + len);
      sb.append(' ');
    } else {
      sb = new SourceBuilder(file, keyword.offset + len + 1);
    }
    return sb;
  }

  bool _statementHasValidBody(Token keyword, Statement body) {
    // A "valid" body is either a non-synthetic block or a single statement
    // on the same line as the parent statement, similar to dart_style.
    if (body.isSynthetic) {
      return false;
    }
    if (body is Block) {
      Block block = body;
      return (!(block.leftBracket.isSynthetic));
    }
    return (lineInfo.getLocation(keyword.offset) ==
        lineInfo.getLocation(body.offset));
  }
}

// Encapsulate common structure of if-statement and while-statement.
class _KeywordConditionBlockStructure {
  final Token keyword;
  final Token leftParenthesis, rightParenthesis;
  final Expression condition;
  final Statement block;

  _KeywordConditionBlockStructure(this.keyword, this.leftParenthesis,
      this.condition, this.rightParenthesis, this.block);

  int get offset => keyword.offset;
}
