<commit_before>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use autocxx_parser::IncludeCpp;
use proc_macro2::{Ident, Span};
use proc_macro_error::{abort, proc_macro_error};
use quote::quote;
use syn::parse::{Parse, ParseStream, Parser};
use syn::{parse_macro_input, Fields, ItemStruct, Result as ParseResult};

struct SelfOwned(bool);

impl Parse for SelfOwned {
    fn parse(input: ParseStream) -> ParseResult<Self> {
        // TODO make this less liberal
        let id = input.parse::<Option<Ident>>()?;
        match id {
            Some(id) if id == "self_owned" => Ok(Self(true)),
            _ => Ok(Self(false)),
        }
    }
}

/// Implementation of the `include_cpp` macro. See documentation for `autocxx` crate.
#[proc_macro_error]
#[proc_macro]
pub fn include_cpp_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let include_cpp = parse_macro_input!(input as IncludeCpp);
    proc_macro::TokenStream::from(include_cpp.generate_rs())
}

/// Attribute to state that a Rust `struct` is a C++ subclass.
/// This adds an additional field to the struct which autocxx uses to
/// track a C++ instantiation of this Rust subclass.
#[proc_macro_error]
#[proc_macro_attribute]
pub fn is_subclass(
    attr: proc_macro::TokenStream,
    item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
    let mut s: ItemStruct =
        syn::parse(item).unwrap_or_else(|_| abort!(Span::call_site(), "Expected a struct"));
    let id = &s.ident;
    let cpp_ident = Ident::new(&format!("{}Cpp", id.to_string()), Span::call_site());
    match &mut s.fields {
        Fields::Named(fields) => {<commit_msg>Fix overly liberal subclass parsing.<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use autocxx_parser::IncludeCpp;
use proc_macro2::{Ident, Span};
use proc_macro_error::{abort, proc_macro_error};
use quote::{quote, ToTokens};
use syn::parse::{Parse, ParseStream, Parser};
use syn::{parse_macro_input, Fields, ItemStruct, Result as ParseResult};

struct SelfOwned(bool);

impl Parse for SelfOwned {
    fn parse(input: ParseStream) -> ParseResult<Self> {
        let id = input.parse::<Option<Ident>>()?;
        match id {
            Some(id) if id == "self_owned" => Ok(Self(true)),
            Some(id) => Err(syn::Error::new_spanned(
                id.into_token_stream(),
                "Expected self_owned",
            )),
            None => Ok(Self(false)),
        }
    }
}

/// Implementation of the `include_cpp` macro. See documentation for `autocxx` crate.
#[proc_macro_error]
#[proc_macro]
pub fn include_cpp_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let include_cpp = parse_macro_input!(input as IncludeCpp);
    proc_macro::TokenStream::from(include_cpp.generate_rs())
}

/// Attribute to state that a Rust `struct` is a C++ subclass.
/// This adds an additional field to the struct which autocxx uses to
/// track a C++ instantiation of this Rust subclass.
#[proc_macro_error]
#[proc_macro_attribute]
pub fn is_subclass(
    attr: proc_macro::TokenStream,
    item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
    let mut s: ItemStruct =
        syn::parse(item).unwrap_or_else(|_| abort!(Span::call_site(), "Expected a struct"));
    let id = &s.ident;
    let cpp_ident = Ident::new(&format!("{}Cpp", id.to_string()), Span::call_site());
    match &mut s.fields {
        Fields::Named(fields) => {
{'fraction_non_alphanumeric': 0.1274793848896813, 'fraction_numerical': 0.004011589034989971, 'mean_word_length': 3.7897545357524014, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 22, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, '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': '4285830', 'n_tokens_mistral': 1353, 'n_tokens_neox': 1324, 'n_words': 436}