Permalink
Browse files

Implement 'is hidden' and 'hides'.

  • Loading branch information...
1 parent 6f71e7e commit 64a2e8359874ead1abdd8724ce6389346bef2d65 @jnthn jnthn committed Sep 28, 2012
View
@@ -2288,15 +2288,17 @@ class Perl6::Actions is HLL::Actions {
));
}
unless @params[+@params - 1]<named_slurpy> {
- @params.push(hash(
- variable_name => '%_',
- nominal_type => $*W.find_symbol(['Mu']),
- named_slurpy => 1,
- is_multi_invocant => 1,
- is_method_named_slurpy => 1
- ));
- $past[0].unshift(QAST::Var.new( :name('%_'), :scope('lexical'), :decl('var') ));
- $past.symbol('%_', :scope('lexical'), :lazyinit(1));
+ unless nqp::can($*PACKAGE.HOW, 'hidden') && $*PACKAGE.HOW.hidden($*PACKAGE) {
+ @params.push(hash(
+ variable_name => '%_',
+ nominal_type => $*W.find_symbol(['Mu']),
+ named_slurpy => 1,
+ is_multi_invocant => 1,
+ is_method_named_slurpy => 1
+ ));
+ $past[0].unshift(QAST::Var.new( :name('%_'), :scope('lexical'), :decl('var') ));
+ $past.symbol('%_', :scope('lexical'), :lazyinit(1));
+ }
}
set_default_parameter_type(@params, 'Any');
my $signature := create_signature_object($/, %sig_info, $past);
@@ -2,6 +2,9 @@ role Perl6::Metamodel::C3MRO {
# Storage of the MRO.
has @!mro;
+ # The MRO minus anything that is hidden.
+ has @!mro_unhidden;
+
# Computes C3 MRO.
method compute_mro($class) {
my @immediate_parents := $class.HOW.parents($class, :local);
@@ -26,6 +29,30 @@ role Perl6::Metamodel::C3MRO {
# Put this class on the start of the list, and we're done.
@result.unshift($class);
@!mro := @result;
+
+ # Also compute the unhidden MRO (all the things in the MRO that
+ # are not somehow hidden).
+ my @unhidden;
+ my @hidden;
+ for @result -> $c {
+ unless nqp::can($c.HOW, 'hidden') && $c.HOW.hidden($c) {
+ my $is_hidden := 0;
+ for @hidden {
+ if pir::nqp_decontainerize__PP($c) =:= pir::nqp_decontainerize__PP($_) {
+ $is_hidden := 1;
+ }
+ }
+ nqp::push(@unhidden, $c) unless $is_hidden;
+ }
+ if nqp::can($c.HOW, 'hides') {
+ for $c.HOW.hides($c) {
+ nqp::push(@hidden, $_);
+ }
+ }
+ }
+ @!mro_unhidden := @unhidden;
+
+ @!mro
}
# C3 merge routine.
@@ -107,4 +134,19 @@ role Perl6::Metamodel::C3MRO {
self.compute_mro($obj)
}
}
+
+ # Introspects the Method Resolution Order without anything that has
+ # been hidden.
+ method mro_unhidden($obj) {
+ my @result := @!mro_unhidden;
+ if +@result {
+ @result
+ }
+ else {
+ # Never computed before; do it best we can so far (and it will
+ # be finalized at compose time).
+ self.compute_mro($obj);
+ @!mro_unhidden
+ }
+ }
}
@@ -52,7 +52,9 @@ class Perl6::Metamodel::MethodDispatcher is Perl6::Metamodel::BaseDispatcher {
method vivify_for($sub, $lexpad) {
my $obj := $lexpad<self>;
my $name := $sub.name;
- my @mro := $obj.HOW.mro($obj);
+ my @mro := nqp::can($obj.HOW, 'mro_unhidden')
+ ?? $obj.HOW.mro_unhidden($obj)
+ !! $obj.HOW.mro($obj);
my @methods;
for @mro {
my %mt := $_.HOW.method_table($_);
@@ -2,14 +2,20 @@ role Perl6::Metamodel::MultipleInheritance {
# Array of parents.
has @!parents;
+ # Are any of the parents hidden?
+ has @!hides;
+
+ # Is this class hidden?
+ has $!hidden;
+
# Classes to exclude from the parents list in introspection by default.
my @excluded;
method exclude_parent($parent) {
@excluded.push($parent);
}
# Adds a parent.
- method add_parent($obj, $parent) {
+ method add_parent($obj, $parent, :$hides) {
if self.is_composed($obj) {
nqp::die("Parents cannot be added to a class after it has been composed");
}
@@ -23,6 +29,9 @@ role Perl6::Metamodel::MultipleInheritance {
$parent.HOW.name($parent) ~ "'");
}
}
+ if $hides {
+ @!hides[+@!hides] := $parent;
+ }
@!parents[+@!parents] := $parent;
}
@@ -58,4 +67,16 @@ role Perl6::Metamodel::MultipleInheritance {
@parents
}
}
+
+ method hides($obj) {
+ @!hides
+ }
+
+ method hidden($obj) {
+ $!hidden ?? 1 !! 0
+ }
+
+ method set_hidden($obj) {
+ $!hidden := 1;
+ }
}
View
@@ -38,6 +38,9 @@ multi trait_mod:<is>(Mu:U $type, :$rw!) {
multi trait_mod:<is>(Mu:U $type, :$nativesize!) {
$type.HOW.set_nativesize($type, $nativesize);
}
+multi trait_mod:<is>(Mu:U $type, :$hidden!) {
+ $type.HOW.set_hidden($type);
+}
multi trait_mod:<is>(Attribute:D $attr, :$rw!) {
$attr.set_rw();
@@ -276,3 +279,19 @@ proto trait_mod:<trusts>(|) { * }
multi trait_mod:<trusts>(Mu:U $truster, Mu:U $trustee) {
$truster.HOW.add_trustee($truster, $trustee);
}
+
+proto trait_mod:<hides>(|) { * }
+multi trait_mod:<hides>(Mu:U $child, Mu:U $parent) {
+ if $parent.HOW.archetypes.inheritable() {
+ $child.HOW.add_parent($child, $parent, :hides);
+ }
+ elsif $parent.HOW.archetypes.inheritalizable() {
+ $child.HOW.add_parent($child, $parent.HOW.inheritalize($parent), :hides)
+ }
+ else {
+ X::Inheritance::Unsupported.new(
+ :child-typename($child.HOW.name($child)),
+ :$parent,
+ ).throw;
+ }
+}

0 comments on commit 64a2e83

Please sign in to comment.