Skip to content

Instantly share code, notes, and snippets.

@kalkin
Last active March 6, 2016 13:41
Show Gist options
  • Save kalkin/7e3492ac9c47f749fea5 to your computer and use it in GitHub Desktop.
Save kalkin/7e3492ac9c47f749fea5 to your computer and use it in GitHub Desktop.
my role X::Comp { ... }
my class X::ControlFlow { ... }
my class Exception {
has $!ex;
has $!bt;
method backtrace(Exception:D:) {
if $!bt { $!bt }
elsif nqp::isconcrete($!ex) {
nqp::bindattr(self, Exception, '$!bt', Backtrace.new($!ex));
}
else { '' }
}
# Only valid if .backtrace has not been called yet
method vault-backtrace(Exception:D:) {
nqp::isconcrete($!ex) && $!bt ?? Backtrace.new($!ex) !! ''
}
method reset-backtrace(Exception:D:) {
nqp::bindattr(self, Exception, '$!ex', Nil)
}
multi method Str(Exception:D:) {
my $str;
if nqp::isconcrete($!ex) {
my str $message = nqp::getmessage($!ex);
$str = nqp::isnull_s($message) ?? '' !! nqp::p6box_s($message);
}
$str ||= (try self.?message);
$str = ~$str if defined $str;
$str // "Something went wrong in {self.WHAT.gist}";
}
multi method gist(Exception:D:) {
my $str;
if nqp::isconcrete($!ex) {
my str $message = nqp::getmessage($!ex);
$str = nqp::isnull_s($message)
?? "Died with {self.^name}"
!! nqp::p6box_s($message);
$str ~= "\n";
try $str ~= self.backtrace
|| Backtrace.new()
|| ' (no backtrace available)';
}
else {
$str = (try self.?message) // "Unthrown {self.^name} with no message";
}
$str;
}
method throw(Exception:D: $bt?) {
nqp::bindattr(self, Exception, '$!ex', nqp::newexception())
unless nqp::isconcrete($!ex) and $bt;
nqp::bindattr(self, Exception, '$!bt', $bt); # Even if !$bt
nqp::setpayload($!ex, nqp::decont(self));
my $msg := try self.?message;
if defined($msg) {
$msg := try ~$msg;
}
$msg := $msg // "{self.^name} exception produced no message";
nqp::setmessage($!ex, nqp::unbox_s($msg));
nqp::throw($!ex)
}
method rethrow(Exception:D:) {
nqp::setpayload($!ex, nqp::decont(self));
nqp::rethrow($!ex)
}
method resumable(Exception:D:) {
nqp::p6bool(nqp::istrue(nqp::atkey($!ex, 'resume')));
}
method resume(Exception:D: --> True) {
nqp::resume($!ex);
}
method die(Exception:D:) { self.throw }
method fail(Exception:D:) {
try self.throw;
my $fail := Failure.new($!);
my Mu $return := nqp::getlexrel(nqp::ctxcallerskipthunks(nqp::ctx()), 'RETURN');
$return($fail) unless nqp::isnull($return);
$fail.exception.throw
}
method is-compile-time { False }
}
my class X::SecurityPolicy is Exception {}
my class X::SecurityPolicy::Eval is X::SecurityPolicy {
has $.payload = "EVAL is a very dangerous function!!!";
my role SlurpySentry { }
method message() {
do {
# Remove spaces for die(*@msg)/fail(*@msg) forms
given $.payload {
when SlurpySentry {
$_.list.join;
}
default {
.Str;
}
}
} ~ " (use MONKEY-SEE-NO-EVAL to override,\nbut only if you're VERY sure your data contains no injection attacks)";
}
method Numeric() { $.payload.Numeric }
method from-slurpy (|cap) {
self.new(:payload(cap does SlurpySentry))
}
}
my class X::AdHoc is Exception {
has $.payload = "Unexplained error";
my role SlurpySentry { }
method message() {
# Remove spaces for die(*@msg)/fail(*@msg) forms
given $.payload {
when SlurpySentry {
$_.list.join;
}
default {
.Str;
}
}
}
method Numeric() { $.payload.Numeric }
method from-slurpy (|cap) {
self.new(:payload(cap does SlurpySentry))
}
}
my class X::NQP::NotFound is Exception {
has $.op;
method message() {
"Could not find nqp::$.op, did you forget 'use nqp;' ?"
}
}
my class X::Dynamic::NotFound is Exception {
has $.name;
method message() {
"Dynamic variable $.name not found";
}
}
my class X::Method::NotFound is Exception {
has $.invocant;
has $.method;
has $.typename;
has Bool $.private = False;
method message() {
my $message = $.private
?? "No such private method '$.method' for invocant of type '$.typename'"
!! "No such method '$.method' for invocant of type '$.typename'";
if $.method eq 'length' {
$message ~= "\nDid you mean 'elems', 'chars', 'graphs' or 'codes'?";
}
elsif $.method eq 'bytes' {
$message ~= "\nDid you mean '.encode(\$encoding).bytes'?";
}
$message;
}
}
my class X::Method::InvalidQualifier is Exception {
has $.method;
has $.invocant;
has $.qualifier-type;
method message() {
"Cannot dispatch to method $.method on {$.qualifier-type.^name} "
~ "because it is not inherited or done by {$.invocant.^name}";
}
}
my class X::Role::Parametric::NoSuchCandidate is Exception {
has Mu $.role;
method message {
"No appropriate parametric role variant available for '"
~ $.role.^name
~ "'";
}
}
my class X::Pragma::NoArgs is Exception {
has $.name;
method message { "The '$.name' pragma does not take any arguments." }
}
my class X::Pragma::CannotPrecomp is Exception {
has $.what = 'This compilation unit';
method message { "$.what may not be pre-compiled" }
}
my class X::Pragma::CannotWhat is Exception {
has $.what;
has $.name;
method message { "'$.what $.name' is not an option." }
}
my class X::Pragma::MustOneOf is Exception {
has $.name;
has $.alternatives;
method message { "'$.name' pragma expects one parameter out of $.alternatives." }
}
my class X::Pragma::UnknownArg is Exception {
has $.name;
has $.arg;
method message { "Unknown argument '{$.arg.perl}' specified with the '$.name' pragma." }
}
my class X::Pragma::OnlyOne is Exception {
has $.name;
method message { "The '$.name' pragma only takes one argument." }
}
my role X::Control is Exception {
}
my class CX::Next does X::Control {
method message() { "<next control exception>" }
}
my class CX::Redo does X::Control {
method message() { "<redo control exception>" }
}
my class CX::Last does X::Control {
method message() { "<last control exception>" }
}
my class CX::Take does X::Control {
method message() { "<take control exception>" }
}
my class CX::Warn does X::Control {
has $.message;
}
my class CX::Succeed does X::Control {
method message() { "<succeed control exception>" }
}
my class CX::Proceed does X::Control {
method message() { "<proceed control exception>" }
}
sub EXCEPTION(|) {
my Mu $vm_ex := nqp::shift(nqp::p6argvmarray());
my Mu $payload := nqp::getpayload($vm_ex);
if nqp::p6bool(nqp::istype($payload, Exception)) {
nqp::bindattr($payload, Exception, '$!ex', $vm_ex);
$payload;
} else {
my int $type = nqp::getextype($vm_ex);
my $ex;
if $type == nqp::const::CONTROL_NEXT {
$ex := CX::Next.new();
}
elsif $type == nqp::const::CONTROL_REDO {
$ex := CX::Redo.new();
}
elsif $type == nqp::const::CONTROL_LAST {
$ex := CX::Last.new();
}
elsif $type == nqp::const::CONTROL_TAKE {
$ex := CX::Take.new();
}
elsif $type == nqp::const::CONTROL_WARN {
my str $message = nqp::getmessage($vm_ex);
$message = 'Warning' if nqp::isnull_s($message) || $message eq '';
$ex := CX::Warn.new(:$message);
}
elsif $type == nqp::const::CONTROL_SUCCEED {
$ex := CX::Succeed.new();
}
elsif $type == nqp::const::CONTROL_PROCEED {
$ex := CX::Proceed.new();
}
elsif !nqp::isnull_s(nqp::getmessage($vm_ex)) &&
nqp::p6box_s(nqp::getmessage($vm_ex)) ~~ /"Method '" (.*?) "' not found for invocant of class '" (.+)\'$/ {
$ex := X::Method::NotFound.new(
method => ~$0,
typename => ~$1,
);
}
else {
$ex := nqp::create(X::AdHoc);
nqp::bindattr($ex, X::AdHoc, '$!payload', nqp::p6box_s(nqp::getmessage($vm_ex)));
}
nqp::bindattr($ex, Exception, '$!ex', $vm_ex);
$ex;
}
}
my class X::Comp::AdHoc { ... }
sub COMP_EXCEPTION(|) {
my Mu $vm_ex := nqp::shift(nqp::p6argvmarray());
my Mu $payload := nqp::getpayload($vm_ex);
if nqp::p6bool(nqp::istype($payload, Exception)) {
nqp::bindattr($payload, Exception, '$!ex', $vm_ex);
$payload;
} else {
my $ex := nqp::create(X::Comp::AdHoc);
nqp::bindattr($ex, Exception, '$!ex', $vm_ex);
nqp::bindattr($ex, X::AdHoc, '$!payload', nqp::p6box_s(nqp::getmessage($vm_ex)));
$ex;
}
}
do {
sub print_exception(|) {
my Mu $ex := nqp::atpos(nqp::p6argvmarray(), 0);
try {
my $e := EXCEPTION($ex);
my $v := $e.vault-backtrace;
my Mu $err := nqp::getstderr();
$e.backtrace; # This is where most backtraces actually happen
if $e.is-compile-time || $e.backtrace && $e.backtrace.is-runtime {
if so Rakudo::Internals.NUMERIC-ENV-KEY(<RAKUDO_ONLY_ROBOTS>) {
nqp::printfh($err, $e.filename ~ ':' ~ $e.line ~ ',' ~ $e.column ~ '⇒' ~ $e.message ~ "\n");
} else {
nqp::printfh($err, $e.gist);
nqp::printfh($err, "\n");
if $v {
nqp::printfh($err, "Actually thrown at:\n");
nqp::printfh($err, $v.Str);
nqp::printfh($err, "\n");
}
}
}
elsif Rakudo::Internals.VERBATIM-EXCEPTION(0) {
nqp::printfh($err, $e.Str);
}
else {
if so Rakudo::Internals.NUMERIC-ENV-KEY(<RAKUDO_ONLY_ROBOTS>) {
nqp::printfh($err, $e.filename ~ ':' ~ $e.line ~ ',' ~ $e.column ~ '⇒' ~ $e.message ~ "\n");
} else {
nqp::printfh($err, "===SORRY!===\n");
nqp::printfh($err, $e.Str);
nqp::printfh($err, "\n");
}
}
Rakudo::Internals.THE_END();
CONTROL { when CX::Warn { .resume } }
}
if $! {
nqp::rethrow(nqp::getattr(nqp::decont($!), Exception, '$!ex'));
$ex
}
}
sub print_control(|) {
my Mu $ex := nqp::atpos(nqp::p6argvmarray(), 0);
my int $type = nqp::getextype($ex);
my $backtrace = Backtrace.new(nqp::backtrace($ex), 0);
if ($type == nqp::const::CONTROL_WARN) {
my Mu $err := nqp::getstderr();
my $msg = nqp::p6box_s(nqp::getmessage($ex));
nqp::printfh($err, $msg.chars ?? "$msg" !! "Warning");
nqp::printfh($err, $backtrace.first-none-setting-line);
nqp::resume($ex)
}
if $type == nqp::const::CONTROL_LAST {
X::ControlFlow.new(illegal => 'last', enclosing => 'loop construct', :$backtrace).throw;
}
elsif $type == nqp::const::CONTROL_NEXT {
X::ControlFlow.new(illegal => 'next', enclosing => 'loop construct', :$backtrace).throw;
}
elsif $type == nqp::const::CONTROL_REDO {
X::ControlFlow.new(illegal => 'redo', enclosing => 'loop construct', :$backtrace).throw;
}
elsif $type == nqp::const::CONTROL_PROCEED {
X::ControlFlow.new(illegal => 'proceed', enclosing => 'when clause', :$backtrace).throw;
}
elsif $type == nqp::const::CONTROL_SUCCEED {
# XXX: should work like leave() ?
X::ControlFlow.new(illegal => 'succeed', enclosing => 'when clause', :$backtrace).throw;
}
elsif $type == nqp::const::CONTROL_TAKE {
X::ControlFlow.new(illegal => 'take', enclosing => 'gather', :$backtrace).throw;
}
elsif $type == nqp::const::CONTROL_EMIT {
X::ControlFlow.new(illegal => 'emit', enclosing => 'supply or react', :$backtrace).throw;
}
elsif $type == nqp::const::CONTROL_DONE {
X::ControlFlow.new(illegal => 'done', enclosing => 'supply or react', :$backtrace).throw;
}
else {
X::ControlFlow.new(illegal => 'control exception', enclosing => 'handler', :$backtrace).throw;
}
}
my Mu $comp := nqp::getcomp('perl6');
$comp.^add_method('handle-exception',
method (|) {
my Mu $ex := nqp::atpos(nqp::p6argvmarray(), 1);
print_exception($ex);
nqp::exit(1);
0;
}
);
$comp.^add_method('handle-control',
method (|) {
my Mu $ex := nqp::atpos(nqp::p6argvmarray(), 1);
print_control($ex);
nqp::rethrow($ex);
}
);
}
my role X::OS is Exception {
has $.os-error;
method message() { $.os-error }
}
my role X::IO does X::OS { };
my class X::IO::Unknown does X::IO {
has $.trying;
method message { "Unknown IO error trying '$.trying'" }
}
my class X::IO::Rename does X::IO {
has $.from;
has $.to;
method message() {
"Failed to rename '$.from' to '$.to': $.os-error"
}
}
my class X::IO::Copy does X::IO {
has $.from;
has $.to;
method message() {
"Failed to copy '$.from' to '$.to': $.os-error"
}
}
my class X::IO::Move does X::IO {
has $.from;
has $.to;
method message() {
"Failed to move '$.from' to '$.to': $.os-error"
}
}
my class X::IO::DoesNotExist does X::IO {
has $.path;
has $.trying;
method message() {
"Failed to find '$.path' while trying to do '.$.trying'"
}
}
my class X::IO::NotAFile does X::IO {
has $.path;
has $.trying;
method message() {
"'$.path' is not a regular file while trying to do '.$.trying'"
}
}
my class X::IO::Directory does X::IO {
has $.path;
has $.trying;
has $.use;
method message () {
my $x = "'$.path' is a directory, cannot do '.$.trying' on a directory";
if $.use { $x ~= ", try '{$.use}()' instead" }
$x;
}
}
my class X::IO::Symlink does X::IO {
has $.target;
has $.name;
method message() {
"Failed to create symlink called '$.name' on target '$.target': $.os-error"
}
}
my class X::IO::Link does X::IO {
has $.target;
has $.name;
method message() {
"Failed to create link called '$.name' on target '$.target': $.os-error"
}
}
my class X::IO::Mkdir does X::IO {
has $.path;
has $.mode;
method message() {
"Failed to create directory '$.path' with mode '0o{$.mode.fmt("%03o")}': $.os-error"
}
}
my class X::IO::Chdir does X::IO {
has $.path;
method message() {
"Failed to change the working directory to '$.path': $.os-error"
}
}
my class X::IO::Dir does X::IO {
has $.path;
method message() {
"Failed to get the directory contents of '$.path': $.os-error"
}
}
my class X::IO::Cwd does X::IO {
method message() {
"Failed to get the working directory: $.os-error"
}
}
my class X::IO::Rmdir does X::IO {
has $.path;
method message() {
"Failed to remove the directory '$.path': $.os-error"
}
}
my class X::IO::Unlink does X::IO {
has $.path;
method message() {
"Failed to remove the file '$.path': $.os-error"
}
}
my class X::IO::Chmod does X::IO {
has $.path;
has $.mode;
method message() {
"Failed to set the mode of '$.path' to '0o{$.mode.fmt("%03o")}': $.os-error"
}
}
my role X::Comp is Exception {
has $.filename;
has $.pos;
has $.line;
has $.column;
has @.modules;
has $.is-compile-time = False;
has $.pre;
has $.post;
has @.highexpect;
multi method gist(::?CLASS:D: :$sorry = True, :$expect = True) {
if $.is-compile-time {
my ($red,$clear,$green,$yellow,$eject) =
Rakudo::Internals.error-rcgye;
my $r = $sorry ?? self.sorry_heading() !! "";
$r ~= "$.message\nat $.filename():$.line";
$r ~= "\n------> $green$.pre$yellow$eject$red$.post$clear" if defined $.pre;
if $expect && @.highexpect {
$r ~= "\n expecting any of:";
for @.highexpect {
$r ~= "\n $_";
}
}
for @.modules.reverse[1..*] {
my $line = nqp::p6box_i($_<line>);
$r ~= $_<module>.defined
?? "\n from module $_<module> ($_<filename> line $line)"
!! "\n from $_<filename> line $line";
}
$r;
}
else {
self.Exception::gist;
}
}
method sorry_heading() {
my ($red, $clear) = Rakudo::Internals.error-rcgye;
"$red==={$clear}SORRY!$red===$clear Error while compiling $.filename\n"
}
method SET_FILE_LINE($file, $line) {
$!filename = $file;
$!line = $line;
$!is-compile-time = True;
}
}
my class X::Comp::Group is Exception {
has $.panic;
has @.sorrows;
has @.worries;
method is-compile-time() { True }
multi method gist(::?CLASS:D:) {
my $r = "";
if $.panic || @.sorrows {
my ($red, $clear) = Rakudo::Internals.error-rcgye;
$r ~= "$red==={$clear}SORRY!$red===$clear\n";
for @.sorrows {
$r ~= .gist(:!sorry, :!expect) ~ "\n";
}
if $.panic {
$r ~= $.panic.gist(:!sorry) ~ "\n";
}
}
if @.worries {
$r ~= $.panic || @.sorrows
?? "Other potential difficulties:\n"
!! "Potential difficulties:\n";
for @.worries {
$r ~= .gist(:!sorry, :!expect).indent(4) ~ "\n";
}
}
$r
}
method message() {
my @m;
for @.sorrows {
@m.append(.message);
}
if $.panic {
@m.append($.panic.message);
}
for @.worries {
@m.append(.message);
}
@m.join("\n")
}
}
my role X::MOP is Exception { }
my class X::Comp::BeginTime does X::Comp {
has $.use-case;
has $.exception;
method message() {
$!exception ~~ X::MOP
?? $!exception.message
!! "An exception occurred while $!use-case"
}
multi method gist(::?CLASS:D: :$sorry = True) {
my $r = $sorry ?? self.sorry_heading() !! "";
$r ~= "$.message\nat $.filename():$.line";
for @.modules.reverse[1..*] {
my $line = nqp::p6box_i($_<line>);
$r ~= $_<module>.defined
?? "\n from module $_<module> ($_<filename> line $line)"
!! "\n from $_<filename> line $line";
}
unless $!exception ~~ X::MOP {
$r ~= "\nException details:\n" ~ $!exception.gist.indent(2);
}
$r;
}
}
# XXX a hack for getting line numbers from exceptions from the metamodel
my class X::Comp::AdHoc is X::AdHoc does X::Comp {
method is-compile-time() { True }
}
my class X::Comp::FailGoal does X::Comp {
has $.dba;
has $.goal;
method is-compile-time() { True }
method message { "Unable to parse expression in $.dba; couldn't find final $.goal" }
}
my role X::Syntax does X::Comp { }
my role X::Pod { }
my class X::NYI is Exception {
has $.feature;
method message() { "$.feature not yet implemented. Sorry. " }
}
my class X::Comp::NYI is X::NYI does X::Comp { };
my class X::NYI::Available is X::NYI {
has @.available = die("Must give :available<modules> for installation. ");
method available-str {
my @a = @.available;
my $a = @a.pop;
@a ?? (@a.join(', ') || (), $a).join(" or ") !! $a;
}
method message() {
"Please install { self.available-str } for $.feature support. "
}
}
my class X::NYI::BigInt is Exception {
has $.op;
has $.big;
has $.side = 'right';
method message() {
"Big integer $!big not yet supported on {$!side}hand side of '$!op' operator"
}
}
my class X::Experimental does X::Comp {
has $.feature;
has $.use = $!feature;
method message() { "Use of $.feature is experimental; please 'use experimental :$.use'" }
}
my class X::Worry is Exception { }
my class X::Worry::P5 is X::Worry { }
my class X::Worry::P5::Reference is X::Worry::P5 {
method message {
q/To pass an array, hash or sub to a function in Perl 6, just pass it as is.
For other uses of Perl 5's ref operator consider binding with ::= instead.
Parenthesize as \\(...) if you intended a capture of a single variable./
}
}
my class X::Worry::P5::BackReference is X::Worry::P5 {
method message {
q/To refer to a positional match capture, just use $0 (numbering starts at 0).
Parenthesize as \\(...) if you intended a capture of a single numeric value./
}
}
my class X::Worry::P5::LeadingZero is X::Worry::P5 {
has $.value;
method message {
qq/Leading 0 does not indicate octal in Perl 6.
Please use 0o$!value if you mean that./
}
}
my class X::Trait::Unknown is Exception {
has $.type; # is, will, of etc.
has $.subtype; # wrong subtype being tried
has $.declaring; # variable, sub, parameter, etc.
method message () {
"Can't use unknown trait '$.type $.subtype' in a$.declaring declaration."
}
}
my class X::Comp::Trait::Unknown is X::Trait::Unknown does X::Comp { };
my class X::Trait::NotOnNative is Exception {
has $.type; # is, will, of etc.
has $.subtype; # wrong subtype being tried
has $.native; # type of native (optional)
method message () {
"Can't use trait '$.type $.subtype' on a native"
~ ( $.native ?? " $.native." !! "." );
}
}
my class X::Comp::Trait::NotOnNative is X::Trait::NotOnNative does X::Comp { };
my class X::Trait::Scope is Exception {
has $.type; # is, will, of etc.
has $.subtype; # export
has $.declaring; # type name of the object
has $.scope; # not supported (but used) scope
has $.supported; # hint about what is allowed instead
method message () {
"Can't apply trait '$.type $.subtype' on a $.scope scoped $.declaring."
~ ( $.supported ?? " Only {$.supported.join(' and ')} scoped {$.declaring}s are supported." !! '' );
}
}
my class X::Comp::Trait::Scope is X::Trait::Scope does X::Comp { };
my class X::OutOfRange is Exception {
has $.what = 'Argument';
has $.got = '<unknown>';
has $.range = '<unknown>';
has $.comment;
method message() {
my $result = $.comment.defined
?? "$.what out of range. Is: $.got, should be in $.range.gist(); $.comment"
!! "$.what out of range. Is: $.got, should be in $.range.gist()";
$result;
}
}
my class X::Buf::AsStr is Exception {
has $.method;
method message() {
"Cannot use a Buf as a string, but you called the $.method method on it";
}
}
my class X::Buf::Pack is Exception {
has $.directive;
method message() {
"Unrecognized directive '$.directive'";
}
}
my class X::Buf::Pack::NonASCII is Exception {
has $.char;
method message() {
"non-ASCII character '$.char' while processing an 'A' template in pack";
}
}
my class X::Signature::Placeholder does X::Comp {
has $.placeholder;
method message() {
"Placeholder variable '$.placeholder' cannot override existing signature";
}
}
my class X::Placeholder::Block does X::Comp {
has $.placeholder;
method message() {
"Placeholder variable $.placeholder may not be used here because the surrounding block takes no signature";
}
}
my class X::Placeholder::NonPlaceholder does X::Comp {
has $.variable_name;
has $.placeholder;
has $.decl;
method message() {
my $decl = $!decl ?? ' ' ~ $!decl !! '';
"$!variable_name has already been used as a non-placeholder in the surrounding$decl block,\n" ~
" so you will confuse the reader if you suddenly declare $!placeholder here"
}
}
my class X::Placeholder::Mainline is X::Placeholder::Block {
method message() {
"Cannot use placeholder parameter $.placeholder in the mainline"
}
}
my class X::Placeholder::Attribute is X::Placeholder::Block {
method message() {
"Cannot use placeholder parameter $.placeholder in an attribute initializer"
}
}
my class X::Undeclared does X::Comp {
has $.what = 'Variable';
has $.symbol;
has @.suggestions;
method message() {
my $message := "$.what '$.symbol' is not declared";
if +@.suggestions == 1 {
$message := "$message. Did you mean '@.suggestions[0]'?";
} elsif +@.suggestions > 1 {
$message := "$message. Did you mean any of these?\n { @.suggestions.join("\n ") }\n";
}
$message;
}
}
my class X::Attribute::Undeclared is X::Undeclared {
has $.package-kind;
has $.package-name;
method message() {
"Attribute $.symbol not declared in $.package-kind $.package-name";
}
}
my class X::Attribute::Regex is X::Undeclared {
method message() {
"Attribute $.symbol not available inside of a regex, since regexes are methods on Cursor.\n" ~
"Consider storing the attribute in a lexical, and using that in the regex.";
}
}
my class X::Undeclared::Symbols does X::Comp {
has %.post_types;
has %.unk_types;
has %.unk_routines;
has %.routine_suggestion;
has %.type_suggestion;
multi method gist(X::Undeclared::Symbols:D: :$sorry = True) {
($sorry ?? self.sorry_heading() !! "") ~ self.message
}
method message(X::Undeclared::Symbols:D:) {
sub l(@l) {
my @lu = @l.map({ nqp::hllize($_) }).unique.sort;
'used at line' ~ (@lu == 1 ?? ' ' !! 's ') ~ @(', ')
}
sub s(@s) {
"Did you mean '{ @s.join("', '") }'?";
}
my Str @r;
if %.post_types {
@r <== "Illegally post-declared type" ~ (%.post_types.elems == 1 ?? "" !! "s") ~ ":";
for %.post_types.sort(*.key) {
@r <== " $_.key() &l($_.value)";
}
}
if %.unk_types {
@r <== "Undeclared name" ~ (%.unk_types.elems == 1 ?? "" !! "s") ~ ":";
for %.unk_types.sort(*.key) {
@r <== " $_.key() &l($_.value)";
if +%.type_suggestion{$_.key()} {
@r <== ". " ~ s(%.type_suggestion{$_.key()});
}
}
}
if %.unk_routines {
my $obs = {
y => "tr",
qr => "rx",
local => "temp (or dynamic var)",
new => "method call syntax",
foreach => "for",
}
if self!only-robots {
for %.unk_routines.sort(*.key) -> $routine {
my @l = $routine.value;
my @lu = @l.map({ nqp::hllize($routine) }).unique.sort;
@r <== @lu.join(', ');
}
} else {
@r <== "Undeclared routine" ~ (%.unk_routines.elems == 1 ?? "" !! "s") ~ ":";
for %.unk_routines.sort(*.key) {
@r <== " $_.key() &l($_.value)";
@r <== " (in Perl 6 please use " ~ $obs{$_.key()} ~ " instead)" if $obs{$_.key()};
if +%.routine_suggestion{$_.key()}.list {
@r <== ". " ~ s(%.routine_suggestion{$_.key()}.list);
}
}
}
}
join("\n", @r).trim
}
method !only-robots(){
return so Rakudo::Internals.NUMERIC-ENV-KEY(<RAKUDO_ONLY_ROBOTS>);
}
}
my class X::Redeclaration does X::Comp {
has $.symbol;
has $.postfix = '';
has $.what = 'symbol';
method message() {
"Redeclaration of $.what $.symbol$.postfix";
}
}
my class X::Redeclaration::Outer does X::Comp {
has $.symbol;
method message() {
"Lexical symbol '$.symbol' is already bound to an outer symbol;\n" ~
"the implicit outer binding must be rewritten as OUTER::<$.symbol>\n" ~
"before you can unambiguously declare a new '$.symbol' in this scope";
}
}
my class X::Dynamic::Postdeclaration does X::Comp {
has $.symbol;
method message() {
"Illegal post-declaration of dynamic variable '$.symbol';\n" ~
"earlier access must be written as CALLERS::<$.symbol>\n" ~
"if that's what you meant"
}
}
my class X::Dynamic::Package does X::Comp {
has $.symbol;
method message() {
"Dynamic variables cannot have package-like names, like $!symbol"
}
}
my class X::Import::Redeclaration does X::Comp {
has @.symbols;
has $.source-package-name;
method message() {
@.symbols == 1
?? "Cannot import symbol @.symbols[0] from $.source-package-name, because it already exists in this lexical scope"
!! ("Cannot import the following symbols from $.source-package-name, because they already exist in this lexical scope: ", @.symbols.join(', '));
}
}
my class X::Import::OnlystarProto does X::Comp {
has @.symbols;
has $.source-package-name;
method message() {
@.symbols == 1
?? "Cannot import symbol @.symbols[0] from $.source-package-name, only onlystar-protos can be merged"
!! ("Cannot import the following symbols from $.source-package-name, only onlystar-protos can be merged: ", @.symbols.join(', '));
}
}
my class X::PoisonedAlias does X::Comp {
has $.alias;
has $.package-type = 'package';
has $.package-name;
method message() {
"Cannot use poisoned alias $!alias, because it was declared by several {$!package-type}s." ~
($!package-name ?? "\nPlease access it via explicit package name like: {$!package-name}::{$!alias}" !! '')
}
}
my class X::Phaser::Multiple does X::Comp {
has $.block;
method message() { "Only one $.block block is allowed" }
}
my class X::Obsolete does X::Comp {
has $.old;
has $.replacement; # can't call it $.new, collides with constructor
has $.when = 'in Perl 6';
method message() { "Unsupported use of $.old; $.when please use $.replacement" }
}
my class X::Parameter::Default does X::Comp {
has $.how;
has $.parameter;
method message() {
$.parameter
?? "Cannot put default on $.how parameter $.parameter"
!! "Cannot put default on anonymous $.how parameter";
}
}
my class X::Parameter::Default::TypeCheck does X::Comp {
has $.got is default(Nil);
has $.expected is default(Nil);
method message() {
"Default value '$.got.gist()' will never bind to a parameter of type $.expected.^name()"
}
}
my class X::Parameter::AfterDefault does X::Syntax {
has $.type;
has $.modifier;
has $.default;
method message() {
"The $.type \"$.modifier\" came after the default value\n"
~ "(did you mean \"...$.modifier $.default\"?)"
}
}
my class X::Parameter::Placeholder does X::Comp {
has $.parameter;
has $.right;
method message() {
"In signature parameter, placeholder variables like $.parameter are illegal\n"
~ "you probably meant a named parameter: '$.right'";
}
}
my class X::Parameter::Twigil does X::Comp {
has $.parameter;
has $.twigil;
method message() {
"In signature parameter $.parameter, it is illegal to use the $.twigil twigil";
}
}
my class X::Parameter::MultipleTypeConstraints does X::Comp {
has $.parameter;
method message() {
($.parameter ?? "Parameter $.parameter" !! 'A parameter')
~ " may only have one prefix type constraint";
}
}
my class X::Parameter::BadType does X::Comp {
has Mu $.type;
method message() {
my $what = ~$!type.HOW.WHAT.^name.match(/ .* '::' <(.*)> HOW/) // 'Namespace';
"$what $!type.^name() is insufficiently type-like to qualify a parameter"
}
}
my class X::Parameter::WrongOrder does X::Comp {
has $.misplaced;
has $.parameter;
has $.after;
method message() {
"Cannot put $.misplaced parameter $.parameter after $.after parameters";
}
}
my class X::Parameter::InvalidType does X::Comp {
has $.typename;
has @.suggestions;
method message() {
my $msg := "Invalid typename '$.typename' in parameter declaration.";
if +@.suggestions > 0 {
$msg := $msg ~ " Did you mean '" ~ @.suggestions.join("', '") ~ "'?";
}
$msg;
}
}
my class X::Parameter::RW is Exception {
has $.got;
has $.symbol;
method message() {
"Parameter '$.symbol' expected a writable container, but got $.got.^name() value"
}
}
my class X::Parameter::TypedSlurpy does X::Comp {
has $.kind;
method message() {
"Slurpy $.kind parameters with type constraints are not supported"
}
}
my class X::Signature::NameClash does X::Comp {
has $.name;
method message() {
"Name $.name used for more than one named parameter";
}
}
my class X::Method::Private::Permission does X::Comp {
has $.method;
has $.source-package;
has $.calling-package;
method message() {
"Cannot call private method '$.method' on package $.source-package because it does not trust $.calling-package";
}
}
my class X::Method::Private::Unqualified does X::Comp {
has $.method;
method message() {
"Private method call to $.method must be fully qualified with the package containing the method";
}
}
my class X::Adverb is Exception {
has $.what;
has $.source;
has @.unexpected;
has @.nogo;
method message {
my $text = '';
if @!unexpected.elems -> $elems {
$text = $elems > 1
?? "$elems unexpected adverbs (@.unexpected[])"
!! "Unexpected adverb '@!unexpected[0]'"
}
if @!nogo {
$text ~= $text ?? " and u" !! "U";
$text ~= "nsupported combination of adverbs (@.nogo[])";
}
$text ~ " passed to $!what on $!source";
}
method unexpected { @!unexpected.sort }
method nogo { @!nogo.sort }
}
my class X::Bind is Exception {
has $.target;
method message() {
$.target.defined
?? "Cannot bind to $.target"
!! 'Cannot use bind operator with this left-hand side'
}
}
my class X::Bind::NativeType does X::Comp {
has $.name;
method message() {
"Cannot bind to natively typed variable '$.name'; use assignment instead"
}
}
my class X::Bind::Slice is Exception {
has $.type;
method message() {
"Cannot bind to {$.type.^name} slice";
}
}
my class X::Bind::ZenSlice is X::Bind::Slice {
method message() {
"Cannot bind to {$.type.^name} zen slice";
}
}
my class X::Subscript::Negative is Exception {
has $.index;
has $.type;
method message() {
"Calculated index ({$.index}) is negative, but {$.type.^name} allows only 0-based indexing";
}
}
my class X::Invalid::Value is Exception {
has $.method;
has $.name;
has $.value;
method message {
"Invalid value '$.value' for :$.name on method $.method"
}
}
my class X::Value::Dynamic does X::Comp {
has $.what;
method message() { "$.what value must be known at compile time" }
}
my class X::Syntax::Name::Null does X::Syntax {
method message() { 'Name component may not be null'; }
}
my class X::Syntax::UnlessElse does X::Syntax {
method message() { '"unless" does not take "else", please rewrite using "if"' }
}
my class X::Syntax::KeywordAsFunction does X::Syntax {
has $.word;
has $.needparens;
method message {
"Word '$.word' interpreted as '{$.word}()' function call; please use whitespace "
~ ($.needparens ?? 'around the parens' !! 'instead of parens')
}
}
my class X::Syntax::Malformed::Elsif does X::Syntax {
has $.what = 'else if';
method message() { qq{In Perl 6, please use "elsif' instead of "$.what"} }
}
my class X::Syntax::Reserved does X::Syntax {
has $.reserved;
has $.instead = '';
method message() { "The $.reserved is reserved$.instead" }
}
my class X::Syntax::P5 does X::Syntax {
method message() { 'This appears to be Perl 5 code' }
}
my class X::Syntax::NegatedPair does X::Syntax {
has $.key;
method message() { "Argument not allowed on negated pair with key '$.key'" }
}
my class X::Syntax::Variable::Numeric does X::Syntax {
has $.what = 'variable';
method message() { "Cannot declare a numeric $.what" }
}
my class X::Syntax::Variable::Match does X::Syntax {
method message() { 'Cannot declare a match variable' }
}
my class X::Syntax::Variable::Initializer does X::Syntax {
has $.name = '<anon>';
method message() { "Cannot use variable $!name in declaration to initialize itself" }
}
my class X::Syntax::Variable::Twigil does X::Syntax {
has $.what = 'variable';
has $.twigil;
has $.scope;
has $.additional;
method message() { "Cannot use $.twigil twigil on '$.scope' $.what$.additional" }
}
my class X::Syntax::Variable::IndirectDeclaration does X::Syntax {
method message() { 'Cannot declare a variable by indirect name (use a hash instead?)' }
}
my class X::Syntax::Variable::BadType does X::Comp {
has Mu $.type;
method message() {
my $what = ~$!type.HOW.WHAT.^name.match(/ .* '::' <(.*)> HOW/) // 'Namespace';
"$what $!type.^name() is insufficiently type-like to qualify a variable"
}
}
my class X::Syntax::Variable::ConflictingTypes does X::Comp {
has Mu $.outer;
has Mu $.inner;
method message() {
"$!inner.^name() not allowed here; variable list already declared with type $!outer.^name()"
}
}
my class X::Syntax::Augment::WithoutMonkeyTyping does X::Syntax {
method message() { "augment not allowed without 'use MONKEY-TYPING'" };
}
my class X::Syntax::Augment::Illegal does X::Syntax {
has $.package;
method message() { "Cannot augment $.package because it is closed" };
}
my class X::Syntax::Augment::Adverb does X::Syntax {
method message() { "Cannot put adverbs on a typename when augmenting" }
}
my class X::Syntax::Type::Adverb does X::Syntax {
has $.adverb;
method message() { "Cannot use adverb $.adverb on a type name (only 'ver' and 'auth' are understood)" }
}
my class X::Syntax::Argument::MOPMacro does X::Syntax {
has $.macro;
method message() { "Cannot give arguments to $.macro" };
}
my class X::Role::Initialization is Exception {
has $.role;
method message() { "Can only supply an initialization value for a role if it has a single public attribute, but this is not the case for '{$.role.^name}'" }
}
my class X::Syntax::Comment::Embedded does X::Syntax {
method message() { "Opening bracket required for #` comment" }
}
my class X::Syntax::Pod::BeginWithoutIdentifier does X::Syntax does X::Pod {
method message() {
'=begin must be followed by an identifier; (did you mean "=begin pod"?)'
}
}
my class X::Syntax::Pod::BeginWithoutEnd does X::Syntax does X::Pod {
has $.type;
has $.spaces;
has $.instead;
method message() {
if $.instead {
qq{Expected "=end $.type" to terminate "=begin $.type"; found "=end $.instead" instead.}
} else {
"'=begin' not terminated by matching '$.spaces=end $.type'"
}
}
}
my class X::Syntax::Confused does X::Syntax {
has $.reason = 'unknown';
method message() { $.reason eq 'unknown' ?? 'Confused' !! $.reason }
}
my class X::Syntax::Malformed does X::Syntax {
has $.what;
method message() { "Malformed $.what" }
}
my class X::Syntax::Missing does X::Syntax {
has $.what;
method message() { "Missing $.what" }
}
my class X::Syntax::BlockGobbled does X::Syntax {
has $.what;
method message() {
my $looks_like_type = $.what ~~ /'::' | <[A..Z]><[a..z]>+/;
$.what ~~ /^'is '/
?? "Trait '$.what' needs whitespace before block"
!! "{ $.what ?? "Function '$.what'" !! 'Expression' } needs parens to avoid gobbling block" ~
($looks_like_type ?? " (or perhaps it's a class that's not declared or available in this scope?)" !! "");
};
}
my class X::Syntax::ConditionalOperator::PrecedenceTooLoose does X::Syntax {
has $.operator;
method message() { "Precedence of $.operator is too loose to use inside ?? !!; please parenthesize" }
}
my class X::Syntax::ConditionalOperator::SecondPartGobbled does X::Syntax {
method message() { "Your !! was gobbled by the expression in the middle; please parenthesize" }
}
my class X::Syntax::ConditionalOperator::SecondPartInvalid does X::Syntax {
has $.second-part;
method message() { "Please use !! rather than $.second-part" }
}
my class X::Syntax::Perl5Var does X::Syntax {
has $.name;
my %m =
'$*' => '^^ and $$',
'$"' => '.join() method',
'$$' => '$*PID',
'$(' => '$*GID',
'$)' => '$*EGID',
'$<' => '$*UID',
'$>' => '$*EUID',
'$;' => 'real multidimensional hashes',
'$&' => '$<>',
'$`' => '$/.prematch',
'$\'' => '$/.postmatch',
'$,' => '$*OUT.output_field_separator()',
'$.' => "the filehandle's .ins method",
'$/' => "the filehandle's .nl-in attribute",
'$\\' => "the filehandle's .nl-out attribute",
'$|' => ':autoflush on open',
'$?' => '$! for handling child errors also',
'$@' => '$!',
'$#' => '.fmt',
'$[' => 'user-defined array indices',
'$]' => '$*PERL.version or $*PERL.compiler.version',
'$^C' => 'COMPILING namespace',
'$^D' => '$*DEBUGGING',
'$^E' => '$!.extended_os_error',
'$^F' => '$*SYSTEM_FD_MAX',
'$^H' => '$?FOO variables',
'$^I' => '$*INPLACE',
'$^M' => 'a global form such as $*M',
'$^N' => '$/[*-1]',
'$^O' => '$?DISTRO.name or $*DISTRO.name',
'$^R' => 'an explicit result variable',
'$^S' => 'context function',
'$^T' => '$*INITTIME',
'$^V' => '$*PERL.version or $*PERL.compiler.version',
'$^W' => '$*WARNING',
'$^X' => '$*EXECUTABLE-NAME',
'$:' => 'Form module',
'$-' => 'Form module',
'$+' => 'Form module',
'$=' => 'Form module',
'$%' => 'Form module',
'$^' => 'Form module',
'$~' => 'Form module',
'$^A' => 'Form module',
'$^L' => 'Form module',
'@-' => '.from method',
'@+' => '.to method',
'%-' => '.from method',
'%+' => '.to method',
'%^H' => '$?FOO variables',
;
method message() {
my $v = $.name ~~ m/ <[ $ @ % & ]> [ \^ <[ A..Z ]> | \W ] /;
$v
?? %m{~$v}
?? "Unsupported use of $v variable; in Perl 6 please use {%m{~$v}}"
!! "Unsupported use of $v variable"
!! 'Weird unrecognized variable name: ' ~ $.name;
}
}
my class X::Syntax::Self::WithoutObject does X::Syntax {
method message() { "'self' used where no object is available" }
}
my class X::Syntax::VirtualCall does X::Syntax {
has $.call;
method message() { "Virtual method call $.call may not be used on partially constructed object (maybe you mean {$.call.subst('.','!')} for direct attribute access here?)" }
}
my class X::Syntax::NoSelf does X::Syntax {
has $.variable;
method message() { "Variable $.variable used where no 'self' is available" }
}
my class X::Syntax::Number::RadixOutOfRange does X::Syntax {
has $.radix;
method message() { "Radix $.radix out of range (allowed: 2..36)" }
}
my class X::Syntax::Number::IllegalDecimal does X::Syntax {
method message() { "Decimal point must be followed by digit" }
}
my class X::Syntax::Number::LiteralType does X::Syntax {
has $.varname;
has $.vartype;
has $.value;
has $.valuetype;
has $.suggestiontype;
method message() {
my $vartype := $!vartype.WHAT.^name;
my $value := $!value.perl;
my $val = "Cannot assign a literal of type {$.valuetype} ($value) to a variable of type $vartype. You can declare the variable to be of type $.suggestiontype, or try to coerce the value with { $value ~ '.' ~ $vartype } or $vartype\($value\)";
try $val ~= ", or just write the value as " ~ $!value."$vartype"().perl;
$val;
}
}
my class X::Syntax::NonAssociative does X::Syntax {
has $.left;
has $.right;
method message() {
"Only identical operators may be list associative; since '$.left' and '$.right' differ, they are non-associative and you need to clarify with parentheses";
}
}
my class X::Syntax::CannotMeta does X::Syntax {
has $.meta;
has $.operator;
has $.reason;
has $.dba;
method message() {
"Cannot $.meta $.operator because $.dba operators are $.reason";
}
}
my class X::Syntax::Adverb does X::Syntax {
has $.what;
method message() { "You can't adverb " ~ $.what }
}
my class X::Syntax::Regex::Adverb does X::Syntax {
has $.adverb;
has $.construct;
method message() { "Adverb $.adverb not allowed on $.construct" }
}
my class X::Syntax::Regex::UnrecognizedMetachar does X::Syntax {
has $.metachar;
method message() { "Unrecognized regex metacharacter $.metachar (must be quoted to match literally)" }
}
my class X::Syntax::Regex::UnrecognizedModifier does X::Syntax {
has $.modifier;
method message() { "Unrecognized regex modifier :$.modifier" }
}
my class X::Syntax::Regex::NullRegex does X::Syntax {
method message() { 'Null regex not allowed' }
}
my class X::Syntax::Regex::MalformedRange does X::Syntax {
method message() { 'Malformed Range' }
}
my class X::Syntax::Regex::Unspace does X::Syntax {
has $.char;
method message { "No unspace allowed in regex; if you meant to match the literal character, " ~
"please enclose in single quotes ('" ~ $.char ~ "') or use a backslashed form like \\x" ~
sprintf('%02x', $.char.ord)
}
}
my class X::Syntax::Regex::Unterminated does X::Syntax {
method message { 'Regex not terminated.' }
}
my class X::Syntax::Regex::SpacesInBareRange does X::Syntax {
method message { 'Spaces not allowed in bare range.' }
}
my class X::Syntax::Regex::SolitaryQuantifier does X::Syntax {
method message { 'Quantifier quantifies nothing' }
}
my class X::Syntax::Regex::NonQuantifiable does X::Syntax {
method message { 'Can only quantify a construct that produces a match' }
}
my class X::Syntax::Regex::SolitaryBacktrackControl does X::Syntax {
method message { "Backtrack control ':' does not seem to have a preceding atom to control" }
}
my class X::Syntax::Term::MissingInitializer does X::Syntax {
method message { 'Term definition requires an initializer' }
}
my class X::Syntax::Variable::MissingInitializer does X::Syntax {
has $.type;
has $.implicit;
method message {
$.implicit ??
"Variable definition of type $.type (implicit $.implicit) requires an initializer" !!
"Variable definition of type $.type requires an initializer"
}
}
my class X::Syntax::AddCategorical::TooFewParts does X::Syntax {
has $.category;
has $.needs;
method message() { "Not enough symbols provided for categorical of type $.category; needs $.needs" }
}
my class X::Syntax::AddCategorical::TooManyParts does X::Syntax {
has $.category;
has $.needs;
method message() { "Too many symbols provided for categorical of type $.category; needs only $.needs" }
}
my class X::Syntax::Signature::InvocantMarker does X::Syntax {
method message() {
"Can only use : as invocant marker in a signature after the first parameter"
}
}
my class X::Syntax::Signature::InvocantNotAllowed does X::Syntax {
method message() {
"Can only use the : invocant marker in the signature for a method"
}
}
my class X::Syntax::Extension::Category does X::Syntax {
has $.category;
method message() {
"Cannot add tokens of category '$.category'";
}
}
my class X::Syntax::Extension::Null does X::Syntax {
method message() {
"Null operator is not allowed";
}
}
my class X::Syntax::Extension::TooComplex does X::Syntax {
has $.name;
method message() {
"Colon pair value '$.name' too complex to use in name";
}
}
my class X::Syntax::Extension::SpecialForm does X::Syntax {
has $.category;
has $.opname;
has $.hint;
method message() {
"Cannot override $.category operator '$.opname', as it is a special form " ~
"handled directly by the compiler" ~ ($!hint ?? "\n$!hint" !! "")
}
}
my class X::Syntax::InfixInTermPosition does X::Syntax {
has $.infix;
method message() {
"Preceding context expects a term, but found infix $.infix instead";
}
}
my class X::Syntax::DuplicatedPrefix does X::Syntax {
has $.prefixes;
method message() {
my $prefix = substr($.prefixes,0,1);
"Expected a term, but found either infix $.prefixes or redundant prefix $prefix\n"
~ " (to suppress this message, please use a space like $prefix $prefix)";
}
}
my class X::Attribute::Package does X::Comp {
has $.package-kind;
has $.name;
method message() { "A $.package-kind cannot have attributes, but you tried to declare '$.name'" }
}
my class X::Attribute::NoPackage does X::Comp {
has $.name;
method message() { "You cannot declare attribute '$.name' here; maybe you'd like a class or a role?" }
}
my class X::Attribute::Required does X::MOP {
has $.name;
method message() { "The attribute '$.name' is required, but you did not provide a value for it." }
}
my class X::Declaration::Scope does X::Comp {
has $.scope;
has $.declaration;
method message() { "Cannot use '$.scope' with $.declaration declaration" }
}
my class X::Declaration::Scope::Multi is X::Declaration::Scope {
method message() {
"Cannot use '$.scope' with individual multi candidates. Please declare an {$.scope}-scoped proto instead";
}
}
my class X::Declaration::OurScopeInRole does X::Comp {
has $.declaration;
method message() {
"Cannot declare our-scoped $.declaration inside of a role\n" ~
"(the scope inside of a role is generic, so there is no unambiguous\n" ~
"package to install the symbol in)"
}
}
my class X::Anon::Multi does X::Comp {
has $.multiness;
has $.routine-type = 'routine';
method message() { "An anonymous $.routine-type may not take a $.multiness declarator" }
}
my class X::Anon::Augment does X::Comp {
has $.package-kind;
method message() { "Cannot augment anonymous $.package-kind" }
}
my class X::Augment::NoSuchType does X::Comp {
has $.package-kind;
has $.package;
method message() { "You tried to augment $.package-kind $.package, but it does not exist" }
}
my class X::Routine::Unwrap is Exception {
method message() { "Cannot unwrap routine: invalid wrap handle" }
}
my class X::Constructor::Positional is Exception {
has $.type;
method message() { "Default constructor for '" ~ $.type.^name ~ "' only takes named arguments" }
}
my class X::Hash::Store::OddNumber is Exception {
method message() { "Odd number of elements found where hash initializer expected" }
}
my class X::Pairup::OddNumber is Exception {
method message() { "Odd number of elements found for .pairup()" }
}
my class X::Match::Bool is Exception {
has $.type;
method message() { "Cannot use Bool as Matcher with '" ~ $.type ~ "'. Did you mean to use \$_ inside a block?" }
}
my class X::Package::UseLib does X::Comp {
has $.what;
method message { "Cannot 'use lib' inside a $.what" }
}
my class X::Package::Stubbed does X::Comp {
has @.packages;
# TODO: suppress display of line number
method message() {
"The following packages were stubbed but not defined:\n "
~ @.packages.join("\n ");
}
}
my class X::Phaser::PrePost is Exception {
has $.phaser = 'PRE';
has $.condition;
method message {
my $what = $.phaser eq 'PRE' ?? 'Precondition' !! 'Postcondition';
$.condition.defined
?? "$what '$.condition.trim()' failed"
!! "$what failed";
}
}
my class X::Str::Numeric is Exception {
has $.source;
has $.pos;
has $.reason;
method source-indicator {
my ($red,$clear,$green,$,$eject) = Rakudo::Internals.error-rcgye;
my sub escape($str) { $str.perl.substr(1).chop }
join '', "in '",
$green,
escape(substr($.source,0, $.pos)),
$eject,
$red,
escape(substr($.source,$.pos)),
$clear,
"' (indicated by ",
$eject,
$clear,
")",
;
}
method message() {
"Cannot convert string to number: $.reason $.source-indicator";
}
}
my class X::Str::Match::x is Exception {
has $.got is default(Nil);
method message() {
"in Str.match, got invalid value of type {$.got.^name} for :x, must be Int or Range"
}
}
my class X::Str::Trans::IllegalKey is Exception {
has $.key;
method message {
"in Str.trans, got illegal substitution key of type {$.key.^name} (should be a Regex or Str)"
}
}
my class X::Str::Trans::InvalidArg is Exception {
has $.got is default(Nil);
method message() {
"Only Pair objects are allowed as arguments to Str.trans, got {$.got.^name}";
}
}
my class X::Range::InvalidArg is Exception {
has $.got is default(Nil);
method message() {
"{$.got.^name} objects are not valid endpoints for Ranges";
}
}
my class X::Sequence::Deduction is Exception {
has $.from;
method message() {
$!from ?? "Unable to deduce arithmetic or geometric sequence from $!from (or did you really mean '..'?)"
!! 'Unable to deduce sequence for some unfathomable reason'
}
}
my class X::Cannot::Lazy is Exception {
has $.action;
has $.what;
method message() {
$.what
?? "Cannot $.action a lazy list onto a $.what"
!! "Cannot $.action a lazy list";
}
}
my class X::Cannot::Empty is Exception {
has $.action;
has $.what;
method message() {
"Cannot $.action from an empty $.what";
}
}
my class X::Cannot::New is Exception {
has $.class;
method message() {
"Cannot make a {$.class.^name} object using .new";
}
}
my class X::Backslash::UnrecognizedSequence does X::Syntax {
has $.sequence;
method message() { "Unrecognized backslash sequence: '\\$.sequence'" }
}
my class X::Backslash::NonVariableDollar does X::Syntax {
method message() { "Non-variable \$ must be backslashed" }
}
my class X::ControlFlow is Exception {
has $.illegal; # something like 'next'
has $.enclosing; # .... outside a loop
has $.backtrace; # where the bogus control flow op was
method backtrace() {
$!backtrace || nextsame();
}
method message() { "$.illegal without $.enclosing" }
}
my class X::ControlFlow::Return is X::ControlFlow {
method illegal() { 'return' }
method enclosing() { 'Routine' }
method message() { 'Attempt to return outside of any Routine' }
}
my class X::Composition::NotComposable does X::Comp {
has $.target-name;
has $.composer;
method message() {
$.composer.^name ~ " is not composable, so $.target-name cannot compose it";
}
}
my class X::TypeCheck is Exception {
has $.operation;
has $.got is default(Nil);
has $.expected is default(Nil);
method gotn() {
my $perl = (try $!got.perl) // "?";
$perl = "$perl.substr(0,21)..." if $perl.chars > 24;
(try $!got.^name eq $!expected.^name
?? $perl
!! "$!got.^name() ($perl)"
) // "?"
}
method expectedn() {
(try $!got.^name eq $!expected.^name
?? $!expected.perl
!! $!expected.^name
) // "?"
}
method priors() {
my $prior = do if nqp::isconcrete($!got) && $!got ~~ Failure {
"Earlier failure:\n " ~ $!got.mess ~ "\nFinal error:\n ";
}
else { '' }
$prior;
}
method message() {
self.priors() ~
"Type check failed in $.operation; expected $.expectedn but got $.gotn";
}
}
my class X::TypeCheck::Binding is X::TypeCheck {
has $.symbol;
method operation { 'binding' }
method message() {
if $.symbol {
self.priors() ~
"Type check failed in $.operation $.symbol; expected $.expectedn but got $.gotn";
} else {
self.priors() ~
"Type check failed in $.operation; expected $.expectedn but got $.gotn";
}
}
}
my class X::TypeCheck::Return is X::TypeCheck {
method operation { 'returning' }
method message() {
self.priors() ~
"Type check failed for return value; expected $.expectedn but got $.gotn";
}
}
my class X::TypeCheck::Assignment is X::TypeCheck {
has $.symbol;
method operation { 'assignment' }
method message {
self.priors() ~ do
$.symbol.defined && $.symbol ne '$'
?? "Type check failed in assignment to $.symbol; expected $.expectedn but got $.gotn"
!! "Type check failed in assignment; expected $.expectedn but got $.gotn";
}
}
my class X::TypeCheck::Argument is X::TypeCheck {
has $.protoguilt;
has @.arguments;
has $.objname;
has $.signature;
method message {
my $multi = $!signature ~~ /\n/ // '';
"Calling {$!objname}({ join(', ', @!arguments) }) will never work with " ~ (
$!protoguilt ?? 'proto signature ' !!
$multi ?? 'any of these multi signatures:' !!
'declared signature '
) ~ $!signature;
}
}
my class X::TypeCheck::Splice is X::TypeCheck does X::Comp {
has $.action;
method message {
self.priors() ~
"Type check failed in {$.action}; expected $.expectedn but got $.gotn";
}
}
my class X::Assignment::RO is Exception {
has $.typename = "value";
method message {
"Cannot modify an immutable {$.typename}";
}
}
my class X::Assignment::RO::Comp does X::Comp {
has $.variable;
method message {
"Cannot assign to readonly variable {$.variable}"
}
}
my class X::Immutable is Exception {
has $.typename;
has $.method;
method message {
"Cannot call '$.method' on an immutable '$.typename'";
}
}
my class X::NoDispatcher is Exception {
has $.redispatcher;
method message() {
"$.redispatcher is not in the dynamic scope of a dispatcher";
}
}
my class X::Localizer::NoContainer is Exception {
has $.localizer;
method message() {
"Can only use '$.localizer' on a container";
}
}
my class X::Mixin::NotComposable is Exception {
has $.target;
has $.rolish;
method message() {
"Cannot mix in non-composable type {$.rolish.^name} into object of type {$.target.^name}";
}
}
my class X::Inheritance::Unsupported does X::Comp {
# note that this exception is thrown before the child type object
# has been composed, so it's useless to carry it around. Use the
# name instead.
has $.child-typename;
has $.parent;
method message {
$.parent.^name ~ ' does not support inheritance, so '
~ $.child-typename ~ ' cannot inherit from it';
}
}
my class X::Inheritance::UnknownParent is Exception {
has $.child;
has $.parent;
has @.suggestions is rw;
method message {
my $message := "'" ~ $.child ~ "' cannot inherit from '" ~ $.parent ~ "' because it is unknown.";
if +@.suggestions > 1 {
$message := $message ~ "\nDid you mean one of these?\n '" ~ @.suggestions.join("'\n '") ~ "'\n";
} elsif +@.suggestions == 1 {
$message := $message ~ "\nDid you mean '" ~ @.suggestions[0] ~ "'?\n";
}
$message;
}
}
my class X::Inheritance::SelfInherit is Exception {
has $.name;
method message {
"'$.name' cannot inherit from itself."
}
}
my class X::Export::NameClash does X::Comp {
has $.symbol;
method message() {
"A symbol '$.symbol' has already been exported";
}
}
my class X::HyperOp::NonDWIM is Exception {
has &.operator;
has $.left-elems;
has $.right-elems;
has $.recursing;
method message() {
"Lists on either side of non-dwimmy hyperop of &.operator.name() are not of the same length"
~ " while recursing" x +$.recursing
~ "\nleft: $.left-elems elements, right: $.right-elems elements";
}
}
my class X::HyperOp::Infinite is Exception {
has &.operator;
has $.side;
method message() {
$.side eq "both"
?? "Lists on both sides of hyperop of &.operator.name() are known to be infinite"
!! "List on $.side side of hyperop of &.operator.name() is known to be infinite"
}
}
my class X::Set::Coerce is Exception {
has $.thing;
method message {
"Cannot coerce object of type {$.thing.^name} to Set. To create a one-element set, pass it to the 'set' function";
}
}
my role X::Temporal is Exception { }
my class X::Temporal::InvalidFormat does X::Temporal {
has $.invalid-str;
has $.target = 'Date';
has $.format;
method message() {
"Invalid $.target string '$.invalid-str'; use $.format instead";
}
}
my class X::DateTime::TimezoneClash does X::Temporal {
method message() {
'DateTime.new(Str): :timezone argument not allowed with a timestamp offset';
}
}
my class X::DateTime::InvalidDeltaUnit does X::Temporal {
has $.unit;
method message() {
"Cannnot use unit $.unit with Date.delta";
}
}
my class X::Eval::NoSuchLang is Exception {
has $.lang;
method message() {
"No compiler available for language '$.lang'";
}
}
my class X::Import::MissingSymbols is Exception {
has $.from;
has @.missing;
method message() {
"Trying to import from '$.from', but the following symbols are missing: "
~ @.missing.join(', ');
}
}
my class X::Import::NoSuchTag is Exception {
has $.source-package;
has $.tag;
method message() {
"Error while importing from '$.source-package': no such tag '$.tag'"
}
}
my class X::Import::Positional is Exception {
has $.source-package;
method message() {
"Error while importing from '$.source-package':\n"
~ "no EXPORT sub, but you provided positional argument in the 'use' statement"
}
}
my class X::Numeric::Real is Exception {
has $.target;
has $.reason;
has $.source;
method message() {
"Can not convert $.source to {$.target.^name}: $.reason";
}
}
my class X::Numeric::DivideByZero is Exception {
has $.using;
has $.numerator;
method message() {
"Attempt to divide{$.numerator ?? " $.numerator" !! ''} by zero"
~ ( $.using ?? " using $.using" !! '' );
}
}
my class X::Numeric::Overflow is Exception {
method message() { "Numeric overflow" }
}
my class X::Numeric::Underflow is Exception {
method message() { "Numeric underflow" }
}
my class X::Numeric::Confused is Exception {
has $.num;
has $.base;
method message() {
"This call only converts base-$.base strings to numbers; value {$.num.perl} is of type {$.num.WHAT.^name}, so cannot be converted!\n"
~ "(If you really wanted to convert {$.num.perl} to a base-$.base string, use {$.num.perl}.base($.base) instead.)";
}
}
my class X::PseudoPackage::InDeclaration does X::Comp {
has $.pseudo-package;
has $.action;
method message() {
"Cannot use pseudo package $.pseudo-package in $.action";
}
}
my class X::NoSuchSymbol is Exception {
has $.symbol;
method message { "No such symbol '$.symbol'" }
}
my class X::Item is Exception {
has $.aggregate;
has $.index;
method message { "Cannot index {$.aggregate.^name} with $.index" }
}
my class X::Multi::Ambiguous is Exception {
has $.dispatcher;
has @.ambiguous;
has $.capture;
method message {
join "\n",
"Ambiguous call to '$.dispatcher.name()'; these signatures all match:",
@.ambiguous.map(*.signature.perl)
}
}
my class X::Multi::NoMatch is Exception {
has $.dispatcher;
has $.capture;
method message {
my @cand = $.dispatcher.dispatchees.map(*.signature.gist);
my $where = so first / where /, @cand;
my @bits;
my @priors;
if $.capture {
for $.capture.list {
try @bits.push($where ?? .perl !! .WHAT.perl );
@bits.push($_.^name) if $!;
when Failure {
@priors.push(" " ~ .mess);
}
}
for $.capture.hash {
if .value ~~ Failure {
@priors.push(" " ~ .value.mess);
}
if .value ~~ Bool {
@bits.push(':' ~ ('!' x !.value) ~ .key);
}
else {
try @bits.push(":$(.key)($($where ?? .value.?perl !! .value.WHAT.?perl ))");
@bits.push($_.value.^name) if $!;
}
}
}
else {
@bits.push('...');
}
if @cand[0] ~~ /': '/ {
my $invocant = @bits.shift;
my $first = @bits ?? @bits.shift !! '';
@bits.unshift($invocant ~ ': ' ~ $first);
}
my $cap = '(' ~ @bits.join(", ") ~ ')';
@priors = flat "Earlier failures:\n", @priors, "\nFinal error:\n " if @priors;
@priors.join ~
join "\n ",
"Cannot call $.dispatcher.name()$cap; none of these signatures match:",
@cand;
}
}
my class X::Caller::NotDynamic is Exception {
has $.symbol;
method message() {
"Cannot access '$.symbol' through CALLER, because it is not declared as dynamic";
}
}
my class X::Inheritance::NotComposed does X::MOP {
# normally, we try very hard to capture the types
# and not just their names. But in this case, both types
# involved aren't composed yet, so they basically aren't
# usable at all.
has $.child-name;
has $.parent-name;
method message() {
"'$.child-name' cannot inherit from '$.parent-name' because '$.parent-name' isn't composed yet"
~ ' (maybe it is stubbed)';
}
}
my class X::PhaserExceptions is Exception {
has @.exceptions;
method message() {
"Multiple exceptions were thrown by LEAVE/POST phasers"
}
multi method gist(X::PhaserExceptions:D:) {
join "\n", flat
"Multiple exceptions were thrown by LEAVE/POST phasers\n",
@!exceptions>>.gist>>.indent(4)
}
}
nqp::bindcurhllsym('P6EX', nqp::hash(
'X::TypeCheck::Binding',
sub (Mu $got, Mu $expected, $symbol?) {
X::TypeCheck::Binding.new(:$got, :$expected, :$symbol).throw;
},
'X::TypeCheck::Assignment',
sub (Mu $symbol, Mu $got, Mu $expected) {
X::TypeCheck::Assignment.new(:$symbol, :$got, :$expected).throw;
},
'X::TypeCheck::Return',
sub (Mu $got, Mu $expected) {
X::TypeCheck::Return.new(:$got, :$expected).throw;
},
'X::Assignment::RO',
sub ($typename = "value") {
X::Assignment::RO.new(:$typename).throw;
},
'X::ControlFlow::Return',
sub () {
X::ControlFlow::Return.new().throw;
},
'X::NoDispatcher',
sub ($redispatcher) {
X::NoDispatcher.new(:$redispatcher).throw;
},
'X::Multi::Ambiguous',
sub ($dispatcher, @ambiguous, $capture) {
X::Multi::Ambiguous.new(:$dispatcher, :@ambiguous, :$capture).throw
},
'X::Multi::NoMatch',
sub ($dispatcher, $capture) {
X::Multi::NoMatch.new(:$dispatcher, :$capture).throw
},
'X::Role::Initialization',
sub ($role) {
X::Role::Initialization.new(:$role).throw
},
'X::Role::Parametric::NoSuchCandidate',
sub (Mu $role) {
X::Role::Parametric::NoSuchCandidate.new(:$role).throw;
},
'X::Inheritance::NotComposed',
sub ($child-name, $parent-name) {
X::Inheritance::NotComposed.new(:$child-name, :$parent-name).throw;
},
'X::Parameter::RW',
sub (Mu $got, $symbol) {
X::Parameter::RW.new(:$got, :$symbol).throw;
},
'X::PhaserExceptions',
sub (@exceptions) {
X::PhaserExceptions.new(exceptions =>
@exceptions.map(-> Mu \e { EXCEPTION(e) })).throw;
},
));
my class X::HyperWhatever::Multiple is Exception {
method message() {
"Multiple HyperWhatevers and Whatevers may not be used together"
}
}
my class X::EXPORTHOW::InvalidDirective does X::Comp {
has $.directive;
method message() {
"Unknown EXPORTHOW directive '$.directive' encountered during import"
}
}
my class X::EXPORTHOW::NothingToSupersede does X::Comp {
has $.declarator;
method message() {
"There is no package declarator '$.declarator' to supersede"
}
}
my class X::EXPORTHOW::Conflict does X::Comp {
has $.declarator;
has $.directive;
method message() {
"'EXPORTHOW::{$.directive}::{$.declarator}' conflicts with an existing meta-object imported into this lexical scope"
}
}
my class X::UnitScope::Invalid does X::Syntax {
has $.what;
has $.where;
method message() {
"A unit-scoped $.what definition is not allowed $.where;\n"
~ "Please use the block form."
}
}
my class X::UnitScope::TooLate does X::Syntax {
has $.what;
method message() {
"Too late for unit-scoped $.what definition;\n"
~ "Please use the block form."
}
}
my class X::StubCode is Exception {
has $.message = 'Stub code executed';
}
my class X::TooLateForREPR is X::Comp {
has $.type;
method message() {
"Cannot change REPR of $!type.^name() now (must be set at initial declaration)";
}
}
my class X::NotParametric is Exception {
has $.type;
method message() {
"$!type.^name() cannot be parameterized";
}
}
my class X::InvalidType does X::Comp {
has $.typename;
has @.suggestions;
method message() {
my $msg := "Invalid typename '$.typename'";
if +@.suggestions > 0 {
$msg := $msg ~ ". Did you mean '" ~ @.suggestions.join("', '") ~ "'?";
}
$msg;
}
}
my class X::InvalidTypeSmiley does X::Comp {
has $.name;
method message() {
"Invalid type smiley '$.name' used in type name";
}
}
my class X::Seq::Consumed is Exception {
method message() {
"This Seq has already been iterated, and its values consumed\n" ~
"(you might solve this by adding .cache on usages of the Seq, or\n" ~
"by assigning the Seq into an array)"
}
}
my class X::Seq::NotIndexable is Exception {
method message() {
"Cannot index a Seq; coerce it to a list or assign it to an array first"
}
}
my class X::WheneverOutOfScope is Exception {
method message() {
"Cannot have a 'whenever' block outside the scope of a 'supply' block"
}
}
my class X::IllegalOnFixedDimensionArray is Exception {
has $.operation;
method message() {
"Cannot $.operation a fixed-dimension array"
}
}
my class X::NotEnoughDimensions is Exception {
has $.operation;
has $.got-dimensions;
has $.needed-dimensions;
method message() {
"Cannot $.operation a $.needed-dimensions dimension array with only $.got-dimensions dimensions"
}
}
my class X::TooManyDimensions is Exception {
has $.operation;
has $.got-dimensions;
has $.needed-dimensions;
method message() {
"Cannot $.operation a $.needed-dimensions dimension array with $.got-dimensions dimensions"
}
}
my class X::Assignment::ArrayShapeMismatch is Exception {
has $.target-shape;
has $.source-shape;
method message() {
"Cannot assign an array of shape $.source-shape to an array of shape $.target-shape"
}
}
my class X::Assignment::ToShaped is Exception {
has $.shape;
method message() {
"Assignment to array with shape $.shape must provide structured data"
}
}
my class X::Language::Unsupported is Exception {
has $.version;
method message() {
"No compiler available for Perl $.version"
}
}
my class X::Proc::Unsuccessful is Exception {
has $.proc;
method message() {
"The spawned process exited unsuccessfully (exit code: $.proc.exitcode())"
}
}
class CompUnit::DependencySpecification { ... }
my class X::CompUnit::UnsatisfiedDependency is Exception {
has CompUnit::DependencySpecification $.specification;
has $.filename;
has $.line;
has $.pos;
my sub is-core($name) {
my @parts = $name.split("::");
my $ns := ::CORE.WHO;
for @parts {
return False unless $ns{$_}:exists;
$ns := $ns{$_}.WHO;
};
True
};
method message() {
my $name = $.specification.short-name;
is-core($name)
?? "{$name} is a builtin type. You can use it without loading a module."
!! "Could not find $.specification in:\n" ~ $*REPO.repo-chain.map(*.Str).join("\n").indent(4)
}
}
# vim: ft=perl6 expandtab sw=4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment