// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/element.dart';

/// Keeps track of the set of non-synthetic child elements of an element,
/// yielding them one at a time in response to "get" method calls.
class ElementWalker {
  /// The element whose child elements are being walked.
  final Element element;

  List<PropertyAccessorElement> _accessors;
  int _accessorIndex = 0;
  List<ClassElement> _classes;
  int _classIndex = 0;
  List<ConstructorElement> _constructors;
  int _constructorIndex = 0;
  List<ClassElement> _enums;
  int _enumIndex = 0;
  List<ExtensionElement> _extensions;
  int _extensionIndex = 0;
  List<ExecutableElement> _functions;
  int _functionIndex = 0;
  List<ClassElement> _mixins;
  int _mixinIndex = 0;
  List<ParameterElement> _parameters;
  int _parameterIndex = 0;
  List<FunctionTypeAliasElement> _typedefs;
  int _typedefIndex = 0;
  List<TypeParameterElement> _typeParameters;
  int _typeParameterIndex = 0;
  List<VariableElement> _variables;
  int _variableIndex = 0;

  /// Creates an [ElementWalker] which walks the child elements of a class
  /// element.
  ElementWalker.forClass(ClassElement element)
      : element = element,
        _accessors = element.accessors.where(_isNotSynthetic).toList(),
        _constructors = element.isMixinApplication
            ? null
            : element.constructors.where(_isNotSynthetic).toList(),
        _functions = element.methods,
        _typeParameters = element.typeParameters,
        _variables = element.fields.where(_isNotSynthetic).toList();

  /// Creates an [ElementWalker] which walks the child elements of a compilation
  /// unit element.
  ElementWalker.forCompilationUnit(CompilationUnitElement element)
      : element = element,
        _accessors = element.accessors.where(_isNotSynthetic).toList(),
        _classes = element.types,
        _enums = element.enums,
        _extensions = element.extensions,
        _functions = element.functions,
        _mixins = element.mixins,
        _typedefs = element.functionTypeAliases,
        _variables = element.topLevelVariables.where(_isNotSynthetic).toList();

  /// Creates an [ElementWalker] which walks the child elements of a compilation
  /// unit element.
  ElementWalker.forExecutable(ExecutableElement element)
      : element = element,
        _functions = const <ExecutableElement>[],
        _parameters = element.parameters,
        _typeParameters = element.typeParameters;

  /// Creates an [ElementWalker] which walks the child elements of an extension
  /// element.
  ElementWalker.forExtension(ExtensionElement element)
      : element = element,
        _accessors = element.accessors.where(_isNotSynthetic).toList(),
        _functions = element.methods,
        _typeParameters = element.typeParameters,
        _variables = element.fields.where(_isNotSynthetic).toList();

  /// Creates an [ElementWalker] which walks the child elements of a typedef
  /// element.
  ElementWalker.forGenericFunctionType(GenericFunctionTypeElement element)
      : element = element,
        _parameters = element.parameters,
        _typeParameters = element.typeParameters;

  /// Creates an [ElementWalker] which walks the child elements of a typedef
  /// element defined using a generic function type.
  ElementWalker.forGenericTypeAlias(FunctionTypeAliasElement element)
      : element = element,
        _typeParameters = element.typeParameters;

  /// Creates an [ElementWalker] which walks the child elements of a parameter
  /// element.
  ElementWalker.forParameter(ParameterElement element)
      : element = element,
        _parameters = element.parameters,
        _typeParameters = element.typeParameters;

  /// Creates an [ElementWalker] which walks the child elements of a typedef
  /// element.
  ElementWalker.forTypedef(GenericTypeAliasElementImpl element)
      : element = element,
        _parameters = element.function.parameters,
        _typeParameters = element.typeParameters;

  void consumeLocalElements() {
    _functionIndex = _functions.length;
  }

  void consumeParameters() {
    _parameterIndex = _parameters.length;
  }

  /// Returns the next non-synthetic child of [element] which is an accessor;
  /// throws an [IndexError] if there are no more.
  PropertyAccessorElement getAccessor() => _accessors[_accessorIndex++];

  /// Returns the next non-synthetic child of [element] which is a class; throws
  /// an [IndexError] if there are no more.
  ClassElement getClass() => _classes[_classIndex++];

  /// Returns the next non-synthetic child of [element] which is a constructor;
  /// throws an [IndexError] if there are no more.
  ConstructorElement getConstructor() => _constructors[_constructorIndex++];

  /// Returns the next non-synthetic child of [element] which is an enum; throws
  /// an [IndexError] if there are no more.
  ClassElement getEnum() => _enums[_enumIndex++];

  ExtensionElement getExtension() => _extensions[_extensionIndex++];

  /// Returns the next non-synthetic child of [element] which is a top level
  /// function, method, or local function; throws an [IndexError] if there are
  /// no more.
  ExecutableElement getFunction() => _functions[_functionIndex++];

  /// Returns the next non-synthetic child of [element] which is a mixin; throws
  /// an [IndexError] if there are no more.
  ClassElement getMixin() => _mixins[_mixinIndex++];

  /// Returns the next non-synthetic child of [element] which is a parameter;
  /// throws an [IndexError] if there are no more.
  ParameterElement getParameter() => _parameters[_parameterIndex++];

  /// Returns the next non-synthetic child of [element] which is a typedef;
  /// throws an [IndexError] if there are no more.
  FunctionTypeAliasElement getTypedef() => _typedefs[_typedefIndex++];

  /// Returns the next non-synthetic child of [element] which is a type
  /// parameter; throws an [IndexError] if there are no more.
  TypeParameterElement getTypeParameter() =>
      _typeParameters[_typeParameterIndex++];

  /// Returns the next non-synthetic child of [element] which is a top level
  /// variable, field, or local variable; throws an [IndexError] if there are no
  /// more.
  VariableElement getVariable() => _variables[_variableIndex++];

  /// Verifies that all non-synthetic children of [element] have been obtained
  /// from their corresponding "get" method calls; if not, throws a
  /// [StateError].
  void validate() {
    void check(List<Element> elements, int index) {
      if (elements != null && elements.length != index) {
        throw StateError(
            'Unmatched ${elements[index].runtimeType} ${elements[index]}');
      }
    }

    check(_accessors, _accessorIndex);
    check(_classes, _classIndex);
    check(_constructors, _constructorIndex);
    check(_enums, _enumIndex);
    check(_functions, _functionIndex);
    check(_parameters, _parameterIndex);
    check(_typedefs, _typedefIndex);
    check(_typeParameters, _typeParameterIndex);
    check(_variables, _variableIndex);
  }

  static bool _isNotSynthetic(Element e) => !e.isSynthetic;
}
