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

raphw / byte-buddy / #811

03 Nov 2025 10:41AM UTC coverage: 83.677% (-0.3%) from 84.023%
#811

push

raphw
Fix null handling.

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

791 existing lines in 12 files now uncovered.

29814 of 35630 relevant lines covered (83.68%)

0.84 hits per line

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

57.41
/byte-buddy-dep/src/main/java/net/bytebuddy/build/RenamingPlugin.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.build;
17

18
import net.bytebuddy.asm.AsmVisitorWrapper;
19
import net.bytebuddy.description.field.FieldDescription;
20
import net.bytebuddy.description.field.FieldList;
21
import net.bytebuddy.description.method.MethodList;
22
import net.bytebuddy.description.type.TypeDescription;
23
import net.bytebuddy.dynamic.ClassFileLocator;
24
import net.bytebuddy.dynamic.DynamicType;
25
import net.bytebuddy.implementation.Implementation;
26
import net.bytebuddy.matcher.ElementMatcher;
27
import net.bytebuddy.pool.TypePool;
28
import net.bytebuddy.utility.OpenedClassReader;
29
import net.bytebuddy.utility.nullability.MaybeNull;
30
import org.objectweb.asm.ClassVisitor;
31
import org.objectweb.asm.commons.ClassRemapper;
32
import org.objectweb.asm.commons.Remapper;
33

34
import java.util.ArrayList;
35
import java.util.Arrays;
36
import java.util.HashMap;
37
import java.util.List;
38
import java.util.Map;
39
import java.util.regex.Matcher;
40
import java.util.regex.Pattern;
41

42
import static net.bytebuddy.matcher.ElementMatchers.any;
43
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
44

45
/**
46
 * A plugin that replaces names that are discovered in class files.
47
 */
