// 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:analysis_server/src/services/completion/dart/keyword_contributor.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;

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(protocol.CompletionSuggestion completionSuggestion) {
    if (completionSuggestion.completion == completion) {
      if (kind != null &&
          completionSuggestion.kind != null &&
          completionSuggestion.kind != kind) {
        return false;
      }
      if (elementKind != null &&
          completionSuggestion.element?.kind != null &&
          completionSuggestion.element?.kind != elementKind) {
        return false;
      }
      return true;
    }
    return false;
  }

  /// Return a map used to represent this expected completion in a JSON structure.
  Map<String, dynamic> toJson() {
    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> {
  final List<ExpectedCompletion> expectedCompletions;

  final String filePath;

  CompilationUnit _enclosingCompilationUnit;

  /// 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.filePath)
      : expectedCompletions = <ExpectedCompletion>[],
        assert(filePath != null);

  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) {
      // Compute the line number at this offset
      var lineNumber = _enclosingCompilationUnit.lineInfo
          .getLocation(entity.offset)
          .lineNumber;

      var columnNumber = _enclosingCompilationUnit.lineInfo
          .getLocation(entity.offset)
          .columnNumber;

      // Some special cases in the if and if-else blocks, 'import' from the
      // DAS is "import '';" which we want to be sure to match.
      if (entity.toString() == 'async') {
        expectedCompletions.add(ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            ASYNC_STAR,
            kind,
            elementKind));
      } else if (entity.toString() == 'default') {
        expectedCompletions.add(ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            DEFAULT_COLON,
            kind,
            elementKind));
      } else if (entity.toString() == 'deferred') {
        expectedCompletions.add(ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            DEFERRED_AS,
            kind,
            elementKind));
      } else if (entity.toString() == 'export') {
        expectedCompletions.add(ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            EXPORT_STATEMENT,
            kind,
            elementKind));
      } else if (entity.toString() == 'import') {
        expectedCompletions.add(ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            IMPORT_STATEMENT,
            kind,
            elementKind));
      } else if (entity.toString() == 'part') {
        expectedCompletions.add(ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            PART_STATEMENT,
            kind,
            elementKind));
      } else if (entity.toString() == 'sync') {
        expectedCompletions.add(ExpectedCompletion.specialCompletionString(
            filePath,
            entity,
            lineNumber,
            columnNumber,
            SYNC_STAR,
            kind,
            elementKind));
      } else if (entity.toString() == '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 visitCompilationUnit(CompilationUnit node) {
    _enclosingCompilationUnit = node;
    super.visitCompilationUnit(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.keyword);
    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.onKeyword);
    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.keyword);
    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 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 visitOnClause(OnClause node) {
    safelyRecordKeywordCompletion(node.onKeyword);
    super.visitOnClause(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;
      if (node.staticElement?.kind != null) {
        elementKind = protocol.convertElementKind(node.staticElement.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) {
          if (node.parent?.parent is ConstructorName) {
            var constructorName = node.parent.parent as ConstructorName;
            var instanceCreationExpression = constructorName.parent;
            if (instanceCreationExpression is InstanceCreationExpression &&
                constructorName.type.name == node) {
              if (instanceCreationExpression.keyword != null ||
                  constructorName.name == null) {
                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 == null || node.isSynthetic || node.inDeclarationContext()) {
      return false;
    }

    // If the type of the SimpleIdentifier is dynamic, don't include.
    if (node.staticType != null && node.staticType.isDynamic) {
      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;
    }

    // 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.staticElement == null ||
            node.staticElement?.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;
}
