Parent Directory
|
Revision Log
Revision 1.2 - (view) (download) (as text)
| 1 : | tim | 1.1 | #!perl |
| 2 : | |||
| 3 : | # | ||
| 4 : | # Takes the Tiger out of your tank. Accepts a JSR-166 main source directory and | ||
| 5 : | # a target root directory for the result, and processes files in several packages | ||
| 6 : | # to corresponding files in the target hierarchy, renaming java.* packages to | ||
| 7 : | # jsr166.* packages. | ||
| 8 : | # | ||
| 9 : | # Makes use of custom sources in emulation directory tree | ||
| 10 : | # | ||
| 11 : | # Processing does the following: | ||
| 12 : | # - renames packages | ||
| 13 : | # - renames imports | ||
| 14 : | # - removes generics | ||
| 15 : | # - adds casts and changes types to cope with loss of generics | ||
| 16 : | # - replaces calls to System.nanoTime() | ||
| 17 : | # | ||
| 18 : | |||
| 19 : | use Getopt::Std; | ||
| 20 : | use File::Copy; | ||
| 21 : | use File::Find; | ||
| 22 : | use File::Path; | ||
| 23 : | use FindBin; | ||
| 24 : | |||
| 25 : | my %args; | ||
| 26 : | |||
| 27 : | getopts("e:s:t:v", \%args) or die <<USAGE; | ||
| 28 : | |||
| 29 : | Usage: | ||
| 30 : | |||
| 31 : | defang.pl [-v] [-s sourcedir] [-t targetdir] [-e emulationdir] | ||
| 32 : | |||
| 33 : | USAGE | ||
| 34 : | |||
| 35 : | my $verbose = $args{v}; | ||
| 36 : | (my $srcdir = $args{s} || "$FindBin::Bin/../src/main") =~ s#\\#/#g; | ||
| 37 : | (my $tgtdir = $args{t} || "$FindBin::Bin/../src/pretiger") =~ s#\\#/#g; | ||
| 38 : | (my $emudir = $args{e} || "$FindBin::Bin/pretiger") =~ s#\\#/#g; | ||
| 39 : | |||
| 40 : | print "source is $srcdir\n" if $verbose; | ||
| 41 : | print "target is $tgtdir\n" if $verbose; | ||
| 42 : | print "emulation is $emudir\n" if $verbose; | ||
| 43 : | |||
| 44 : | my @pkgs = qw( | ||
| 45 : | java/util | ||
| 46 : | java/util/concurrent | ||
| 47 : | java/util/concurrent/atomic | ||
| 48 : | java/util/concurrent/locks | ||
| 49 : | ); | ||
| 50 : | my %pkgs; | ||
| 51 : | $pkgs{$_}++ for @pkgs; | ||
| 52 : | |||
| 53 : | print "packages:\n\t" . join("\n\t", sort keys %pkgs) . "\n" if $verbose; | ||
| 54 : | |||
| 55 : | find(\&processSource, $srcdir); | ||
| 56 : | find(\©Emulation, $emudir); | ||
| 57 : | |||
| 58 : | sub copyEmulation { | ||
| 59 : | -d and /CVS/ and $File::Find::prune = 1, return; | ||
| 60 : | |||
| 61 : | (my $old = $File::Find::name) =~ s#^$emudir##; $old =~ s#^/##; | ||
| 62 : | (my $new = $File::Find::name) =~ s#^$emudir#$tgtdir#; | ||
| 63 : | if (-d) { | ||
| 64 : | mkpath $new; | ||
| 65 : | print "mkdir $old\n" if $verbose; | ||
| 66 : | } | ||
| 67 : | else { | ||
| 68 : | copy $File::Find::name, $new; | ||
| 69 : | print "copied $old\n" if $verbose; | ||
| 70 : | } | ||
| 71 : | } | ||
| 72 : | |||
| 73 : | sub processSource { | ||
| 74 : | -d and /CVS/ and $File::Find::prune = 1, return; | ||
| 75 : | |||
| 76 : | (my $dir = $File::Find::dir ) =~ s#^$srcdir##; $dir =~ s#^/##; | ||
| 77 : | (my $old = $File::Find::name) =~ s#^$srcdir##; $old =~ s#^/##; | ||
| 78 : | (my $new = $File::Find::name) =~ s#^$srcdir/java#$tgtdir/jsr166#; | ||
| 79 : | |||
| 80 : | if (-d) { | ||
| 81 : | if ($pkgs{$old}) { | ||
| 82 : | mkpath $new; | ||
| 83 : | print "mkdir $old\n" if $verbose; | ||
| 84 : | } | ||
| 85 : | } | ||
| 86 : | else { | ||
| 87 : | if ($pkgs{$dir} && !exclude($old)) { | ||
| 88 : | process($File::Find::name, $new); | ||
| 89 : | print "processed $old\n" if $verbose; | ||
| 90 : | } | ||
| 91 : | } | ||
| 92 : | } | ||
| 93 : | |||
| 94 : | sub exclude { | ||
| 95 : | local $_ = shift; | ||
| 96 : | |||
| 97 : | /Random.java$/ || | ||
| 98 : | /LinkedList.java$/ || | ||
| 99 : | /AtomicMarkableReference.java$/ || | ||
| 100 : | /AtomicStampedReference.java$/ || | ||
| 101 : | 0; | ||
| 102 : | } | ||
| 103 : | |||
| 104 : | my $indent = 0; | ||
| 105 : | |||
| 106 : | sub process { | ||
| 107 : | my ($from, $to) = @_; | ||
| 108 : | if ($from !~ /.java$/) { | ||
| 109 : | copy $from, $to; | ||
| 110 : | return; | ||
| 111 : | } | ||
| 112 : | |||
| 113 : | open S, "<", $from or die "can't open $from for reading\n"; | ||
| 114 : | open T, ">", $to or die "can't open $to for writing\n"; | ||
| 115 : | |||
| 116 : | while (<S>) { | ||
| 117 : | # rename package | ||
| 118 : | s/^package java.util;/package jsr166.util;\n\nimport java.util.*;/; | ||
| 119 : | s/^package java.(.*);/package jsr166.$1;/; | ||
| 120 : | |||
| 121 : | # deal with imports | ||
| 122 : | s/^import java.util.(\w*Queue);/import jsr166.util.$1;/; | ||
| 123 : | s/^import java.util.concurrent/import jsr166.util.concurrent/; | ||
| 124 : | s/^(import java.util.\*;)/$1\nimport jsr166.util.*;/; | ||
| 125 : | s/^import sun.misc.(?:Unsafe|\*);/import jsr166.misc.Unsafe;/; | ||
| 126 : | |||
| 127 : | # remove generics | ||
| 128 : | s/\s?<([A-Z?][^<>]*)>//g; # remove inner type parameters | ||
| 129 : | s/\s?<([A-Z?][^<>]*)>//g; # remove outer type parameters | ||
| 130 : | s/\([A-Z]\[]\)\s?//g; # remove array casts | ||
| 131 : | s/\([A-Z]\)\s?//g; # remove Object casts | ||
| 132 : | s/\b[A-Z]\b/Object/g; # replace generic types with Object | ||
| 133 : | |||
| 134 : | |||
| 135 : | # convert use of locks to synchronized blocks where possible | ||
| 136 : | # (not in LBQ or in comments), ignoring use of newCondition | ||
| 137 : | if ($from !~ /LinkedBlockingQueue/ && !m/^\s*\*\s+/) { | ||
| 138 : | if ($indent) { | ||
| 139 : | s/^/ /; | ||
| 140 : | } | ||
| 141 : | if (s/\b(\w+)\.lock\(\);/synchronized ($1) {/) { | ||
| 142 : | ++$indent; | ||
| 143 : | } | ||
| 144 : | if (s/\b(\w+)\.lockInterruptibly\(\);/if (Thread.interrupted()) throw new InterruptedException(); synchronized ($1) {/) { | ||
| 145 : | ++$indent; | ||
| 146 : | } | ||
| 147 : | if (s/if \((\w+)\.tryLock\(\)\)/synchronized ($1) {/) { | ||
| 148 : | ++$indent; | ||
| 149 : | } | ||
| 150 : | if (s/(\s{4}\b\w+)\.unlock\(\);/} \/\/ vacuous try-finally/g) { | ||
| 151 : | --$indent; | ||
| 152 : | } | ||
| 153 : | } | ||
| 154 : | |||
| 155 : | # casts and generic arguments for various methods | ||
| 156 : | s/\b(workQueue\.(?:poll|peek|take|remove|element))/(Runnable)$1/g; | ||
| 157 : | s/public Runnable (poll|peek|take|remove|element|next)/public Object $1/g; | ||
| 158 : | s/(put|add|offer)\(Runnable/$1(Object/g; | ||
| 159 : | |||
| 160 : | # only use of newCondition in source is with RL.ConditionObject. | ||
| 161 : | s/\b((?:this|\w*[Ll]ock)\.newCondition\(\))/((ReentrantLock.ConditionObject)$1)/g; | ||
| 162 : | s/\b([A-Z]\w+)\s+newCondition\(\)/Condition newCondition()/g; | ||
| 163 : | |||
| 164 : | # cast it.next() to Worker in TPE | ||
| 165 : | if ($from =~ /ThreadPoolExecutor/) { | ||
| 166 : | s/(it.next\(\))/((Worker)$1)/g; | ||
| 167 : | } | ||
| 168 : | |||
| 169 : | # cast to Entry in CHM | ||
| 170 : | if ($from =~ /ConcurrentHashMap/) { | ||
| 171 : | s/\bMap.Entry next\(\)/Object next()/g; | ||
| 172 : | s/\b([a-z]+).next\(\)/((Entry)$1.next())/g; | ||
| 173 : | } | ||
| 174 : | |||
| 175 : | # cast to Delayed/Comparable in DQ | ||
| 176 : | if ($from =~ /DelayQueue/) { | ||
| 177 : | s/Object first/Delayed first/g; | ||
| 178 : | s/\bq\.peek\(\)/((Delayed)q.peek())/g; | ||
| 179 : | s/\b(\w+)(\.compareTo)/((Comparable)$1)$2/g; | ||
| 180 : | } | ||
| 181 : | |||
| 182 : | # cast Array.newInstance result to Object[] | ||
| 183 : | s/([\w.]+Array\.newInstance)/(Object[])$1/g; | ||
| 184 : | |||
| 185 : | |||
| 186 : | # replace calls to System.nanoTime() | ||
| 187 : | s/System.nanoTime\(\)/(1000*1000*System.currentTimeMillis())/g; | ||
| 188 : | |||
| 189 : | |||
| 190 : | print T; | ||
| 191 : | |||
| 192 : | } | ||
| 193 : | close T; | ||
| 194 : | close S; | ||
| 195 : | } | ||
| 196 : | |||
| 197 : | |||
| 198 : | __END__ |
| Doug Lea | ViewVC Help |
| Powered by ViewVC 1.0.8 |