<commit_before>/**
 */
#include "ast_iterate.hpp"
#include "../ast/ast.hpp"

void CASTIterator::handle_path(AST::Path& path, CASTIterator::PathMode pm)
{
}
void CASTIterator::handle_type(TypeRef& type)
{
    TRACE_FUNCTION_F("type = " << type);
    
    TU_MATCH(TypeData, (type.m_data), (ent),
    (None),
    (Any),
    (Unit),
    (Primitive),
    (Path,
        handle_path(ent.path, MODE_TYPE);
        ),
    (Tuple,
        for(auto& subtype : ent.inner_types)
            handle_type(subtype);
        ),
    (Borrow,
        handle_type(*ent.inner);
        ),
    (Pointer,
        handle_type(*ent.inner);
        ),
    (Array,
        handle_type(*ent.inner);
        ),
    (Function,
        handle_type(*ent.info.m_rettype);
        for(auto& arg : ent.info.m_arg_types)
            handle_type(arg);
        ),
    (Generic),
    (TraitObject,
        for(auto& trait : ent.traits)
            handle_path(trait, MODE_TYPE);
        )
    )
}
void CASTIterator::handle_expr(AST::ExprNode& node)
{
}
void CASTIterator::handle_params(AST::GenericParams& params)
{
    DEBUG("params");
    for( auto& param : params.ty_params() )
    {
        handle_type(param.get_default());
        local_type( param.name(), TypeRef(TypeRef::TagArg(), param.name(), params) );
    }
    DEBUG("Bounds");
    for( auto& bound : params.bounds() )
    {
        TU_MATCH( AST::GenericBound, (bound), (ent),
        (Lifetime,
            DEBUG("namecheck lifetime bounds?");
            ),
        (TypeLifetime,
            handle_type(ent.type);
            DEBUG("namecheck lifetime bounds?");
            ),
        (IsTrait,
            handle_type(ent.type);
            // TODO: Define HRLs
            push_self(ent.type);
            handle_path(ent.trait, CASTIterator::MODE_TYPE);
            pop_self();
            ),
        (MaybeTrait,
            handle_type(ent.type);
            push_self(ent.type);
            handle_path(ent.trait, CASTIterator::MODE_TYPE);
            pop_self();
            // TODO: Process trait, ensuring that it's a valid lang item
            ),
        (NotTrait,
            handle_type(ent.type);
            push_self(ent.type);
            handle_path(ent.trait, CASTIterator::MODE_TYPE);
            pop_self();
            ),
        (Equality,
            handle_type(ent.type);
            handle_type(ent.replacement);
            )
        )
    }
}


void CASTIterator::start_scope()
{
    INDENT();
}
void CASTIterator::local_type(::std::string name, TypeRef type)
{
    DEBUG("type " << name << " = " << type);
}
void CASTIterator::local_variable(bool is_mut, ::std::string name, const TypeRef& type)
{
    DEBUG( (is_mut ? "mut " : "") << name << " : " << type );
}
void CASTIterator::local_use(::std::string name, AST::Path path)
{
    DEBUG( name << " = " << path );
}
void CASTIterator::end_scope()
{
    UNINDENT();
}

