// 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/syntactic_entity.dart';
import 'package:analyzer/dart/ast/token.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/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
import 'package:collection/collection.dart';

typedef SuggestionsFilter = int? Function(DartType dartType, int relevance);

/// An [AstVisitor] for determining whether top level suggestions or invocation
/// suggestions should be made based upon the type of node in which the
/// suggestions were requested.
class OpType {
  /// Indicates whether constructor suggestions should be included.
  bool includeConstructorSuggestions = false;

  /// Indicates whether type names should be suggested.
  bool includeTypeNameSuggestions = false;

  /// Indicates whether setters along with methods and functions that
  /// have a [void] return type should be suggested.
  bool includeVoidReturnSuggestions = false;

  /// Indicates whether fields and getters along with methods and functions that
  /// have a non-[void] return type should be suggested.
  bool includeReturnValueSuggestions = false;

  /// Indicates whether named arguments should be suggested.
  bool includeNamedArgumentSuggestions = false;

  /// Indicates whether statement labels should be suggested.
  bool includeStatementLabelSuggestions = false;

  /// Indicates whether case labels should be suggested.
  bool includeCaseLabelSuggestions = false;

  /// Indicates whether variable names should be suggested.
  bool includeVarNameSuggestions = false;

  /// Indicates whether the completion location is in a field declaration.
  bool inFieldDeclaration = false;

  /// Indicates whether the completion location is in a top-level variable
  /// declaration.
  bool inTopLevelVariableDeclaration = false;

  /// Indicates whether the completion location is in the body of a static
  /// method.
  bool inStaticMethodBody = false;

  /// Indicates whether the completion target is prefixed.
  bool isPrefixed = false;

  /// The suggested completion kind.
  CompletionSuggestionKind suggestKind = CompletionSuggestionKind.INVOCATION;

  /// An representation of the location at which completion was requested.
  String? completionLocation;

  /// Determine the suggestions that should be made based upon the given
  /// [CompletionTarget] and [offset].
  factory OpType.forCompletion(CompletionTarget target, int offset) {
    var optype = OpType._();

    // Don't suggest anything right after double or integer literals.
    if (target.isDoubleOrIntLiteral()) {
      return optype;
    }

    var targetNode = target.containingNode;
    targetNode.accept(_OpTypeAstVisitor(optype, target.entity, offset));

    var functionBody = targetNode.thisOrAncestorOfType<FunctionBody>();
    if (functionBody != null) {
      var parent = functionBody.parent;

      if (parent is MethodDeclaration) {
        optype.inStaticMethodBody = parent.isStatic;
      }
    }

    optype.inFieldDeclaration =
        targetNode.thisOrAncestorOfType<FieldDeclaration>() != null;
    optype.inTopLevelVariableDeclaration =
        targetNode.thisOrAncestorOfType<TopLevelVariableDeclaration>() != null;

    // If a value should be suggested, suggest also constructors.
    if (optype.includeReturnValueSuggestions) {
      optype.includeConstructorSuggestions = true;
    }

    return optype;
  }

  OpType._();

  /// Return `true` if free standing identifiers should be suggested
  bool get includeIdentifiers {
    return !isPrefixed &&
        (includeReturnValueSuggestions ||
            includeTypeNameSuggestions ||
            includeVoidReturnSuggestions ||
            includeConstructorSuggestions);
  }

  /// Indicate whether only type names should be suggested
  bool get includeOnlyNamedArgumentSuggestions =>
      includeNamedArgumentSuggestions &&
      !includeTypeNameSuggestions &&
      !includeReturnValueSuggestions &&
      !includeVoidReturnSuggestions;

  /// Return the statement before [entity]
  /// where [entity] can be a statement or the `}` closing the given block.
  static Statement? getPreviousStatement(Block node, Object? entity) {
    if (entity == node.rightBracket) {
      return node.statements.isNotEmpty ? node.statements.last : null;
    }
    if (entity is Statement) {
      var index = node.statements.indexOf(entity);
      if (index > 0) {
        return node.statements[index - 1];
      }
      return null;
    }
    return null;
  }
}

class _OpTypeAstVisitor extends GeneralizingAstVisitor<void> {
  /// The entity (AstNode or Token) that will be replaced or displaced by the
  /// added text.
  final SyntacticEntity? entity;

  /// The offset within the source at which the completion is requested.
  final int offset;

  /// The [OpType] being initialized
  final OpType optype;

  _OpTypeAstVisitor(this.optype, this.entity, this.offset);

  @override
  void visitAnnotation(Annotation node) {
    if (identical(entity, node.name)) {
      optype.completionLocation = 'Annotation_name';
      optype.includeTypeNameSuggestions = true;
      optype.includeReturnValueSuggestions = true;
    } else if (identical(entity, node.constructorName)) {
      // There is no location for the constructor name because only named
      // constructors are valid.
      // TODO(brianwilkerson) The following looks wrong. I think we want to set
      //  includeConstructorSuggestions = true, but not type names or return
      //  values. On the other hand, I can't construct a test case that reaches
      //  this point, so perhaps we should just remove this branch.
      optype.includeTypeNameSuggestions = true;
      optype.includeReturnValueSuggestions = true;
      optype.isPrefixed = true;
    }
  }

  @override
  void visitArgumentList(ArgumentList node) {
    final entity = this.entity;
    var parent = node.parent;
    List<ParameterElement>? parameters;
    if (parent is InstanceCreationExpression) {
      Element? constructor;
      var name = parent.constructorName.name;
      if (name != null) {
        constructor = name.staticElement;
      } else {
        var classElem = parent.constructorName.type.name.staticElement;
        if (classElem is ClassElement) {
          constructor = classElem.unnamedConstructor;
        }
      }
      if (constructor is ConstructorElement) {
        parameters = constructor.parameters;
      } else if (constructor == null) {
        // If unresolved, then include named arguments
        optype.includeNamedArgumentSuggestions = true;
      }
    } else if (parent is InvocationExpression) {
      var function = parent.function;
      if (function is SimpleIdentifier) {
        var elem = function.staticElement;
        if (elem is FunctionTypedElement) {
          parameters = elem.parameters;
        } else if (elem == null) {
          // If unresolved, then include named arguments
          optype.includeNamedArgumentSuggestions = true;
        }
      }
    } else if (parent is SuperConstructorInvocation) {
      parameters = parent.staticElement?.parameters;
    } else if (parent is RedirectingConstructorInvocation) {
      parameters = parent.staticElement?.parameters;
    } else if (parent is Annotation) {
      var constructor = parent.element;
      if (constructor is ConstructorElement) {
        parameters = constructor.parameters;
      } else if (constructor == null) {
        // If unresolved, then include named arguments
        optype.includeNamedArgumentSuggestions = true;
      }
    }
    // Based upon the insertion location and declared parameters
    // determine whether only named arguments should be suggested
    if (parameters != null) {
      int index;
      if (node.arguments.isEmpty) {
        index = 0;
      } else if (entity == node.rightParenthesis) {
        // Parser ignores trailing commas
        var previous = node.findPrevious(node.rightParenthesis);
        if (previous?.lexeme == ',') {
          index = node.arguments.length;
        } else {
          index = node.arguments.length - 1;
        }
      } else if (entity is Expression) {
        index = node.arguments.indexOf(entity);
      } else {
        return;
      }
      if (0 <= index && index < parameters.length) {
        var param = parameters[index];
        var paramType = param.type;
        if (paramType is FunctionType && paramType.returnType.isVoid) {
          optype.includeVoidReturnSuggestions = true;
        }
        if (param.isNamed == true) {
          var context = _argumentListContext(node);
          optype.completionLocation = 'ArgumentList_${context}_named';
          optype.includeNamedArgumentSuggestions = true;
          return;
        }
      }
    }
    var context = _argumentListContext(node);
    optype.completionLocation = 'ArgumentList_${context}_unnamed';
    optype.includeReturnValueSuggestions = true;
    optype.includeTypeNameSuggestions = true;
  }

