<commit_before>//! Bindgen's core intermediate representation type.

use clang;
use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};
use regex::Regex;
use std::cell::{Cell, RefCell};
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
use super::annotations::Annotations;
use super::context::BindgenContext;
use super::function::Function;
use super::item_kind::ItemKind;
use super::module::Module;
use super::ty::{Type, TypeKind};
use super::type_collector::{ItemSet, TypeCollector};

/// A trait to get the canonical name from an item.
///
/// This is the trait that will eventually isolate all the logic related to name
/// mangling and that kind of stuff.
///
/// This assumes no nested paths, at some point I'll have to make it a more
/// complex thing.
///
/// This name is required to be safe for Rust, that is, is not expected to
/// return any rust keyword from here.
pub trait ItemCanonicalName {
    /// Get the canonical name for this item.
    fn canonical_name(&self, ctx: &BindgenContext) -> String;
}

/// The same, but specifies the path that needs to be followed to reach an item.
///
/// To contrast with canonical_name, here's an example:
///
/// ```c++
/// namespace foo {
///     const BAR = 3;
/// }
/// ```
///
/// For bar, the canonical path is `vec!["foo", "BAR"]`, while the canonical
/// name is just `"BAR"`.
pub trait ItemCanonicalPath {
    /// Get the canonical path for this item.
    fn canonical_path(&self, ctx: &BindgenContext) -> Vec<String>;
}

/// A trait for iterating over an item and its parents and up its ancestor chain
/// up to (but not including) the implicit root module.
pub trait ItemAncestors {
    /// Get an iterable over this item's ancestors.
    fn ancestors<'a, 'b>(&self, ctx: &'a BindgenContext<'b>) -> ItemAncestorsIter<'a, 'b>;
}

/// An iterator over an item and its ancestors.
pub struct ItemAncestorsIter<'a, 'b>
    where 'b: 'a,
{
    item: ItemId,
    ctx: &'a BindgenContext<'b>,
}

impl<'a, 'b> Iterator for ItemAncestorsIter<'a, 'b>
    where 'b: 'a,
{
    type Item = ItemId;

    fn next(&mut self) -> Option<Self::Item> {
        let item = self.ctx.resolve_item(self.item);
        if item.parent_id() == self.item {
            None
        } else {
            self.item = item.parent_id();
            Some(item.id())
        }
    }
}

/// A single identifier for an item.
///
/// TODO: Build stronger abstractions on top of this, like TypeId(ItemId)?
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ItemId(usize);

impl ItemId {
    /// Allocate the next `ItemId`.
    pub fn next() -> Self {
        static NEXT_ITEM_ID: AtomicUsize = ATOMIC_USIZE_INIT;
        ItemId(NEXT_ITEM_ID.fetch_add(1, Ordering::Relaxed))
    }
}
<commit_msg>Use a temporary for the return value in IteId::next()<commit_after>//! Bindgen's core intermediate representation type.

use clang;
use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};
use regex::Regex;
use std::cell::{Cell, RefCell};
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
use super::annotations::Annotations;
use super::context::BindgenContext;
use super::function::Function;
use super::item_kind::ItemKind;
use super::module::Module;
use super::ty::{Type, TypeKind};
use super::type_collector::{ItemSet, TypeCollector};

/// A trait to get the canonical name from an item.
///
/// This is the trait that will eventually isolate all the logic related to name
/// mangling and that kind of stuff.
///
/// This assumes no nested paths, at some point I'll have to make it a more
/// complex thing.
///
/// This name is required to be safe for Rust, that is, is not expected to
/// return any rust keyword from here.
pub trait ItemCanonicalName {
    /// Get the canonical name for this item.
    fn canonical_name(&self, ctx: &BindgenContext) -> String;
}

/// The same, but specifies the path that needs to be followed to reach an item.
///
/// To contrast with canonical_name, here's an example:
///
/// ```c++
/// namespace foo {
///     const BAR = 3;
/// }
/// ```
///
/// For bar, the canonical path is `vec!["foo", "BAR"]`, while the canonical
/// name is just `"BAR"`.
pub trait ItemCanonicalPath {
    /// Get the canonical path for this item.
    fn canonical_path(&self, ctx: &BindgenContext) -> Vec<String>;
}

/// A trait for iterating over an item and its parents and up its ancestor chain
/// up to (but not including) the implicit root module.
pub trait ItemAncestors {
    /// Get an iterable over this item's ancestors.
    fn ancestors<'a, 'b>(&self, ctx: &'a BindgenContext<'b>) -> ItemAncestorsIter<'a, 'b>;
}

/// An iterator over an item and its ancestors.
pub struct ItemAncestorsIter<'a, 'b>
    where 'b: 'a,
{
    item: ItemId,
    ctx: &'a BindgenContext<'b>,
}

impl<'a, 'b> Iterator for ItemAncestorsIter<'a, 'b>
    where 'b: 'a,
{
    type Item = ItemId;

    fn next(&mut self) -> Option<Self::Item> {
        let item = self.ctx.resolve_item(self.item);
        if item.parent_id() == self.item {
            None
        } else {
            self.item = item.parent_id();
            Some(item.id())
        }
    }
}

/// A single identifier for an item.
///
/// TODO: Build stronger abstractions on top of this, like TypeId(ItemId)?
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ItemId(usize);

impl ItemId {
    /// Allocate the next `ItemId`.
    pub fn next() -> Self {
        static NEXT_ITEM_ID: AtomicUsize = ATOMIC_USIZE_INIT;
        let next_id = NEXT_ITEM_ID.fetch_add(1, Ordering::Relaxed);
        ItemId(next_id)
    }
}

{'fraction_non_alphanumeric': 0.14120986340251906, 'fraction_numerical': 0.0007095973035302466, 'mean_word_length': 3.17939214232765, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 31, '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': '4373294', 'n_tokens_mistral': 1786, 'n_tokens_neox': 1779, 'n_words': 633}