48
@HashCodeAndEqualsPlugin.Enhance
49
public class RenamingPlugin extends AsmVisitorWrapper.AbstractBase implements Plugin, Plugin.Factory {
50

51
    /**
52
     * The renaming to apply.
53
     */
54
    private final Renaming renaming;
55

56
    /**
57
     * A matcher that determines what types to consider for renaming.
58
     */
59
    private final ElementMatcher<? super TypeDescription> matcher;
60

61
    /**
62
     * Creates a renaming plugin for a given regular expression and replacement that applies to all types.
63
     *
64
     * @param pattern     The pattern to consider.
65
     * @param replacement The replacement to apply if the supplied pattern is matched.
66
     */
67
    public RenamingPlugin(String pattern, String replacement) {
68
        this(new Renaming.ForPattern(Pattern.compile(pattern), replacement));
1✔
69
    }
1✔
70

71
    /**
72
     * Creates a renaming plugin for a given regular expression and replacement that applies to all types that start with a given prefix.
73
     *
74
     * @param pattern     The pattern to consider.
75
     * @param replacement The replacement to apply if the supplied pattern is matched.
76
     * @param prefix      The prefix for types to consider for renaming.
77
     */
78
    public RenamingPlugin(String pattern, String replacement, String prefix) {
79
        this(new Renaming.ForPattern(Pattern.compile(pattern), replacement), nameStartsWith(prefix));
×
80
    }
×
81

82
    /**
83
     * Creates a renaming plugin for the given renaming that applies to all types.
84
     *
85
     * @param renaming The renaming to apply.
86
     */
87
    public RenamingPlugin(Renaming renaming) {
88
        this(renaming, any());
1✔
89
    }
1✔
90

91
    /**
92
     * Creates a renaming plugin for the given renaming and type matcher.
93
     *
94
     * @param renaming The renaming to apply.
95
     * @param matcher  A matcher that determines what types to consider for renaming.
96
     */
97
    public RenamingPlugin(Renaming renaming, ElementMatcher<? super TypeDescription> matcher) {
1✔
98
        this.renaming = renaming;
1✔
99
        this.matcher = matcher;
1✔
100
    }
1✔
101

102
    /**
103
     * {@inheritDoc}
104
     */
105
    public Plugin make() {
UNCOV
106
        return this;
×
107
    }
108

109
    /**
110
     * {@inheritDoc}
111
     */
112
    public DynamicType.Builder<?> apply(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassFileLocator classFileLocator) {
113
        return builder.visit(this);
1✔
114
    }
115

116
    /**
117
     * {@inheritDoc}
118
     */
119
    public boolean matches(@MaybeNull TypeDescription target) {
UNCOV
120
        return matcher.matches(target);
×
121
    }
122

123
    /**
124
     * {@inheritDoc}
125
     */
126
    public void close() {
127
        /* do nothing */
UNCOV
128
    }
×
129

130
    /**
131
     * {@inheritDoc}
132
     */
133
    public ClassVisitor wrap(TypeDescription instrumentedType,
134
                             ClassVisitor classVisitor,
135
                             Implementation.Context implementationContext,
136
                             TypePool typePool,
137
                             FieldList<FieldDescription.InDefinedShape> fields,
138
                             MethodList<?> methods,
139
                             int writerFlags,
140
                             int readerFlags) {
141
        return new ClassRemapper(classVisitor, new RenamingRemapper(renaming));
1✔
142
    }
143

144
    /**
145
     * A renaming function tho transform a type's binary name.
146
     */
147
    public interface Renaming {
148

149
        /**
150
         * Applies a renaming.
151
         *
152
         * @param name The previous name.
153
         * @return The former name.
154
         */
155
        String apply(String name);
156

157
        /**
158
         * A non-operational renaming.
159
         */
UNCOV
160
        enum NoOp implements Renaming {
×
161

162
            /**
163
             * The singleton instance.
164
             */
UNCOV
165
            INSTANCE;
×
166

167
            /**
168
             * {@inheritDoc}
169
             */
170
            public String apply(String name) {
UNCOV
171
                return name;
×
172
            }
173
        }
174

175
        /**
176
         * A renaming that renames types by a given regular expression.
177
         */
178
        @HashCodeAndEqualsPlugin.Enhance
179
        class ForPattern implements Renaming {
180

181
            /**
182
             * The regular expression to use.
183
             */
184
            private final Pattern pattern;
185

186
            /**
187
             * The replacement to apply.
188
             */
189
            private final String replacement;
190

191
            /**
192
             * Creates a new renaming for a regular expression.
193
             *
194
             * @param pattern     The regular expression to use.
195
             * @param replacement The replacement to apply.
196
             */
197
            public ForPattern(Pattern pattern, String replacement) {
1✔
198
                this.pattern = pattern;
1✔
199
                this.replacement = replacement;
1✔
200
            }
1✔
201

202
            /**
203
             * {@inheritDoc}
204
             */
205
            public String apply(String name) {
206
                Matcher matcher = pattern.matcher(name);
1✔
207
                if (matcher.find()) {
1✔
208
                    StringBuffer buffer = new StringBuffer();
1✔
209
                    do {
210
                        matcher.appendReplacement(buffer, replacement);
1✔
211
                    } while (matcher.find());
1✔
212
                    return matcher.appendTail(buffer).toString();
1✔
213
                } else {
214
                    return name;
1✔
215
                }
216
            }
217
        }
218

219
        /**
220
         * A compound renaming.
221
         */
222
        @HashCodeAndEqualsPlugin.Enhance
223
        class Compound implements Renaming {
224

225
            /**
226
             * The renamings to apply.
227
             */
228
            private final List<Renaming> renamings;
229

230
            /**
231
             * Creates a new compound renaming.
232
             *
233
             * @param renaming The renaming to apply.
234
             */
235
            public Compound(Renaming... renaming) {
UNCOV
236
                this(Arrays.asList(renaming));
×
237
            }
×
238

239
            /**
240
             * Creates a new compound renaming.
241
             *
242
             * @param renamings The renamings to apply.
243
             */
UNCOV
244
            public Compound(List<? extends Renaming> renamings) {
×
245
                this.renamings = new ArrayList<Renaming>(renamings.size());
×
246
                for (Renaming remapping : renamings) {
×
UNCOV
247
                    if (remapping instanceof Compound) {
×
UNCOV
248
                        this.renamings.addAll(((Compound) remapping).renamings);
×
UNCOV
249
                    } else if (!(remapping instanceof NoOp)) {
×
UNCOV
250
                        this.renamings.add(remapping);
×
251
                    }
252
                }
×
253
            }
×
254

255
            /**
256
             * {@inheritDoc}
257
             */
258
            public String apply(String name) {
UNCOV
259
                for (Renaming remapping : renamings) {
×
UNCOV
260
                    name = remapping.apply(name);
×
UNCOV
261
                }
×
UNCOV
262
                return name;
×
263
            }
264
        }
265
    }
266

267
    /**
268
     * An ASM {@link Remapper} to apply renamings.
269
     */
270
    protected static class RenamingRemapper extends Remapper {
271

272
        /**
273
         * The renaming to apply.
274
         */
275
        private final Renaming renaming;
276

277
        /**
278
         * A cache of previously applied renamings.
279
         */
280
        private final Map<String, String> cache = new HashMap<String, String>();
1✔
281

282
        /**
283
         * Creates a new renaming remapper.
284
         * @param renaming The renaming to apply.
285
         */
286
        protected RenamingRemapper(Renaming renaming) {
287
            super(OpenedClassReader.ASM_API);
1✔
288
            this.renaming = renaming;
1✔
289
        }
1✔
290

291
        @Override
292
        public String map(String internalName) {
293
            String renamed = cache.get(internalName);
1✔
294
            if (renamed != null) {
1✔
295
                return renamed;
1✔
296
            }
297
            renamed = renaming.apply(internalName.replace('/', '.')).replace('.', '/');
1✔
298
            cache.put(internalName, renamed);
1✔
299
            return renamed;
1✔
300
        }
301
    }
302
}
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