<commit_before>role Perl6::Metamodel::MethodContainer {
    # Lookup table of the methods.
    has %!methods;
    has %!submethods;

    # The order that the methods were added in.
    has @!method_order;
    has @!method_names;

    # Cache that expires when we add methods (primarily to support NFA stuff).
    # The hash here is readonly; we copy/replace in on addition, for thread
    # safety (additions are dominated by lookups, so a lock - even a rw-lock -
    # is not ideal here).
    has %!cache;

    # Add a method.
    method add_method($obj, $name, $code_obj) {
        # Ensure we haven't already got it.
        $code_obj := nqp::decont($code_obj);
        $name := nqp::decont_s($name);
        if nqp::existskey(%!methods, $name) || nqp::existskey(%!submethods, $name) {
            nqp::die("Package '"
              ~ self.name($obj)
              ~ "' already has a "
              ~ (try { nqp::lc($code_obj.HOW.name($code_obj)) } // 'method')
              ~ " '"
              ~ $name
              ~ "' (did you mean to declare a multi-method?)");
        }

        # Add to correct table depending on if it's a Submethod.
        if !nqp::isnull(Perl6::Metamodel::Configuration.submethod_type)
            && nqp::istype($code_obj, Perl6::Metamodel::Configuration.submethod_type) {
            %!submethods{$name} := $code_obj;
        }
        else {
            %!methods{$name} := $code_obj;
        }

        # Adding a method means any cache is no longer authoritative.
        nqp::setmethcacheauth($obj, 0);
        %!cache := {};
        @!method_order[+@!method_order] := $code_obj;
        @!method_names[+@!method_names] := $name;
    }

    # Gets the method hierarchy.
    method methods($obj, :$local, :$excl, :$all) {
        # Always need local methods on the list.
        my @meths;
        for @!method_order {
            @meths.push(nqp::hllizefor($_, 'perl6'));<commit_msg>Fix a hang when adding a duplicate submethod<commit_after>role Perl6::Metamodel::MethodContainer {
    # Lookup table of the methods.
    has %!methods;
    has %!submethods;

    # The order that the methods were added in.
    has @!method_order;
    has @!method_names;

    # Cache that expires when we add methods (primarily to support NFA stuff).
    # The hash here is readonly; we copy/replace in on addition, for thread
    # safety (additions are dominated by lookups, so a lock - even a rw-lock -
    # is not ideal here).
    has %!cache;

    # Add a method.
    method add_method($obj, $name, $code_obj) {
        # Ensure we haven't already got it.
        $code_obj := nqp::decont($code_obj);
        $name := nqp::decont_s($name);
        if nqp::existskey(%!methods, $name) || nqp::existskey(%!submethods, $name) {
            # XXX try within nqp::die() causes a hang. Pre-cache the result and use it later.
            my $method_type := try { nqp::lc($code_obj.HOW.name($code_obj)) } // 'method';
            nqp::die("Package '"
              ~ self.name($obj)
              ~ "' already has a "
              ~ $method_type
              ~ " '"
              ~ $name
              ~ "' (did you mean to declare a multi-method?)");
        }

        # Add to correct table depending on if it's a Submethod.
        if !nqp::isnull(Perl6::Metamodel::Configuration.submethod_type)
            && nqp::istype($code_obj, Perl6::Metamodel::Configuration.submethod_type) {
            %!submethods{$name} := $code_obj;
        }
        else {
            %!methods{$name} := $code_obj;
        }

        # Adding a method means any cache is no longer authoritative.
        nqp::setmethcacheauth($obj, 0);
        %!cache := {};
        @!method_order[+@!method_order] := $code_obj;
        @!method_names[+@!method_names] := $name;
    }

    # Gets the method hierarchy.
    method methods($obj, :$local, :$excl, :$all) {
        # Always need local methods on the list.
        my @meths;
        for @!method_order {
            @meths.push(nqp::hllizefor($_, 'perl6'));
{'fraction_non_alphanumeric': 0.13570717131474103, 'fraction_numerical': 0.00249003984063745, 'mean_word_length': 2.25, 'pattern_counts': {'":': 0, '<': 3, '<?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': '6632589', 'n_tokens_mistral': 1277, 'n_tokens_neox': 1238, 'n_words': 345}