// Copyright (c) 2023, 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:kernel/ast.dart';

/// Dart scope
///
/// Provides information about symbols available inside a dart scope.
class DartScope {
  final Library library;
  final Class? cls;
  final Member? member;
  final bool isStatic;
  final Map<String, DartType> definitions;
  final List<TypeParameter> typeParameters;

  DartScope(this.library, this.cls, this.member, this.definitions,
      this.typeParameters)
      : isStatic = member is Procedure ? member.isStatic : false;

  @override
  String toString() {
    return '''DartScope {
      Library: ${library.importUri},
      Class: ${cls?.name},
      Procedure: $member,
      isStatic: $isStatic,
      Scope: $definitions,
      typeParameters: $typeParameters
    }
    ''';
  }
}

/// Dart scope
///
/// Provides information about symbols available inside a dart scope.
class DartScope2 {
  final TreeNode node;
  final Library library;
  final Class? cls;
  final Member? member;
  final bool isStatic;
  final Map<String, VariableDeclaration> definitions;
  final List<TypeParameter> typeParameters;

  DartScope2(this.node, this.library, this.cls, this.member, this.definitions,
      this.typeParameters)
      : isStatic = member is Procedure ? member.isStatic : false;

  @override
  String toString() {
    return '''DartScope {
      Library: ${library.importUri},
      Class: ${cls?.name},
      Procedure: $member,
      isStatic: $isStatic,
      Scope: $definitions,
      typeParameters: $typeParameters
    }
    ''';
  }
}

/// DartScopeBuilder finds dart scope information for a location.
///
/// Find all definitions in scope at a given 1-based [line] and [column]:
///
/// - library
/// - class
/// - locals
/// - formals
/// - captured variables (for closures)
class DartScopeBuilder extends VisitorDefault<void> with VisitorVoidMixin {
  final Component _component;
  final int _line;
  final int _column;

  Library? _library;
  Class? _cls;
  Member? _member;
  int _offset = -1;

  final List<FunctionNode> _functions = [];
  final Map<String, DartType> _definitions = {};
  final List<TypeParameter> _typeParameters = [];

  DartScopeBuilder._(this._component, this._line, this._column);

  static DartScope? findScope(
      Component component, Library library, int line, int column) {
    DartScopeBuilder builder = DartScopeBuilder._(component, line, column);
    library.accept(builder);
    return builder.build();
  }

  DartScope? build() {
    if (_offset < 0 || _library == null) return null;

    return DartScope(_library!, _cls, _member, _definitions, _typeParameters);
  }

  @override
  void defaultTreeNode(Node node) {
    node.visitChildren(this);
  }

  @override
  void visitLibrary(Library library) {
    _library = library;
    _offset = 0;
    if (_line > 0) {
      _offset = _component.getOffset(_library!.fileUri, _line, _column);
    }

    // Exit early if the evaluation offset is not found.
    // Note: the complete scope is not found in this case,
    // so the expression compiler will report an error.
    if (_offset >= 0) super.visitLibrary(library);
  }

  @override
  void visitClass(Class cls) {
    if (_scopeContainsOffset(cls.fileOffset, cls.fileEndOffset, _offset)) {
      _cls = cls;
      _typeParameters.addAll(cls.typeParameters);

      super.visitClass(cls);
    }
  }

  @override
  void defaultMember(Member m) {
    if (_scopeContainsOffset(m.fileOffset, m.fileEndOffset, _offset)) {
      _member = m;

      super.defaultMember(m);
    }
  }

  @override
  void visitFunctionNode(FunctionNode fun) {
    if (_scopeContainsOffset(fun.fileOffset, fun.fileEndOffset, _offset)) {
      _functions.add(fun);
      _typeParameters.addAll(fun.typeParameters);

      super.visitFunctionNode(fun);
    }
  }

  @override
  void visitVariableDeclaration(VariableDeclaration decl) {
    String? name = decl.name;
    // Collect locals and formals appearing before current breakpoint.
    // Note that we include variables with no offset because the offset
    // is not set in many cases in generated code, so omitting them would
    // make expression evaluation fail in too many cases.
    // Issue: https://github.com/dart-lang/sdk/issues/43966
    //
    // A null name signals that the variable was synthetically introduced by the
    // compiler so they are skipped.
    if ((decl.fileOffset < 0 || decl.fileOffset < _offset) && name != null) {
      _definitions[name] = decl.type;
    }
    super.visitVariableDeclaration(decl);
  }

  @override
  void visitBlock(Block block) {
    int fileEndOffset = FileEndOffsetCalculator.calculateEndOffset(block);
    if (_scopeContainsOffset(block.fileOffset, fileEndOffset, _offset)) {
      super.visitBlock(block);
    }
  }