void CASTIterator::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint)
{
    //DEBUG("pat = " << pat);
    // Resolve names
    TU_MATCH(AST::Pattern::Data, (pat.data()), (v),
    (Any,
        // Wildcard, nothing to do
        ),
    (Macro,
        // Macro, nothing really (should be impossible?)
        ),
    (Box, {
        auto& v = pat.data().as_Box();
        if( type_hint.is_wildcard() )
            handle_pattern(*v.sub, (const TypeRef&)TypeRef());
        else {
            throw ::std::runtime_error("TODO: Handle box patterns in CASTIterator::handle_pattern");
            handle_pattern(*v.sub, type_hint.inner_type());
        }
        }),
    (Ref, {
        auto& v = pat.data().as_Ref();
        if( type_hint.is_wildcard() )
            handle_pattern(*v.sub, (const TypeRef&)TypeRef());
        else if( !type_hint.is_reference() )
            throw ::std::runtime_error( FMT("Ref pattern on non-ref value: " << type_hint) );
        else
            handle_pattern(*v.sub, type_hint.inner_type());
        }),
    (MaybeBind,
        throw ::std::runtime_error("Calling CASTIterator::handle_pattern on MAYBE_BIND, not valid");
        ),
    (Value, {
        auto& v = pat.data().as_Value();
        handle_expr( *v.start );
        if( v.end.get() )
            handle_expr( *v.end );
        }),
    (Tuple, {
        auto& v = pat.data().as_Tuple();
        // Tuple is handled by subpattern code
        if( type_hint.is_wildcard() )
        {
            for( auto& sp : v.sub_patterns )
                handle_pattern(sp, (const TypeRef&)TypeRef());
        }
        else if( !type_hint.is_tuple() )
        {
            throw ::std::runtime_error("Tuple pattern on non-tuple value");
        }
        else
        {
            const auto& inner_types = type_hint.m_data.as_Tuple().inner_types;
            if( inner_types.size() != v.sub_patterns.size() )
            {
                throw ::std::runtime_error("Tuple pattern count doesn't match");
            }
            for( unsigned int i = 0; i < v.sub_patterns.size(); i ++ )
            {
                handle_pattern(v.sub_patterns[i], inner_types[i]);
            }
        }
        }),
    (Struct, {
        auto& v = pat.data().as_Struct();
        handle_path( v.path, CASTIterator::MODE_TYPE );
        if( type_hint.is_wildcard() )
        {
            for( auto& sp : v.sub_patterns )
                handle_pattern(sp.second, (const TypeRef&)TypeRef());
        }
        else if( !type_hint.is_path() )
        {
            throw ::std::runtime_error("Tuple struct pattern on non-tuple value");
        }
        else
        {
            throw ::std::runtime_error("TODO: Struct typecheck/iterate");<commit_msg>Convert - Defer struct pattern typecheck further<commit_after>/**
 */
#include "ast_iterate.hpp"
#include "../ast/ast.hpp"

void CASTIterator::handle_path(AST::Path& path, CASTIterator::PathMode pm)
{
}
void CASTIterator::handle_type(TypeRef& type)
{
    TRACE_FUNCTION_F("type = " << type);
    
    TU_MATCH(TypeData, (type.m_data), (ent),
    (None),
    (Any),
    (Unit),
    (Primitive),
    (Path,
        handle_path(ent.path, MODE_TYPE);
        ),
    (Tuple,
        for(auto& subtype : ent.inner_types)
            handle_type(subtype);
        ),
    (Borrow,
        handle_type(*ent.inner);
        ),
    (Pointer,
        handle_type(*ent.inner);
        ),
    (Array,
        handle_type(*ent.inner);
        ),
    (Function,
        handle_type(*ent.info.m_rettype);
        for(auto& arg : ent.info.m_arg_types)
            handle_type(arg);
        ),
    (Generic),
    (TraitObject,
        for(auto& trait : ent.traits)
            handle_path(trait, MODE_TYPE);
        )
    )
}
void CASTIterator::handle_expr(AST::ExprNode& node)
{
}
void CASTIterator::handle_params(AST::GenericParams& params)
{
    DEBUG("params");
    for( auto& param : params.ty_params() )
    {
        handle_type(param.get_default());
        local_type( param.name(), TypeRef(TypeRef::TagArg(), param.name(), params) );
    }
    DEBUG("Bounds");
    for( auto& bound : params.bounds() )
    {
        TU_MATCH( AST::GenericBound, (bound), (ent),
        (Lifetime,
            DEBUG("namecheck lifetime bounds?");
            ),
        (TypeLifetime,
            handle_type(ent.type);
            DEBUG("namecheck lifetime bounds?");
            ),
        (IsTrait,
            handle_type(ent.type);
            // TODO: Define HRLs
            push_self(ent.type);
            handle_path(ent.trait, CASTIterator::MODE_TYPE);
            pop_self();
            ),
        (MaybeTrait,
            handle_type(ent.type);
            push_self(ent.type);
            handle_path(ent.trait, CASTIterator::MODE_TYPE);
            pop_self();
            // TODO: Process trait, ensuring that it's a valid lang item
            ),
        (NotTrait,
            handle_type(ent.type);
            push_self(ent.type);
            handle_path(ent.trait, CASTIterator::MODE_TYPE);
            pop_self();
            ),
        (Equality,
            handle_type(ent.type);
            handle_type(ent.replacement);
            )
        )
    }
}


void CASTIterator::start_scope()
{
    INDENT();
}
void CASTIterator::local_type(::std::string name, TypeRef type)
{
    DEBUG("type " << name << " = " << type);
}
void CASTIterator::local_variable(bool is_mut, ::std::string name, const TypeRef& type)
{
    DEBUG( (is_mut ? "mut " : "") << name << " : " << type );
}
void CASTIterator::local_use(::std::string name, AST::Path path)
{
    DEBUG( name << " = " << path );
}
void CASTIterator::end_scope()
{
    UNINDENT();
}

void CASTIterator::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint)
{
    //DEBUG("pat = " << pat);
    // Resolve names
    TU_MATCH(AST::Pattern::Data, (pat.data()), (v),
    (Any,
        // Wildcard, nothing to do
        ),
    (Macro,
        // Macro, nothing really (should be impossible?)
        ),
    (Box, {
        auto& v = pat.data().as_Box();
        if( type_hint.is_wildcard() )
            handle_pattern(*v.sub, (const TypeRef&)TypeRef());
        else {
            throw ::std::runtime_error("TODO: Handle box patterns in CASTIterator::handle_pattern");
            handle_pattern(*v.sub, type_hint.inner_type());
        }
        }),
    (Ref, {
        auto& v = pat.data().as_Ref();
        if( type_hint.is_wildcard() )
            handle_pattern(*v.sub, (const TypeRef&)TypeRef());
        else if( !type_hint.is_reference() )
            throw ::std::runtime_error( FMT("Ref pattern on non-ref value: " << type_hint) );
        else
            handle_pattern(*v.sub, type_hint.inner_type());
        }),
    (MaybeBind,
        throw ::std::runtime_error("Calling CASTIterator::handle_pattern on MAYBE_BIND, not valid");
        ),
    (Value, {
        auto& v = pat.data().as_Value();
        handle_expr( *v.start );
        if( v.end.get() )
            handle_expr( *v.end );
        }),
    (Tuple, {
        auto& v = pat.data().as_Tuple();
        // Tuple is handled by subpattern code
        if( type_hint.is_wildcard() )
        {
            for( auto& sp : v.sub_patterns )
                handle_pattern(sp, (const TypeRef&)TypeRef());
        }
        else if( !type_hint.is_tuple() )
        {
            throw ::std::runtime_error("Tuple pattern on non-tuple value");
        }
        else
        {
            const auto& inner_types = type_hint.m_data.as_Tuple().inner_types;
            if( inner_types.size() != v.sub_patterns.size() )
            {
                throw ::std::runtime_error("Tuple pattern count doesn't match");
            }
            for( unsigned int i = 0; i < v.sub_patterns.size(); i ++ )
            {
                handle_pattern(v.sub_patterns[i], inner_types[i]);
            }
        }
        }),
    (Struct, {
        auto& v = pat.data().as_Struct();
        handle_path( v.path, CASTIterator::MODE_TYPE );
        if( type_hint.is_wildcard() )
        {
            for( auto& sp : v.sub_patterns )
                handle_pattern(sp.second, (const TypeRef&)TypeRef());
        }
        else if( !type_hint.is_path() )
        {
            throw ::std::runtime_error("Tuple struct pattern on non-tuple value");
        }
        else
        {
            auto& path = type_hint.m_data.as_Path().path;
            if( path.is_bound() ) {
                throw ::std::runtime_error("TODO: Typecheck/iterate struct pattern (with known type)");
            }
            else {
                for( auto& sp : v.sub_patterns )
                    handle_pattern(sp.second, (const TypeRef&)TypeRef());
            }
{'fraction_non_alphanumeric': 0.1480425200933368, 'fraction_numerical': 0.00017284590787313111, 'mean_word_length': 1.9573217480194225, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 3, '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': '5257867', 'n_tokens_mistral': 3661, 'n_tokens_neox': 3616, 'n_words': 663}