36 |
36 |
37 // A KlassStream is an abstract stream for streaming over self, superclasses |
37 // A KlassStream is an abstract stream for streaming over self, superclasses |
38 // and (super)interfaces. Streaming is done in reverse order (subclasses first, |
38 // and (super)interfaces. Streaming is done in reverse order (subclasses first, |
39 // interfaces last). |
39 // interfaces last). |
40 // |
40 // |
41 // for (KlassStream st(k, false, false); !st.eos(); st.next()) { |
41 // for (KlassStream st(k, false, false, false); !st.eos(); st.next()) { |
42 // Klass* k = st.klass(); |
42 // Klass* k = st.klass(); |
43 // ... |
43 // ... |
44 // } |
44 // } |
45 |
45 |
46 class KlassStream VALUE_OBJ_CLASS_SPEC { |
46 class KlassStream VALUE_OBJ_CLASS_SPEC { |
47 protected: |
47 protected: |
48 instanceKlassHandle _klass; // current klass/interface iterated over |
48 instanceKlassHandle _klass; // current klass/interface iterated over |
49 Array<Klass*>* _interfaces; // transitive interfaces for initial class |
49 instanceKlassHandle _base_klass; // initial klass/interface to iterate over |
|
50 Array<Klass*>* _interfaces; // transitive interfaces for initial class |
50 int _interface_index; // current interface being processed |
51 int _interface_index; // current interface being processed |
51 bool _local_only; // process initial class/interface only |
52 bool _local_only; // process initial class/interface only |
52 bool _classes_only; // process classes only (no interfaces) |
53 bool _classes_only; // process classes only (no interfaces) |
|
54 bool _walk_defaults; // process default methods |
|
55 bool _base_class_search_defaults; // time to process default methods |
|
56 bool _defaults_checked; // already checked for default methods |
53 int _index; |
57 int _index; |
54 |
58 |
55 virtual int length() const = 0; |
59 virtual int length() = 0; |
56 |
60 |
57 public: |
61 public: |
58 // constructor |
62 // constructor |
59 KlassStream(instanceKlassHandle klass, bool local_only, bool classes_only); |
63 KlassStream(instanceKlassHandle klass, bool local_only, bool classes_only, bool walk_defaults); |
60 |
64 |
61 // testing |
65 // testing |
62 bool eos(); |
66 bool eos(); |
63 |
67 |
64 // iterating |
68 // iterating |
65 virtual void next() = 0; |
69 virtual void next() = 0; |
66 |
70 |
67 // accessors |
71 // accessors |
68 instanceKlassHandle klass() const { return _klass; } |
72 instanceKlassHandle klass() const { return _klass; } |
69 int index() const { return _index; } |
73 int index() const { return _index; } |
|
74 bool base_class_search_defaults() const { return _base_class_search_defaults; } |
|
75 void base_class_search_defaults(bool b) { _base_class_search_defaults = b; } |
70 }; |
76 }; |
71 |
77 |
72 |
78 |
73 // A MethodStream streams over all methods in a class, superclasses and (super)interfaces. |
79 // A MethodStream streams over all methods in a class, superclasses and (super)interfaces. |
74 // Streaming is done in reverse order (subclasses first, methods in reverse order) |
80 // Streaming is done in reverse order (subclasses first, methods in reverse order) |
79 // ... |
85 // ... |
80 // } |
86 // } |
81 |
87 |
82 class MethodStream : public KlassStream { |
88 class MethodStream : public KlassStream { |
83 private: |
89 private: |
84 int length() const { return methods()->length(); } |
90 int length() { return methods()->length(); } |
85 Array<Method*>* methods() const { return _klass->methods(); } |
91 Array<Method*>* methods() { |
|
92 if (base_class_search_defaults()) { |
|
93 base_class_search_defaults(false); |
|
94 return _klass->default_methods(); |
|
95 } else { |
|
96 return _klass->methods(); |
|
97 } |
|
98 } |
86 public: |
99 public: |
87 MethodStream(instanceKlassHandle klass, bool local_only, bool classes_only) |
100 MethodStream(instanceKlassHandle klass, bool local_only, bool classes_only) |
88 : KlassStream(klass, local_only, classes_only) { |
101 : KlassStream(klass, local_only, classes_only, true) { |
89 _index = length(); |
102 _index = length(); |
90 next(); |
103 next(); |
91 } |
104 } |
92 |
105 |
93 void next() { _index--; } |
106 void next() { _index--; } |
94 Method* method() const { return methods()->at(index()); } |
107 Method* method() { return methods()->at(index()); } |
95 }; |
108 }; |
96 |
109 |
97 |
110 |
98 // A FieldStream streams over all fields in a class, superclasses and (super)interfaces. |
111 // A FieldStream streams over all fields in a class, superclasses and (super)interfaces. |
99 // Streaming is done in reverse order (subclasses first, fields in reverse order) |
112 // Streaming is done in reverse order (subclasses first, fields in reverse order) |
105 // } |
118 // } |
106 |
119 |
107 |
120 |
108 class FieldStream : public KlassStream { |
121 class FieldStream : public KlassStream { |
109 private: |
122 private: |
110 int length() const { return _klass->java_fields_count(); } |
123 int length() { return _klass->java_fields_count(); } |
111 |
124 |
112 fieldDescriptor _fd_buf; |
125 fieldDescriptor _fd_buf; |
113 |
126 |
114 public: |
127 public: |
115 FieldStream(instanceKlassHandle klass, bool local_only, bool classes_only) |
128 FieldStream(instanceKlassHandle klass, bool local_only, bool classes_only) |
116 : KlassStream(klass, local_only, classes_only) { |
129 : KlassStream(klass, local_only, classes_only, false) { |
117 _index = length(); |
130 _index = length(); |
118 next(); |
131 next(); |
119 } |
132 } |
120 |
133 |
121 void next() { _index -= 1; } |
134 void next() { _index -= 1; } |