<commit_before># for our tantrums
my class X::Comp::NYI { ... };
my class X::Comp::Trait::Unknown { ... };
my class X::Comp::Trait::NotOnNative { ... };
my class X::Comp::Trait::Scope { ... };

# Variable traits come here, not in traits.pm, since we declare Variable
# in the setting rather than BOOTSTRAP.

my class Variable {
    has str $.name;
    has str $.scope;
    has $.var is rw;
    has $.block;
    has $.slash;

    # make throwing easier
    submethod throw ( |c ) {
        $*W.throw( self.slash, |c );
    }

    submethod willdo(&block, $caller-levels = 3) {
        $caller-levels == 3
            ?? -> { block(nqp::atkey(nqp::ctxcaller(nqp::ctxcaller(nqp::ctxcaller(nqp::ctx()))), self.name)) }
            !! -> { block(nqp::atkey(nqp::ctxcaller(nqp::ctx()), self.name)) }
    }
}

# "is" traits
multi sub trait_mod:<is>(Variable:D $v, |c ) {
    $v.throw( 'X::Comp::Trait::Unknown',
      type      => 'is',
      subtype   => c.hash.keys[0],
      declaring => ' variable',
      expected  => <TypeObject default dynamic>,
    );
}
multi sub trait_mod:<is>(Variable:D $v, Mu :$default!) {
    my $var  := $v.var;
    my $what := $var.VAR.WHAT;

    my $descriptor;
    try {
        $descriptor := nqp::getattr($var, $what.^mixin_base, '$!descriptor');
        CATCH {
            nqp::istype($default,Whatever)
              ?? $v.throw( 'X::Comp::NYI',
                :feature<is default(*) on natives> )
              !! $v.throw( 'X::Comp::Trait::NotOnNative',
                :type<is>, :subtype<default> ); # can't find out native type yet
        }
    }

    my $of := $descriptor.of;
    $v.throw( 'X::Parameter::Default::TypeCheck',
      :expected($var.WHAT), :got($default =:= Nil ?? 'Nil' !! $default) )
      unless nqp::istype($default, $of) or $default =:= Nil or $of =:= Mu;
    $descriptor.set_default(nqp::decont($default));

    # make sure we start with the default if a scalar
    $var = $default if nqp::istype($what, Scalar);
}
multi sub trait_mod:<is>(Variable:D $v, :$dynamic!) {
    my $var  := $v.var;
    my $what := $var.VAR.WHAT;
    try { nqp::getattr(
            $var,
            $what.^mixin_base,
            '$!descriptor',
          ).set_dynamic($dynamic);
        CATCH {
            $v.throw( 'X::Comp::Trait::NotOnNative',
              :type<is>, :subtype<dynamic> ); # can't find out native type yet
        }
    }
}
multi sub trait_mod:<is>(Variable:D $v, :$export!) {
    if $v.scope ne 'our' {
        $v.throw( 'X::Comp::Trait::Scope',
          type      => 'is',
          subtype   => 'export',
          declaring => 'variable',
          scope     => $v.scope,
          supported => ['our'],
        );
    }
    my $var  := $v.var;
    my @tags = flat 'ALL', (nqp::istype($export,Pair) ?? $export.key() !!
                            nqp::istype($export,Positional) ?? @($export)>>.key !!
                            'DEFAULT');
    Rakudo::Internals.EXPORT_SYMBOL($var.VAR.name, @tags, $var);
}<commit_msg>We don't need a try to have a CATCH<commit_after># for our tantrums
my class X::Comp::NYI { ... };
my class X::Comp::Trait::Unknown { ... };
my class X::Comp::Trait::NotOnNative { ... };
my class X::Comp::Trait::Scope { ... };

# Variable traits come here, not in traits.pm, since we declare Variable
# in the setting rather than BOOTSTRAP.

my class Variable {
    has str $.name;
    has str $.scope;
    has $.var is rw;
    has $.block;
    has $.slash;

    # make throwing easier
    submethod throw ( |c ) {
        $*W.throw( self.slash, |c );
    }

    submethod willdo(&block, $caller-levels = 3) {
        $caller-levels == 3
            ?? -> { block(nqp::atkey(nqp::ctxcaller(nqp::ctxcaller(nqp::ctxcaller(nqp::ctx()))), self.name)) }
            !! -> { block(nqp::atkey(nqp::ctxcaller(nqp::ctx()), self.name)) }
    }
}

# "is" traits
multi sub trait_mod:<is>(Variable:D $v, |c ) {
    $v.throw( 'X::Comp::Trait::Unknown',
      type      => 'is',
      subtype   => c.hash.keys[0],
      declaring => ' variable',
      expected  => <TypeObject default dynamic>,
    );
}
multi sub trait_mod:<is>(Variable:D $v, Mu :$default!) {
    my $var  := $v.var;
    my $what := $var.VAR.WHAT;

    my $descriptor;
    {
        $descriptor := nqp::getattr($var, $what.^mixin_base, '$!descriptor');
        CATCH {
            nqp::istype($default,Whatever)
              ?? $v.throw( 'X::Comp::NYI',
                :feature<is default(*) on natives> )
              !! $v.throw( 'X::Comp::Trait::NotOnNative',
                :type<is>, :subtype<default> ); # can't find out native type yet
        }
    }

    my $of := $descriptor.of;
    $v.throw( 'X::Parameter::Default::TypeCheck',
      :expected($var.WHAT), :got($default =:= Nil ?? 'Nil' !! $default) )
      unless nqp::istype($default, $of) or $default =:= Nil or $of =:= Mu;
    $descriptor.set_default(nqp::decont($default));

    # make sure we start with the default if a scalar
    $var = $default if nqp::istype($what, Scalar);
}
multi sub trait_mod:<is>(Variable:D $v, :$dynamic!) {
    my $var  := $v.var;
    my $what := $var.VAR.WHAT;
    { nqp::getattr(
            $var,
            $what.^mixin_base,
            '$!descriptor',
          ).set_dynamic($dynamic);
        CATCH {
            $v.throw( 'X::Comp::Trait::NotOnNative',
              :type<is>, :subtype<dynamic> ); # can't find out native type yet
        }
    }
}
multi sub trait_mod:<is>(Variable:D $v, :$export!) {
    if $v.scope ne 'our' {
        $v.throw( 'X::Comp::Trait::Scope',
          type      => 'is',
          subtype   => 'export',
          declaring => 'variable',
          scope     => $v.scope,
          supported => ['our'],
        );
    }
    my $var  := $v.var;
    my @tags = flat 'ALL', (nqp::istype($export,Pair) ?? $export.key() !!
                            nqp::istype($export,Positional) ?? @($export)>>.key !!
                            'DEFAULT');
    Rakudo::Internals.EXPORT_SYMBOL($var.VAR.name, @tags, $var);
}
{'fraction_non_alphanumeric': 0.1911519198664441, 'fraction_numerical': 0.001001669449081803, 'mean_word_length': 2.2899505766062602, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 49, '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': '6919365', 'n_tokens_mistral': 2098, 'n_tokens_neox': 2037, 'n_words': 454}