javaclass 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
@@ -1,99 +1,113 @@
|
|
1
1
|
require 'javaclass/classfile/constants/single_reference'
|
2
2
|
require 'javaclass/java_name'
|
3
3
|
|
4
|
-
module JavaClass
|
5
|
-
module ClassFile
|
6
|
-
module Constants
|
7
|
-
|
8
|
-
# Superclass of double reference constants like +ConstantField+ (+FieldRef+) in the constant pool.
|
4
|
+
module JavaClass
|
5
|
+
module ClassFile
|
6
|
+
module Constants
|
7
|
+
|
8
|
+
# Superclass of double reference constants like +ConstantField+ (+FieldRef+) in the constant pool.
|
9
9
|
# Author:: Peter Kofler
|
10
10
|
class DoubleReference < SingleReference
|
11
|
-
|
11
|
+
|
12
12
|
attr_reader :second_index
|
13
|
-
|
13
|
+
|
14
14
|
# Define a double reference into _pool_ from _data_ beginning at _start_
|
15
15
|
def initialize(pool, data, start, name=nil)
|
16
16
|
super(pool, data, start, name)
|
17
17
|
@size = 5
|
18
|
-
|
18
|
+
|
19
19
|
@second_index = data.u2(start+3)
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
# Return the second value, which is the referenced value from the pool.
|
23
23
|
def second_value
|
24
24
|
get(@second_index)
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
# Return the value, which are both referenced values from the pool.
|
28
28
|
def to_s
|
29
29
|
"#{super}.#{second_value}"
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
# Return part of debug output.
|
33
33
|
def dump
|
34
34
|
"#{@name}\t##{@first_index}.##{@second_index};\t// #{to_s}"
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
class ConstantField < DoubleReference # ZenTest SKIP
|
40
|
-
alias class_index first_index
|
41
|
-
alias name_and_type_index second_index
|
42
|
-
|
40
|
+
alias class_index first_index
|
41
|
+
alias name_and_type_index second_index
|
42
|
+
|
43
|
+
def initialize(pool, data, start)
|
43
44
|
super(pool, data, start)
|
44
45
|
end
|
45
|
-
|
46
|
-
|
47
|
-
super
|
46
|
+
|
47
|
+
def first_value
|
48
|
+
JavaVMName.new(super) # this is a classname
|
48
49
|
end
|
49
50
|
alias class_name first_value
|
50
51
|
alias signature second_value
|
52
|
+
|
53
|
+
def const_field?
|
54
|
+
true
|
55
|
+
end
|
51
56
|
end
|
52
|
-
|
57
|
+
|
53
58
|
class ConstantMethod < DoubleReference # ZenTest SKIP
|
54
|
-
alias class_index first_index
|
55
|
-
alias name_and_type_index second_index
|
56
|
-
|
59
|
+
alias class_index first_index
|
60
|
+
alias name_and_type_index second_index
|
61
|
+
|
62
|
+
def initialize(pool, data, start)
|
57
63
|
super(pool, data, start)
|
58
|
-
end
|
59
|
-
def first_value
|
60
|
-
# is a classname
|
61
|
-
super.to_javaname
|
62
64
|
end
|
65
|
+
|
66
|
+
def first_value
|
67
|
+
JavaVMName.new(super) # this is a classname
|
68
|
+
end
|
69
|
+
|
63
70
|
alias class_name first_value
|
64
71
|
alias signature second_value
|
72
|
+
|
73
|
+
def const_method?
|
74
|
+
true
|
75
|
+
end
|
65
76
|
end
|
66
|
-
|
77
|
+
|
67
78
|
class ConstantInterfaceMethod < DoubleReference # ZenTest SKIP
|
68
|
-
alias class_index first_index
|
69
|
-
alias name_and_type_index second_index
|
70
|
-
|
79
|
+
alias class_index first_index
|
80
|
+
alias name_and_type_index second_index
|
81
|
+
|
82
|
+
def initialize(pool, data, start)
|
71
83
|
super(pool, data, start)
|
72
|
-
end
|
73
|
-
def first_value
|
74
|
-
# is a classname
|
75
|
-
super.to_javaname
|
76
84
|
end
|
85
|
+
|
86
|
+
def first_value
|
87
|
+
JavaVMName.new(super) # this is a classname
|
88
|
+
end
|
89
|
+
|
77
90
|
alias class_name first_value
|
78
91
|
alias signature second_value
|
79
92
|
end
|
80
|
-
|
93
|
+
|
81
94
|
class ConstantNameAndType < DoubleReference # ZenTest SKIP
|
82
|
-
alias name_index first_index
|
83
|
-
alias descriptor_index second_index
|
95
|
+
alias name_index first_index
|
96
|
+
alias descriptor_index second_index
|
97
|
+
|
84
98
|
def initialize(pool, data, start)
|
85
99
|
super(pool, data, start)
|
86
100
|
end
|
87
|
-
|
101
|
+
|
88
102
|
def to_s
|
89
103
|
"#{get(name_index)}:#{get(descriptor_index)}"
|
90
104
|
end
|
91
|
-
|
105
|
+
|
92
106
|
def dump
|
93
107
|
"#{@name}\t##{name_index}:##{descriptor_index};// #{to_s}"
|
94
108
|
end
|
95
109
|
end
|
96
|
-
|
110
|
+
|
97
111
|
end
|
98
112
|
end
|
99
113
|
end
|
@@ -1,65 +1,73 @@
|
|
1
1
|
require 'javaclass/classfile/constants/base'
|
2
2
|
require 'javaclass/java_name'
|
3
3
|
|
4
|
-
module JavaClass
|
5
|
-
module ClassFile
|
6
|
-
module Constants
|
7
|
-
|
8
|
-
# Superclass of single reference constants like +ConstantClass+ (+Class+) in the constant pool.
|
4
|
+
module JavaClass
|
5
|
+
module ClassFile
|
6
|
+
module Constants
|
7
|
+
|
8
|
+
# Superclass of single reference constants like +ConstantClass+ (+Class+) in the constant pool.
|
9
9
|
# Author:: Peter Kofler
|
10
10
|
class SingleReference < Base
|
11
|
-
|
11
|
+
|
12
12
|
attr_reader :first_index
|
13
|
-
|
13
|
+
|
14
14
|
# Define a single reference into _pool_ from _data_ beginning at _start_
|
15
15
|
def initialize(pool, data, start, name=nil)
|
16
16
|
super(name)
|
17
17
|
@tag = data.u1(start)
|
18
|
-
|
18
|
+
|
19
19
|
@enclosing_pool = pool
|
20
20
|
@first_index = data.u2(start+1)
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# Return the value, which is the referenced value from the pool.
|
24
24
|
def first_value
|
25
25
|
get(@first_index)
|
26
26
|
end
|
27
|
-
|
28
|
-
|
27
|
+
def to_s
|
28
|
+
first_value
|
29
|
+
end
|
30
|
+
|
29
31
|
# Return part of debug output.
|
30
32
|
def dump
|
31
33
|
super + "##{@first_index};\t// #{to_s}"
|
32
34
|
end
|
33
|
-
|
35
|
+
|
34
36
|
protected
|
35
|
-
|
37
|
+
|
36
38
|
# Get a reference _ref_ from the +enclosing_pool+
|
37
39
|
def get(ref)
|
38
40
|
@enclosing_pool[ref].to_s
|
39
41
|
end
|
40
|
-
|
42
|
+
|
41
43
|
end
|
42
|
-
|
44
|
+
|
43
45
|
class ConstantClass < SingleReference # ZenTest SKIP
|
44
46
|
alias name_index first_index
|
47
|
+
|
45
48
|
def initialize(pool, data, start)
|
46
49
|
super(pool, data, start, "class")
|
47
50
|
end
|
48
|
-
|
49
|
-
|
50
|
-
super
|
51
|
+
|
52
|
+
def first_value
|
53
|
+
JavaVMName.new(super) # this is a classname
|
51
54
|
end
|
52
55
|
alias class_name first_value
|
56
|
+
|
57
|
+
def const_class?
|
58
|
+
true
|
59
|
+
end
|
53
60
|
end
|
54
|
-
|
61
|
+
|
55
62
|
class ConstantString < SingleReference # ZenTest SKIP
|
56
63
|
alias string_index first_index
|
57
|
-
|
64
|
+
|
65
|
+
def initialize(pool, data, start)
|
58
66
|
super(pool, data, start)
|
59
67
|
end
|
60
68
|
alias string_value first_value
|
61
69
|
end
|
62
|
-
|
70
|
+
|
63
71
|
end
|
64
72
|
end
|
65
73
|
end
|
@@ -1,116 +1,126 @@
|
|
1
1
|
require 'javaclass/classfile/constants/base'
|
2
2
|
|
3
|
-
module JavaClass
|
4
|
-
module ClassFile
|
5
|
-
module Constants
|
6
|
-
|
7
|
-
# Superclass of value constants like +ConstantInt+ (+Integer+) in the constant pool.
|
3
|
+
module JavaClass
|
4
|
+
module ClassFile
|
5
|
+
module Constants
|
6
|
+
|
7
|
+
# Superclass of value constants like +ConstantInt+ (+Integer+) in the constant pool.
|
8
8
|
# Author:: Peter Kofler
|
9
9
|
class Value < Base
|
10
|
-
|
10
|
+
|
11
11
|
attr_reader :value
|
12
|
-
|
12
|
+
|
13
13
|
# Create a constant value with an optional downcase _name_
|
14
14
|
def initialize(name=self.class.to_s[/::[^:]+$/][10..-1].downcase)
|
15
15
|
super(name)
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
# Return the value as string.
|
19
19
|
def to_s
|
20
20
|
@value.to_s
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# Return part of debug output.
|
24
24
|
def dump
|
25
|
-
super +
|
25
|
+
super + to_s
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
protected
|
29
|
-
|
29
|
+
|
30
30
|
# Define a +value+ from _data_ beginning at position _start_ with the _size_ in bytes and _slots_ (1 or 2).
|
31
31
|
def get_value(data, start, size, slots=1)
|
32
32
|
@tag = data.u1(start)
|
33
33
|
@size = size
|
34
34
|
@slots = slots
|
35
|
-
|
35
|
+
|
36
36
|
data[start+1..start+size-1]
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
# Dummy method to "fix" unused warning of param _pool_ in Eclipse.
|
40
40
|
def silence_unused_warning(pool)
|
41
|
-
raise
|
41
|
+
raise ArgumentError, 'pool is nil' unless pool
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
class ConstantInt < Value # ZenTest SKIP
|
47
|
-
|
47
|
+
|
48
|
+
def initialize(pool, data, start)
|
48
49
|
super()
|
49
50
|
silence_unused_warning(pool)
|
50
51
|
@value = get_value(data, start, 5).u4
|
51
52
|
end
|
52
|
-
|
53
|
+
|
53
54
|
def dump
|
54
55
|
super + ';'
|
55
56
|
end
|
56
57
|
end
|
57
|
-
|
58
|
+
|
58
59
|
class ConstantFloat < Value # ZenTest SKIP
|
59
|
-
|
60
|
+
|
61
|
+
def initialize(pool, data, start)
|
60
62
|
super()
|
61
63
|
silence_unused_warning(pool)
|
62
|
-
@value = get_value(data, start, 5).single
|
64
|
+
@value = get_value(data, start, 5).single
|
63
65
|
end
|
66
|
+
|
64
67
|
def to_s
|
65
|
-
|
68
|
+
sprintf('%.14e', @value).sub(/e(\+|-)0+/, 'e\\1')
|
66
69
|
end
|
70
|
+
|
67
71
|
def dump
|
68
72
|
super + 'f;'
|
69
73
|
end
|
70
74
|
end
|
71
|
-
|
75
|
+
|
72
76
|
class ConstantLong < Value # ZenTest SKIP
|
73
|
-
|
77
|
+
|
78
|
+
def initialize(pool, data, start)
|
74
79
|
super()
|
75
80
|
silence_unused_warning(pool)
|
76
81
|
@value = get_value(data, start, 9, 2).u8
|
77
82
|
end
|
83
|
+
|
78
84
|
def dump
|
79
85
|
super + 'l;'
|
80
86
|
end
|
81
87
|
end
|
82
|
-
|
88
|
+
|
83
89
|
class ConstantDouble < Value # ZenTest SKIP
|
84
|
-
|
90
|
+
|
91
|
+
def initialize(pool, data, start)
|
85
92
|
super()
|
86
93
|
silence_unused_warning(pool)
|
87
94
|
@value = get_value(data, start, 9, 2).double
|
88
95
|
end
|
96
|
+
|
89
97
|
def to_s
|
90
|
-
@value.
|
98
|
+
sprintf('%.14e', @value).sub(/e(\+|-)0+/, 'e\\1')
|
91
99
|
end
|
100
|
+
|
92
101
|
def dump
|
93
102
|
super + 'd;'
|
94
103
|
end
|
95
104
|
end
|
96
|
-
|
105
|
+
|
97
106
|
class ConstantAsciz < Value # ZenTest SKIP
|
98
107
|
alias string value
|
99
|
-
|
108
|
+
|
109
|
+
def initialize(pool, data, start)
|
100
110
|
super('Asciz')
|
101
111
|
silence_unused_warning(pool)
|
102
112
|
@tag = data.u1(start)
|
103
|
-
|
113
|
+
|
104
114
|
@length = data.u2(start+1)
|
105
115
|
@size = 3 + @length
|
106
116
|
@value = data[start+3..start+3+@length-1]
|
107
117
|
end
|
108
|
-
|
118
|
+
|
109
119
|
def dump
|
110
120
|
super + ';'
|
111
121
|
end
|
112
122
|
end
|
113
|
-
|
123
|
+
|
114
124
|
end
|
115
125
|
end
|
116
126
|
end
|
@@ -6,89 +6,115 @@ require 'javaclass/classfile/references'
|
|
6
6
|
require 'javaclass/classfile/access_flags'
|
7
7
|
require 'javaclass/java_name'
|
8
8
|
|
9
|
-
module JavaClass
|
10
|
-
|
11
|
-
|
9
|
+
module JavaClass
|
10
|
+
|
11
|
+
# The module ClassFile is for separating namespaces. It contains the logic
|
12
|
+
# to parse a Java class file. This logic is tied to the JVM specification
|
13
|
+
# of class files, very low-level and has no usage/DSL features.
|
14
|
+
# The main entry point is JavaClassHeader. It's the only "public" class
|
15
|
+
# of the module, so the only class to require from outside.
|
16
|
+
# Author:: Peter Kofler
|
17
|
+
module ClassFile
|
18
|
+
|
12
19
|
# Parse and disassemble Java class files, similar to the +javap+ command.
|
13
20
|
# Provides all information of a Java class file. This is just a container for all kind of
|
14
|
-
# specialised elements. The constuctor parses and creates all contained elements.
|
21
|
+
# specialised elements. The constuctor parses and creates all contained elements.
|
15
22
|
# See:: http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html
|
16
23
|
# See:: {en.wikipedia.org/wiki/Class}[http://en.wikipedia.org/wiki/Class_(file_format)]
|
17
24
|
# Author:: Peter Kofler
|
18
25
|
class JavaClassHeader
|
19
|
-
|
20
|
-
attr_reader :magic
|
26
|
+
|
27
|
+
attr_reader :magic
|
21
28
|
attr_reader :version
|
22
29
|
attr_reader :constant_pool
|
23
30
|
attr_reader :access_flags
|
24
31
|
attr_reader :references
|
25
|
-
|
32
|
+
attr_reader :interfaces
|
33
|
+
|
26
34
|
# Create a header with the binary _data_ from the class file.
|
27
35
|
def initialize(data)
|
28
|
-
|
36
|
+
|
29
37
|
# ClassFile {
|
30
|
-
# u4 magic;
|
31
|
-
|
32
|
-
|
33
|
-
# u2
|
34
|
-
#
|
35
|
-
|
36
|
-
|
37
|
-
# u2
|
38
|
-
#
|
38
|
+
# u4 magic;
|
39
|
+
@magic = ClassMagic.new(data)
|
40
|
+
|
41
|
+
# u2 minor_version;
|
42
|
+
# u2 major_version;
|
43
|
+
@version = ClassVersion.new(data)
|
44
|
+
|
45
|
+
# u2 constant_pool_count;
|
46
|
+
# cp_info constant_pool[constant_pool_count-1];
|
47
|
+
@constant_pool = ConstantPool.new(data)
|
48
|
+
pos = 8 + @constant_pool.size
|
49
|
+
|
50
|
+
# u2 access_flags;
|
51
|
+
@access_flags = AccessFlags.new(data, pos)
|
52
|
+
pos += 2
|
53
|
+
|
54
|
+
# u2 this_class;
|
55
|
+
@this_class_idx = data.u2(pos)
|
56
|
+
pos += 2
|
57
|
+
|
58
|
+
# u2 super_class;
|
59
|
+
@super_class_idx = data.u2(pos)
|
60
|
+
pos += 2
|
61
|
+
|
39
62
|
# u2 interfaces_count;
|
40
63
|
# u2 interfaces[interfaces_count];
|
64
|
+
count = data.u2(pos)
|
65
|
+
@interfaces = data.u2rep(count, pos + 2).collect { |i| @constant_pool.class_item(i) }
|
66
|
+
pos += 2 + count*2
|
67
|
+
|
68
|
+
# TODO Implement parsing of fields and methods of the JVM spec
|
41
69
|
# u2 fields_count;
|
42
70
|
# field_info fields[fields_count];
|
71
|
+
# count = data.u2(pos)
|
72
|
+
# @fields = data.u2rep(count, pos + 2).collect { |i| @constant_pool.field_item(i) }
|
73
|
+
# pos += 2 + count*2
|
74
|
+
|
43
75
|
# u2 methods_count;
|
44
76
|
# method_info methods[methods_count];
|
77
|
+
# count = data.u2(pos)
|
78
|
+
# @methods = data.u2rep(count, pos + 2).collect { |i| @constant_pool.method_item(i) }
|
79
|
+
# pos += 2 + count*2
|
80
|
+
|
45
81
|
# u2 attributes_count;
|
46
82
|
# attribute_info attributes[attributes_count];
|
47
83
|
# }
|
48
|
-
# TODO Java 1.0 - "private protected" fields.
|
49
|
-
|
50
|
-
@magic = ClassMagic.new(data)
|
51
|
-
@version = ClassVersion.new(data)
|
52
|
-
|
53
|
-
@constant_pool = ConstantPool.new(data)
|
54
|
-
pos = 8 + @constant_pool.size
|
55
|
-
|
56
|
-
@access_flags = AccessFlags.new(data, pos)
|
57
|
-
pos += 2
|
58
|
-
|
59
|
-
idx = data.u2(pos)
|
60
|
-
pos += 2
|
61
|
-
@this_class_idx = idx
|
62
|
-
|
63
84
|
@references = References.new(@constant_pool, @this_class_idx)
|
64
85
|
|
65
|
-
|
66
|
-
|
67
|
-
|
86
|
+
# Body {
|
87
|
+
# Class: add the byte code sequences to the methods so it can be analysed later (see JVM spec)
|
88
|
+
# }
|
89
|
+
|
68
90
|
end
|
69
|
-
|
70
|
-
# Return the name of this class.
|
91
|
+
|
92
|
+
# Return the name of this class. Returns a JavaVMName.
|
71
93
|
def this_class
|
72
|
-
|
94
|
+
# This is a ConstantClass entry in the constant pool.
|
95
|
+
@jvmname ||= @constant_pool.class_item(@this_class_idx).class_name
|
73
96
|
end
|
74
|
-
|
75
|
-
# Return the name of the superclass of this class or +nil+.
|
97
|
+
|
98
|
+
# Return the name of the superclass of this class or +nil+. Returns a JavaVMName.
|
76
99
|
def super_class
|
77
100
|
if @super_class_idx > 0
|
78
|
-
|
101
|
+
# This is a ConstantClass entry in the constant pool.
|
102
|
+
@constant_pool.class_item(@super_class_idx).class_name
|
79
103
|
else
|
104
|
+
# special case: java.lang.Object has no superclass
|
80
105
|
nil
|
81
106
|
end
|
82
107
|
end
|
83
|
-
|
108
|
+
|
84
109
|
# Return a debug output of this class that looks similar to +javap+ output.
|
85
110
|
def dump
|
86
111
|
d = []
|
87
112
|
mod = @access_flags.public? ? 'public ' : ''
|
88
|
-
ext = super_class ? "extends #{super_class.to_classname}" : ''
|
89
|
-
|
113
|
+
ext = super_class ? " extends #{super_class.to_classname}" : ''
|
114
|
+
int = !@interfaces.empty? ? " implements #{@interfaces.join(',')}" : ''
|
115
|
+
d << "#{mod}class #{this_class.to_classname}#{ext}#{int}"
|
90
116
|
# d << " SourceFile: \"#{read from LineNumberTable?}\""
|
91
|
-
d += @version.dump
|
117
|
+
d += @version.dump
|
92
118
|
d += @constant_pool.dump
|
93
119
|
d << ''
|
94
120
|
d << '{'
|
@@ -97,6 +123,6 @@ module JavaClass
|
|
97
123
|
end
|
98
124
|
|
99
125
|
end
|
100
|
-
|
126
|
+
|
101
127
|
end
|
102
128
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'javaclass/delegate_directive'
|
2
|
+
|
3
|
+
module JavaClass
|
4
|
+
module ClassFile
|
5
|
+
|
6
|
+
class JavaClassHeader
|
7
|
+
extend DelegateDirective
|
8
|
+
|
9
|
+
# Extend JavaClassHeader to behave like a JavaName in delegating to _this_class_ method which returns a JavaVMName.
|
10
|
+
def to_javaname
|
11
|
+
this_class
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_jvmname
|
15
|
+
this_class
|
16
|
+
end
|
17
|
+
|
18
|
+
delegate :to_classname, :this_class
|
19
|
+
delegate :to_java_file, :this_class
|
20
|
+
delegate :to_class_file, :this_class
|
21
|
+
|
22
|
+
delegate :package, :this_class
|
23
|
+
delegate :simple_name, :this_class
|
24
|
+
delegate :full_name, :this_class
|
25
|
+
delegate :same_or_subpackage_of?, :this_class
|
26
|
+
delegate :subpackage_of?, :this_class
|
27
|
+
delegate :split_simple_name, :this_class
|
28
|
+
delegate :in_jdk?, :this_class
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module JavaClass
|
2
|
+
module ClassFile
|
3
|
+
|
4
|
+
class JavaClassHeader
|
5
|
+
|
6
|
+
# Is this class an interface (and not an annotation)?
|
7
|
+
def interface?
|
8
|
+
access_flags.interface? && !access_flags.annotation?
|
9
|
+
end
|
10
|
+
|
11
|
+
# Is this class an abstract class (and not an interface)?
|
12
|
+
def abstract_class?
|
13
|
+
access_flags.abstract? && !access_flags.interface?
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|