  bool _scopeContainsOffset(int startOffset, int endOffset, int offset) {
    if (offset < 0 || startOffset < 0 || endOffset < 0) {
      return false;
    }
    return startOffset <= offset && offset <= endOffset;
  }
}

/// File end offset calculator.
///
/// Helps calculate file end offsets for nodes with internal scope
/// that do not have .fileEndOffset field.
///
/// For example - [Block]
class FileEndOffsetCalculator extends VisitorDefault<int?>
    with VisitorNullMixin<int> {
  static const int noOffset = -1;

  final int _startOffset;
  final TreeNode _root;
  final TreeNode _original;

  int _endOffset = noOffset;

  /// Create calculator for a scoping node with no .fileEndOffset.
  ///
  /// [_root] is the parent of the scoping node.
  /// [_startOffset] is the start offset of the scoping node.
  FileEndOffsetCalculator._(this._root, this._original)
      : _startOffset = _original.fileOffset;

  /// Calculate file end offset for a scoping node.
  ///
  /// This calculator finds the first node in the ancestor chain that
  /// can give such information for a given [node], i.e. satisfies one
  /// of the following conditions:
  ///
  /// - a node with a greater start offset that is a child of the
  ///   closest ancestor. The start offset of this child is used as a
  ///   file end offset of the [node].
  ///
  /// - the closest ancestor with .fileEndOffset information. The file
  ///   end offset of the ancestor is used as the file end offset of
  ///   the [node.]
  ///
  /// If none found, return [noOffset].
  static int calculateEndOffset(TreeNode node) {
    for (TreeNode? n = node.parent; n != null; n = n.parent) {
      FileEndOffsetCalculator calculator = FileEndOffsetCalculator._(n, node);
      int? offset = n.accept(calculator);
      if (offset != noOffset) return offset!;
    }
    return noOffset;
  }

  @override
  int defaultTreeNode(TreeNode node) {
    if (node == _original) return _endOffset;
    if (node == _root) {
      node.visitChildren(this);
      if (_endOffset != noOffset) return _endOffset;
      return _endOffsetForNode(node);
    }
    // Skip synthesized variables as they could have offsets
    // from later code (in case they are hoisted, for example).
    if ((node is! VariableDeclaration || !node.isSynthesized) &&
        _endOffset == noOffset &&
        node.fileOffset > _startOffset) {
      _endOffset = node.fileOffset;
    }
    return _endOffset;
  }

  static int _endOffsetForNode(TreeNode node) {
    if (node is Class) return node.fileEndOffset;
    if (node is Constructor) return node.fileEndOffset;
    if (node is Procedure) return node.fileEndOffset;
    if (node is Field) return node.fileEndOffset;
    if (node is FunctionNode) return node.fileEndOffset;
    return noOffset;
  }
}

class DartScopeBuilder2 extends VisitorDefault<void> with VisitorVoidMixin {
  final Library _library;
  final Uri _scriptUri;
  final int _offset;
  final List<DartScope2> findScopes = [];
  final Set<int> foundOffsets = {};

  final Set<VariableDeclaration> hoistedUnwritten = {};
  final List<List<VariableDeclaration>> scopes = [];
  final List<List<TypeParameter>> typeParameterScopes = [];

  Class? _currentCls = null;
  Member? _currentMember = null;

  bool checkClasses = true;
  Uri _currentUri;

  DartScopeBuilder2._(this._library, this._scriptUri, this._offset)
      : _currentUri = _library.fileUri;

  void clearScope() {
    scopes.clear();
    hoistedUnwritten.clear();
  }

  void addFound(TreeNode node) {
    Map<String, VariableDeclaration> definitions = {};
    for (List<VariableDeclaration> scope in scopes) {
      for (VariableDeclaration decl in scope) {
        String? name = decl.name;
        if (name != null &&
            !decl.isSynthesized &&
            !hoistedUnwritten.contains(decl)) {
          definitions[name] = decl;
        }
      }
    }
    // TODO(jensj): If the current member is static and we're in a class we have
    // to skip the typeParameters from the class.
    List<TypeParameter> typeParameters = [];
    for (List<TypeParameter> typeParameterScope in typeParameterScopes) {
      typeParameters.addAll(typeParameterScope);
    }
    DartScope2 findScope = new DartScope2(node, _library, _currentCls,
        _currentMember, definitions, typeParameters);
    findScopes.add(findScope);
  }

  @override
  void defaultDartType(DartType node) {
    return;
  }

  @override
  void defaultTreeNode(TreeNode node) {
    Uri prevUri = _currentUri;
    if (node is FileUriNode) {
      _currentUri = node.fileUri;
    }
    _checkOffset(node);
    node.visitChildren(this);
    _currentUri = prevUri;
  }

  @override
  void visitAssertBlock(AssertBlock node) {
    scopes.add([]);
    super.visitAssertBlock(node);
    scopes.removeLast();
  }

