• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

raphw / byte-buddy / #717

17 Jan 2025 09:06PM UTC coverage: 85.373% (-0.1%) from 85.479%
#717

push

raphw
Fix build.

0 of 4 new or added lines in 1 file covered. (0.0%)

572 existing lines in 8 files now uncovered.

28973 of 33937 relevant lines covered (85.37%)

0.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.14
/byte-buddy-dep/src/main/java/net/bytebuddy/utility/AsmClassReader.java
1
/*
2
 * Copyright 2014 - Present Rafael Winterhalter
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package net.bytebuddy.utility;
17

18
import net.bytebuddy.ClassFileVersion;
19
import net.bytebuddy.build.AccessControllerPlugin;
20
import net.bytebuddy.build.HashCodeAndEqualsPlugin;
21
import net.bytebuddy.utility.dispatcher.JavaDispatcher;
22
import net.bytebuddy.utility.nullability.MaybeNull;
23
import net.bytebuddy.utility.privilege.GetSystemPropertyAction;
24
import org.objectweb.asm.Attribute;
25
import org.objectweb.asm.ClassReader;
26
import org.objectweb.asm.ClassVisitor;
27

28
import java.security.PrivilegedAction;
29

30
/**
31
 * A facade for creating a class reader that accepts {@link ClassVisitor} instances and reader flags.
32
 */
