Permalink
Browse files

Merge branch 'froggs_mergemulti' into nom

  • Loading branch information...
2 parents f083685 + fad34f8 commit fec0ef86bd26a96e2a881d92d2d9228496c4180b @jnthn jnthn committed Jan 11, 2013
Showing with 53 additions and 3 deletions.
  1. +43 −3 src/Perl6/World.pm
  2. +9 −0 src/core/Exception.pm
  3. +1 −0 t/spectest.data
View
@@ -263,17 +263,57 @@ class Perl6::World is HLL::World {
# outright conflicts, and handle any situations where we need to merge.
my %to_install;
my @clash;
+ my @clash_onlystar;
for %stash {
- if $target.symbol($_.key) {
- # XXX TODO: Merge handling.
- nqp::push(@clash, $_.key);
+ if $target.symbol($_.key) -> %sym {
+ # There's already a symbol. However, we may be able to merge
+ # if both are multis and have onlystar dispatchers.
+ my $installed := %sym<value>;
+ my $foreign := $_.value;
+ if nqp::can($installed, 'is_dispatcher') && $installed.is_dispatcher
+ && nqp::can($foreign, 'is_dispatcher') && $foreign.is_dispatcher {
+ # Both dispatchers, but are they onlystar? If so, we can
+ # go ahead and merge them.
+ if $installed.onlystar && $foreign.onlystar {
+ # Replace installed one with a derived one, to avoid any
+ # weird action at a distance.
+ $installed := self.derive_dispatcher($installed);
+ self.install_lexical_symbol($target, $_.key, $installed, :clone(1));
+
+ # Incorporate dispatchees of foreign proto, avoiding
+ # duplicates.
+ my %seen;
+ for $installed.dispatchees {
+ %seen{$_.static_id} := $_;
+ }
+ for $foreign.dispatchees {
+ unless nqp::existskey(%seen, $_.static_id) {
+ self.add_dispatchee_to_proto($installed, $_);
+ }
+ }
+ }
+ else {
+ nqp::push(@clash_onlystar, $_.key);
+ }
+ }
+ else {
+ nqp::push(@clash, $_.key);
+ }
}
else {
$target.symbol($_.key, :scope('lexical'), :value($_.value));
$target[0].push(QAST::Var.new( :scope('lexical'), :name($_.key), :decl('var') ));
%to_install{$_.key} := $_.value;
}
}
+
+ if +@clash_onlystar {
+ self.throw($/, 'X::Import::OnlystarProto',
+ symbols => @clash_onlystar,
+ source-package-name => $source_package_name,
+ );
+ }
+
if +@clash {
self.throw($/, 'X::Import::Redeclaration',
symbols => @clash,
View
@@ -538,7 +538,16 @@ my class X::Import::Redeclaration does X::Comp {
?? "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::Phaser::Multiple does X::Comp {
View
@@ -417,6 +417,7 @@ S10-packages/joined-namespaces.t
S10-packages/use-with-class.t
# S11-modules/export.t # err: Could not find symbol 'Foo::&Foo_exp_parens
S11-modules/importing.t
+S11-modules/import-multi.t
S11-modules/import-tag.t
S11-modules/import.t
S11-modules/lexical.t

0 comments on commit fec0ef8

Please sign in to comment.