  @override
  void visitBlock(Block node) {
    scopes.add([]);

    _checkOffset(node);

    bool shouldSkip;

    // See also the test [DillBlockChecker] which checks that we can do this
    // pruning!
    if (_currentUri != _scriptUri) {
      shouldSkip = true;
    } else if (node.parent is ForInStatement) {
      // E.g. dart2js implicit cast in for-in loop
      shouldSkip = false;
    } else if (node.parent?.parent is ForStatement) {
      // A vm transformation turns
      // `for (var foo in bar) {}`
      // into
      // `for(;iterator.moveNext; ) { var foo = iterator.current; {} }`
      // where the block directly containing `foo` has the original blocks
      // offset, i.e. after the variable declaration, but it still contain
      // it. So we pretend it has no offsets.
      shouldSkip = false;
    } else if (node.fileOffset >= 0 &&
        node.fileEndOffset >= 0 &&
        node.fileOffset != node.fileEndOffset) {
      if (_offset < node.fileOffset || _offset > node.fileEndOffset) {
        // Not contained in the block.
        shouldSkip = true;
      } else {
        // Contained in the block.
        shouldSkip = false;
      }
    } else {
      // The block doesn't have valid offsets.
      shouldSkip = false;
    }

    if (!shouldSkip) {
      node.visitChildren(this);
    }

    scopes.removeLast();
  }

  @override
  void visitBlockExpression(BlockExpression node) {
    scopes.add([]);
    super.visitBlockExpression(node);
    scopes.removeLast();
  }

  @override
  void visitCatch(Catch node) {
    scopes.add([]);
    super.visitCatch(node);
    scopes.removeLast();
  }

  @override
  void visitClass(Class node) {
    if (!checkClasses) {
      return;
    }
    _currentCls = node;
    typeParameterScopes.add([...node.typeParameters]);
    scopes.add([]);
    super.visitClass(node);
    clearScope();
    typeParameterScopes.removeLast();
    assert(typeParameterScopes.isEmpty);
    _currentCls = null;
  }

  @override
  void visitConstructor(Constructor node) {
    Uri prevUri = _currentUri;
    _currentUri = node.fileUri;

    _currentMember = node;
    clearScope();
    scopes.add([]);

    _checkOffset(node);

    // The constructor is special in that the parameters from the contained
    // function node is in scope in the initializers.
    node.function.accept(this);
    for (VariableDeclaration param in node.function.positionalParameters) {
      scopes.last.add(param);
    }
    for (VariableDeclaration param in node.function.namedParameters) {
      scopes.last.add(param);
    }
    for (Initializer initializer in node.initializers) {
      initializer.accept(this);
    }

    clearScope();
    _currentMember = null;
    _currentUri = prevUri;
  }

  @override
  void visitExtension(Extension node) {
    typeParameterScopes.add([...node.typeParameters]);
    super.visitExtension(node);
    typeParameterScopes.removeLast();
  }