33
public interface AsmClassReader {
34

35
    /**
36
     * Unwraps a class reader to the underlying reader mechanism.
37
     *
38
     * @param type The type of the reader that should be unwrapped.
39
     * @param <T>  The type to unwrap.
40
     * @return The unwrapped instance or {@code null} if the underlying instance does not represent this type.
41
     */
42
    @MaybeNull
43
    <T> T unwrap(Class<T> type);
44

45
    /**
46
     * Accepts a class visitor to read a class.
47
     *
48
     * @param classVisitor The class visitor who should be used as a callback for a class file.
49
     * @param flags        The flags to consider while reading a class.
50
     */
51
    void accept(ClassVisitor classVisitor, int flags);
52

53
    /**
54
     * A factory to create a {@link AsmClassReader}.
55
     */
56
    interface Factory {
57

58
        /**
59
         * Creates a class reader for a given class file.
60
         *
61
         * @param binaryRepresentation The class file's binary representation.
62
         * @return A class reader representation for the supplied class file.
63
         */
64
        AsmClassReader make(byte[] binaryRepresentation);
65

66
        /**
67
         * Creates a class reader for a given class file.
68
         *
69
         * @param binaryRepresentation The class file's binary representation.
70
         * @param experimental         {@code true} if unknown Java class files versions should also be considered.
71
         * @return A class reader representation for the supplied class file.
72
         */
73
        AsmClassReader make(byte[] binaryRepresentation, boolean experimental);
74

75
        /**
76
         * Default implementations for factories of {@link AsmClassReader}s.
77
         */
78
        enum Default implements Factory {
1✔
79

80
            /**
81
             * Uses a processor as it is configured by {@link OpenedClassReader#PROCESSOR_PROPERTY},
82
             * or {@link AsmClassWriter.Factory.Default#ASM_FIRST} if no implicit processor is defined.
83
             */
84
            IMPLICIT {
1✔
85
                /**
86
                 * {@inheritDoc}
87
                 */
88
                public AsmClassReader make(byte[] binaryRepresentation, boolean experimental) {
89
                    return FACTORY.make(binaryRepresentation, experimental);
1✔
90
                }
91
            },
92

93
            /**
94
             * A factory for a class reader that uses ASM's internal implementation whenever possible.
95
             */
96
            ASM_FIRST {
1✔
97
                /**
98
                 * {@inheritDoc}
99
                 */
100
                public AsmClassReader make(byte[] binaryRepresentation, boolean experimental) {
101
                    return ClassFileVersion.ofClassFile(binaryRepresentation).isGreaterThan(ClassFileVersion.latest())
1✔
102
                            ? CLASS_FILE_API_ONLY.make(binaryRepresentation)
1✔
103
                            : ASM_ONLY.make(binaryRepresentation);
1✔
104
                }
105
            },
106

107
            /**
108
             * A factory for a class reader that uses the class file API whenever possible.
109
             */
110
            CLASS_FILE_API_FIRST {
1✔
111
                /**
112
                 * {@inheritDoc}
113
                 */
114
                public AsmClassReader make(byte[] binaryRepresentation, boolean experimental) {
UNCOV
115
                    return ClassFileVersion.ofThisVm().isAtLeast(ClassFileVersion.JAVA_V24)
×
UNCOV
116
                            ? CLASS_FILE_API_ONLY.make(binaryRepresentation)
×
UNCOV
117
                            : ASM_ONLY.make(binaryRepresentation);
×
118
                }
119
            },
120

121
            /**
122
             * A factory for a class reader that always uses ASM's internal implementation.
123
             */
124
            ASM_ONLY {
1✔
125
                /**
126
                 * {@inheritDoc}
127
                 */
128
                public AsmClassReader make(byte[] binaryRepresentation, boolean experimental) {
129
                    return new ForAsm(OpenedClassReader.of(binaryRepresentation, experimental));
1✔
130
                }
131
            },
132

133
            /**
134
             * A factory for a class reader that always uses the class file API.
135
             */
136
            CLASS_FILE_API_ONLY {
1✔
137
                /**
138
                 * {@inheritDoc}
139
                 */
140
                public AsmClassReader make(byte[] binaryRepresentation, boolean experimental) {
UNCOV
141
                    return new AsmClassReader.ForClassFileApi(ForClassFileApi.DISPATCHER.make(binaryRepresentation));
×
142
                }
143
            };
144

145
            /**
146
             * The implicit factory to use for writing class files.
147
             */
148
            private static final Factory FACTORY;
149

150
            /*
151
             * Resolves the implicit reader factory, if any.
152
             */
153
            static {
154
                String processor;
155
                try {
156
                    processor = doPrivileged(new GetSystemPropertyAction(OpenedClassReader.PROCESSOR_PROPERTY));
1✔
UNCOV
157
                } catch (Throwable ignored) {
×
UNCOV
158
                    processor = null;
×
159
                }
1✔
160
                FACTORY = processor == null ? Default.ASM_FIRST : Default.valueOf(processor);
1✔
161
            }
1✔
162

163
            /**
164
             * A proxy for {@code java.security.AccessController#doPrivileged} that is activated if available.
165
             *
166
             * @param action The action to execute from a privileged context.
167
             * @param <T>    The type of the action's resolved value.
168
             * @return The action's resolved value.
169
             */
170
            @MaybeNull
171
            @AccessControllerPlugin.Enhance
172
            private static <T> T doPrivileged(PrivilegedAction<T> action) {
UNCOV
173
                return action.run();
×
174
            }
175

176
            /**
177
             * {@inheritDoc}
178
             */
179
            public AsmClassReader make(byte[] binaryRepresentation) {
180
                return make(binaryRepresentation, OpenedClassReader.EXPERIMENTAL);
1✔
181
            }
182
        }
183
    }
184

185
    /**
186
     * A class reader for ASM's own {@link ClassReader}.
187
     */
188
    class ForAsm implements AsmClassReader {
189

190
        /**
191
         * Indicates that no custom attributes should be mapped.
192
         */
193
        private static final Attribute[] NO_ATTRIBUTES = new Attribute[0];
1✔
194

195
        /**
196
         * The class reader that represents the class file to be read.
197
         */
198
        private final ClassReader classReader;
199

200
        /**
201
         * Creates a new ASM class reader that uses ASM's internal implementation.
202
         *
203
         * @param classReader The class reader that represents the class file to be read.
204
         */
205
        public ForAsm(ClassReader classReader) {
1✔
206
            this.classReader = classReader;
1✔
207
        }
1✔
208

209
        /**
210
         * {@inheritDoc}
211
         */
212
        @MaybeNull
213
        public <T> T unwrap(Class<T> type) {
214
            return type.isInstance(classReader)
1✔
215
                    ? type.cast(classReader)
1✔
216
                    : null;
217
        }
218

219
        /**
220
         * {@inheritDoc}
221
         */
222
        public void accept(ClassVisitor classVisitor, int flags) {
223
            classReader.accept(classVisitor, NO_ATTRIBUTES, flags);
1✔
224
        }
1✔
225
    }
226

227
    /**
228
     * A class reader that is based upon the Class File API.
229
     */
230
    @HashCodeAndEqualsPlugin.Enhance
231
    class ForClassFileApi implements AsmClassReader {
232

233
        /**
234
         * A dispatcher to interact with {@code codes.rafael.asmjdkbridge.JdkClassReader}.
235
         */
UNCOV
236
        protected static final JdkClassReader DISPATCHER = doPrivileged(JavaDispatcher.of(
×
237
                JdkClassReader.class,
UNCOV
238
                ForClassFileApi.class.getClassLoader()));
×
239

240
        /**
241
         * The class reader that represents the class file to be read.
242
         */
243
        private final Object classReader;
244

245
        /**
246
         * Creates a new class reader that is based upon the Class File API.
247
         *
248
         * @param classReader The class reader that represents the class file to be read.
249
         */
UNCOV
250
        public ForClassFileApi(Object classReader) {
×
UNCOV
251
            if (!DISPATCHER.isInstance(classReader)) {
×
UNCOV
252
                throw new IllegalArgumentException();
×
253
            }
UNCOV
254
            this.classReader = classReader;
×
UNCOV
255
        }
×
256

257
        /**
258
         * A proxy for {@code java.security.AccessController#doPrivileged} that is activated if available.
259
         *
260
         * @param action The action to execute from a privileged context.
261
         * @param <T>    The type of the action's resolved value.
262
         * @return The action's resolved value.
263
         */
264
        @AccessControllerPlugin.Enhance
265
        private static <T> T doPrivileged(PrivilegedAction<T> action) {
UNCOV
266
            return action.run();
×
267
        }
268

269
        /**
270
         * {@inheritDoc}
271
         */
272
        @MaybeNull
273
        public <T> T unwrap(Class<T> type) {
UNCOV
274
            return null;
×
275
        }
276

277
        /**
278
         * {@inheritDoc}
279
         */
280
        public void accept(ClassVisitor classVisitor, int flags) {
UNCOV
281
            DISPATCHER.accept(classReader, classVisitor, flags);
×
UNCOV
282
        }
×
283

284
        /**
285
         * A dispatcher to interact with {@code codes.rafael.asmjdkbridge.JdkClassReader}.
286
         */
287
        @JavaDispatcher.Proxied("codes.rafael.asmjdkbridge.JdkClassReader")
288
        protected interface JdkClassReader {
289

290
            /**
291
             * Checks if the supplied object is an instance of {@code codes.rafael.asmjdkbridge.JdkClassReader}.
292
             *
293
             * @param value The instance to evaluate.
294
             * @return {@code true} if the supplied object is an instance of {@code codes.rafael.asmjdkbridge.JdkClassReader}.
295
             */
296
            @JavaDispatcher.IsConstructor
297
            boolean isInstance(Object value);
298

299
            /**
300
             * Creates an instance of {@code codes.rafael.asmjdkbridge.JdkClassReader}.
301
             *
302
             * @param binaryRepresentation The binary representation of a class file to represent through the reader.
303
             * @return A new instance of {@code codes.rafael.asmjdkbridge.JdkClassReader}.
304
             */
305
            @JavaDispatcher.IsConstructor
306
            Object make(byte[] binaryRepresentation);
307

308
            /**
309
             * Accepts a class reader to visit the represented class file.
310
             *
311
             * @param classReader  The class reader that is being visited.
312
             * @param classVisitor The class visitor to visit the class.
313
             * @param flags        The flags to consider during reading.
314
             */
315
            void accept(Object classReader, ClassVisitor classVisitor, int flags);
316
        }
317
    }
318
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc