// Copyright (c) 2020, 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:analysis_server/src/protocol/protocol_internal.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
import 'package:analyzer/dart/analysis/results.dart';
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' as element;
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/source/line_info.dart';

import 'completion_metrics.dart';

class ExpectedCompletion {
  final String _filePath;

  final SyntacticEntity _entity;

  /// Some completions are special cased from the DAS "import" for instance is
  /// suggested as a completion "import '';", the completion string here in this
  /// instance would have the value "import '';".
  final String? _completionString;

  final protocol.CompletionSuggestionKind? _kind;

  final int _lineNumber;

  final int _columnNumber;

  final protocol.ElementKind? _elementKind;

  ExpectedCompletion(
    this._filePath,
    this._entity,
    this._lineNumber,
    this._columnNumber,
    this._kind,
    this._elementKind,
  ) : _completionString = null;

  /// Return an instance extracted from the decoded JSON [map].
  factory ExpectedCompletion.fromJson(Map<String, dynamic> map) {
    var jsonDecoder = ResponseDecoder(null);
    var filePath = map['filePath'] as String;
    var offset = map['offset'] as int;
    var lineNumber = map['lineNumber'] as int;
    var columnNumber = map['columnNumber'] as int;
    var completionString = map['completionString'] as String;
    var kind =
        map['kind'] != null
            ? protocol.CompletionSuggestionKind.fromJson(
              jsonDecoder,
              '',
              map['kind'] as String,
            )
            : null;
    var elementKind =
        map['elementKind'] != null
            ? protocol.ElementKind.fromJson(
              jsonDecoder,
              '',
              map['elementKind'] as String,
            )
            : null;
    return ExpectedCompletion.specialCompletionString(
      filePath,
      _SyntacticEntity(offset),
      lineNumber,
      columnNumber,
      completionString,
      kind,
      elementKind,
    );
  }

  ExpectedCompletion.specialCompletionString(
    this._filePath,
    this._entity,
    this._lineNumber,
    this._columnNumber,
    this._completionString,
    this._kind,
    this._elementKind,
  );

  int get columnNumber => _columnNumber;

  String get completion => _completionString ?? _entity.toString();

  protocol.ElementKind? get elementKind => _elementKind;

  String get filePath => _filePath;

  protocol.CompletionSuggestionKind? get kind => _kind;

  int get lineNumber => _lineNumber;

  String get location => '$filePath:$lineNumber:$columnNumber';

  int get offset => _entity.offset;

  SyntacticEntity get syntacticEntity => _entity;

  bool matches(CompletionSuggestionLite completionSuggestion) {
    if (completionSuggestion.completion == completion) {
      if (kind != null && completionSuggestion.kind != kind) {
        return false;
      }
      if (elementKind != null &&
          completionSuggestion.elementKind != null &&
          completionSuggestion.elementKind != elementKind) {
        return false;
      }
      return true;
    }
    return false;
  }

  /// Return a map used to represent this expected completion in a JSON structure.
  Map<String, dynamic> toJson() {
    var kind = _kind;
    var elementKind = _elementKind;
    return {
      'filePath': _filePath,
      'offset': _entity.offset,
      'lineNumber': _lineNumber,
      'columnNumber': _columnNumber,
      'completionString': _completionString,
      if (kind != null) 'kind': kind.toJson(),
      if (elementKind != null) 'elementKind': elementKind.toJson(),
    };
  }

  @override
  String toString() =>
      "'$completion', kind = $kind, elementKind = $elementKind, $location";
}

class ExpectedCompletionsVisitor extends RecursiveAstVisitor<void> {
  static const ASYNC_STAR = 'async*';

  static const DEFAULT_COLON = 'default:';

  static const DEFERRED_AS = 'deferred as';

  static const EXPORT_STATEMENT = "export '';";

  static const IMPORT_STATEMENT = "import '';";

  static const PART_STATEMENT = "part '';";
  static const SYNC_STAR = 'sync*';
  static const YIELD_STAR = 'yield*';

  /// The result of resolving the file being visited.
  final ResolvedUnitResult result;

  /// The offset from the location of each entity passed to
  /// [safelyRecordEntity], to be used as the column for each
  /// [ExpectedCompletion] created.
  final int _caretOffset;

  /// The completions that are expected to be produced in the file being
  /// visited.
  final List<ExpectedCompletion> expectedCompletions = [];

  /// This boolean is set to enable whether or not we should assert that some
  /// found keyword in Dart syntax should be in the completion set returned from
  /// the analysis server.  This is off by default because with syntax such as
  /// "^get foo() => _foo;", "get" and "set" won't be suggested because this
  /// syntax has specified the "get" modifier, i.e. it would be invalid to
  /// include it again: "get get foo() => _foo;".
  final bool _doExpectKeywordCompletions = false;

  /// This boolean is set to enable if identifiers in comments should be
  /// expected to be completed. The default is false as typos in a dartdoc
  /// comment don't yield an error like Dart syntax mistakes would yield.
  final bool _doExpectCommentRefs = false;

  ExpectedCompletionsVisitor(this.result, {required int caretOffset})
    : _caretOffset = caretOffset;

  /// Return the path of the file that is being visited.
  String get filePath => result.path;

  /// Return the line info for the file that is being visited.
  LineInfo get lineInfo => result.lineInfo;

  void safelyRecordEntity(
    SyntacticEntity? entity, {
    protocol.CompletionSuggestionKind? kind,
    protocol.ElementKind? elementKind,
  }) {
    // Only record if this entity is not null, has a length, etc.
    if (entity != null && entity.offset >= 0 && entity.length > 0) {
      var location = lineInfo.getLocation(entity.offset);
      var lineNumber = location.lineNumber;
      var columnNumber = location.columnNumber;
      if (entity.length >= _caretOffset) {
        columnNumber += _caretOffset;
      }

      bool isKeyword() => kind == protocol.CompletionSuggestionKind.KEYWORD;

      // Some special cases in the if and if-else blocks, 'import' from the
      // DAS is "import '';" which we want to be sure to match.
      var lexeme = entity.toString();
      if (lexeme == 'async') {
        expectedCompletions.add(
          ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            ASYNC_STAR,
            kind,
            elementKind,
          ),
        );
      } else if (lexeme == 'default') {
        expectedCompletions.add(
          ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            DEFAULT_COLON,
            kind,
            elementKind,
          ),
        );
      } else if (lexeme == 'deferred') {
        expectedCompletions.add(
          ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            DEFERRED_AS,
            kind,
            elementKind,
          ),
        );
      } else if (lexeme == 'export' && isKeyword()) {
        expectedCompletions.add(
          ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            EXPORT_STATEMENT,
            kind,
            elementKind,
          ),
        );
      } else if (lexeme == 'import' && isKeyword()) {
        expectedCompletions.add(
          ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            IMPORT_STATEMENT,
            kind,
            elementKind,
          ),
        );
      } else if (lexeme == 'part' && isKeyword()) {
        expectedCompletions.add(
          ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            PART_STATEMENT,
            kind,
            elementKind,
          ),
        );
      } else if (lexeme == 'sync') {
        expectedCompletions.add(
          ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            SYNC_STAR,
            kind,
            elementKind,
          ),
        );
      } else if (lexeme == 'yield') {
        expectedCompletions.add(
          ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            YIELD_STAR,
            kind,
            elementKind,
          ),
        );
      } else {
        expectedCompletions.add(
          ExpectedCompletion(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            kind,
            elementKind,
          ),
        );
      }
    }
  }

  void safelyRecordKeywordCompletion(SyntacticEntity? entity) {
    if (_doExpectKeywordCompletions) {
      safelyRecordEntity(
        entity,
        kind: protocol.CompletionSuggestionKind.KEYWORD,
      );
    }
  }

  @override
  void visitAsExpression(AsExpression node) {
    safelyRecordKeywordCompletion(node.asOperator);
    super.visitAsExpression(node);
  }

  @override
  void visitAssertInitializer(AssertInitializer node) {
    safelyRecordKeywordCompletion(node.assertKeyword);
    super.visitAssertInitializer(node);
  }

  @override
  void visitAssertStatement(AssertStatement node) {
    safelyRecordKeywordCompletion(node.assertKeyword);
    super.visitAssertStatement(node);
  }

  @override
  void visitAwaitExpression(AwaitExpression node) {
    safelyRecordKeywordCompletion(node.awaitKeyword);
    super.visitAwaitExpression(node);
  }

  @override
  void visitBlockFunctionBody(BlockFunctionBody node) {
    // 'async' | 'async' '*' | 'sync' '*':
    safelyRecordKeywordCompletion(node.keyword);
    super.visitBlockFunctionBody(node);
  }

  @override
  void visitBooleanLiteral(BooleanLiteral node) {
    // 'false' | 'true'
    safelyRecordKeywordCompletion(node.literal);
    super.visitBooleanLiteral(node);
  }

  @override
  void visitBreakStatement(BreakStatement node) {
    safelyRecordKeywordCompletion(node.breakKeyword);
    super.visitBreakStatement(node);
  }

  @override
  void visitCatchClause(CatchClause node) {
    safelyRecordKeywordCompletion(node.catchKeyword);
    safelyRecordKeywordCompletion(node.onKeyword);
    super.visitCatchClause(node);
  }

  @override
  void visitClassDeclaration(ClassDeclaration node) {
    safelyRecordKeywordCompletion(node.abstractKeyword);
    safelyRecordKeywordCompletion(node.classKeyword);
    super.visitClassDeclaration(node);
  }

  @override
  void visitClassTypeAlias(ClassTypeAlias node) {
    safelyRecordKeywordCompletion(node.abstractKeyword);
    safelyRecordKeywordCompletion(node.typedefKeyword);
    super.visitClassTypeAlias(node);
  }

  @override
  void visitConfiguration(Configuration node) {
    safelyRecordKeywordCompletion(node.ifKeyword);
    super.visitConfiguration(node);
  }

  @override
  void visitConstructorDeclaration(ConstructorDeclaration node) {
    safelyRecordKeywordCompletion(node.externalKeyword);
    safelyRecordKeywordCompletion(node.constKeyword);
    safelyRecordKeywordCompletion(node.factoryKeyword);
    super.visitConstructorDeclaration(node);
  }

  @override
  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
    safelyRecordKeywordCompletion(node.thisKeyword);
    super.visitConstructorFieldInitializer(node);
  }

  @override
  void visitContinueStatement(ContinueStatement node) {
    safelyRecordKeywordCompletion(node.continueKeyword);
    super.visitContinueStatement(node);
  }

  @override
  void visitDeclaredIdentifier(DeclaredIdentifier node) {
    // 'final', 'const' or 'var'
    safelyRecordKeywordCompletion(node.keyword);
    super.visitDeclaredIdentifier(node);
  }

  @override
  void visitDoStatement(DoStatement node) {
    safelyRecordKeywordCompletion(node.doKeyword);
    safelyRecordKeywordCompletion(node.whileKeyword);
    super.visitDoStatement(node);
  }

  @override
  void visitEnumDeclaration(EnumDeclaration node) {
    safelyRecordKeywordCompletion(node.enumKeyword);
    super.visitEnumDeclaration(node);
  }

  @override
  void visitExportDirective(ExportDirective node) {
    safelyRecordKeywordCompletion(node.exportKeyword);
    super.visitExportDirective(node);
  }

  @override
  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
    safelyRecordKeywordCompletion(node.keyword);
    super.visitExpressionFunctionBody(node);
  }

  @override
  void visitExtendsClause(ExtendsClause node) {
    safelyRecordKeywordCompletion(node.extendsKeyword);
    super.visitExtendsClause(node);
  }

  @override
  void visitExtensionDeclaration(ExtensionDeclaration node) {
    safelyRecordKeywordCompletion(node.extensionKeyword);
    safelyRecordKeywordCompletion(node.onClause);
    super.visitExtensionDeclaration(node);
  }

  @override
  void visitFieldDeclaration(FieldDeclaration node) {
    safelyRecordKeywordCompletion(node.abstractKeyword);
    safelyRecordKeywordCompletion(node.covariantKeyword);
    safelyRecordKeywordCompletion(node.externalKeyword);
    safelyRecordKeywordCompletion(node.staticKeyword);
    super.visitFieldDeclaration(node);
  }

  @override
  void visitFieldFormalParameter(FieldFormalParameter node) {
    // 'final', 'const' or 'var'
    safelyRecordKeywordCompletion(node.keyword);
    safelyRecordKeywordCompletion(node.thisKeyword);
    super.visitFieldFormalParameter(node);
  }

  @override
  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
    safelyRecordKeywordCompletion(node.inKeyword);
    super.visitForEachPartsWithDeclaration(node);
  }

  @override
  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
    safelyRecordKeywordCompletion(node.inKeyword);
    super.visitForEachPartsWithIdentifier(node);
  }

  @override
  void visitForElement(ForElement node) {
    safelyRecordKeywordCompletion(node.awaitKeyword);
    safelyRecordKeywordCompletion(node.forKeyword);
    super.visitForElement(node);
  }

  @override
  void visitForStatement(ForStatement node) {
    safelyRecordKeywordCompletion(node.awaitKeyword);
    safelyRecordKeywordCompletion(node.forKeyword);
    super.visitForStatement(node);
  }

  @override
  void visitFunctionDeclaration(FunctionDeclaration node) {
    safelyRecordKeywordCompletion(node.externalKeyword);
    // 'get' or 'set':
    safelyRecordKeywordCompletion(node.propertyKeyword);
    super.visitFunctionDeclaration(node);
  }

  @override
  void visitFunctionTypeAlias(FunctionTypeAlias node) {
    safelyRecordKeywordCompletion(node.typedefKeyword);
    super.visitFunctionTypeAlias(node);
  }

  @override
  void visitGenericFunctionType(GenericFunctionType node) {
    safelyRecordKeywordCompletion(node.functionKeyword);
    super.visitGenericFunctionType(node);
  }

  @override
  void visitGenericTypeAlias(GenericTypeAlias node) {
    safelyRecordKeywordCompletion(node.typedefKeyword);
    super.visitGenericTypeAlias(node);
  }

  @override
  void visitHideCombinator(HideCombinator node) {
    safelyRecordKeywordCompletion(node.keyword);
    super.visitHideCombinator(node);
  }

  @override
  void visitIfElement(IfElement node) {
    safelyRecordKeywordCompletion(node.ifKeyword);
    safelyRecordKeywordCompletion(node.elseKeyword);
    super.visitIfElement(node);
  }

  @override
  void visitIfStatement(IfStatement node) {
    safelyRecordKeywordCompletion(node.ifKeyword);
    safelyRecordKeywordCompletion(node.elseKeyword);
    super.visitIfStatement(node);
  }

  @override
  void visitImplementsClause(ImplementsClause node) {
    safelyRecordKeywordCompletion(node.implementsKeyword);
    super.visitImplementsClause(node);
  }

  @override
  void visitImportDirective(ImportDirective node) {
    safelyRecordKeywordCompletion(node.importKeyword);
    safelyRecordKeywordCompletion(node.asKeyword);
    safelyRecordKeywordCompletion(node.deferredKeyword);
    super.visitImportDirective(node);
  }

  @override
  void visitInstanceCreationExpression(InstanceCreationExpression node) {
    // Here we explicitly do not record 'new' as we don't suggest it in the
    // completion service.
    // https://dart-review.googlesource.com/c/sdk/+/131020
    if (node.keyword?.type == Keyword.CONST) {
      safelyRecordKeywordCompletion(node.keyword);
    }
    super.visitInstanceCreationExpression(node);
  }

  @override
  void visitIsExpression(IsExpression node) {
    safelyRecordKeywordCompletion(node.isOperator);
    super.visitIsExpression(node);
  }

  @override
  void visitLibraryDirective(LibraryDirective node) {
    safelyRecordKeywordCompletion(node.libraryKeyword);
    super.visitLibraryDirective(node);
  }

  @override
  void visitListLiteral(ListLiteral node) {
    safelyRecordKeywordCompletion(node.constKeyword);
    super.visitListLiteral(node);
  }

  @override
  void visitMethodDeclaration(MethodDeclaration node) {
    safelyRecordKeywordCompletion(node.externalKeyword);
    safelyRecordKeywordCompletion(node.modifierKeyword);
    safelyRecordKeywordCompletion(node.operatorKeyword);
    safelyRecordKeywordCompletion(node.propertyKeyword);
    super.visitMethodDeclaration(node);
  }

  @override
  void visitMixinDeclaration(MixinDeclaration node) {
    safelyRecordKeywordCompletion(node.mixinKeyword);
    super.visitMixinDeclaration(node);
  }

  @override
  void visitMixinOnClause(MixinOnClause node) {
    safelyRecordKeywordCompletion(node.onKeyword);
    super.visitMixinOnClause(node);
  }

  @override
  void visitNativeClause(NativeClause node) {
    safelyRecordKeywordCompletion(node.nativeKeyword);
    super.visitNativeClause(node);
  }

  @override
  void visitNativeFunctionBody(NativeFunctionBody node) {
    safelyRecordKeywordCompletion(node.nativeKeyword);
    super.visitNativeFunctionBody(node);
  }

  @override
  void visitNullLiteral(NullLiteral node) {
    safelyRecordKeywordCompletion(node.literal);
    super.visitNullLiteral(node);
  }

  @override
  void visitPartDirective(PartDirective node) {
    safelyRecordKeywordCompletion(node.partKeyword);
    super.visitPartDirective(node);
  }

  @override
  void visitPartOfDirective(PartOfDirective node) {
    safelyRecordKeywordCompletion(node.partKeyword);
    safelyRecordKeywordCompletion(node.ofKeyword);
    super.visitPartOfDirective(node);
  }

  @override
  void visitRedirectingConstructorInvocation(
    RedirectingConstructorInvocation node,
  ) {
    safelyRecordKeywordCompletion(node.thisKeyword);
    super.visitRedirectingConstructorInvocation(node);
  }

  @override
  void visitRethrowExpression(RethrowExpression node) {
    safelyRecordKeywordCompletion(node.rethrowKeyword);
    return super.visitRethrowExpression(node);
  }

  @override
  void visitReturnStatement(ReturnStatement node) {
    safelyRecordKeywordCompletion(node.returnKeyword);
    super.visitReturnStatement(node);
  }

  @override
  void visitSetOrMapLiteral(SetOrMapLiteral node) {
    safelyRecordKeywordCompletion(node.constKeyword);
    super.visitSetOrMapLiteral(node);
  }

  @override
  void visitShowCombinator(ShowCombinator node) {
    safelyRecordKeywordCompletion(node.keyword);
    super.visitShowCombinator(node);
  }

  @override
  void visitSimpleFormalParameter(SimpleFormalParameter node) {
    // 'final', 'const' or 'var'
    safelyRecordKeywordCompletion(node.keyword);
    safelyRecordKeywordCompletion(node.covariantKeyword);
    super.visitSimpleFormalParameter(node);
  }

  @override
  void visitSimpleIdentifier(SimpleIdentifier node) {
    if (_doIncludeSimpleIdentifier(node)) {
      protocol.ElementKind? elementKind;
      var kind = node.element?.kind;
      if (kind != null) {
        elementKind = protocol.convertElementKind(kind);

        // If the completed element kind is a getter or setter set the element
        // kind to null as the exact kind from the DAS is unknown at this
        // point.
        if (elementKind == protocol.ElementKind.GETTER ||
            elementKind == protocol.ElementKind.SETTER) {
          elementKind = null;
        }

        // Map PREFIX element kinds to LIBRARY kinds as this is the ElementKind
        // used for prefixes reported from the completion engine.
        if (elementKind == protocol.ElementKind.PREFIX) {
          elementKind = protocol.ElementKind.LIBRARY;
        }

        // For identifiers in a FieldFormalParameter, i.e. the 'foo' in some
        // ClassName(this.foo), set the elementKind to FIELD which is what the
        // completion engine does (elementKind before this if statement is a
        // PARAMETER).
        if (node.parent is FieldFormalParameter) {
          elementKind = protocol.ElementKind.FIELD;
        }

        // Class references that are constructor calls are constructor kinds,
        // unless either:
        //   1) the constructor is a named constructor, i.e. some "Foo.bar()",
        //      the "Foo" in this case is a class,
        //   2) or, there is an explicit const or new keyword before the
        //      constructor invocation in which case the "Foo" above is
        //      considered a constructor still
        if (elementKind == protocol.ElementKind.CLASS) {
          var constructorName = node.parent?.parent;
          if (constructorName is ConstructorName) {
            // TODO(scheglov): Commented out, probably does not work now.
            // var instanceCreationExpression = constructorName.parent;
            // if (instanceCreationExpression is InstanceCreationExpression &&
            //     constructorName.type.name == node) {
            //   if (instanceCreationExpression.keyword != null ||
            //       constructorName.name == null) {
            //     elementKind = protocol.ElementKind.CONSTRUCTOR;
            //   }
            // }
          }
        }

        // A class reference followed by parens in an annotation is a
        // constructor reference.
        if (elementKind == protocol.ElementKind.CLASS &&
            node.thisOrAncestorOfType<Annotation>() != null &&
            node.endToken.next?.type == TokenType.OPEN_PAREN) {
          elementKind = protocol.ElementKind.CONSTRUCTOR;
        }
      }
      safelyRecordEntity(node, elementKind: elementKind);
    }
    super.visitSimpleIdentifier(node);
  }

  @override
  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
    safelyRecordKeywordCompletion(node.superKeyword);
    super.visitSuperConstructorInvocation(node);
  }

  @override
  void visitSuperExpression(SuperExpression node) {
    safelyRecordKeywordCompletion(node.superKeyword);
    super.visitSuperExpression(node);
  }

  @override
  void visitSwitchCase(SwitchCase node) {
    safelyRecordKeywordCompletion(node.keyword);
    super.visitSwitchCase(node);
  }

  @override
  void visitSwitchDefault(SwitchDefault node) {
    safelyRecordKeywordCompletion(node.keyword);
    super.visitSwitchDefault(node);
  }

  @override
  void visitSwitchStatement(SwitchStatement node) {
    safelyRecordKeywordCompletion(node.switchKeyword);
    super.visitSwitchStatement(node);
  }

  @override
  void visitThisExpression(ThisExpression node) {
    safelyRecordKeywordCompletion(node.thisKeyword);
    super.visitThisExpression(node);
  }

  @override
  void visitThrowExpression(ThrowExpression node) {
    safelyRecordKeywordCompletion(node.throwKeyword);
    super.visitThrowExpression(node);
  }

  @override
  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
    safelyRecordKeywordCompletion(node.externalKeyword);
    super.visitTopLevelVariableDeclaration(node);
  }

  @override
  void visitTryStatement(TryStatement node) {
    safelyRecordKeywordCompletion(node.tryKeyword);
    safelyRecordKeywordCompletion(node.finallyKeyword);
    super.visitTryStatement(node);
  }

  @override
  void visitTypeParameter(TypeParameter node) {
    safelyRecordKeywordCompletion(node.extendsKeyword);
    super.visitTypeParameter(node);
  }

  @override
  void visitVariableDeclarationList(VariableDeclarationList node) {
    // 'final', 'const' or 'var'
    safelyRecordKeywordCompletion(node.keyword);
    safelyRecordKeywordCompletion(node.lateKeyword);
    super.visitVariableDeclarationList(node);
  }

  @override
  void visitWhileStatement(WhileStatement node) {
    safelyRecordKeywordCompletion(node.whileKeyword);
    super.visitWhileStatement(node);
  }

  @override
  void visitWithClause(WithClause node) {
    safelyRecordKeywordCompletion(node.withKeyword);
    super.visitWithClause(node);
  }

  @override
  void visitYieldStatement(YieldStatement node) {
    safelyRecordKeywordCompletion(node.yieldKeyword);
    super.visitYieldStatement(node);
  }

  bool _doIncludeSimpleIdentifier(SimpleIdentifier node) {
    // Do not continue if this node is synthetic, or if the node is in a
    // declaration context
    if (node.isSynthetic || node.inDeclarationContext()) {
      return false;
    }

    // If the type of the SimpleIdentifier is dynamic, don't include.
    var staticType = node.staticType;
    if (staticType != null && staticType is DynamicType) {
      return false;
    }

    // If we are in a comment reference context, return if we should include
    // such identifiers.
    if (node.thisOrAncestorOfType<CommentReference>() != null) {
      return _doExpectCommentRefs;
    }

    // Ignore the SimpleIdentifiers that make up library directives.
    if (node.thisOrAncestorOfType<LibraryDirective>() != null) {
      return false;
    }
    // Ignore identifiers in hide and show combinators because we don't suggest
    // names that are already in the list.
    if (node.parent is HideCombinator || node.parent is ShowCombinator) {
      return false;
    }

    // TODO(jwren): If there is a mode of completing at a token location where
    //  the token is removed before the completion query happens, then this
    //  should be disabled in such a case:
    // Named arguments, i.e. the 'foo' in 'method_call(foo: 1)' should not be
    // included, by design, the completion engine won't suggest named arguments
    // already it the source.
    //
    // The null check, node.staticElement == null, handles the cases where the
    // invocation is unknown, i.e. the 'arg' in 'foo.bar(arg: 1)', where foo is
    // dynamic.
    if ((node.element == null ||
            node.element?.kind == element.ElementKind.PARAMETER) &&
        node.parent is Label &&
        node.thisOrAncestorOfType<ArgumentList>() != null) {
      return false;
    }

    return true;
  }
}

class _SyntacticEntity implements SyntacticEntity {
  @override
  final int offset;

  _SyntacticEntity(this.offset);

  @override
  int get end => offset + length;

  @override
  int get length => 0;
}
