From 858ac4e3ff279fcf666530b9cc48b78d318d13c8 Mon Sep 17 00:00:00 2001 From: jnthn Date: Wed, 11 Mar 2015 23:01:32 +0100 Subject: [PATCH] Catch wrong attribute usage in a regex. Regexes are methods on Cursor (or some subclass of it), meaning that an attribute access inside of them is relative to that. Rather than failing silently or exploding noisily at runtime, catch the problem at compile time. The typed exception's message explains the issue and offers a suggestion; wording tweaks welcome. --- src/Perl6/Grammar.nqp | 26 ++++++++++++++++++++++++-- src/core/Exception.pm | 7 +++++++ src/core/core_prologue.pm | 1 + 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/Perl6/Grammar.nqp b/src/Perl6/Grammar.nqp index e241f09ec76..966676659ea 100644 --- a/src/Perl6/Grammar.nqp +++ b/src/Perl6/Grammar.nqp @@ -4923,7 +4923,25 @@ grammar Perl6::QGrammar is HLL::Grammar does STD { } } -grammar Perl6::RegexGrammar is QRegex::P6Regex::Grammar does STD { +my role CursorPackageNibbler { + method nibble-in-cursor($parent) { + my $*PACKAGE := $*W.find_symbol(['Cursor']); + my %*ATTR_USAGES; + my $cur := nqp::findmethod($parent, 'nibbler')(self); + for %*ATTR_USAGES { + my $name := $_.key; + my $node := $_.value[0].node; + $node.CURSOR.typed_sorry('X::Attribute::Regex', symbol => $name); + } + $cur + } +} + +grammar Perl6::RegexGrammar is QRegex::P6Regex::Grammar does STD does CursorPackageNibbler { + method nibbler() { + self.nibble-in-cursor(QRegex::P6Regex::Grammar) + } + method throw_unrecognized_metachar ($metachar) { self.typed_sorry('X::Syntax::Regex::UnrecognizedMetachar', :$metachar); } @@ -5016,7 +5034,11 @@ grammar Perl6::RegexGrammar is QRegex::P6Regex::Grammar does STD { } } -grammar Perl6::P5RegexGrammar is QRegex::P5Regex::Grammar does STD { +grammar Perl6::P5RegexGrammar is QRegex::P5Regex::Grammar does STD does CursorPackageNibbler { + method nibbler() { + self.nibble-in-cursor(QRegex::P5Regex::Grammar) + } + token rxstopper { } token p5metachar:sym<(?{ })> { diff --git a/src/core/Exception.pm b/src/core/Exception.pm index 5ea1cfddeae..9c005d8d954 100644 --- a/src/core/Exception.pm +++ b/src/core/Exception.pm @@ -583,6 +583,13 @@ my class X::Attribute::Undeclared is X::Undeclared { } } +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; diff --git a/src/core/core_prologue.pm b/src/core/core_prologue.pm index 7b2599e2946..69fb92c8b47 100644 --- a/src/core/core_prologue.pm +++ b/src/core/core_prologue.pm @@ -5,6 +5,7 @@ my class Pair { ... } my class Whatever { ... } my class HyperWhatever { ... } my class WhateverCode { ... } +my class Cursor { ... } # Stub these or we can't use any sigil other than $. my role Positional { ... }