Skip to content

Commit 307f1fc

Browse files
authored
Merge pull request DOCGroup#181 from DOCGroup/generation_sort_order
Rewrote the sorting of generated components
2 parents 2ba2603 + f5ac89c commit 307f1fc

File tree

1 file changed

+75
-27
lines changed

1 file changed

+75
-27
lines changed

modules/ProjectCreator.pm

Lines changed: 75 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,7 +1386,6 @@ sub process_component_line {
13861386
$key =~ s/\\/\//g if ($self->{'convert_slashes'});
13871387
my $cmdflags = $$flags{'commandflags'};
13881388
my($add_out, $deps) = $cmdHelper->get_output($key, $cmdflags);
1389-
13901389
push(@{$self->{'custom_special_output'}->{$tag}->{$key}}, @$add_out);
13911390
foreach my $depTag (keys %$deps) {
13921391
foreach my $depFile (keys %{$deps->{$depTag}}) {
@@ -3183,10 +3182,9 @@ sub correct_generated_files {
31833182
sub generate_default_components {
31843183
my($self, $files, $passed) = @_;
31853184
my $genext = $self->{'generated_exts'};
3186-
my @gc = reverse sort { $self->sort_generated_types($a, $b)
3187-
} keys %$genext;
31883185
my @tags = (defined $passed ? $passed :
3189-
(@gc, keys %{$language{$self->get_language()}->[0]}));
3186+
($self->get_generated_components(),
3187+
keys %{$language{$self->get_language()}->[0]}));
31903188
my $pchh = $self->get_assignment('pch_header');
31913189
my $pchc = $self->get_assignment('pch_source');
31923190
my $recurse = $self->get_assignment('recurse');
@@ -3195,11 +3193,9 @@ sub generate_default_components {
31953193
my $cmdflags = 'commandflags';
31963194

31973195
## The order of @tags does make a difference in the way that generated
3198-
## files get added. Hence the sort call on the generate_exts keys to
3199-
## ensure that user defined types come first. They are reverse sorted
3200-
## using the custom sort function to ensure that user defined types
3201-
## that rely on other user defined types for input files are processed
3202-
## first.
3196+
## files get added. The function that returns the generated components
3197+
## sorts the tags such that user defined types that rely on other user
3198+
## defined types for input files are processed first.
32033199
foreach my $tag (@tags) {
32043200
if (!defined $genext->{$tag} ||
32053201
$genext->{$tag}->{'automatic_in'}) {
@@ -3688,27 +3684,80 @@ sub remove_excluded {
36883684
}
36893685

36903686

3691-
sub sort_generated_types {
3692-
## We need to sort the custom component types such that a custom type
3693-
## that generates input for another custom type comes first in the
3694-
## list.
3695-
my($self, $left, $right, $norecurse) = @_;
3696-
foreach my $key (keys %{$self->{'generated_exts'}->{$left}}) {
3687+
sub get_outputexts {
3688+
my($self, $type) = @_;
3689+
my @outputexts;
3690+
3691+
## Get all generated output extensions for this generated type.
3692+
foreach my $key (keys %{$self->{'generated_exts'}->{$type}}) {
36973693
if ($key =~ /_files$/) {
3698-
foreach my $regex (@{$self->{'generated_exts'}->{$left}->{$key}}) {
3699-
my $ext = $regex;
3700-
$ext =~ s/\\//g;
3701-
foreach my $vreg (@{$self->{'valid_components'}->{$right}}) {
3702-
return -1 if ($ext =~ /$vreg$/);
3694+
push(@outputexts, @{$self->{'generated_exts'}->{$type}->{$key}});
3695+
}
3696+
}
3697+
3698+
## If the generated type has a helper, get it and add the output exstensions
3699+
## to the list.
3700+
my $cmdHelper = $self->find_command_helper($type);
3701+
push(@outputexts, @{$cmdHelper->get_outputexts()}) if (defined $cmdHelper);
3702+
3703+
return \@outputexts;
3704+
}
3705+
3706+
sub get_generated_components {
3707+
my $self = shift;
3708+
my @list = keys %{$self->{'generated_exts'}};
3709+
my $len = scalar(@list);
3710+
my %geninfo;
3711+
my %movedfor;
3712+
for(my $i = 1; $i < $len; $i++) {
3713+
my $right = $list[$i];
3714+
3715+
## Cache the outputexts into a hash map so that we do not have to call a
3716+
## function more than once per type. Since items in the list will be
3717+
## swapped and $i modified, we are very likely to hit this cache multiple
3718+
## times.
3719+
my $outputexts;
3720+
if (exists $geninfo{$right}) {
3721+
$outputexts = $geninfo{$right};
3722+
}
3723+
else {
3724+
$geninfo{$right} = $outputexts = $self->get_outputexts($right);
3725+
}
3726+
3727+
## Go backwards in the list to see if $right will generate inputs for
3728+
## anything to the left.
3729+
for(my $j = $i - 1; $j >= 0; $j--) {
3730+
my $left = $list[$j];
3731+
## See if $right generates input for $left
3732+
my $generates;
3733+
foreach my $inputext (@{$self->{'valid_components'}->{$left}}) {
3734+
if (grep { $_ eq $inputext } @$outputexts) {
3735+
$generates = 1;
3736+
last;
37033737
}
37043738
}
3739+
3740+
if ($generates) {
3741+
## If it does and we haven't already moved $right because of $left,
3742+
## then we will move $right in front of $left, push everything to the
3743+
## right up to $i, and reset $i to $j (after the increment of the outer
3744+
## for loop).
3745+
if (exists $movedfor{$right} && $movedfor{$right} eq $left) {
3746+
$self->warning("Circular generation dependency for $right and $left");
3747+
}
3748+
else {
3749+
$movedfor{$right} = $left;
3750+
for(my $k = $i; $k > $j; $k--) {
3751+
$list[$k] = $list[$k - 1];
3752+
}
3753+
$list[$j] = $right;
3754+
$i = $j - 1;
3755+
}
3756+
last;
3757+
}
37053758
}
37063759
}
3707-
if (!$norecurse && $self->sort_generated_types($right, $left, 1) == -1) {
3708-
return 1;
3709-
}
3710-
3711-
return 0;
3760+
return @list;
37123761
}
37133762

37143763
sub generate_defaults {
@@ -3747,8 +3796,7 @@ sub generate_defaults {
37473796
my @vc = sort { return -1 if $a eq 'source_files';
37483797
return 1 if $b eq 'source_files';
37493798
return $b cmp $a; } keys %{$self->{'valid_components'}};
3750-
my @gvc = sort { $self->sort_generated_types($a, $b)
3751-
} keys %{$self->{'generated_exts'}};
3799+
my @gvc = $self->get_generated_components();
37523800
foreach my $gentype (@gvc) {
37533801
$self->list_default_generated($gentype, \@vc);
37543802
}

0 commit comments

Comments
 (0)