javaclass 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +67 -56
- data/Readme.txt +42 -39
- data/example_task.rb +172 -0
- data/examples/check_interface_names.rb +44 -0
- data/examples/corpus.rb +19 -0
- data/examples/count_classes_in_modules.rb +38 -0
- data/examples/cumulative_dependencies.rb +39 -0
- data/examples/find_all_imported_types.rb +44 -0
- data/examples/find_referenced_modules.rb +53 -0
- data/examples/find_unreferenced_classes.rb +65 -0
- data/examples/generate_class_lists.rb +67 -43
- data/examples/profiler_scratchpad.rb +33 -0
- data/examples/simple_usage.rb +42 -0
- data/history.txt +29 -7
- data/javaclass.gemspec +31 -0
- data/lib/javaclass/adder_tree.rb +92 -0
- data/lib/javaclass/analyse/dependencies.rb +52 -0
- data/lib/javaclass/{metric/metrics.txt → analyse/ideas.txt} +2 -2
- data/lib/javaclass/analyse/transitive_dependencies.rb +52 -0
- data/lib/javaclass/classfile/access_flag_constants.rb +24 -0
- data/lib/javaclass/classfile/access_flags.rb +49 -26
- data/lib/javaclass/classfile/class_format_error.rb +37 -0
- data/lib/javaclass/classfile/class_magic.rb +16 -8
- data/lib/javaclass/classfile/class_version.rb +19 -25
- data/lib/javaclass/classfile/constant_pool.rb +110 -45
- data/lib/javaclass/classfile/constants/base.rb +33 -12
- data/lib/javaclass/classfile/constants/double_reference.rb +55 -41
- data/lib/javaclass/classfile/constants/single_reference.rb +29 -21
- data/lib/javaclass/classfile/constants/value.rb +43 -33
- data/lib/javaclass/classfile/java_class_header.rb +72 -46
- data/lib/javaclass/classfile/java_class_header_as_java_name.rb +33 -0
- data/lib/javaclass/classfile/java_class_header_shortcuts.rb +19 -0
- data/lib/javaclass/classfile/references.rb +21 -19
- data/lib/javaclass/classlist/class_entry.rb +26 -27
- data/lib/javaclass/classlist/jar_searcher.rb +34 -25
- data/lib/javaclass/classlist/list.rb +31 -31
- data/lib/javaclass/classlist/package_entry.rb +25 -24
- data/lib/javaclass/classpath/any_classpath.rb +48 -0
- data/lib/javaclass/classpath/class_not_found_error.rb +20 -0
- data/lib/javaclass/classpath/classpaths.txt +2 -2
- data/lib/javaclass/classpath/composite_classpath.rb +56 -54
- data/lib/javaclass/classpath/convention_classpath.rb +38 -0
- data/lib/javaclass/classpath/eclipse_classpath.rb +74 -0
- data/lib/javaclass/classpath/factory.rb +65 -0
- data/lib/javaclass/classpath/file_classpath.rb +47 -0
- data/lib/javaclass/classpath/folder_classpath.rb +42 -44
- data/lib/javaclass/classpath/jar_classpath.rb +91 -52
- data/lib/javaclass/classpath/java_home_classpath.rb +24 -13
- data/lib/javaclass/classpath/maven_classpath.rb +44 -0
- data/lib/javaclass/classpath/temporary_unpacker.rb +111 -0
- data/lib/javaclass/classpath/tracking_classpath.rb +144 -0
- data/lib/javaclass/classscanner/ideas.txt +3 -0
- data/lib/javaclass/classscanner/imported_types.rb +29 -0
- data/lib/javaclass/classscanner/scanners.rb +29 -0
- data/lib/javaclass/delegate_directive.rb +15 -0
- data/lib/javaclass/dsl/caching_classpath.rb +38 -0
- data/lib/javaclass/dsl/classpath_analysers.rb +27 -0
- data/lib/javaclass/dsl/java_name_factory.rb +79 -0
- data/lib/javaclass/dsl/loader.rb +42 -0
- data/lib/javaclass/dsl/loading_classpath.rb +53 -0
- data/lib/javaclass/dsl/mixin.rb +54 -0
- data/lib/javaclass/gems/zip_file.rb +154 -0
- data/lib/javaclass/java_language.rb +50 -0
- data/lib/javaclass/java_name.rb +329 -55
- data/lib/javaclass/java_name_scanner.rb +95 -0
- data/lib/javaclass/resources/iso_3166_countries.txt +240 -0
- data/lib/javaclass/resources/jdk0_packages.txt +6 -0
- data/lib/javaclass/resources/jdk1_packages.txt +6 -0
- data/lib/javaclass/resources/jdk2_packages.txt +4 -0
- data/lib/javaclass/resources/jdk3_packages.txt +6 -0
- data/lib/javaclass/resources/jdk4_packages.txt +22 -0
- data/lib/javaclass/resources/jdk5_packages.txt +5 -0
- data/lib/javaclass/resources/jdk6_packages.txt +7 -0
- data/lib/javaclass/resources/jdk7_packages.txt +0 -0
- data/lib/javaclass/resources/jdk_packages.txt +53 -0
- data/lib/javaclass/resources/reserved_words.txt +50 -0
- data/lib/javaclass/string_hexdump.rb +76 -0
- data/lib/javaclass/string_ux.rb +21 -10
- data/lib/javaclass.rb +16 -41
- data/license.txt +28 -0
- data/planned.txt +13 -0
- data/test/data/Object_102.class +0 -0
- data/test/data/Runnable_102.class +0 -0
- data/test/data/access_flags/AccessFlagsTestAnnotation.class +0 -0
- data/test/data/access_flags/AccessFlagsTestAnnotation.java +3 -0
- data/test/data/access_flags/AccessFlagsTestEnum$1.class +0 -0
- data/test/data/access_flags/AccessFlagsTestEnum.class +0 -0
- data/test/data/access_flags/AccessFlagsTestEnum.java +6 -0
- data/test/data/access_flags/AccessFlagsTestInner$1.class +0 -0
- data/test/data/access_flags/AccessFlagsTestInner$2.class +0 -0
- data/test/data/access_flags/AccessFlagsTestInner.class +0 -0
- data/test/data/access_flags/AccessFlagsTestInner.java +13 -0
- data/test/data/access_flags/AccessFlagsTestPackage.class +0 -0
- data/test/data/access_flags/AccessFlagsTestPackage.java +1 -1
- data/test/data/api/packagename/AccessFlagsTestPublic.class +0 -0
- data/test/data/class_version/ClassVersionTest17.class +0 -0
- data/test/data/class_version/make.bat +6 -2
- data/test/data/eclipse_classpath/classes/ClassVersionTest12.class +0 -0
- data/test/data/eclipse_classpath/lib/JarClasspathTest.jar +0 -0
- data/test/data/eclipse_classpath/test-classes/ClassVersionTest13.class +0 -0
- data/test/data/folder_classpath/{JarClasspathTestFolder → classes}/ClassVersionTest10.class +0 -0
- data/test/data/folder_classpath/{JarClasspathTestFolder → classes}/package/ClassVersionTest11.class +0 -0
- data/test/data/jar_classpath/JarClasspathTest.jar +0 -0
- data/test/data/jar_classpath/JarClasspathTest.zip +0 -0
- data/test/data/jar_classpath/JarClasspathTestManifest.jar +0 -0
- data/test/data/jar_classpath/JarClasspathTestMultiManifest.jar +0 -0
- data/test/data/jar_classpath/make.bat +6 -2
- data/test/data/jar_searcher/BrokenRunnable_102.class +0 -0
- data/test/data/java_home_classpath/jdk118/lib/classes.zip +0 -0
- data/test/data/java_name_scanner/META-INF/MANIFEST.MF +12 -0
- data/test/data/java_name_scanner/plugin.xml +18 -0
- data/test/data/maven_classpath/module/pom.xml +8 -0
- data/test/data/maven_classpath/module/target/classes/ClassVersionTest12.class +0 -0
- data/test/data/maven_classpath/pom.xml +8 -0
- data/test/data/maven_classpath/target/classes/ClassVersionTest10.class +0 -0
- data/test/data/maven_classpath/target/test-classes/ClassVersionTest11.class +0 -0
- data/test/data/transitive_dependencies/A.class +0 -0
- data/test/data/transitive_dependencies/A.java +5 -0
- data/test/data/transitive_dependencies/B.class +0 -0
- data/test/data/transitive_dependencies/B.java +3 -0
- data/test/data/transitive_dependencies/C.class +0 -0
- data/test/data/transitive_dependencies/C.java +3 -0
- data/test/data/transitive_dependencies/Start.class +0 -0
- data/test/data/transitive_dependencies/Start.java +4 -0
- data/test/data/transitive_dependencies/make.bat +3 -0
- data/test/data/zip_file/commons-math-2.2-broken.zip +0 -0
- data/test/data/zip_file/regenerated-with-7zip.zip +0 -0
- data/test/data/zip_file/regenerated-with-jar.zip +0 -0
- data/test/dot_classpath.rb +33 -0
- data/test/logging_folder_classpath.rb +19 -0
- data/test/setup.rb +1 -1
- data/test/test_access_flags.rb +58 -32
- data/test/test_adder_tree.rb +78 -0
- data/test/test_any_classpath.rb +39 -0
- data/test/test_base.rb +9 -7
- data/test/test_caching_classpath.rb +41 -0
- data/test/test_class_entry.rb +60 -60
- data/test/test_class_magic.rb +31 -0
- data/test/test_class_version.rb +25 -25
- data/test/test_composite_classpath.rb +22 -23
- data/test/test_constant_pool.rb +37 -13
- data/test/test_convention_classpath.rb +39 -0
- data/test/test_eclipse_classpath.rb +73 -0
- data/test/test_factory.rb +61 -0
- data/test/test_folder_classpath.rb +26 -10
- data/test/test_imported_types.rb +34 -0
- data/test/test_jar_classpath.rb +29 -14
- data/test/test_jar_searcher.rb +27 -14
- data/test/test_java_class_header.rb +22 -10
- data/test/test_java_class_header_as_java_name.rb +41 -0
- data/test/test_java_home_classpath.rb +17 -11
- data/test/test_java_name.rb +204 -64
- data/test/test_java_name_factory.rb +52 -0
- data/test/test_java_name_scanner.rb +24 -0
- data/test/test_javaclass_api.rb +43 -0
- data/test/test_list.rb +58 -44
- data/test/test_load_directive.rb +34 -0
- data/test/test_maven_classpath.rb +46 -0
- data/test/test_package_entry.rb +27 -22
- data/test/test_references.rb +14 -14
- data/test/test_string_hexdump.rb +24 -0
- data/test/test_string_ux.rb +18 -106
- data/test/test_tracking_classpath.rb +112 -0
- data/test/test_transitive_dependencies.rb +31 -0
- data/test/test_unpacking_jar_classpath.rb +43 -0
- data/test/test_zip_file.rb +33 -0
- data/test/ts_all_tests.rb +80 -18
- data/thanks.txt +2 -0
- metadata +151 -22
- data/lib/javaclass/classpath/port_ClassPathEntry.java +0 -202
- data/lib/javaclass/classpath/port_ClassPathEntryFactory.java +0 -311
- data/lib/javaclass/classpath/port_DirectoryRepository.java +0 -24
- data/lib/javaclass/metric/ccd.rb +0 -68
- data/lib/javaclass/metric/class_usage.rb +0 -41
- data/test/test_javaclass.rb +0 -22
data/Rakefile
CHANGED
@@ -1,63 +1,56 @@
|
|
1
|
-
#require 'FileUtils' # already required
|
2
1
|
require 'net/http'
|
3
2
|
require 'rubygems'
|
4
3
|
require 'rubygems/gem_runner' # install and uninstall
|
4
|
+
require 'rubygems/package_task'
|
5
5
|
require 'rake'
|
6
6
|
require 'rake/clean' # for clean/clobber
|
7
7
|
require 'rake/testtask'
|
8
|
-
require 'rake/gempackagetask'
|
9
8
|
require 'rake/packagetask'
|
10
9
|
require 'rake/rdoctask'
|
10
|
+
require 'example_task'
|
11
11
|
|
12
12
|
# Test, package and publish functions.
|
13
|
-
# Author::
|
14
|
-
# See
|
15
|
-
|
16
|
-
|
13
|
+
# Author:: Peter Kofler
|
14
|
+
# See:: http://rake.rubyforge.org/files/doc/rakefile_rdoc.html
|
15
|
+
# Acknowledgement:: Building this Rake file was supported as System One Research Day. Thank you System One for funding Open Source :-)
|
16
|
+
|
17
17
|
RDOC_DIR = 'html'
|
18
18
|
RDOC_REPO = 'api'
|
19
19
|
|
20
|
-
gemspec =
|
21
|
-
s.version = '0.0.3'
|
22
|
-
s.name = GEM_NAME
|
23
|
-
s.rubyforge_project = 'javaclass' # old, just redirects
|
24
|
-
s.summary = 'A parser and disassembler for Java class files'
|
25
|
-
s.description = 'Provides access to the package, protected, and public fields and methods of the classes passed to it together with a list of all outgoing references.'
|
26
|
-
s.homepage = "http://code.google.com/p/#{GOOGLE_PROJECT}/"
|
27
|
-
s.author = 'Peter Kofler'
|
28
|
-
s.email = 'peter dot kofler at code minus cop dot org'
|
29
|
-
|
30
|
-
s.files = FileList['Readme.txt', '{lib,test,examples}/**/*.*', 'history.txt', 'Rakefile']
|
31
|
-
s.test_files = FileList['test/**/test_*.rb']
|
32
|
-
s.require_path = 'lib'
|
33
|
-
s.add_dependency('rubyzip', '>= 0.9.1')
|
34
|
-
s.required_ruby_version = '>= 1.8.6'
|
35
|
-
s.platform = Gem::Platform::RUBY
|
36
|
-
s.add_development_dependency('rake', '>= 0.8.4')
|
37
|
-
s.add_development_dependency('ZenTest', '>= 4.4.0')
|
38
|
-
|
39
|
-
s.has_rdoc = true
|
40
|
-
s.extra_rdoc_files = ['Readme.txt', 'history.txt']
|
41
|
-
s.rdoc_options << '--title' << "#{s.name}-#{s.version} Documentation" <<
|
42
|
-
'--main' << 'Readme.txt'
|
43
|
-
end
|
20
|
+
gemspec = eval(IO.readlines('javaclass.gemspec').join)
|
44
21
|
full_gem_name = "#{gemspec.name}-#{gemspec.version}"
|
45
22
|
|
46
23
|
desc 'Validates the gemspec'
|
47
|
-
task :validate_gem do
|
24
|
+
task :validate_gem do
|
48
25
|
gemspec.validate
|
49
26
|
end
|
50
27
|
|
51
28
|
desc 'Displays the current version'
|
52
|
-
task :version do
|
29
|
+
task :version do
|
53
30
|
puts gemspec.version
|
54
31
|
end
|
55
32
|
|
56
33
|
# :test
|
57
|
-
Rake::TestTask.new do |t|
|
34
|
+
Rake::TestTask.new do |t|
|
35
|
+
t.test_files = gemspec.test_files
|
36
|
+
t.warning = true
|
37
|
+
# t.verbose = false is default
|
38
|
+
end
|
39
|
+
|
40
|
+
begin
|
41
|
+
require 'rcov/rcovtask'
|
42
|
+
|
43
|
+
# :rcov
|
44
|
+
Rcov::RcovTask.new do |t|
|
58
45
|
t.test_files = gemspec.test_files
|
59
46
|
t.warning = true
|
60
|
-
|
47
|
+
t.rcov_opts << "--sort=coverage"
|
48
|
+
t.rcov_opts << "--only-uncovered"
|
49
|
+
end
|
50
|
+
|
51
|
+
rescue LoadError
|
52
|
+
# skip if not installed
|
53
|
+
warn("rcov not installed. coverage not available. #{$!}")
|
61
54
|
end
|
62
55
|
|
63
56
|
desc 'Find missing test methods with ZenTest'
|
@@ -68,12 +61,12 @@ task :zentest do
|
|
68
61
|
end
|
69
62
|
|
70
63
|
# :gem
|
71
|
-
|
64
|
+
Gem::PackageTask.new(gemspec) do |pkg|
|
72
65
|
pkg.need_zip = true
|
73
66
|
end
|
74
67
|
|
75
68
|
# :package, :clobber_package, :repackage
|
76
|
-
Rake::PackageTask.new(gemspec.name, gemspec.version) do |pkg|
|
69
|
+
Rake::PackageTask.new(gemspec.name, gemspec.version) do |pkg|
|
77
70
|
#pkg.need_tar = true - no compress in tar on unxutils in Windows
|
78
71
|
#pkg.need_tar_gz = true - no compress in tar on unxutils in Windows
|
79
72
|
pkg.need_zip = true
|
@@ -99,7 +92,9 @@ end
|
|
99
92
|
desc 'Tag current version in Hg'
|
100
93
|
task :tag do
|
101
94
|
hg ['tag', '-f', "-m \"Released gem version #{gemspec.version}\"", "#{full_gem_name}"]
|
95
|
+
# hg ['push']
|
102
96
|
puts 'Tag created. Don\'t forget to push'
|
97
|
+
puts 'hg push'
|
103
98
|
end
|
104
99
|
|
105
100
|
# internal - desc 'Release the gem to Rubygems'
|
@@ -112,11 +107,11 @@ end
|
|
112
107
|
# <code>HOME</code> environment must be set.
|
113
108
|
def user_pass_from_hgrc(authname)
|
114
109
|
lines = IO.readlines(File.expand_path('~/.hgrc'))
|
115
|
-
user = lines.find{ |l| l =~ /#{authname}.username/ }[/[^\s=]+$/]
|
110
|
+
user = lines.find{ |l| l =~ /#{authname}.username/ }[/[^\s=]+$/]
|
116
111
|
raise "could not find key #{authname}.username in ~/.hgrc" unless user
|
117
112
|
pass = lines.find{ |l| l =~ /#{authname}.password/ }[/[^\s=]+$/]
|
118
113
|
raise "could not find key #{authname}.password in ~/.hgrc" unless pass
|
119
|
-
[user, pass]
|
114
|
+
[user, pass]
|
120
115
|
end
|
121
116
|
|
122
117
|
# Download the <code>googlecode_upload.py</code> from Google Code repository and save it as _name_ .
|
@@ -142,19 +137,34 @@ task :release_googlecode => :package do
|
|
142
137
|
download_googlecode_upload_py 'googlecode_upload.py'
|
143
138
|
['gem', 'zip'].each do |extension|
|
144
139
|
puts "uploading \"pkg/#{full_gem_name}.#{extension}\"..."
|
145
|
-
python ['googlecode_upload.py', "-s \"JavaClass #{gemspec.version} #{extension.capitalize}\"",
|
140
|
+
python ['googlecode_upload.py', "-s \"JavaClass #{gemspec.version} #{extension.capitalize}\"",
|
141
|
+
"-p #{GOOGLE_PROJECT}", "-u #{user}", "-w #{pass}",
|
142
|
+
"pkg/#{full_gem_name}.#{extension}"]
|
146
143
|
end
|
147
144
|
end
|
148
145
|
|
149
146
|
desc 'Package and upload gem to Rubygems and Google Code'
|
150
|
-
task :publish_gem => [:clobber_package, :package, :release_rubygems, :release_googlecode]
|
147
|
+
task :publish_gem => [:clobber_package, :example, :package, :release_rubygems, :release_googlecode]
|
148
|
+
|
149
|
+
# :example, :clobber_example, :reexample
|
150
|
+
example_task_lib = Rake::ExampleTask.new do |example|
|
151
|
+
example.example_files.include 'examples/**/*.rb'
|
152
|
+
end
|
153
|
+
task :clobber_rdoc => [:clobber_example]
|
154
|
+
task :rdoc => [:example]
|
155
|
+
task :package => [:example]
|
151
156
|
|
152
157
|
# :rdoc, :clobber_rdoc, :rerdoc
|
153
158
|
Rake::RDocTask.new do |rdoc|
|
154
159
|
rdoc.rdoc_dir = RDOC_DIR # 'html' is default anyway
|
155
160
|
rdoc.title = "#{full_gem_name} Documentation"
|
156
161
|
rdoc.main = 'Readme.txt'
|
157
|
-
|
162
|
+
|
163
|
+
# examples are generated later and not necessarily available at definition time
|
164
|
+
examples = example_task_lib.conversion_pairs.map { |a| a[1] }
|
165
|
+
|
166
|
+
rdoc.rdoc_files.include *examples
|
167
|
+
rdoc.rdoc_files.include 'lib/**/*.rb', *gemspec.extra_rdoc_files
|
158
168
|
end
|
159
169
|
|
160
170
|
# Helper method to add target="_parent" to all external links in _file_ html.
|
@@ -162,7 +172,7 @@ def add_href_parent(file)
|
|
162
172
|
lines = IO.readlines(file).collect do |line|
|
163
173
|
if line =~ /(href=(?:'|")https?:\/\/)/
|
164
174
|
"#{$`}target=\"_parent\" #{$1}#{$'}"
|
165
|
-
else
|
175
|
+
else
|
166
176
|
line
|
167
177
|
end
|
168
178
|
end
|
@@ -170,8 +180,8 @@ def add_href_parent(file)
|
|
170
180
|
end
|
171
181
|
|
172
182
|
desc 'Fix the RDoc hrefs in framesets'
|
173
|
-
task :fix_rdoc => [:rdoc] do
|
174
|
-
Dir["#{RDOC_DIR}/**/*.html"].each { |file| add_href_parent(file) }
|
183
|
+
task :fix_rdoc => [:rdoc] do
|
184
|
+
Dir["#{RDOC_DIR}/**/*.html"].each { |file| add_href_parent(file) }
|
175
185
|
end
|
176
186
|
|
177
187
|
# Helper method to add the gem version _dir_ into index _file_ to frameset links.
|
@@ -179,7 +189,7 @@ def add_frameset_version(file, dir)
|
|
179
189
|
lines = IO.readlines(file).collect do |line|
|
180
190
|
if line =~ /(frame src=")/
|
181
191
|
"#{$`}#{$1}#{dir}/#{$'}"
|
182
|
-
else
|
192
|
+
else
|
183
193
|
line
|
184
194
|
end
|
185
195
|
end
|
@@ -187,35 +197,36 @@ def add_frameset_version(file, dir)
|
|
187
197
|
end
|
188
198
|
|
189
199
|
desc 'Publish the RDoc files to Google Code'
|
190
|
-
task :publish_rdoc => [:clobber_rdoc, :
|
200
|
+
task :publish_rdoc => [:clobber_rdoc, :fix_rdoc] do
|
191
201
|
puts "Releasing #{full_gem_name} to API"
|
192
|
-
|
193
|
-
remote_repo = "https://#{RDOC_REPO}.#{GOOGLE_PROJECT}.googlecode.com/hg/"
|
202
|
+
remote_repo = "https://code.google.com/p/#{GOOGLE_PROJECT}.#{RDOC_REPO}"
|
194
203
|
remote_dir = "#{gemspec.version}"
|
195
|
-
|
204
|
+
|
196
205
|
FileUtils.rm_r RDOC_REPO rescue nil
|
197
206
|
hg ['clone', remote_repo, RDOC_REPO]
|
198
|
-
|
207
|
+
|
199
208
|
FileUtils.rm_r "#{RDOC_REPO}/#{remote_dir}" rescue nil
|
200
209
|
FileUtils.cp_r RDOC_DIR, "#{RDOC_REPO}/#{remote_dir}"
|
201
|
-
|
210
|
+
|
202
211
|
# modify index, update redirect in frameset
|
203
212
|
file = "#{RDOC_REPO}/index.html"
|
204
213
|
FileUtils.cp "#{RDOC_REPO}/#{remote_dir}/index.html", file
|
205
214
|
add_frameset_version(file, remote_dir)
|
206
|
-
|
215
|
+
|
207
216
|
hg ['addremove', '-q', "-R #{RDOC_REPO}"]
|
208
217
|
hg ['ci', "-m \"Update Rdoc for version #{gemspec.version}\"", "-R #{RDOC_REPO}"]
|
209
218
|
hg ['tag', '-f', "-m \"Released gem version #{gemspec.version}\"", "-R #{RDOC_REPO}", "#{full_gem_name}"]
|
210
|
-
hg ['push', "-R #{RDOC_REPO}"]
|
219
|
+
# hg ['push', "-R #{RDOC_REPO}"]
|
220
|
+
puts 'API site created. Don\'t forget to push'
|
221
|
+
puts "hg push -R #{RDOC_REPO}"
|
211
222
|
end
|
212
223
|
|
213
|
-
# :clean :clobber
|
214
|
-
CLOBBER.include(RDOC_REPO, 'googlecode_upload.py')
|
224
|
+
# :clean :clobber
|
225
|
+
CLOBBER.include(RDOC_REPO, 'googlecode_upload.py', 'ClassLists', 'fullClassList*.txt')
|
215
226
|
|
216
227
|
# Helper method to grep all the sources for some _pattern_ words.
|
217
228
|
def egrep(pattern)
|
218
|
-
Dir['**/*'].find_all { |fn| FileTest.file? fn }.each do |fn|
|
229
|
+
Dir['**/*'].find_all { |fn| FileTest.file?(fn) && File.basename(fn) != /^\./ }.each do |fn|
|
219
230
|
line_count = 0
|
220
231
|
open(fn) do |f|
|
221
232
|
while line = f.gets
|
data/Readme.txt
CHANGED
@@ -17,10 +17,10 @@ of the classes passed to it together with a list of all outgoing references.
|
|
17
17
|
I am still doing Java most of the time. I used to be quite enthusiastic about
|
18
18
|
it, but after 11 years I can see the advantages of being a polyglot. So I use
|
19
19
|
Ruby for all kind of stuff, just for fun. When I needed some Java class
|
20
|
-
analysis I wrote it
|
20
|
+
analysis I wrote it in Ruby. As I am a puritan, I did not
|
21
21
|
want to call javap from my script, so I started disassembling the class files,
|
22
22
|
which might be the base for some serious static code analysis tools. (I
|
23
|
-
started adding methods to that end
|
23
|
+
{started adding methods}[link:/files/history_txt.html] to that end.)
|
24
24
|
|
25
25
|
== Install
|
26
26
|
|
@@ -29,56 +29,59 @@ started adding methods to that end...)
|
|
29
29
|
* {Gem Hosting}[http://rubygems.org/gems/javaclass]
|
30
30
|
* {Download of tarballs and gems}[http://code.google.com/p/javaclass-rb/downloads/list]
|
31
31
|
|
32
|
-
== Usage
|
33
|
-
|
34
|
-
require 'javaclass'
|
35
|
-
|
36
|
-
# load the class directly from the file system
|
37
|
-
clazz = JavaClass.load_fs('packagename/Public.class')
|
38
|
-
|
39
|
-
# better lookup the class from some classpath
|
40
|
-
classpath = JavaClass.classpath('some/path')
|
41
|
-
clazz = JavaClass.load_cp('packagename.Public', classpath)
|
42
|
-
|
43
|
-
clazz.version # => 50.0
|
44
|
-
clazz.constant_pool.items[1] # => packagename/Public
|
45
|
-
clazz.access_flags.public? # => true
|
46
|
-
clazz.this_class # => packagename/Public
|
47
|
-
clazz.this_class.to_java_file # => packagename/Public.java
|
48
|
-
clazz.super_class # => java/lang/Object
|
49
|
-
clazz.super_class.to_classname # => java.lang.Object
|
50
|
-
clazz.references.referenced_methods[0] # => java/lang/Object.<init>:()V
|
51
|
-
|
52
32
|
== Documentation
|
53
33
|
|
54
|
-
Module
|
55
|
-
|
56
|
-
|
57
|
-
|
34
|
+
Module JavaClass is the entry point for basic functions. All advanced functions are
|
35
|
+
available in Object through the JavaClass::Dsl::Mixin. The main class or the parser
|
36
|
+
is JavaClass::ClassFile::JavaClassHeader which provides access to all information
|
37
|
+
of a Java class file.
|
58
38
|
|
59
39
|
* {API RDoc}[http://api.javaclass-rb.googlecode.com/hg/index.html]
|
60
40
|
|
41
|
+
I tried hard to rdoc all classes and public methods, so just {read it}[http://api.javaclass-rb.googlecode.com/hg/index.html].
|
42
|
+
|
43
|
+
== Usage
|
44
|
+
|
45
|
+
See the various examples in the examples folder of the gem.
|
46
|
+
|
47
|
+
* {Basic Usage}[link:/files/lib/generated/examples/simple_usage_txt.html]
|
48
|
+
* {Number of classes in modules/JARs}[link:/files/lib/generated/examples/count_classes_in_modules_txt.html]
|
49
|
+
* {Check names of all interfaces}[link:/files/lib/generated/examples/check_interface_names_txt.html]
|
50
|
+
* {All imported types}[link:/files/lib/generated/examples/find_all_imported_types_txt.html]
|
51
|
+
* {Cumulative dependencies of a class}[link:/files/lib/generated/examples/cumulative_dependencies_txt.html]
|
52
|
+
* {Find (un)referenced JARs}[link:/files/lib/generated/examples/find_referenced_modules_txt.html]
|
53
|
+
* {Find unused classes}[link:/files/lib/generated/examples/find_unreferenced_classes_txt.html]
|
54
|
+
* {Generate lists of JDK classes}[link:/files/lib/generated/examples/generate_class_lists_txt.html]
|
55
|
+
|
56
|
+
There is some experimental logic to recognize Java class name literals in Ruby
|
57
|
+
which are mapped to JavaClass::JavaQualifiedName. Packages have to be suffixed
|
58
|
+
with ".*" to be recognized. See JavaClass::Dsl::JavaNameFactory for its usage.
|
59
|
+
|
61
60
|
== Support
|
62
61
|
|
63
|
-
The bug tracker is available at http://code.google.com/p/javaclass-rb/issues/list
|
62
|
+
The bug tracker is available at {Google Code}[http://code.google.com/p/javaclass-rb/issues/list]
|
63
|
+
or just drop me an email.
|
64
|
+
|
65
|
+
== How to submit patches
|
66
|
+
|
67
|
+
Read the {8 steps for fixing other people's code}[http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/]
|
68
|
+
and for section 8, use the {Issue Tracker}[http://code.google.com/p/javaclass-rb/issues/list].
|
69
|
+
|
70
|
+
The trunk repository is available with
|
71
|
+
|
72
|
+
hg clone https://javaclass-rb.googlecode.com/hg/ javaclass-rb
|
64
73
|
|
65
74
|
== Dependencies
|
66
75
|
|
67
|
-
* Ruby 1.8.6
|
68
|
-
* {rubyzip}[http://rubyzip.sourceforge.net/]
|
76
|
+
* Ruby 1.8.6 (runs with 1.8.7 and 1.9.1, too)
|
77
|
+
* {rubyzip}[http://rubyzip.sourceforge.net/] 0.9.1
|
69
78
|
|
70
79
|
== References
|
71
80
|
|
72
|
-
* {
|
73
|
-
* {
|
74
|
-
* {Similar Project by unageanu}[http://github.com/unageanu/javaclass]
|
81
|
+
* {The Java class file lifestyle}[http://www.javaworld.com/javaworld/jw-07-1996/jw-07-classfile.html], JavaWorld 1996.
|
82
|
+
* {The class File Format}[http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html], The Java Virtual Machine Specification, Second Edition.
|
83
|
+
* {Similar Project by unageanu}[http://github.com/unageanu/javaclass], GitHub 2010.
|
75
84
|
|
76
85
|
== License
|
77
86
|
|
78
|
-
* {
|
79
|
-
|
80
|
-
== Disclaimer Note
|
81
|
-
|
82
|
-
This software is provided "as is" and without any express or implied warranties,
|
83
|
-
including, without limitation, the implied warranties of merchantability and
|
84
|
-
fitness for a particular purpose.
|
87
|
+
* {BSD License}[http://www.opensource.org/licenses/bsd-license.php], it's enclosed in {license.txt}[link:/files/license_txt.html].
|
data/example_task.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
module Rake
|
5
|
+
|
6
|
+
# Create a documentation task that will generate the example files for a project.
|
7
|
+
#
|
8
|
+
# The ExampleTask will create the following targets:
|
9
|
+
#
|
10
|
+
# [<b>:<em>example</em></b>]
|
11
|
+
# Main task for this example task.
|
12
|
+
#
|
13
|
+
# [<b>:clobber_<em>example</em></b>]
|
14
|
+
# Delete all the example files. This target is automatically added to the main clobber target.
|
15
|
+
#
|
16
|
+
# [<b>:re<em>example</em></b>]
|
17
|
+
# Rebuild the example files from scratch, even if they are not out of date.
|
18
|
+
#
|
19
|
+
# Simple example:
|
20
|
+
#
|
21
|
+
# Rake::ExampleTask.new do |rd|
|
22
|
+
# rd.target_dir = 'generated/examples'
|
23
|
+
# rd.example_files.include('examples/**/*.rb')
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# The +rd+ object passed to the block is an ExampleTask object. See the
|
27
|
+
# attributes list for the ExampleTask class for available customization options.
|
28
|
+
#
|
29
|
+
# == Specifying different task names
|
30
|
+
#
|
31
|
+
# You may wish to give the task a different name, such as if you are generating two
|
32
|
+
# sets of examples. For instance, if you want to have a development set of examples:
|
33
|
+
#
|
34
|
+
# Rake::ExampleTask.new(:example_dev) do |rd|
|
35
|
+
# rd.example_files.include('dev_examples/**/*.rb')
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# The tasks would then be named :<em>example_dev</em>, :clobber_<em>example_dev</em>, and :re<em>example_dev</em>.
|
39
|
+
#
|
40
|
+
class ExampleTask < TaskLib
|
41
|
+
|
42
|
+
# Name of the main, top level task. (default is :example)
|
43
|
+
attr_accessor :name
|
44
|
+
|
45
|
+
# Name of directory to receive the example output files. (default is 'lib/generated/examples')
|
46
|
+
attr_accessor :target_dir
|
47
|
+
|
48
|
+
# List of files to be included in the example generation. (default is [])
|
49
|
+
attr_accessor :example_files
|
50
|
+
|
51
|
+
# Create the Example tasks with the given base _name_ .
|
52
|
+
def initialize(name = :example) # :yield: self
|
53
|
+
@name = name
|
54
|
+
@example_files = Rake::FileList.new
|
55
|
+
@target_dir = 'lib/generated/examples'
|
56
|
+
|
57
|
+
yield self if block_given?
|
58
|
+
|
59
|
+
define_tasks
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# Create the tasks defined by this task lib.
|
65
|
+
def define_tasks
|
66
|
+
define_repeat_task
|
67
|
+
define_clobber_task
|
68
|
+
define_build_task
|
69
|
+
end
|
70
|
+
|
71
|
+
def define_repeat_task
|
72
|
+
desc 'Force a rebuild of the example files'
|
73
|
+
task repeat_task_name => [clobber_task_name, build_task_name]
|
74
|
+
end
|
75
|
+
|
76
|
+
def define_clobber_task
|
77
|
+
desc 'Remove example products'
|
78
|
+
task clobber_task_name do
|
79
|
+
rm_r @target_dir rescue nil
|
80
|
+
end
|
81
|
+
|
82
|
+
task :clobber => [clobber_task_name]
|
83
|
+
end
|
84
|
+
|
85
|
+
def define_build_task
|
86
|
+
desc "Build the #{build_task_name} files"
|
87
|
+
task build_task_name
|
88
|
+
|
89
|
+
directory @target_dir
|
90
|
+
conversion_pairs.each { | a | define_transform(*a) }
|
91
|
+
end
|
92
|
+
|
93
|
+
def conversion_pairs
|
94
|
+
files_to_convert.map do |example_path|
|
95
|
+
[example_path, to_target_file(example_path)]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
public :conversion_pairs
|
99
|
+
|
100
|
+
def files_to_convert
|
101
|
+
@example_files.find_all { |example_path| convert?(example_path) }
|
102
|
+
end
|
103
|
+
|
104
|
+
def define_transform(example_path, example_target)
|
105
|
+
task build_task_name => [example_target]
|
106
|
+
file example_target => [example_path, Rake.application.rakefile] do
|
107
|
+
print '.'
|
108
|
+
transform(example_path, example_target)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def build_task_name
|
113
|
+
name.to_s
|
114
|
+
end
|
115
|
+
|
116
|
+
def clobber_task_name
|
117
|
+
"clobber_#{name}"
|
118
|
+
end
|
119
|
+
|
120
|
+
def repeat_task_name
|
121
|
+
"re#{name}"
|
122
|
+
end
|
123
|
+
|
124
|
+
def convert?(text_file)
|
125
|
+
IO.readlines(text_file).find { |line| line =~ /# *:nodoc:/ } == nil
|
126
|
+
end
|
127
|
+
|
128
|
+
def to_target_file(file)
|
129
|
+
target_file = File.basename(file)
|
130
|
+
target_file[/\.rb$/] = '.txt'
|
131
|
+
File.join(@target_dir, target_file)
|
132
|
+
end
|
133
|
+
|
134
|
+
def transform(source, dest)
|
135
|
+
input = IO.readlines(source)
|
136
|
+
if source =~ /\.rb$/
|
137
|
+
lines = commentify(input)
|
138
|
+
else
|
139
|
+
lines = source
|
140
|
+
end
|
141
|
+
save(dest, lines)
|
142
|
+
end
|
143
|
+
|
144
|
+
def commentify(input)
|
145
|
+
lines = []
|
146
|
+
input.inject(true) do |add, line|
|
147
|
+
if line =~ /^#--/
|
148
|
+
false
|
149
|
+
elsif line =~ /^#\+\+/
|
150
|
+
true
|
151
|
+
elsif !add
|
152
|
+
false
|
153
|
+
elsif line =~ /^#/
|
154
|
+
lines << line
|
155
|
+
true
|
156
|
+
else
|
157
|
+
lines << "# #{line}"
|
158
|
+
true
|
159
|
+
end
|
160
|
+
end
|
161
|
+
lines
|
162
|
+
end
|
163
|
+
|
164
|
+
def save(name, lines)
|
165
|
+
folder = File.dirname(name)
|
166
|
+
mkdir_p folder unless File.exist?(folder)
|
167
|
+
File.delete name rescue nil
|
168
|
+
File.open(name, 'w') { |f| f.print lines.join }
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Example usage of classpath and class files: Scan all classes of an workspace.
|
2
|
+
# Find all interfaces, print their names and find all which are prefixed with 'I'.
|
3
|
+
# Author:: Peter Kofler
|
4
|
+
# Copyright:: Copyright (c) 2009, Peter Kofler.
|
5
|
+
# License:: {BSD License}[link:/files/license_txt.html]
|
6
|
+
#
|
7
|
+
# === Steps
|
8
|
+
|
9
|
+
#--
|
10
|
+
# add the lib of this gem to the load path
|
11
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
12
|
+
require File.join(File.dirname(__FILE__), 'corpus')
|
13
|
+
|
14
|
+
location = Corpus[:Base]
|
15
|
+
package = 'at.kugel'
|
16
|
+
#++
|
17
|
+
require 'javaclass/dsl/mixin'
|
18
|
+
|
19
|
+
# 1) define the location of the project and a package you are interrested
|
20
|
+
# location = 'C:\Eclipse\workspace'
|
21
|
+
# package = 'com.biz.app'
|
22
|
+
|
23
|
+
# e.g. add an Eclipse classpath variable to find external dependencies.
|
24
|
+
Eclipse.add_variable('KOR_HOME', location)
|
25
|
+
|
26
|
+
# 2) create the classpath of the given workspace
|
27
|
+
cp = workspace(location)
|
28
|
+
puts "#{cp.elements.size} classpaths found under the workspace #{location}:"
|
29
|
+
puts " #{cp.elements.join("\n ")}"
|
30
|
+
puts "#{cp.count} classes found on classpath"
|
31
|
+
|
32
|
+
# 3) filter the classes to analyse, using JavaClass::JavaQualifiedName methods
|
33
|
+
to_analyse = cp.names { |classname| classname.same_or_subpackage_of?(package) }
|
34
|
+
puts "#{to_analyse.size} classes matched #{package}"
|
35
|
+
|
36
|
+
# 4) load all selected classes, parse into JavaClass::ClassFile, find all interfaces and collect their qualified names
|
37
|
+
names = cp.values(to_analyse).
|
38
|
+
find_all { |clazz| clazz.interface? }.
|
39
|
+
collect { |clazz| clazz.to_classname }
|
40
|
+
puts "#{names.size} interfaces found:\n #{names.sort.join("\n ")}"
|
41
|
+
|
42
|
+
# 5) print all qualified names have a simple namee staring with an I
|
43
|
+
inames = names.find_all { |classname| classname.simple_name =~ /^I[A-Z][a-z]/ }
|
44
|
+
puts "#{inames.size} interfaces start with I:\n #{inames.join("\n ")}"
|
data/examples/corpus.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# :nodoc:
|
2
|
+
# Set location of the test data corpus.
|
3
|
+
corpus_root = 'E:\OfficeDateien\Corpus'
|
4
|
+
Corpus = Hash[
|
5
|
+
*[
|
6
|
+
%w[Sun10 Java1_JDK-1.0.2(Sun_official) ],
|
7
|
+
%w[WF Java2_Swing(WF_iMagine) ],
|
8
|
+
%w[S1 Java5_Batch(S1_Fabric) ],
|
9
|
+
%w[Harmony15 Java5_JDK-1.5M15-r991518(Apache_Harmony) ],
|
10
|
+
%w[Harmony16 Java5_JDK-1.6M3-r991881(Apache_Harmony) ],
|
11
|
+
%w[RCP Java5_RCP_2011(IBM_Costing) ],
|
12
|
+
%w[BIA Java6_Swing(BIA_Monarch) ],
|
13
|
+
%w[HBD Java6_Web(HBD_Online) ],
|
14
|
+
].map { |pair|
|
15
|
+
[pair[0].to_sym, File.join(corpus_root, pair[1])]
|
16
|
+
}.flatten
|
17
|
+
]
|
18
|
+
Corpus[:Base] = 'E:\Develop\Java'
|
19
|
+
Corpus[:Lib] = 'E:\Develop\Java\CodeLib'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Example usage of classpath (JavaClass::Classpath): Scan all classpaths (e.g. modules)
|
2
|
+
# of an an Eclipse "workspace". A workspace is a folder containing several Eclipse
|
3
|
+
# projects, e.g. JavaClass::Classpath::EclipseClasspath. Report the number of found
|
4
|
+
# classes per module.
|
5
|
+
# Author:: Peter Kofler
|
6
|
+
# Copyright:: Copyright (c) 2009, Peter Kofler.
|
7
|
+
# License:: {BSD License}[link:/files/license_txt.html]
|
8
|
+
#
|
9
|
+
# === Steps
|
10
|
+
|
11
|
+
#--
|
12
|
+
# add the lib of this gem to the load path
|
13
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
14
|
+
require File.join(File.dirname(__FILE__), 'corpus')
|
15
|
+
|
16
|
+
location = Corpus[:HBD]
|
17
|
+
#++
|
18
|
+
require 'javaclass/classpath/factory'
|
19
|
+
include JavaClass::Classpath::Factory
|
20
|
+
# The require/include above just imports what is needed, but usually one would require the whole
|
21
|
+
# JavaClass::Dsl::Mixin for conveniance, e.g. require 'javaclass/dsl/mixin'.
|
22
|
+
|
23
|
+
# 1) define the location of the project
|
24
|
+
# location = 'C:\Eclipse\workspace'
|
25
|
+
|
26
|
+
# 2) create a JavaClass::Classpath::CompositeClasspath of the complete workspace, which will contain many classpath elements.
|
27
|
+
cp = workspace(location)
|
28
|
+
puts "#{cp.elements.size} classpaths found under the workspace #{location}"
|
29
|
+
|
30
|
+
# 3a) find all empty elements by querying the classpath elements
|
31
|
+
empty = cp.elements.find_all { |clp| clp.count == 0 }
|
32
|
+
puts "\n#{empty.size} empty modules found:\n #{empty.join("\n ")}"
|
33
|
+
|
34
|
+
# 3b) or print the list of each element with its class count
|
35
|
+
puts "library (module path): number of contained classes"
|
36
|
+
puts cp.elements.map { |clp| [clp.to_s, clp.count] }.
|
37
|
+
sort { |a,b| a[1] <=> b[1] }.
|
38
|
+
map { |e| " #{e[0]}: #{e[1]}" }
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Example usage of the featuress of JavaClass::Analyse::TransitiveDependencies
|
2
|
+
# to collect all transitive dependencies of a certain class or a whole package
|
3
|
+
# (Cumulative Component Dependencies).
|
4
|
+
# Author:: Peter Kofler
|
5
|
+
# Copyright:: Copyright (c) 2009, Peter Kofler.
|
6
|
+
# License:: {BSD License}[link:/files/license_txt.html]
|
7
|
+
# See:: Another example how to {list all imported types}[link:/files/lib/generated/examples/find_all_imported_types_txt.html]
|
8
|
+
#
|
9
|
+
# === Steps
|
10
|
+
|
11
|
+
#--
|
12
|
+
# add the lib of this gem to the load path
|
13
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
14
|
+
require File.join(File.dirname(__FILE__), 'corpus')
|
15
|
+
|
16
|
+
location = Corpus[:HBD]
|
17
|
+
package = 'at.herold'
|
18
|
+
start_class = 'at.herold.waf.hbd.servlet.HBDServlet'
|
19
|
+
# 'at/spardat/krimiaps/service/client/service/impl/ClientSmeSearchServiceImpl'
|
20
|
+
# 'at/spardat/krimiaps/service/client/service/impl/ClientPrivateSearchServiceImpl'
|
21
|
+
#++
|
22
|
+
require 'javaclass/dsl/mixin'
|
23
|
+
|
24
|
+
# 1) create the classpath of the given workspace
|
25
|
+
cp = workspace(location)
|
26
|
+
puts "#{cp.count} classes found on classpath"
|
27
|
+
|
28
|
+
# define a filter to limit all operations to the classes we are interested in
|
29
|
+
filter = Proc.new { |classname| classname.same_or_subpackage_of?(package) }
|
30
|
+
|
31
|
+
# 2a) collect all transitive dependencies of a single class into an AdderTree
|
32
|
+
dependencies = cp.transitive_dependency_tree(start_class.to_javaname, &filter)
|
33
|
+
puts "#{dependencies.size} classes in transitive dependency graph of class #{start_class}"
|
34
|
+
dependencies.debug_print
|
35
|
+
|
36
|
+
# 2b) or collect all transitive dependencies of a whole package
|
37
|
+
dependencies = cp.transitive_dependencies_package(start_class.to_javaname.package, &filter)
|
38
|
+
puts "#{dependencies.size} classes in transitive dependency graph of package"
|
39
|
+
# dependencies.debug_print
|