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

raphw / byte-buddy / #642

20 Aug 2024 09:12AM CUT coverage: 85.383% (-0.006%) from 85.389%
#642

push

raphw
Delegate class reader to factories.

28757 of 33680 relevant lines covered (85.38%)

0.85 hits per line

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

28.26
/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/RecordComponentRegistry.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.dynamic.scaffold;
17

18
import net.bytebuddy.build.HashCodeAndEqualsPlugin;
19
import net.bytebuddy.description.type.RecordComponentDescription;
20
import net.bytebuddy.description.type.TypeDescription;
21
import net.bytebuddy.dynamic.Transformer;
22
import net.bytebuddy.implementation.attribute.RecordComponentAttributeAppender;
23
import net.bytebuddy.matcher.ElementMatcher;
24
import net.bytebuddy.matcher.LatentMatcher;
25
import net.bytebuddy.utility.nullability.MaybeNull;
26

27
import java.util.*;
28

29
/**
30
 * A record component registry represents an extendable collection of record components which are identified by their names that are mapped
31
 * to a given {@link RecordComponentAttributeAppender}. Record components
32
 * can be uniquely identified by their name for a given type since record components are never inherited.
33
 * <p>&nbsp;</p>
34
 * This registry is the counterpart of a {@link MethodRegistry}.
35
 * However, a record component registry is implemented simpler since it does not have to deal with complex signatures or
36
 * inheritance. For the sake of consistency, the record component registry follows however a similar pattern without introducing
37
 * unnecessary complexity.
38
 */