  @override
  void visitAsExpression(AsExpression node) {
    if (identical(entity, node.type)) {
      optype.completionLocation = 'AsExpression_type';
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitAssertInitializer(AssertInitializer node) {
    if (identical(entity, node.condition)) {
      optype.completionLocation = 'AssertInitializer_condition';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    } else if (identical(entity, node.message)) {
      optype.completionLocation = 'AssertInitializer_message';
      // TODO(brianwilkerson) Consider including return value suggestions and
      //  type name suggestions here.
    }
  }

  @override
  void visitAssertStatement(AssertStatement node) {
    if (identical(entity, node.condition)) {
      optype.completionLocation = 'AssertStatement_condition';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    } else if (identical(entity, node.message)) {
      optype.completionLocation = 'AssertStatement_message';
      // TODO(brianwilkerson) Consider including return value suggestions and
      //  type name suggestions here.
    }
  }

  @override
  void visitAssignmentExpression(AssignmentExpression node) {
    if (identical(entity, node.rightHandSide)) {
      optype.completionLocation = 'AssignmentExpression_rightHandSide';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitAwaitExpression(AwaitExpression node) {
    if (identical(entity, node.expression)) {
      optype.completionLocation = 'AwaitExpression_expression';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitBinaryExpression(BinaryExpression node) {
    if (identical(entity, node.rightOperand)) {
      optype.completionLocation =
          'BinaryExpression_${node.operator}_rightOperand';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitBlock(Block node) {
    optype.completionLocation = 'Block_statement';
    var prevStmt = OpType.getPreviousStatement(node, entity);
    if (prevStmt is TryStatement) {
      if (prevStmt.catchClauses.isEmpty && prevStmt.finallyBlock == null) {
        return;
      }
    }
    optype.includeReturnValueSuggestions = true;
    optype.includeTypeNameSuggestions = true;
    optype.includeVoidReturnSuggestions = true;
  }

  @override
  void visitBreakStatement(BreakStatement node) {
    if (node.label == null || identical(entity, node.label)) {
      optype.includeStatementLabelSuggestions = true;
    }
  }

  @override
  void visitCascadeExpression(CascadeExpression node) {
    if (node.cascadeSections.contains(entity)) {
      optype.completionLocation = 'CascadeExpression_cascadeSection';
      optype.includeReturnValueSuggestions = true;
      optype.includeVoidReturnSuggestions = true;
      optype.isPrefixed = true;
    }
  }

  @override
  void visitCatchClause(CatchClause node) {
    if (identical(entity, node.exceptionType)) {
      optype.completionLocation = 'CatchClause_exceptionType';
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitClassDeclaration(ClassDeclaration node) {
    // Make suggestions in the body of the class declaration
    if (node.members.contains(entity) || identical(entity, node.rightBracket)) {
      optype.completionLocation = 'ClassDeclaration_member';
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitClassMember(ClassMember node) {}

  @override
  void visitClassTypeAlias(ClassTypeAlias node) {
    if (identical(entity, node.superclass)) {
      optype.completionLocation = 'ClassTypeAlias_superclass';
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitCommentReference(CommentReference node) {
    optype.completionLocation = 'CommentReference_identifier';
    optype.includeReturnValueSuggestions = true;
    optype.includeTypeNameSuggestions = true;
    optype.includeVoidReturnSuggestions = true;
    optype.suggestKind = CompletionSuggestionKind.IDENTIFIER;
  }

  @override
  void visitCompilationUnit(CompilationUnit node) {
    if (entity is! CommentToken) {
      int declarationStart() {
        var declarations = node.declarations;
        if (declarations.isNotEmpty) {
          return declarations[0].offset;
        }
        var directives = node.directives;
        if (directives.isNotEmpty) {
          return directives.last.end;
        }
        return node.end;
      }

      final entity = this.entity;
      if (entity != null) {
        if (entity.offset <= declarationStart()) {
          optype.completionLocation = 'CompilationUnit_directive';
        } else {
          optype.completionLocation = 'CompilationUnit_declaration';
        }
      }
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitConditionalExpression(ConditionalExpression node) {
    if (identical(entity, node.thenExpression)) {
      optype.completionLocation = 'ConditionalExpression_thenExpression';
    } else if (identical(entity, node.elseExpression)) {
      optype.completionLocation = 'ConditionalExpression_elseExpression';
    }
    optype.includeReturnValueSuggestions = true;
    optype.includeTypeNameSuggestions = true;
  }

  @override
  void visitConstructorDeclaration(ConstructorDeclaration node) {
    if (identical(entity, node.returnType)) {
      optype.completionLocation = 'ConstructorDeclaration_returnType';
      optype.includeTypeNameSuggestions = true;
    } else if (node.initializers.contains(entity)) {
      optype.completionLocation = 'ConstructorDeclaration_initializer';
    }
  }

  @override
  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
    if (identical(entity, node.expression)) {
      optype.completionLocation = 'ConstructorFieldInitializer_expression';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitConstructorName(ConstructorName node) {
    // some PrefixedIdentifier nodes are transformed into
    // ConstructorName nodes during the resolution process.
    if (identical(entity, node.name)) {
      optype.includeConstructorSuggestions = true;
      optype.isPrefixed = true;
    }
  }

  @override
  void visitConstructorSelector(ConstructorSelector node) {
    if (identical(entity, node.name)) {
      optype.completionLocation = 'ConstructorSelector_name';
    }
  }

  @override
  void visitContinueStatement(ContinueStatement node) {
    if (node.label == null || identical(entity, node.label)) {
      optype.includeStatementLabelSuggestions = true;
      optype.includeCaseLabelSuggestions = true;
    }
  }

  @override
  void visitDeclaredIdentifier(DeclaredIdentifier node) {
    var identifier = node.identifier;
    if (identifier == entity &&
        offset < identifier.offset &&
        node.type == null) {
      // Adding a type before the identifier.
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitDefaultFormalParameter(DefaultFormalParameter node) {
    if (identical(entity, node.defaultValue)) {
      optype.completionLocation = 'DefaultFormalParameter_defaultValue';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitDoStatement(DoStatement node) {
    if (identical(entity, node.body)) {
      optype.completionLocation = 'DoStatement_body';
    } else if (identical(entity, node.condition)) {
      optype.completionLocation = 'DoStatement_condition';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitEmptyStatement(EmptyStatement node) {
    optype.includeReturnValueSuggestions = true;
    optype.includeTypeNameSuggestions = true;
    optype.includeVoidReturnSuggestions = true;
  }

  @override
  void visitEnumDeclaration(EnumDeclaration node) {
    if (node.semicolon != null) {
      if (node.members.contains(entity) ||
          identical(entity, node.rightBracket)) {
        optype.completionLocation = 'EnumDeclaration_member';
        optype.includeTypeNameSuggestions = true;
      }
    }
  }

  @override
  void visitExpression(Expression node) {
    // This should never be called; we should always dispatch to the visitor
    // for a particular kind of expression.
    assert(false);
  }

  @override
  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
    var expression = node.expression;
    if (identical(entity, expression)) {
      optype.completionLocation = 'ExpressionFunctionBody_expression';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
      var parent = node.parent;
      DartType? type;
      if (parent is FunctionExpression) {
        type = parent.staticType;
        if (type is FunctionType) {
          if (type.returnType.isVoid) {
            // TODO(brianwilkerson) Determine whether the return type can ever
            //  be inferred as void and remove this case if it can't be.
            optype.includeVoidReturnSuggestions = true;
          } else {
            var grandparent = parent.parent;
            if (grandparent is ArgumentList) {
              var parameter = parent.staticParameterElement;
              if (parameter != null) {
                var parameterType = parameter.type;
                if (parameterType is FunctionType &&
                    parameterType.returnType.isVoid) {
                  optype.includeVoidReturnSuggestions = true;
                }
              }
            }
          }
        }
      } else if (parent is MethodDeclaration) {
        type = parent.declaredElement?.returnType;
        if (type != null && type.isVoid) {
          optype.includeVoidReturnSuggestions = true;
        }
      }
    }
  }

  @override
  void visitExpressionStatement(ExpressionStatement node) {
    optype.completionLocation = 'ExpressionStatement_expression';
    // Given f[], the parser drops the [] from the expression statement
    // but the [] token is the CompletionTarget entity
    if (entity is Token) {
      var token = entity as Token;
      if (token.lexeme == '[]' && offset == token.offset + 1) {
        optype.includeReturnValueSuggestions = true;
        optype.includeTypeNameSuggestions = true;
      }
      if ((token.isSynthetic || token.lexeme == ';') &&
          node.expression is Identifier) {
        optype.includeVarNameSuggestions = true;
      }
    }
  }

  @override
  void visitExtendsClause(ExtendsClause node) {
    if (identical(entity, node.superclass)) {
      optype.completionLocation = 'ExtendsClause_superclass';
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitExtensionDeclaration(ExtensionDeclaration node) {
    if (identical(entity, node.extendedType)) {
      optype.completionLocation = 'ExtensionDeclaration_extendedType';
      optype.includeTypeNameSuggestions = true;
    } else if (node.members.contains(entity) ||
        identical(entity, node.rightBracket)) {
      // Make suggestions in the body of the extension declaration
      optype.completionLocation = 'ExtensionDeclaration_member';
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitFieldDeclaration(FieldDeclaration node) {
    if (entity == node.fields) {
      optype.completionLocation = 'FieldDeclaration_fields';
    }

    // Incomplete code looks like a "field" declaration.
    if (node.fields.type == null) {
      var variables = node.fields.variables;
      // class A { static late ^ }
      if (node.staticKeyword != null &&
          variables.length == 1 &&
          variables[0].name.name == 'late') {
        optype.completionLocation = 'FieldDeclaration_static_late';
        optype.includeTypeNameSuggestions = true;
        return;
      }
      // class A { static ^ }
      if (node.staticKeyword == null &&
          offset <= node.semicolon.offset &&
          variables.length == 1 &&
          variables[0].name.name == 'static') {
        optype.completionLocation = 'FieldDeclaration_static';
        optype.includeTypeNameSuggestions = true;
        return;
      }
    }

    if (offset <= node.semicolon.offset) {
      optype.includeVarNameSuggestions = true;
    }
    if (offset <= node.fields.offset) {
      optype.includeTypeNameSuggestions = true;
    }

    // If there is no type then the first "field" could be intended as a type
    // so also include type name suggestions. eg:
    //     class MyClass2 { static MyCl^ }
    if (node.fields.type == null &&
        (node.fields.variables.isEmpty ||
            offset <= node.fields.variables.first.end)) {
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitFieldFormalParameter(FieldFormalParameter node) {
    if (entity == node.identifier) {
      optype.isPrefixed = true;
    } else {
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitForEachParts(ForEachParts node) {
    if (identical(entity, node.inKeyword) && offset <= node.inKeyword.offset) {
      if (!(node is ForEachPartsWithIdentifier ||
          node is ForEachPartsWithDeclaration)) {
        optype.includeTypeNameSuggestions = true;
      }
    }
  }

  @override
  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
    if (identical(entity, node.loopVariable)) {
      optype.completionLocation = 'ForEachPartsWithDeclaration_loopVariable';
      optype.includeTypeNameSuggestions = true;
    } else if (identical(entity, node.iterable)) {
      optype.completionLocation = 'ForEachPartsWithDeclaration_iterable';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
    visitForEachParts(node);
  }

  @override
  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
    if (identical(entity, node.identifier)) {
      optype.completionLocation = 'ForEachPartsWithIdentifier_identifier';
      optype.includeTypeNameSuggestions = true;
    } else if (identical(entity, node.iterable)) {
      optype.completionLocation = 'ForEachPartsWithIdentifier_iterable';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
    visitForEachParts(node);
  }

  @override
  void visitForElement(ForElement node) {
    // for (^) {}
    // for (Str^ str = null;) {}
    // In theory it is possible to specify any expression in initializer,
    // but for any practical use we need only types.
    if (entity == node.forLoopParts) {
      optype.completionLocation = 'ForElement_forLoopParts';
      optype.includeTypeNameSuggestions = true;
    } else if (entity == node.body) {
      optype.completionLocation = 'ForElement_body';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitFormalParameterList(FormalParameterList node) {
    optype.completionLocation = 'FormalParameterList_parameter';
    final entity = this.entity;
    if (entity is Token) {
      var previous = node.findPrevious(entity);
      if (previous != null) {
        var type = previous.type;
        if (type == TokenType.OPEN_PAREN || type == TokenType.COMMA) {
          optype.includeTypeNameSuggestions = true;
        }
      }
    }

    // Find the containing parameter.
    var parameter = CompletionTarget.findFormalParameter(node, offset);
    if (parameter == null) return;

    // Handle default normal parameter just as a normal parameter.
    if (parameter is DefaultFormalParameter) {
      parameter = parameter.parameter;
    }

    // "(^ this.field)"
    if (parameter is FieldFormalParameter) {
      if (offset < parameter.thisKeyword.offset) {
        optype.includeTypeNameSuggestions = true;
      }
      return;
    }

    // "(Type name)"
    if (parameter is SimpleFormalParameter) {
      visitSimpleFormalParameter(parameter);
    }
  }

  @override
  void visitForParts(ForParts node) {
    final entity = this.entity;
    if (_isEntityPrevTokenSynthetic()) {
      // Actual: for (var v i^)
      // Parsed: for (var i; i^;)
    } else if (entity is Token &&
        entity.isSynthetic &&
        node.leftSeparator == entity) {
      // Actual: for (String ^)
      // Parsed: for (String; ;)
      //                    ^
      optype.includeVarNameSuggestions = true;
    } else {
      if (entity == node.condition) {
        // for (; ^) {}
        optype.completionLocation = 'ForParts_condition';
        optype.includeTypeNameSuggestions = true;
        optype.includeReturnValueSuggestions = true;
      } else if (node.updaters.contains(entity)) {
        // for (; ; ^) {}
        optype.completionLocation = 'ForParts_updater';
        optype.includeTypeNameSuggestions = true;
        optype.includeReturnValueSuggestions = true;
        optype.includeVoidReturnSuggestions = true;
      }
    }
  }

  @override
  void visitForStatement(ForStatement node) {
    // for (^) {}
    // for (Str^ str = null;) {}
    // In theory it is possible to specify any expression in initializer,
    // but for any practical use we need only types.
    if (entity == node.forLoopParts) {
      optype.completionLocation = 'ForStatement_forLoopParts';
      optype.includeTypeNameSuggestions = true;
    } else if (entity == node.body) {
      optype.completionLocation = 'ForStatement_body';
    }
  }

  @override
  void visitFunctionDeclaration(FunctionDeclaration node) {
    if (identical(entity, node.returnType) ||
        identical(entity, node.name) && node.returnType == null) {
      optype.completionLocation = 'FunctionDeclaration_returnType';
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitFunctionExpression(FunctionExpression node) {}

  @override
  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {}

  @override
  void visitFunctionTypeAlias(FunctionTypeAlias node) {
    if (identical(entity, node.returnType) ||
        identical(entity, node.name) && node.returnType == null) {
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitGenericTypeAlias(GenericTypeAlias node) {
    if (entity == node.type) {
      optype.includeTypeNameSuggestions = true;
      optype.completionLocation = 'GenericTypeAlias_type';
    }
  }

  @override
  void visitHideCombinator(HideCombinator node) {
    if (node.hiddenNames.contains(entity)) {
      optype.completionLocation = 'HideCombinator_hiddenName';
    }
  }

  @override
  void visitIfElement(IfElement node) {
    if (identical(entity, node.condition)) {
      optype.completionLocation = 'IfElement_condition';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    } else if (identical(entity, node.thenElement)) {
      optype.completionLocation = 'IfElement_thenElement';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
      optype.includeVoidReturnSuggestions = true;
    } else if (identical(entity, node.elseElement)) {
      optype.completionLocation = 'IfElement_elseElement';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
      optype.includeVoidReturnSuggestions = true;
    }
  }

  @override
  void visitIfStatement(IfStatement node) {
    if (_isEntityPrevTokenSynthetic()) {
      // Actual: if (var v i^)
      // Parsed: if (v) i^;
    } else if (identical(entity, node.condition)) {
      optype.completionLocation = 'IfStatement_condition';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    } else if (identical(entity, node.thenStatement)) {
      optype.completionLocation = 'IfStatement_thenStatement';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
      optype.includeVoidReturnSuggestions = true;
    } else if (identical(entity, node.elseStatement)) {
      optype.completionLocation = 'IfStatement_elseStatement';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
      optype.includeVoidReturnSuggestions = true;
    }
  }

  @override
  void visitImplementsClause(ImplementsClause node) {
    optype.completionLocation = 'ImplementsClause_interface';
    optype.includeTypeNameSuggestions = true;
  }

  @override
  void visitIndexExpression(IndexExpression node) {
    optype.completionLocation = 'IndexExpression_index';
    optype.includeReturnValueSuggestions = true;
    optype.includeTypeNameSuggestions = true;
  }

  @override
  void visitInstanceCreationExpression(InstanceCreationExpression node) {
    if (identical(entity, node.constructorName)) {
      optype.completionLocation = 'InstanceCreationExpression_constructorName';
      optype.includeConstructorSuggestions = true;
    }
  }

  @override
  void visitInterpolationExpression(InterpolationExpression node) {
    if (identical(entity, node.expression)) {
      optype.completionLocation = 'InterpolationExpression_expression';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitIsExpression(IsExpression node) {
    if (identical(entity, node.type)) {
      optype.completionLocation = 'IsExpression_type';
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitLabeledStatement(LabeledStatement node) {
    optype.completionLocation = 'LabeledStatement_statement';
  }

  @override
  void visitLibraryIdentifier(LibraryIdentifier node) {
    // No suggestions.
  }

  @override
  void visitListLiteral(ListLiteral node) {
    if (node.elements.contains(entity)) {
      optype.completionLocation = 'ListLiteral_element';
    }
    visitTypedLiteral(node);
  }

  @override
  void visitMapLiteralEntry(MapLiteralEntry node) {
    optype.completionLocation = 'MapLiteralEntry_value';
    optype.includeReturnValueSuggestions = true;
    optype.includeTypeNameSuggestions = true;
  }

  @override
  void visitMethodDeclaration(MethodDeclaration node) {
    if (identical(entity, node.returnType) ||
        identical(entity, node.name) && node.returnType == null) {
      optype.completionLocation = 'MethodDeclaration_returnType';
    }
    // TODO(brianwilkerson) In visitFunctionDeclaration, this is conditional. It
    //  seems like it should be the same in both places.
    optype.includeTypeNameSuggestions = true;
  }

  @override
  void visitMethodInvocation(MethodInvocation node) {
    var isThis = node.target is ThisExpression;
    var operator = node.operator;
    if (operator != null &&
        identical(entity, operator) &&
        offset > operator.offset) {
      // The cursor is between the two dots of a ".." token, so we need to
      // generate the completions we would generate after a "." token.
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = !isThis;
      optype.includeVoidReturnSuggestions = true;
      optype.isPrefixed = true;
    } else if (identical(entity, node.methodName)) {
      optype.includeReturnValueSuggestions = true;
      optype.includeVoidReturnSuggestions = true;
      optype.isPrefixed = true;
    } else if (identical(entity, node.argumentList)) {
      // Note that when the cursor is in a type argument list (f<^>()), the
      // entity is (surprisingly) the invocation's argumentList (and not it's
      // typeArgumentList as you'd expect).
      if (offset < node.argumentList.offset) {
        optype.completionLocation = 'TypeArgumentList_argument';
      } else {
        var argKind = 'unnamed';
        var method = node.methodName.staticElement;
        if (method is MethodElement &&
            method.parameters.isNotEmpty &&
            method.parameters[0].isNamed) {
          argKind = 'named';
        }
        optype.completionLocation = 'ArgumentList_method_$argKind';
      }
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitMixinDeclaration(MixinDeclaration node) {
    // Make suggestions in the body of the mixin declaration
    if (node.members.contains(entity) || identical(entity, node.rightBracket)) {
      optype.completionLocation = 'MixinDeclaration_member';
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitNamedExpression(NamedExpression node) {
    if (identical(entity, node.expression)) {
      var context = _argumentListContext(node.parent);
      optype.completionLocation = 'ArgumentList_${context}_named';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;

      // Check for named parameters in constructor calls.
      var grandparent = node.parent?.parent;
      Element? element;
      if (grandparent is ConstructorReferenceNode) {
        element = grandparent.staticElement;
      } else if (grandparent is InstanceCreationExpression) {
        element = grandparent.constructorName.staticElement;
      } else if (grandparent is MethodInvocation) {
        element = grandparent.methodName.staticElement;
      }
      if (element is ExecutableElement) {
        var parameters = element.parameters;
        var parameterElement = parameters.firstWhereOrNull((e) {
          if (e is DefaultFieldFormalParameterElementImpl) {
            return e.field?.name == node.name.label.name;
          }
          return e.isNamed && e.name == node.name.label.name;
        });
        // Suggest tear-offs.
        if (parameterElement?.type is FunctionType) {
          optype.includeVoidReturnSuggestions = true;
        }
      }
    }
  }

  @override
  void visitNamedType(NamedType node) {
    // The entity won't be the first child entity (node.name), since
    // CompletionTarget would have chosen an edge higher in the parse tree. So
    // it must be node.typeArguments, meaning that the cursor is between the
    // type name and the "<" that starts the type arguments. In this case,
    // we have no completions to offer.
    assert(identical(entity, node.typeArguments));
  }

  @override
  void visitNode(AstNode node) {
    // no suggestion by default
  }

  @override
  void visitNormalFormalParameter(NormalFormalParameter node) {
    if (node.identifier != entity) {
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitOnClause(OnClause node) {
    optype.completionLocation = 'OnClause_superclassConstraint';
    optype.includeTypeNameSuggestions = true;
  }

  @override
  void visitParenthesizedExpression(ParenthesizedExpression node) {
    if (identical(entity, node.expression)) {
      optype.completionLocation = 'ParenthesizedExpression_expression';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitPostfixExpression(PostfixExpression node) {
    optype.includeReturnValueSuggestions = true;
    optype.includeTypeNameSuggestions = true;
  }

  @override
  void visitPrefixedIdentifier(PrefixedIdentifier node) {
    if (identical(entity, node.identifier) ||
        // In addition to the standard case,
        // handle the exceptional case where the parser considers the would-be
        // identifier to be a keyword and inserts a synthetic identifier
        (node.identifier.isSynthetic &&
            identical(entity, node.findPrevious(node.identifier.beginToken)))) {
      if (node.prefix.isSynthetic) {
        // If the access has no target (empty string)
        // then don't suggest anything
        return;
      }
      optype.isPrefixed = true;
      if (node.parent is NamedType && node.parent?.parent is ConstructorName) {
        optype.includeConstructorSuggestions = true;
      } else if (node.parent is Annotation) {
        optype.includeConstructorSuggestions = true;
      } else {
        optype.completionLocation = 'PropertyAccess_propertyName';
        optype.includeReturnValueSuggestions = true;
        optype.includeTypeNameSuggestions = true;
        optype.includeVoidReturnSuggestions =
            node.parent is ExpressionStatement;
      }
    }
  }

  @override
  void visitPrefixExpression(PrefixExpression node) {
    if (identical(entity, node.operand)) {
      optype.completionLocation = 'PrefixExpression_${node.operator}_operand';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitPropertyAccess(PropertyAccess node) {
    if (node.realTarget is SimpleIdentifier && node.realTarget.isSynthetic) {
      // If the access has no target (empty string)
      // then don't suggest anything
      return;
    }
    var isThis = node.target is ThisExpression;
    if (identical(entity, node.operator) && offset > node.operator.offset) {
      // The cursor is between the two dots of a ".." token, so we need to
      // generate the completions we would generate after a "." token.
      optype.completionLocation = 'PropertyAccess_propertyName';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = !isThis;
      optype.includeVoidReturnSuggestions = true;
      optype.isPrefixed = true;
    } else if (identical(entity, node.propertyName)) {
      optype.completionLocation = 'PropertyAccess_propertyName';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions =
          !isThis && (node.parent is! CascadeExpression);
      optype.includeVoidReturnSuggestions = true;
      optype.isPrefixed = true;
    }
  }

  @override
  void visitReturnStatement(ReturnStatement node) {
    if (identical(entity, node.expression) ||
        (identical(entity, node.semicolon) && node.expression == null)) {
      optype.completionLocation = 'ReturnStatement_expression';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitSetOrMapLiteral(SetOrMapLiteral node) {
    if (node.elements.contains(entity)) {
      optype.completionLocation = 'SetOrMapLiteral_element';
    }
    visitTypedLiteral(node);
  }

  @override
  void visitShowCombinator(ShowCombinator node) {
    if (node.shownNames.contains(entity)) {
      optype.completionLocation = 'ShowCombinator_shownName';
    }
  }

  @override
  void visitSimpleFormalParameter(SimpleFormalParameter node) {
    var type = node.type;
    var name = node.identifier;

    // "(Type^)" is parsed as a parameter with the _name_ "Type".
    if (type == null &&
        name != null &&
        name.offset <= offset &&
        offset <= name.end) {
      optype.includeTypeNameSuggestions = true;
      return;
    }

    // If "(^ Type)", then include types.
    if (type == null && name != null && offset < name.offset) {
      optype.includeTypeNameSuggestions = true;
      return;
    }

    // If "(Type ^)", then include parameter names.
    if (type == null && name != null && name.end < offset) {
      var nextToken = name.token.next;
      if (nextToken != null && offset <= nextToken.offset) {
        optype.includeVarNameSuggestions = true;
        return;
      }
    }

    // If inside of "Type" in "(Type^ name)", then include types.
    if (type != null && type.offset <= offset && offset <= type.end) {
      optype.includeTypeNameSuggestions = true;
      return;
    }

    // If "(Type name^)", then include parameter names.
    if (type != null &&
        name != null &&
        name.offset <= offset &&
        offset <= name.end) {
      optype.includeVarNameSuggestions = true;
      return;
    }

    if (_isParameterOfGenericFunctionType(node) && type != null) {
      // If "Function(^ Type)", then include types.
      if (offset < type.offset) {
        optype.includeTypeNameSuggestions = true;
        return;
      }
      // If "Function(Type ^)", then include parameter names.
      if (name == null && type.end < offset) {
        optype.includeVarNameSuggestions = true;
        return;
      }
    }
  }

  @override
  void visitSimpleIdentifier(SimpleIdentifier node) {
    // This should never happen; the containingNode will always be some node
    // higher up in the parse tree, and the SimpleIdentifier will be the
    // entity.
    assert(false);
  }

  @override
  void visitSpreadElement(SpreadElement node) {
    if (identical(entity, node.expression)) {
      optype.completionLocation = 'SpreadElement_expression';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitStringLiteral(StringLiteral node) {
    // no suggestions
  }

  @override
  void visitSwitchCase(SwitchCase node) {
    if (identical(entity, node.expression)) {
      optype.completionLocation = 'SwitchCase_expression';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    } else if (node.statements.contains(entity)) {
      optype.completionLocation = 'SwitchMember_statement';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
      optype.includeVoidReturnSuggestions = true;
    }
  }

  @override
  void visitSwitchStatement(SwitchStatement node) {
    if (identical(entity, node.expression)) {
      optype.completionLocation = 'SwitchStatement_expression';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
    if (identical(entity, node.rightBracket)) {
      if (node.members.isNotEmpty) {
        optype.completionLocation = 'SwitchMember_statement';
        optype.includeReturnValueSuggestions = true;
        optype.includeTypeNameSuggestions = true;
        optype.includeVoidReturnSuggestions = true;
      }
    }
    if (entity is SwitchMember && entity != node.members.first) {
      var member = entity as SwitchMember;
      if (offset <= member.offset) {
        optype.completionLocation = 'SwitchMember_statement';
        optype.includeReturnValueSuggestions = true;
        optype.includeTypeNameSuggestions = true;
        optype.includeVoidReturnSuggestions = true;
      }
    }
  }

  @override
  void visitThrowExpression(ThrowExpression node) {
    optype.completionLocation = 'ThrowExpression_expression';
    optype.includeReturnValueSuggestions = true;
    optype.includeTypeNameSuggestions = true;
  }

  @override
  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
    if (entity is Token) {
      var token = entity as Token;
      if (token.isSynthetic || token.lexeme == ';') {
        optype.includeVarNameSuggestions = true;
      }
    }
    if (offset <= node.variables.offset) {
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitTypeArgumentList(TypeArgumentList node) {
    var arguments = node.arguments;
    for (var type in arguments) {
      if (identical(entity, type)) {
        optype.completionLocation = 'TypeArgumentList_argument';
        optype.includeTypeNameSuggestions = true;
        break;
      }
    }
  }

  @override
  void visitTypedLiteral(TypedLiteral node) {
    optype.includeReturnValueSuggestions = true;
    optype.includeTypeNameSuggestions = true;
  }

  @override
  void visitTypeParameter(TypeParameter node) {
    if (entity == node.bound) {
      optype.completionLocation = 'TypeParameter_bound';
    }
    optype.includeTypeNameSuggestions = true;
  }

  @override
  void visitVariableDeclaration(VariableDeclaration node) {
    // Make suggestions for the RHS of a variable declaration
    if (identical(entity, node.initializer)) {
      optype.completionLocation = 'VariableDeclaration_initializer';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  @override
  void visitVariableDeclarationList(VariableDeclarationList node) {
    if (node.keyword == null || node.keyword?.lexeme != 'var') {
      if (node.type == null || identical(entity, node.type)) {
        optype.completionLocation = 'VariableDeclarationList_type';
        optype.includeTypeNameSuggestions = true;
      } else if (node.type != null && entity is VariableDeclaration) {
        optype.includeVarNameSuggestions = true;
      }
    }
  }

  @override
  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {}

  @override
  void visitWhileStatement(WhileStatement node) {
    if (identical(entity, node.condition)) {
      optype.completionLocation = 'WhileStatement_condition';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    } else if (identical(entity, node.body)) {
      optype.completionLocation = 'WhileStatement_body';
    }
  }

  @override
  void visitWithClause(WithClause node) {
    if (node.mixinTypes.contains(entity)) {
      optype.completionLocation = 'WithClause_mixinType';
    }
    optype.includeTypeNameSuggestions = true;
  }

  @override
  void visitYieldStatement(YieldStatement node) {
    if (identical(entity, node.expression)) {
      optype.completionLocation = 'YieldStatement_expression';
      optype.includeReturnValueSuggestions = true;
      optype.includeTypeNameSuggestions = true;
    }
  }

  /// Return the context in which the [node] occurs. The [node] is expected to
  /// be the parent of the argument expression.
  String _argumentListContext(AstNode? node) {
    if (node is ArgumentList) {
      var parent = node.parent;
      if (parent is Annotation) {
        return 'annotation';
      } else if (parent is EnumConstantArguments) {
        return 'enumConstantArguments';
      } else if (parent is ExtensionOverride) {
        return 'extensionOverride';
      } else if (parent is FunctionExpressionInvocation) {
        return 'function';
      } else if (parent is InstanceCreationExpression) {
        // TODO(brianwilkerson) Enable this case.
//        if (flutter.isWidgetType(parent.staticType)) {
//          return 'widgetConstructor';
//        }
        return 'constructor';
      } else if (parent is MethodInvocation) {
        return 'method';
      } else if (parent is RedirectingConstructorInvocation) {
        return 'constructorRedirect';
      } else if (parent is SuperConstructorInvocation) {
        return 'constructorRedirect';
      }
    } else if (node is AssignmentExpression ||
        node is BinaryExpression ||
        node is PrefixExpression ||
        node is PostfixExpression) {
      return 'operator';
    } else if (node is IndexExpression) {
      return 'index';
    }
    throw ArgumentError(
        'Unknown parent of ${node.runtimeType}: ${node?.parent.runtimeType}');
  }

  bool _isEntityPrevTokenSynthetic() {
    final entity = this.entity;
    if (entity is AstNode) {
      var previous = entity.findPrevious(entity.beginToken);
      if (previous?.isSynthetic ?? false) {
        return true;
      }
    }
    return false;
  }

  static bool _isParameterOfGenericFunctionType(FormalParameter node) {
    var parameterList = node.parent;
    if (parameterList is DefaultFormalParameter) {
      parameterList = parameterList.parent;
    }
    return parameterList is FormalParameterList &&
        parameterList.parent is GenericFunctionType;
  }
}