  @override
  void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) {
    typeParameterScopes.add([...node.typeParameters]);
    super.visitExtensionTypeDeclaration(node);
    typeParameterScopes.removeLast();
  }

  @override
  void visitField(Field node) {
    _currentMember = node;
    clearScope();
    scopes.add([]);
    super.visitField(node);
    clearScope();
    _currentMember = null;
  }

  @override
  void visitForInStatement(ForInStatement node) {
    scopes.add([]);
    super.visitForInStatement(node);
    scopes.removeLast();
  }

  @override
  void visitForStatement(ForStatement node) {
    scopes.add([]);
    super.visitForStatement(node);
    scopes.removeLast();
  }

  @override
  void visitFunctionNode(FunctionNode node) {
    typeParameterScopes.add([...node.typeParameters]);
    scopes.add([]);
    super.visitFunctionNode(node);
    scopes.removeLast();
    typeParameterScopes.removeLast();
  }

  @override
  void visitLet(Let node) {
    scopes.add([]);
    super.visitLet(node);
    scopes.removeLast();
  }

  @override
  void visitLibrary(Library node) {
    scopes.add([]);
    super.visitLibrary(node);
    clearScope();
  }

  @override
  void visitProcedure(Procedure node) {
    _currentMember = node;
    clearScope();
    scopes.add([]);
    super.visitProcedure(node);
    clearScope();
    _currentMember = null;
  }

  @override
  void visitTypedef(Typedef node) {
    clearScope();
    scopes.add([]);
    typeParameterScopes.add([...node.typeParameters]);
    super.visitTypedef(node);
    typeParameterScopes.removeLast();
    clearScope();
  }

  @override
  void visitVariableSet(VariableSet node) {
    super.visitVariableSet(node);
    if (node.variable.isHoisted) {
      hoistedUnwritten.remove(node.variable);
    }
  }

  @override
  void visitVariableDeclaration(VariableDeclaration node) {
    if (node.isHoisted) hoistedUnwritten.add(node);
    super.visitVariableDeclaration(node);
    // Declare it after.
    scopes.last.add(node);
  }

  void _checkOffset(TreeNode node) {
    if (_currentUri == _scriptUri) {
      foundOffsets.add(node.fileOffset);
      if (node.fileOffset == _offset) {
        addFound(node);
      } else {
        List<int>? allOffsets = node.fileOffsetsIfMultiple;
        if (allOffsets != null) {
          for (final int offset in allOffsets) {
            foundOffsets.add(offset);
            if (offset == _offset) {
              addFound(node);
              break;
            }
          }
        }
      }
    }
  }

  static DartScope findScopeFromOffsetAndClass(
      Library library, Uri scriptUri, Class? cls, int offset) {
    DartScopeBuilder2 data = _raw(library, scriptUri, cls, offset);
    if (data.findScopes.isEmpty) {
      int? closestMatchingOrSmallerOffset =
          _findClosestMatchingOrSmallerOffset(data, offset);
      if (closestMatchingOrSmallerOffset != null) {
        offset = closestMatchingOrSmallerOffset;
        data = _raw(library, scriptUri, cls, offset);
      }
    }
    return _findScopePick(data.findScopes, library, cls, offset);
  }

  static int? _findClosestMatchingOrSmallerOffset(
      DartScopeBuilder2 data, int offset) {
    List<int> foundOffsets = data.foundOffsets.toList()..sort();
    if (foundOffsets.isEmpty) return null;
    int low = 0;
    int high = foundOffsets.length - 1;
    while (low < high) {
      int mid = high - ((high - low) >> 1); // Get middle, rounding up.
      int pivot = foundOffsets[mid];
      if (pivot <= offset) {
        low = mid;
      } else {
        high = mid - 1;
      }
    }
    int result = foundOffsets[low];
    if (result < 0) return null;
    return result;
  }

  static DartScope _findScopePick(
      List<DartScope2> scopes, Library library, Class? cls, int offset) {
    DartScope2 scope;
    if (scopes.length == 0) {
      // This shouldn't happen.
      return new DartScope(library, cls, null, {}, []);
    } else if (scopes.length == 1) {
      scope = scopes.single;
    } else {
      List<DartScope2> filteredScopes = _filterAll(scopes, library, offset);
      if (filteredScopes.length == 0) {
        // This shouldn't happen.
        filteredScopes = scopes;
      }
      if (filteredScopes.length == 1) {
        scope = filteredScopes.single;
      } else {
        // TODO(jensj): This shouldn't happen, but inevitably will.
        // When it does, what should we do?
        scope = scopes.last;
      }
    }

    Map<String, DartType> definitions = {};
    for (MapEntry<String, VariableDeclaration> entry
        in scope.definitions.entries) {
      definitions[entry.key] = entry.value.type;
    }
    return new DartScope(scope.library, scope.cls, scope.member, definitions,
        scope.typeParameters);
  }

  static DartScope findScopeFromOffset(
      Library library, Uri scriptUri, int offset) {
    DartScopeBuilder2 data = _rawNoClass(library, scriptUri, offset);
    if (data.findScopes.isEmpty) {
      int? closestMatchingOrSmallerOffset =
          _findClosestMatchingOrSmallerOffset(data, offset);
      if (closestMatchingOrSmallerOffset != null) {
        offset = closestMatchingOrSmallerOffset;
        data = _rawNoClass(library, scriptUri, offset);
      }
    }
    return _findScopePick(data.findScopes, library, null, offset);
  }

  static List<DartScope2> _filterAll(
      List<DartScope2> rawScopes, Library library, int offset) {
    List<DartScope2> firstFilteredScopes =
        _filterScopesWithArtificialNodes(rawScopes, library);
    if (firstFilteredScopes.isEmpty) {
      return rawScopes;
    }
    if (_allHaveTheSameDefinitions(firstFilteredScopes)) {
      return [firstFilteredScopes.first];
    }
    List<DartScope2> filteredScopes =
        _filter(firstFilteredScopes, library, offset);
    if (_allHaveTheSameDefinitions(filteredScopes)) {
      return [filteredScopes.first];
    }
    return filteredScopes;
  }

  static List<DartScope2> filterAllForTesting(
      List<DartScope2> rawScopes, Library library, int offset) {
    return _filterAll(rawScopes, library, offset);
  }

  static List<DartScope2> _filterScopesWithArtificialNodes(
      List<DartScope2> unfilteredScopes, Library library) {
    Set<Member> skipMembers = {};
    for (Extension node in library.extensions) {
      for (ExtensionMemberDescriptor memberDescriptor
          in node.memberDescriptors) {
        // The tear off procedures have two enclosing function nodes with the
        // same offsets, but with (possibly) different type parameters.
        // Skip them.
        Member? skip = memberDescriptor.tearOffReference?.asMember;
        if (skip != null) skipMembers.add(skip);
      }
    }

    List<DartScope2> filtered = [];
    for (DartScope2 node in unfilteredScopes) {
      Member? member = node.member;
      if (skipMembers.contains(member)) {
        // Skip these.
        continue;
      }
      if (member is Field) {
        if (member.isInternalImplementation) {
          // E.g. synthesized fields added by late lowering. Skip those.
          continue;
        }
      } else if (member is Procedure) {
        if (member.isSynthetic) {
          // Skip synthetic procedures.
          continue;
        }
      }
      filtered.add(node);
    }

    return filtered;
  }

  static bool _allHaveTheSameDefinitions(List<DartScope2> scopes) {
    if (scopes.isEmpty) return false;
    Map<String, VariableDeclaration> definitions = scopes.first.definitions;
    for (int i = 1; i < scopes.length; i++) {
      DartScope2 scope = scopes[i];
      if (scope.definitions.length != definitions.length) return false;
      for (MapEntry<String, VariableDeclaration> entry
          in scope.definitions.entries) {
        VariableDeclaration? existing = definitions[entry.key];
        if (existing == null) {
          return false;
        } else {
          if (existing != entry.value) {
            return false;
          }
        }
      }
    }
    return true;
  }

  static List<DartScope2> _filter(
      List<DartScope2> unfilteredScopes, Library library, int offset) {
    List<DartScope2> filtered = unfilteredScopes.toList();
    List<DartScope2> withoutEndOffset = [];
    for (DartScope2 scope in unfilteredScopes) {
      TreeNode? node = scope.node;
      // Possibly filter out nodes that was only included because their end
      // offset matched the offset we we're looking for.
      if (node is Member) {
        if (offset != node.fileEndOffset) {
          withoutEndOffset.add(scope);
        }
      } else if (node is FunctionNode) {
        if (offset != node.fileEndOffset) {
          withoutEndOffset.add(scope);
        }
      } else if (node is Block) {
        if (offset != node.fileEndOffset) {
          withoutEndOffset.add(scope);
        }
      } else {
        withoutEndOffset.add(scope);
      }
    }

    if (withoutEndOffset.length == 1) {
      return withoutEndOffset;
    } else if (withoutEndOffset.isEmpty) {
      // They're all on the end offset. Just return the last one.
      // E.g.
      // ```
      // static makeErrorHandler(_EventSink controller) =>
      // (Object e, StackTrace s) {
      //   controller._addError(e, s);
      //   controller._close();
      // };
      // ```
      // have both the Procedure, the first FunctionNode and the second
      // FunctionNode with the same end offset.
      return [filtered.last];
    } else {
      filtered = withoutEndOffset;
    }

    if ((filtered.length == 2 &&
            filtered[0].node is ForInStatement &&
            filtered[1].node is Block) ||
        (filtered.length == 3 &&
            filtered[0].node is ForInStatement &&
            filtered[1].node is LabeledStatement &&
            filtered[2].node is Block)) {
      // In the below code the for in statement was included on the brace
      // because of the body offset, but as we have the block that's what we
      // should use, so we remove the ForInStatement.
      // ```
      // String? name = node.name;
      // // [...]
      // for (String name in combinator.names) { // <- this brace
      //   // whatnot
      // }
      // ```
      return [filtered.last];
    }

    if (filtered.length == 2 &&
        filtered[0].node is ForInStatement &&
        filtered[1].node is YieldStatement) {
      // E.g.
      // ```
      // for (var key in keys) yield MapEntry<K, V>(key, this[key] as dynamic);
      // ```
      // where the ForIn and the yield has the same (body) offset.
      return [filtered[1]];
    }

    if (filtered.length > 2 &&
        filtered.length < 5 &&
        filtered[0].node is ForInStatement &&
        filtered[1].node is ExpressionStatement) {
      // E.g.
      // ```
      // for (var entry in entries) this[entry.key] = entry.value;
      // ```
      return [filtered.last];
    }

    if (filtered.length == 2 &&
        filtered[0].node is FunctionNode &&
        filtered[1].node is Block) {
      // Remove the function node one(s) --- assume we're on the block
      // to remove some uncertainty in for instance these situations:
      // ```
      // void foo(String? s) {
      //   if (s == null) return;
      //   bar(String s) {
      //     // whatever
      //   } // <- if the position is at this brace.
      //   bar(s);
      // }
      // ```
      // and
      // ```
      // void bla() {
      //   void foo(String foo) {
      //     // Here "foo" is a string.
      //   } // <- if the position is at this brace.
      // }
      // ```
      // In both situations we have two variables with the same name but
      // different types, depending on if the positionals from the function node
      // is "on" or not.
      return [filtered[1]];
    }
    if (filtered.length == 2 &&
        filtered[0].node is VariableDeclaration &&
        filtered[1].node is FieldInitializer) {
      // Pick the FieldInitializer (i.e. have the variable in scope).
      return [filtered[1]];
    }
    if (filtered.length == 2 &&
        filtered[0].node is VariableDeclaration &&
        filtered[1].node is VariableGet &&
        filtered[1].node.parent?.parent is SuperInitializer) {
      // E.g. `Foo(super.bar)`.
      // Pick the VariableGet (with all variables in scope --- this is not
      // great if we can actually stop before, but can we?).
      return [filtered[1]];
    }
    if (filtered.length == 2 &&
        filtered[0].node is Constructor &&
        filtered[1].node is SuperInitializer) {
      // Pick the SuperInitializer (i.e. have any variables in scope).
      return [filtered[1]];
    }
    if (filtered.length == 2 &&
        filtered[0].node is VariableDeclaration &&
        filtered[1].node is VariableGet &&
        filtered[0].node.parent?.parent is Procedure &&
        (filtered[0].node.parent?.parent as Procedure).isRedirectingFactory) {
      return [filtered[1]];
    }
    if (filtered.length == 2 &&
        filtered[0].node is FunctionNode &&
        filtered[1].node is InvocationExpression &&
        filtered[0].node.parent is Procedure &&
        (filtered[0].node.parent as Procedure).isRedirectingFactory) {
      return [filtered[1]];
    }
    if (filtered.length > 1 &&
        filtered[0].node is Class &&
        (filtered[0].node as Class).isEnum) {
      return [filtered[0]];
    }
    if (filtered.length == 2 &&
        filtered[0].node is VariableDeclaration &&
        filtered[1].node is VariableGet &&
        filtered[0].node.parent?.parent is Constructor &&
        filtered[1].node.parent?.parent is Arguments) {
      // E.g. `super.localId`.
      return [filtered[1]];
    }
    if (filtered.length == 2 &&
        filtered[0].node is IfStatement &&
        filtered[1].node is Block) {
      return [filtered[0]];
    }
    if (filtered.length > 1 &&
        filtered[0].node is InstanceGet &&
        (filtered[0].node as InstanceGet).receiver is VariableGet &&
        ((filtered[0].node as InstanceGet).receiver as VariableGet)
            .variable
            .isSynthesized) {
      // E.g. `await for (var fileEntity in stream) { [...] }` that has become
      // FileSystemEntity fileEntity = :for-iterator.{_StreamIterator.current};
      // {
      //   [...]
      // }
      // where the getting of the iterator and the block has the same offset,
      // pointing to the start brace after `fileEntity` was defined in the
      // source. We remove the InstanceGet.
      filtered.removeAt(0);
    }
    if (filtered.length == 1) return filtered;

    DartScope2? lookup;

    // TODO(jensj): Look into rewriting the matching to use patterns.
    // See also
    // https://dart-review.googlesource.com/c/sdk/+/338840/8/pkg/kernel/lib/dart_scope_calculator.dart#924
    lookup = _looksLikeVmForInTransformation(filtered);
    if (lookup != null) return [lookup];

    lookup = _looksLikeVmFfiTransformation(filtered);
    if (lookup != null) return [lookup];

    lookup = _looksLikeLateLoweredField(filtered);
    if (lookup != null) return [lookup];

    lookup = _looksLikePatternMatching(filtered);
    if (lookup != null) return [lookup];

    lookup = _looksLikeLateLoweredLocal(filtered);
    if (lookup != null) return [lookup];

    lookup = _looksLikeThrowPatternMatchingError(filtered);
    if (lookup != null) return [lookup];

    return filtered;
  }

  static DartScope2? _looksLikeVmForInTransformation(
      List<DartScope2> filtered) {
    // The VM has a transformation where
    // ```
    // void foo(String x) {
    //   for(dynamic x in bar()) {
    //     if (x == null) continue;
    //     print(x);
    //   }
    // }
    // List bar() => [1, 2, 3];
    // ```
    // is transformed into something like
    // ```
    // {
    //   synthesized core::Iterator<dynamic> :sync-for-iterator =
    //      self::bar().{core::Iterable::iterator}{core::Iterator<dynamic>};
    //   for (;
    //     :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; )
    //     { // <- this block
    //     dynamic x = :sync-for-iterator.
    //       {core::Iterator::current}{dynamic}; // <- the initializer
    //     #L1: // <- this label
    //     { // <- this block
    //       if(x == null)
    //         break #L1;
    //       core::print(x);
    //     }
    //   }
    // }
    // ```
    // where I've marked the 4 places where the offset is the same.
    // In the first 2 cases the "x" will be String, in the other 2 the "x" will
    // be dynamic.
    // Try to filter this so that we say we're where "x" is dynamic.
    if (filtered.length >= 3 &&
        filtered.first.node is Block &&
        filtered[1].node is InstanceGet) {
      Block firstBlock = filtered.first.node as Block;
      InstanceGet instanceGet = filtered[1].node as InstanceGet;
      Expression receiver = instanceGet.receiver;
      if (firstBlock.parent is ForStatement &&
          receiver is VariableGet &&
          receiver.variable.isSynthesized &&
          receiver.variable.name == ":sync-for-iterator") {
        // Matches the case. Return the last block.
        return filtered.last;
      }
    }
    return null;
  }

  static DartScope2? _looksLikeVmFfiTransformation(List<DartScope2> filtered) {
    if (filtered.length > 4 &&
        filtered[0].node is Procedure &&
        filtered[2].node is Field &&
        (filtered[2].node as Field).name.text.endsWith("\$FfiNative\$Ptr")) {
      return filtered[0];
    } else if (filtered.length > 4 &&
        filtered[0].node is Procedure &&
        filtered[2].node is Procedure &&
        (filtered[2].node as Procedure).name.text.endsWith("\$FfiNative")) {
      return filtered[0];
    }

    return null;
  }

  // TODO(jensj): Possibly move the file to package:front_end and use
  // lowering_predicates.dart.
  static DartScope2? _looksLikeLateLoweredField(List<DartScope2> filtered) {
    if (filtered.length > 10 &&
        filtered[0].node is Procedure &&
        filtered[1].node is FunctionNode &&
        filtered[2].node is ReturnStatement &&
        filtered[3].node is Let &&
        filtered[4].node is VariableDeclaration) {
      // The 10 is not special. This has just been observed to contain lots of
      // scopes.
      return filtered[0];
    } else if (filtered.length > 10 &&
        filtered[0].node is Procedure &&
        filtered[1].node is FunctionNode &&
        filtered[2].node is ReturnStatement) {
      // The 10 is not special. This has just been observed to contain lots of
      // scopes.
      for (int i = 3; i < filtered.length - 1; i++) {
        if (filtered[i].node is Let &&
            filtered[i + 1].node is VariableDeclaration) {
          return filtered[0];
        }
      }
    } else if (filtered.length > 15 &&
        filtered[0].node is Procedure &&
        filtered[1].node is FunctionNode) {
      // The 15 is not special. This has just been observed to contain lots of
      // scopes.
      for (int i = 3; i < filtered.length - 1; i++) {
        if (filtered[i].node is Procedure &&
            filtered[i + 1].node is FunctionNode &&
            filtered[i + 2].node is ReturnStatement) {
          for (int j = i + 1; j < filtered.length - 1; j++) {
            if (filtered[j].node is Let &&
                filtered[j + 1].node is VariableDeclaration) {
              return filtered[0];
            }
          }
        }
      }
    }
    // late final field.
    if (filtered.length > 10 &&
        filtered[0].node is Procedure &&
        filtered[1].node is FunctionNode &&
        filtered[2].node is ReturnStatement &&
        filtered[3].node is ConditionalExpression &&
        filtered[4].node is InstanceGet &&
        filtered[5].node is ThisExpression &&
        filtered[6].node is InstanceGet &&
        filtered[7].node is ThisExpression &&
        filtered[8].node is Throw) {
      // The 10 is not special. This has just been observed to contain lots of
      // scopes.
      return filtered[0];
    }

    return null;
  }

  static DartScope2? _looksLikePatternMatching(List<DartScope2> filtered) {
    if (filtered.length > 5 &&
        filtered[0].node is VariableDeclaration &&
        (filtered[0].node as VariableDeclaration).isHoisted) {
      // The 5 is not special. This has just been observed to contain lots of
      // scopes.
      // Pattern matching looks something like this:
      // ```
      // hoisted variable1; // offset x
      // hoisted variable2; // offset y
      // // some initialization stuff for variable1. // offset x
      // // some initialization stuff for variable2. // offset y
      // if (stuff with variable1 ending in the setting of it /* offset x */ &&
      //     stuff with variable2 ending in the setting of it /* offset y */) {
      //   // body
      // }
      // ```
      // Meaning that even if only seeing a hoisted variable as in scope after
      // it has been written for position y in the above example we'll have
      // variable1 in scope for ~half the scopes.
      // We'll assume we've hit this case if we can find a LogicalExpression
      // followed later by a VariableSet.
      // We'll then pick the VariableSet as the scope.
      int foundLogicalExpressionAt = -1;
      for (int i = 1; i < filtered.length; i++) {
        if (filtered[i].node is LogicalExpression) {
          foundLogicalExpressionAt = i;
        }
      }
      if (foundLogicalExpressionAt >= 0) {
        for (int i = foundLogicalExpressionAt + 1; i < filtered.length; i++) {
          if (filtered[i].node is VariableSet) {
            return filtered[i];
          }
        }
      }
    }
    if (filtered.length > 5 &&
        filtered[0].node is VariableDeclaration &&
        filtered[1].node is VariableDeclaration &&
        filtered.last.node is LocalFunctionInvocation) {
      // It's beginning to look a lot like a late lowered nullable pattern
      // matching case.
      VariableDeclaration variable1 = filtered[0].node as VariableDeclaration;
      VariableDeclaration variable2 = filtered[1].node as VariableDeclaration;
      if (variable1.isSynthesized &&
          variable1.name?.startsWith("#") == true &&
          variable2.isSynthesized &&
          variable2.isLowered &&
          variable2.name?.startsWith("#") == true) {
        // Assume so. We'll pick the last one where we have previous variables
        //that already matched in scope.
        return filtered.last;
      }
    }
    if (filtered.length <= 4 &&
        filtered[0].node is VariableDeclaration &&
        (filtered[0].node as VariableDeclaration).isHoisted &&
        filtered.last.node is VariableSet &&
        (filtered.last.node as VariableSet).variable == filtered[0].node) {
      return filtered.last;
    }
    return null;
  }

  static DartScope2? _looksLikeLateLoweredLocal(List<DartScope2> filtered) {
    VariableDeclaration? variable1;
    VariableDeclaration? variable2;
    if (filtered.length > 5 &&
        filtered[0].node is VariableDeclaration &&
        filtered[1].node is VariableDeclaration) {
      // A nullable one, e.g. `late Foo? foo` becomes something like
      // ```
      // Foo? #foo;
      // bool #foo#isSet = false;
      // ```
      variable1 = filtered[0].node as VariableDeclaration;
      variable2 = filtered[1].node as VariableDeclaration;
    } else if (filtered.length > 5 &&
        filtered[0].node is VariableDeclaration &&
        filtered[2].node is VariableDeclaration) {
      // A non-nullable one, e.g. `late Foo foo` becomes something like
      // ```
      // Foo? #foo;
      // Foo #foo#get() => bla bla
      // ```
      variable1 = filtered[0].node as VariableDeclaration;
      variable2 = filtered[2].node as VariableDeclaration;
    }
    if (variable1 != null && variable2 != null) {
      // isLateLoweredLocalName/isLateLoweredLocalSetter/etc is in the CFE so we
      // can't call it from here.
      if (variable1.isLowered &&
          variable1.name?.startsWith("#") == true &&
          variable2.isLowered &&
          variable2.name?.startsWith("#") == true) {
        // Assume it's a late lowering thing with an exuberant amount of nodes
        // with the same offset. Just pick the first one.
        return filtered[0];
      }
    }
    return null;
  }

  static DartScope2? _looksLikeThrowPatternMatchingError(
      List<DartScope2> filtered) {
    if (filtered.length == 5 &&
        filtered[0].node is IfStatement &&
        filtered[1].node is ExpressionStatement &&
        filtered[2].node is Throw &&
        filtered[3].node is ConstructorInvocation &&
        filtered[4].node is StringLiteral) {
      // Something like
      // `var (Foo? a, Foo? b) = someCall();`
      // becomes something like
      // ```
      //if (!(checks for Foo? and lets with assigns etc))
      //  throw new StateError("Pattern matching error");
      // ```
      // Pick the if.
      return filtered[0];
    } else if (filtered.length == 6 &&
        filtered[0].node is Block &&
        filtered[1].node is IfStatement &&
        filtered[2].node is ExpressionStatement &&
        filtered[3].node is Throw &&
        filtered[4].node is ConstructorInvocation &&
        filtered[5].node is StringLiteral) {
      // As above, but inside a block, e.g. if used in a for-in loop like
      // ```
      // for (var Foo(:Whatnot? bar, :Whatnot? baz ) in entries) { [...] }
      // ```
      // Pick the if.
      return filtered[1];
    }
    return null;
  }

  static DartScopeBuilder2 _raw(
      Library library, Uri scriptUri, Class? cls, int offset) {
    DartScopeBuilder2 builder = DartScopeBuilder2._(library, scriptUri, offset);
    if (cls != null) {
      builder.visitClass(cls);
    } else {
      builder.checkClasses = false;
      builder.visitLibrary(library);
    }

    return builder;
  }

  static DartScopeBuilder2 _rawNoClass(
      Library library, Uri scriptUri, int offset) {
    DartScopeBuilder2 builder = DartScopeBuilder2._(library, scriptUri, offset);
    builder.visitLibrary(library);
    return builder;
  }

  static List<DartScope2> findScopeFromOffsetAndClassRawForTesting(
          Library library, Uri scriptUri, Class? cls, int offset) =>
      _raw(library, scriptUri, cls, offset).findScopes;
}