39
public interface RecordComponentRegistry {
40

41
    /**
42
     * Prepends the given record component definition to this record component registry, i.e. this configuration is applied first.
43
     *
44
     * @param matcher                                 The matcher to identify any record component that this definition concerns.
45
     * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply on any matched record component.
46
     * @param transformer                             The record component transformer to apply to any matched record component.
47
     * @return An adapted version of this method registry.
48
     */
49
    RecordComponentRegistry prepend(LatentMatcher<? super RecordComponentDescription> matcher,
50
                                    RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
51
                                    Transformer<RecordComponentDescription> transformer);
52

53
    /**
54
     * Prepares the record component registry for a given instrumented type.
55
     *
56
     * @param instrumentedType The instrumented type.
57
     * @return A prepared record component registry.
58
     */
59
    Compiled compile(TypeDescription instrumentedType);
60

61
    /**
62
     * Represents a compiled record component registry.
63
     */
64
    interface Compiled extends TypeWriter.RecordComponentPool {
65

66
        /**
67
         * A no-op record component registry that does not register annotations for any record component.
68
         */
69
        enum NoOp implements Compiled {
×
70

71
            /**
72
             * The singleton instance.
73
             */
74
            INSTANCE;
×
75

76
            /**
77
             * {@inheritDoc}
78
             */
79
            public Record target(RecordComponentDescription recordComponentDescription) {
80
                return new Record.ForImplicitRecordComponent(recordComponentDescription);
×
81
            }
82
        }
83
    }
84

85
    /**
86
     * An immutable default implementation of a record component registry.
87
     */
88
    @HashCodeAndEqualsPlugin.Enhance
89
    class Default implements RecordComponentRegistry {
90

91
        /**
92
         * This registries entries.
93
         */
94
        private final List<Entry> entries;
95

96
        /**
97
         * Creates a new empty default record component registry.
98
         */
99
        public Default() {
100
            this(Collections.<Entry>emptyList());
1✔
101
        }
1✔
102

103
        /**
104
         * Creates a new default record component registry.
105
         *
106
         * @param entries The entries of the record component registry.
107
         */
108
        private Default(List<Entry> entries) {
1✔
109
            this.entries = entries;
1✔
110
        }
1✔
111

112
        /**
113
         * {@inheritDoc}
114
         */
115
        public RecordComponentRegistry prepend(LatentMatcher<? super RecordComponentDescription> matcher,
116
                                               RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
117
                                               Transformer<RecordComponentDescription> transformer) {
118
            List<Entry> entries = new ArrayList<Entry>(this.entries.size() + 1);
×
119
            entries.add(new Entry(matcher, recordComponentAttributeAppenderFactory, transformer));
×
120
            entries.addAll(this.entries);
×
121
            return new Default(entries);
×
122
        }
123

124
        /**
125
         * {@inheritDoc}
126
         */
127
        public RecordComponentRegistry.Compiled compile(TypeDescription instrumentedType) {
128
            List<Compiled.Entry> entries = new ArrayList<Compiled.Entry>(this.entries.size());
1✔
129
            Map<RecordComponentAttributeAppender.Factory, RecordComponentAttributeAppender> recordComponentAttributeAppenders = new HashMap<RecordComponentAttributeAppender.Factory, RecordComponentAttributeAppender>();
1✔
130
            for (Entry entry : this.entries) {
1✔
131
                RecordComponentAttributeAppender recordComponentAttributeAppender = recordComponentAttributeAppenders.get(entry.getRecordComponentAttributeAppender());
×
132
                if (recordComponentAttributeAppender == null) {
×
133
                    recordComponentAttributeAppender = entry.getRecordComponentAttributeAppender().make(instrumentedType);
×
134
                    recordComponentAttributeAppenders.put(entry.getRecordComponentAttributeAppender(), recordComponentAttributeAppender);
×
135
                }
136
                entries.add(new Compiled.Entry(entry.resolve(instrumentedType), recordComponentAttributeAppender, entry.getTransformer()));
×
137
            }
×
138
            return new Compiled(instrumentedType, entries);
1✔
139
        }
140

141
        /**
142
         * An entry of the default record component registry.
143
         */
144
        @HashCodeAndEqualsPlugin.Enhance
145
        protected static class Entry implements LatentMatcher<RecordComponentDescription> {
146

147
            /**
148
             * The matcher to identify any record component that this definition concerns.
149
             */
150
            private final LatentMatcher<? super RecordComponentDescription> matcher;
151

152
            /**
153
             * The record component attribute appender factory to apply on any matched record component.
154
             */
155
            private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppender;
156

157
            /**
158
             * The record component transformer to apply to any matched record component.
159
             */
160
            private final Transformer<RecordComponentDescription> transformer;
161

162
            /**
163
             * Creates a new entry.
164
             *
165
             * @param matcher                          The matcher to identify any record component that this definition concerns.
166
             * @param recordComponentAttributeAppender The record component attribute appender factory to apply on any matched record component.
167
             * @param transformer                      The record component transformer to apply to any matched record component.
168
             */
169
            protected Entry(LatentMatcher<? super RecordComponentDescription> matcher,
170
                            RecordComponentAttributeAppender.Factory recordComponentAttributeAppender,
171
                            Transformer<RecordComponentDescription> transformer) {
×
172
                this.matcher = matcher;
×
173
                this.recordComponentAttributeAppender = recordComponentAttributeAppender;
×
174
                this.transformer = transformer;
×
175
            }
×
176

177
            /**
178
             * Returns the record component attribute appender factory to apply on any matched record component.
179
             *
180
             * @return The record component attribute appender factory to apply on any matched record component.
181
             */
182
            protected RecordComponentAttributeAppender.Factory getRecordComponentAttributeAppender() {
183
                return recordComponentAttributeAppender;
×
184
            }
185

186
            /**
187
             * Returns the record component transformer to apply to any matched record component.
188
             *
189
             * @return The record component transformer to apply to any matched record component.
190
             */
191
            protected Transformer<RecordComponentDescription> getTransformer() {
192
                return transformer;
×
193
            }
194

195
            /**
196
             * {@inheritDoc}
197
             */
198
            public ElementMatcher<? super RecordComponentDescription> resolve(TypeDescription typeDescription) {
199
                return matcher.resolve(typeDescription);
×
200
            }
201
        }
202

203
        /**
204
         * A compiled default record component registry.
205
         */
206
        @HashCodeAndEqualsPlugin.Enhance
207
        protected static class Compiled implements RecordComponentRegistry.Compiled {
208

209
            /**
210
             * The instrumented type for which this registry was compiled for.
211
             */
212
            private final TypeDescription instrumentedType;
213

214
            /**
215
             * The entries of this compiled record component registry.
216
             */
217
            private final List<Entry> entries;
218

219
            /**
220
             * Creates a new compiled record component registry.
221
             *
222
             * @param instrumentedType The instrumented type for which this registry was compiled for.
223
             * @param entries          The entries of this compiled record component registry.
224
             */
225
            protected Compiled(TypeDescription instrumentedType, List<Entry> entries) {
1✔
226
                this.instrumentedType = instrumentedType;
1✔
227
                this.entries = entries;
1✔
228
            }
1✔
229

230
            /**
231
             * {@inheritDoc}
232
             */
233
            public Record target(RecordComponentDescription recordComponentDescription) {
234
                for (Entry entry : entries) {
×
235
                    if (entry.matches(recordComponentDescription)) {
×
236
                        return entry.bind(instrumentedType, recordComponentDescription);
×
237
                    }
238
                }
×
239
                return new Record.ForImplicitRecordComponent(recordComponentDescription);
×
240
            }
241

242
            /**
243
             * An entry of a compiled record component registry.
244
             */
245
            @HashCodeAndEqualsPlugin.Enhance
246
            protected static class Entry implements ElementMatcher<RecordComponentDescription> {
247

248
                /**
249
                 * The matcher to identify any record component that this definition concerns.
250
                 */
251
                private final ElementMatcher<? super RecordComponentDescription> matcher;
252

253
                /**
254
                 * The record component attribute appender to apply on any matched record component.
255
                 */
256
                private final RecordComponentAttributeAppender recordComponentAttributeAppender;
257

258
                /**
259
                 * The record component transformer to apply to any matched record component.
260
                 */
261
                private final Transformer<RecordComponentDescription> transformer;
262

263
                /**
264
                 * Creates a new entry.
265
                 *
266
                 * @param matcher                          The matcher to identify any record component that this definition concerns.
267
                 * @param recordComponentAttributeAppender The record component attribute appender to apply on any matched record component.
268
                 * @param transformer                      The record component transformer to apply to any matched record component.
269
                 */
270
                protected Entry(ElementMatcher<? super RecordComponentDescription> matcher,
271
                                RecordComponentAttributeAppender recordComponentAttributeAppender,
272
                                Transformer<RecordComponentDescription> transformer) {
×
273
                    this.matcher = matcher;
×
274
                    this.recordComponentAttributeAppender = recordComponentAttributeAppender;
×
275
                    this.transformer = transformer;
×
276
                }
×
277

278
                /**
279
                 * Binds this entry to the provided record component description.
280
                 *
281
                 * @param instrumentedType           The instrumented type for which this entry applies.
282
                 * @param recordComponentDescription The record component description to be bound to this entry.
283
                 * @return A record representing the binding of this entry to the provided record component.
284
                 */
285
                protected Record bind(TypeDescription instrumentedType, RecordComponentDescription recordComponentDescription) {
286
                    return new Record.ForExplicitRecordComponent(recordComponentAttributeAppender, transformer.transform(instrumentedType, recordComponentDescription));
×
287
                }
288

289
                /**
290
                 * {@inheritDoc}
291
                 */
292
                public boolean matches(@MaybeNull RecordComponentDescription target) {
293
                    return matcher.matches(target);
×
294
                }
295
            }
296
        }
297
    }
298
}
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

© 2025 Coveralls, Inc