<commit_before>// Copyright (c) 2014, 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.

/// The models used to represent Dart code.
library dartdoc.models;

import 'dart:convert';

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart' show FunctionType;
import 'package:analyzer/source/line_info.dart';
// ignore: implementation_imports
import 'package:analyzer/src/dart/element/member.dart'
    show ExecutableMember, Member;
import 'package:collection/collection.dart';
import 'package:dartdoc/src/comment_references/model_comment_reference.dart';
import 'package:dartdoc/src/dartdoc_options.dart';
import 'package:dartdoc/src/element_type.dart';
import 'package:dartdoc/src/model/annotation.dart';
import 'package:dartdoc/src/model/comment_referable.dart';
import 'package:dartdoc/src/model/feature.dart';
import 'package:dartdoc/src/model/feature_set.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/model/model_object_builder.dart';
import 'package:dartdoc/src/model/prefix.dart';
import 'package:dartdoc/src/model_utils.dart' as utils;
import 'package:dartdoc/src/render/model_element_renderer.dart';
import 'package:dartdoc/src/render/parameter_renderer.dart';
import 'package:dartdoc/src/render/source_code_renderer.dart';
import 'package:dartdoc/src/source_linker.dart';
import 'package:dartdoc/src/special_elements.dart';
import 'package:dartdoc/src/tuple.dart';
import 'package:dartdoc/src/warnings.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path show Context;

// TODO(jcollins-g): Implement resolution per ECMA-408 4th edition, page 39 #22.
/// Resolves this very rare case incorrectly by picking the closest element in
/// the inheritance and interface chains from the analyzer.
ModelElement resolveMultiplyInheritedElement(
    MultiplyInheritedExecutableElement e,
    Library library,
    PackageGraph packageGraph,
    Class enclosingClass) {
  var inheritables = e.inheritedElements
      .map((ee) => ModelElement._fromElement(ee, packageGraph) as Inheritable);
  Inheritable foundInheritable;
  var lowIndex = enclosingClass.inheritanceChain.length;
  for (var inheritable in inheritables) {
    var index =
        enclosingClass.inheritanceChain.indexOf(inheritable.enclosingElement);
    if (index < lowIndex) {
      foundInheritable = inheritable;
      lowIndex = index;
    }
  }
  return ModelElement._from(foundInheritable.element, library, packageGraph,
      enclosingContainer: enclosingClass);
}

mixin ModelElementBuilderImpl implements ModelElementBuilder {
  PackageGraph get packageGraph;

  @override
  ModelElement from(Element e, Library library,
          {Container enclosingContainer}) =>
      ModelElement._from(e, library, packageGraph,
          enclosingContainer: enclosingContainer);

  @override
  ModelElement fromElement(Element e) =>
      ModelElement._fromElement(e, packageGraph);

  @override
  ModelElement fromPropertyInducingElement(Element e, Library l,
          {Container enclosingContainer, Accessor getter, Accessor setter}) =>
      ModelElement._fromPropertyInducingElement(e, l, packageGraph,
          enclosingContainer: enclosingContainer,
          getter: getter,
          setter: setter);
}

/// This class is the foundation of Dartdoc's model for source code.
///
/// All ModelElements are contained within a [PackageGraph], and laid out in a
/// structure that mirrors the availability of identifiers in the various
/// namespaces within that package.  For example, multiple [Class] objects for a
/// particular identifier ([ModelElement.element]) may show up in different
/// [Library]s as the identifier is reexported.
///
/// However, ModelElements have an additional concept vital to generating
/// documentation: canonicalization.
///
/// A ModelElement is canonical if it is the element in the namespace where that
/// element 'comes from' in the public interface to this [PackageGraph].  That
/// often means the [ModelElement.library] is contained in
/// [PackageGraph.libraries], but there are many exceptions and ambiguities the
/// code tries to address here.
///
/// Non-canonical elements should refer to their canonical counterparts, making
/// it easy to calculate links via [ModelElement.href] without having to know in
/// a particular namespace which elements are canonical or not.  A number of
/// [PackageGraph] methods, such as [PackageGraph.findCanonicalModelElementFor]
/// can help with this.
///
/// When documenting, Dartdoc should only write out files corresponding to
/// canonical instances of ModelElement ([ModelElement.isCanonical]).  This
/// helps prevent subtle bugs as generated output for a non-canonical
/// ModelElement will reference itself as part of the "wrong" [Library] from the
/// public interface perspective.
abstract class ModelElement extends Canonicalization
    with
        CommentReferable,
        Privacy,
        Warnable,
        Locatable,
        Nameable,
        SourceCodeMixin,
        Indexable,
        FeatureSet,
        DocumentationComment,
        ModelBuilder
    implements Comparable<ModelElement>, Documentable {
  final Element _element;

  // TODO(jcollins-g): This really wants a "member that has a type" class.
  final Member /*?*/ _originalMember;
  final Library /*?*/ _library;

  UnmodifiableListView<Parameter> _parameters;
  String _linkedName;

  ModelElement(this._element, this._library, this._packageGraph,
      [this._originalMember]);

  /// Creates a [ModelElement] from [e].
  factory ModelElement._fromElement(Element e, PackageGraph p) {
    var lib = p.findButDoNotCreateLibraryFor(e);
    if (e is PropertyInducingElement) {
      var getter =
          e.getter != null ? ModelElement._from(e.getter, lib, p) : null;
      var setter =
          e.setter != null ? ModelElement._from(e.setter, lib, p) : null;
      return ModelElement._fromPropertyInducingElement(e, lib, p,
          getter: getter, setter: setter);
    }
    return ModelElement._from(e, lib, p);
  }

  /// Creates a [ModelElement] from [PropertyInducingElement] [e].
  ///
  /// Do not construct any ModelElements except from this constructor or
  /// [ModelElement._from]. Specify [enclosingContainer]
  /// if and only if this is to be an inherited or extended object.
  factory ModelElement._fromPropertyInducingElement(
      PropertyInducingElement e, Library library, PackageGraph packageGraph,
      {Container enclosingContainer,
      @required Accessor getter,
      @required Accessor setter}) {
    assert(packageGraph != null);
    assert(e != null);
    assert(library != null);

    // TODO(jcollins-g): Refactor object model to instantiate 'ModelMembers'
    //                   for members?
    if (e is Member) {
      e = e.declaration;
    }

    // Return the cached ModelElement if it exists.
    var key =
        Tuple3<Element, Library, Container>(e, library, enclosingContainer);
    if (packageGraph.allConstructedModelElements.containsKey(key)) {
      return packageGraph.allConstructedModelElements[key];
    }

    ModelElement newModelElement;
    if (e is FieldElement) {
      if (enclosingContainer == null) {
        if (e.isEnumConstant) {
          var index = e.computeConstantValue().getField(e.name).toIntValue();
          newModelElement =
              EnumField.forConstant(index, e, library, packageGraph, getter);
        } else if (e.enclosingElement is ExtensionElement) {
          newModelElement = Field(e, library, packageGraph, getter, setter);
        } else if (e.enclosingElement is ClassElement &&
            (e.enclosingElement as ClassElement).isEnum) {
          newModelElement = EnumField(e, library, packageGraph, getter, setter);
        } else {
          newModelElement = Field(e, library, packageGraph, getter, setter);<commit_msg>Use 'index' to access the enum value index. (#2865)<commit_after>// Copyright (c) 2014, 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.

/// The models used to represent Dart code.
library dartdoc.models;

import 'dart:convert';

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart' show FunctionType;
import 'package:analyzer/source/line_info.dart';
// ignore: implementation_imports
import 'package:analyzer/src/dart/element/member.dart'
    show ExecutableMember, Member;
import 'package:collection/collection.dart';
import 'package:dartdoc/src/comment_references/model_comment_reference.dart';
import 'package:dartdoc/src/dartdoc_options.dart';
import 'package:dartdoc/src/element_type.dart';
import 'package:dartdoc/src/model/annotation.dart';
import 'package:dartdoc/src/model/comment_referable.dart';
import 'package:dartdoc/src/model/feature.dart';
import 'package:dartdoc/src/model/feature_set.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/model/model_object_builder.dart';
import 'package:dartdoc/src/model/prefix.dart';
import 'package:dartdoc/src/model_utils.dart' as utils;
import 'package:dartdoc/src/render/model_element_renderer.dart';
import 'package:dartdoc/src/render/parameter_renderer.dart';
import 'package:dartdoc/src/render/source_code_renderer.dart';
import 'package:dartdoc/src/source_linker.dart';
import 'package:dartdoc/src/special_elements.dart';
import 'package:dartdoc/src/tuple.dart';
import 'package:dartdoc/src/warnings.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path show Context;

// TODO(jcollins-g): Implement resolution per ECMA-408 4th edition, page 39 #22.
/// Resolves this very rare case incorrectly by picking the closest element in
/// the inheritance and interface chains from the analyzer.
ModelElement resolveMultiplyInheritedElement(
    MultiplyInheritedExecutableElement e,
    Library library,
    PackageGraph packageGraph,
    Class enclosingClass) {
  var inheritables = e.inheritedElements
      .map((ee) => ModelElement._fromElement(ee, packageGraph) as Inheritable);
  Inheritable foundInheritable;
  var lowIndex = enclosingClass.inheritanceChain.length;
  for (var inheritable in inheritables) {
    var index =
        enclosingClass.inheritanceChain.indexOf(inheritable.enclosingElement);
    if (index < lowIndex) {
      foundInheritable = inheritable;
      lowIndex = index;
    }
  }
  return ModelElement._from(foundInheritable.element, library, packageGraph,
      enclosingContainer: enclosingClass);
}

mixin ModelElementBuilderImpl implements ModelElementBuilder {
  PackageGraph get packageGraph;

  @override
  ModelElement from(Element e, Library library,
          {Container enclosingContainer}) =>
      ModelElement._from(e, library, packageGraph,
          enclosingContainer: enclosingContainer);

  @override
  ModelElement fromElement(Element e) =>
      ModelElement._fromElement(e, packageGraph);

  @override
  ModelElement fromPropertyInducingElement(Element e, Library l,
          {Container enclosingContainer, Accessor getter, Accessor setter}) =>
      ModelElement._fromPropertyInducingElement(e, l, packageGraph,
          enclosingContainer: enclosingContainer,
          getter: getter,
          setter: setter);
}

/// This class is the foundation of Dartdoc's model for source code.
///
/// All ModelElements are contained within a [PackageGraph], and laid out in a
/// structure that mirrors the availability of identifiers in the various
/// namespaces within that package.  For example, multiple [Class] objects for a
/// particular identifier ([ModelElement.element]) may show up in different
/// [Library]s as the identifier is reexported.
///
/// However, ModelElements have an additional concept vital to generating
/// documentation: canonicalization.
///
/// A ModelElement is canonical if it is the element in the namespace where that
/// element 'comes from' in the public interface to this [PackageGraph].  That
/// often means the [ModelElement.library] is contained in
/// [PackageGraph.libraries], but there are many exceptions and ambiguities the
/// code tries to address here.
///
/// Non-canonical elements should refer to their canonical counterparts, making
/// it easy to calculate links via [ModelElement.href] without having to know in
/// a particular namespace which elements are canonical or not.  A number of
/// [PackageGraph] methods, such as [PackageGraph.findCanonicalModelElementFor]
/// can help with this.
///
/// When documenting, Dartdoc should only write out files corresponding to
/// canonical instances of ModelElement ([ModelElement.isCanonical]).  This
/// helps prevent subtle bugs as generated output for a non-canonical
/// ModelElement will reference itself as part of the "wrong" [Library] from the
/// public interface perspective.
abstract class ModelElement extends Canonicalization
    with
        CommentReferable,
        Privacy,
        Warnable,
        Locatable,
        Nameable,
        SourceCodeMixin,
        Indexable,
        FeatureSet,
        DocumentationComment,
        ModelBuilder
    implements Comparable<ModelElement>, Documentable {
  final Element _element;

  // TODO(jcollins-g): This really wants a "member that has a type" class.
  final Member /*?*/ _originalMember;
  final Library /*?*/ _library;

  UnmodifiableListView<Parameter> _parameters;
  String _linkedName;

  ModelElement(this._element, this._library, this._packageGraph,
      [this._originalMember]);

  /// Creates a [ModelElement] from [e].
  factory ModelElement._fromElement(Element e, PackageGraph p) {
    var lib = p.findButDoNotCreateLibraryFor(e);
    if (e is PropertyInducingElement) {
      var getter =
          e.getter != null ? ModelElement._from(e.getter, lib, p) : null;
      var setter =
          e.setter != null ? ModelElement._from(e.setter, lib, p) : null;
      return ModelElement._fromPropertyInducingElement(e, lib, p,
          getter: getter, setter: setter);
    }
    return ModelElement._from(e, lib, p);
  }

  /// Creates a [ModelElement] from [PropertyInducingElement] [e].
  ///
  /// Do not construct any ModelElements except from this constructor or
  /// [ModelElement._from]. Specify [enclosingContainer]
  /// if and only if this is to be an inherited or extended object.
  factory ModelElement._fromPropertyInducingElement(
      PropertyInducingElement e, Library library, PackageGraph packageGraph,
      {Container enclosingContainer,
      @required Accessor getter,
      @required Accessor setter}) {
    assert(packageGraph != null);
    assert(e != null);
    assert(library != null);

    // TODO(jcollins-g): Refactor object model to instantiate 'ModelMembers'
    //                   for members?
    if (e is Member) {
      e = e.declaration;
    }

    // Return the cached ModelElement if it exists.
    var key =
        Tuple3<Element, Library, Container>(e, library, enclosingContainer);
    if (packageGraph.allConstructedModelElements.containsKey(key)) {
      return packageGraph.allConstructedModelElements[key];
    }

    ModelElement newModelElement;
    if (e is FieldElement) {
      if (enclosingContainer == null) {
        if (e.isEnumConstant) {
          var index = e.computeConstantValue().getField('index').toIntValue();
          newModelElement =
              EnumField.forConstant(index, e, library, packageGraph, getter);
        } else if (e.enclosingElement is ExtensionElement) {
          newModelElement = Field(e, library, packageGraph, getter, setter);
        } else if (e.enclosingElement is ClassElement &&
            (e.enclosingElement as ClassElement).isEnum) {
          newModelElement = EnumField(e, library, packageGraph, getter, setter);
        } else {
          newModelElement = Field(e, library, packageGraph, getter, setter);
{'fraction_non_alphanumeric': 0.09732860078460676, 'fraction_numerical': 0.0018681113394358303, 'mean_word_length': 3.7868852459016393, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3375829', 'n_tokens_mistral': 4540, 'n_tokens_neox': 4417, 'n_words': 1329}