Skip to content

Commit a253e0f

Browse files
committedJul 15, 2024
8335642: Hide Transform implementation for Class-File API
Reviewed-by: asotona
1 parent 2b0adfc commit a253e0f

File tree

9 files changed

+66
-136
lines changed

9 files changed

+66
-136
lines changed
 

‎src/java.base/share/classes/java/lang/classfile/ClassFileBuilder.java

+6-11
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@
2727
import java.lang.constant.ClassDesc;
2828
import java.util.function.Consumer;
2929

30-
import java.lang.classfile.constantpool.ConstantPool;
3130
import java.lang.classfile.constantpool.ConstantPoolBuilder;
31+
32+
import jdk.internal.classfile.impl.TransformImpl;
3233
import jdk.internal.javac.PreviewFeature;
3334

3435
/**
@@ -71,25 +72,19 @@ default void accept(E e) {
7172
*/
7273
ConstantPoolBuilder constantPool();
7374

74-
/**
75-
* {@return whether the provided constant pool is compatible with this builder}
76-
* @param source the constant pool to test compatibility with
77-
*/
78-
default boolean canWriteDirect(ConstantPool source) {
79-
return constantPool().canWriteDirect(source);
80-
}
81-
8275
/**
8376
* Apply a transform to a model, directing results to this builder.
8477
* @param model the model to transform
8578
* @param transform the transform to apply
79+
* @return this builder
8680
*/
87-
default void transform(CompoundElement<E> model, ClassFileTransform<?, E, B> transform) {
81+
default B transform(CompoundElement<E> model, ClassFileTransform<?, E, B> transform) {
8882
@SuppressWarnings("unchecked")
8983
B builder = (B) this;
90-
var resolved = transform.resolve(builder);
84+
var resolved = TransformImpl.resolve(transform, builder);
9185
resolved.startHandler().run();
9286
model.forEach(resolved.consumer());
9387
resolved.endHandler().run();
88+
return builder;
9489
}
9590
}

‎src/java.base/share/classes/java/lang/classfile/ClassFileTransform.java

+1-44
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,6 @@
2424
*/
2525
package java.lang.classfile;
2626

27-
import java.util.function.Consumer;
2827
import java.util.function.Supplier;
2928

3029
import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
@@ -124,46 +123,4 @@ default void atStart(B builder) {
124123
* @return the chained transform
125124
*/
126125
C andThen(C next);
127-
128-
/**
129-
* The result of binding a transform to a builder. Used primarily within
130-
* the implementation to perform transformation.
131-
*
132-
* @param <E> the element type
133-
*
134-
* @since 22
135-
*/
136-
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
137-
interface ResolvedTransform<E extends ClassFileElement> {
138-
/**
139-
* {@return a {@link Consumer} to receive elements}
140-
*/
141-
Consumer<E> consumer();
142-
143-
/**
144-
* {@return an action to call at the end of transformation}
145-
*/
146-
Runnable endHandler();
147-
148-
/**
149-
* {@return an action to call at the start of transformation}
150-
*/
151-
Runnable startHandler();
152-
}
153-
154-
/**
155-
* Bind a transform to a builder. If the transform is chained, intermediate
156-
* builders are created for each chain link. If the transform is stateful
157-
* (see, e.g., {@link ClassTransform#ofStateful(Supplier)}), the supplier is
158-
* invoked to get a fresh transform object.
159-
*
160-
* <p>This method is a low-level method that should rarely be used by
161-
* user code; most of the time, user code should prefer
162-
* {@link ClassFileBuilder#transform(CompoundElement, ClassFileTransform)},
163-
* which resolves the transform and executes it on the current builder.
164-
*
165-
* @param builder the builder to bind to
166-
* @return the bound result
167-
*/
168-
ResolvedTransform<E> resolve(B builder);
169126
}

‎src/java.base/share/classes/java/lang/classfile/ClassTransform.java

+1-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -171,15 +171,4 @@ static ClassTransform transformingFields(FieldTransform xform) {
171171
default ClassTransform andThen(ClassTransform t) {
172172
return new TransformImpl.ChainedClassTransform(this, t);
173173
}
174-
175-
/**
176-
* @implSpec The default implementation returns a resolved transform bound
177-
* to the given class builder.
178-
*/
179-
@Override
180-
default ResolvedTransform<ClassElement> resolve(ClassBuilder builder) {
181-
return new TransformImpl.ResolvedTransformImpl<>(e -> accept(builder, e),
182-
() -> atEnd(builder),
183-
() -> atStart(builder));
184-
}
185174
}

‎src/java.base/share/classes/java/lang/classfile/CodeBuilder.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
import static java.util.Objects.requireNonNull;
8888
import static jdk.internal.classfile.impl.BytecodeHelpers.handleDescToHandleInfo;
8989

90+
import jdk.internal.classfile.impl.TransformImpl;
9091
import jdk.internal.javac.PreviewFeature;
9192

9293
/**
@@ -190,7 +191,7 @@ public sealed interface CodeBuilder
190191
* @return this builder
191192
*/
192193
default CodeBuilder transforming(CodeTransform transform, Consumer<CodeBuilder> handler) {
193-
var resolved = transform.resolve(this);
194+
var resolved = TransformImpl.resolve(transform, this);
194195
resolved.startHandler().run();
195196
handler.accept(new ChainedCodeBuilder(this, resolved.consumer()));
196197
resolved.endHandler().run();

‎src/java.base/share/classes/java/lang/classfile/CodeTransform.java

+1-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -96,15 +96,4 @@ public void atEnd(CodeBuilder builder) {
9696
default CodeTransform andThen(CodeTransform t) {
9797
return new TransformImpl.ChainedCodeTransform(this, t);
9898
}
99-
100-
/**
101-
* @implSpec The default implementation returns a resolved transform bound
102-
* to the given code builder.
103-
*/
104-
@Override
105-
default ResolvedTransform<CodeElement> resolve(CodeBuilder builder) {
106-
return new TransformImpl.ResolvedTransformImpl<>(e -> accept(builder, e),
107-
() -> atEnd(builder),
108-
() -> atStart(builder));
109-
}
11099
}

‎src/java.base/share/classes/java/lang/classfile/FieldTransform.java

+1-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -111,15 +111,4 @@ static FieldTransform dropping(Predicate<FieldElement> filter) {
111111
default FieldTransform andThen(FieldTransform t) {
112112
return new TransformImpl.ChainedFieldTransform(this, t);
113113
}
114-
115-
/**
116-
* @implSpec The default implementation returns a resolved transform bound
117-
* to the given field builder.
118-
*/
119-
@Override
120-
default ResolvedTransform<FieldElement> resolve(FieldBuilder builder) {
121-
return new TransformImpl.ResolvedTransformImpl<>(e -> accept(builder, e),
122-
() -> atEnd(builder),
123-
() -> atStart(builder));
124-
}
125114
}

‎src/java.base/share/classes/java/lang/classfile/MethodTransform.java

+1-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -111,17 +111,6 @@ static MethodTransform transformingCode(CodeTransform xform) {
111111
return new TransformImpl.MethodCodeTransform(xform);
112112
}
113113

114-
/**
115-
* @implSpec The default implementation returns a resolved transform bound
116-
* to the given method builder.
117-
*/
118-
@Override
119-
default ResolvedTransform<MethodElement> resolve(MethodBuilder builder) {
120-
return new TransformImpl.ResolvedTransformImpl<>(e -> accept(builder, e),
121-
() -> atEnd(builder),
122-
() -> atStart(builder));
123-
}
124-
125114
/**
126115
* @implSpec
127116
* The default implementation returns this method transform chained with another

‎src/java.base/share/classes/jdk/internal/classfile/impl/AbstractDirectBuilder.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
2424
*/
2525
package jdk.internal.classfile.impl;
2626

27+
import java.lang.classfile.constantpool.ConstantPool;
2728
import java.util.Optional;
2829

2930
import java.lang.classfile.Attribute;
@@ -43,6 +44,10 @@ public SplitConstantPool constantPool() {
4344
return constantPool;
4445
}
4546

47+
public boolean canWriteDirect(ConstantPool source) {
48+
return constantPool().canWriteDirect(source);
49+
}
50+
4651
public Optional<M> original() {
4752
return Optional.ofNullable(original);
4853
}

‎src/java.base/share/classes/jdk/internal/classfile/impl/TransformImpl.java

+47-31
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,8 @@
2424
*/
2525
package jdk.internal.classfile.impl;
2626

27+
import java.lang.classfile.ClassFileBuilder;
28+
import java.lang.classfile.ClassFileTransform;
2729
import java.util.function.Consumer;
2830
import java.util.function.Predicate;
2931
import java.util.function.Supplier;
@@ -32,7 +34,6 @@
3234
import java.lang.classfile.ClassElement;
3335
import java.lang.classfile.ClassTransform;
3436
import java.lang.classfile.ClassFileElement;
35-
import java.lang.classfile.ClassFileTransform;
3637
import java.lang.classfile.CodeBuilder;
3738
import java.lang.classfile.CodeElement;
3839
import java.lang.classfile.CodeModel;
@@ -46,7 +47,7 @@
4647
import java.lang.classfile.MethodModel;
4748
import java.lang.classfile.MethodTransform;
4849

49-
public class TransformImpl {
50+
public final class TransformImpl {
5051
// ClassTransform
5152

5253
private TransformImpl() {
@@ -58,7 +59,23 @@ private static Runnable chainRunnable(Runnable a, Runnable b) {
5859

5960
private static final Runnable NOTHING = () -> { };
6061

61-
interface UnresolvedClassTransform extends ClassTransform {
62+
public static <E extends ClassFileElement, B extends ClassFileBuilder<E, B>>
63+
ResolvedTransform<E> resolve(ClassFileTransform<?, E, B> transform, B builder) {
64+
if (transform instanceof ResolvableTransform) {
65+
@SuppressWarnings("unchecked")
66+
var ut = (ResolvableTransform<E, B>) transform;
67+
return ut.resolve(builder);
68+
}
69+
return new ResolvedTransform<>(e -> transform.accept(builder, e),
70+
() -> transform.atEnd(builder),
71+
() -> transform.atStart(builder));
72+
}
73+
74+
interface ResolvableTransform<E extends ClassFileElement, B extends ClassFileBuilder<E, B>> {
75+
ResolvedTransform<E> resolve(B builder);
76+
}
77+
78+
interface UnresolvedClassTransform extends ClassTransform, ResolvableTransform<ClassElement, ClassBuilder> {
6279
@Override
6380
default void accept(ClassBuilder builder, ClassElement element) {
6481
throw new UnsupportedOperationException("transforms must be resolved before running");
@@ -75,12 +92,11 @@ default void atStart(ClassBuilder builder) {
7592
}
7693
}
7794

78-
public record ResolvedTransformImpl<E extends ClassFileElement>(Consumer<E> consumer,
95+
public record ResolvedTransform<E extends ClassFileElement>(Consumer<E> consumer,
7996
Runnable endHandler,
80-
Runnable startHandler)
81-
implements ClassFileTransform.ResolvedTransform<E> {
97+
Runnable startHandler) {
8298

83-
public ResolvedTransformImpl(Consumer<E> consumer) {
99+
public ResolvedTransform(Consumer<E> consumer) {
84100
this(consumer, NOTHING, NOTHING);
85101
}
86102
}
@@ -89,11 +105,11 @@ public record ChainedClassTransform(ClassTransform t,
89105
ClassTransform next)
90106
implements UnresolvedClassTransform {
91107
@Override
92-
public ResolvedTransformImpl<ClassElement> resolve(ClassBuilder builder) {
93-
ResolvedTransform<ClassElement> downstream = next.resolve(builder);
108+
public ResolvedTransform<ClassElement> resolve(ClassBuilder builder) {
109+
ResolvedTransform<ClassElement> downstream = TransformImpl.resolve(next, builder);
94110
ClassBuilder chainedBuilder = new ChainedClassBuilder(builder, downstream.consumer());
95-
ResolvedTransform<ClassElement> upstream = t.resolve(chainedBuilder);
96-
return new ResolvedTransformImpl<>(upstream.consumer(),
111+
ResolvedTransform<ClassElement> upstream = TransformImpl.resolve(t, chainedBuilder);
112+
return new ResolvedTransform<>(upstream.consumer(),
97113
chainRunnable(upstream.endHandler(), downstream.endHandler()),
98114
chainRunnable(upstream.startHandler(), downstream.startHandler()));
99115
}
@@ -103,7 +119,7 @@ public record SupplierClassTransform(Supplier<ClassTransform> supplier)
103119
implements UnresolvedClassTransform {
104120
@Override
105121
public ResolvedTransform<ClassElement> resolve(ClassBuilder builder) {
106-
return supplier.get().resolve(builder);
122+
return TransformImpl.resolve(supplier.get(), builder);
107123
}
108124
}
109125

@@ -112,7 +128,7 @@ public record ClassMethodTransform(MethodTransform transform,
112128
implements UnresolvedClassTransform {
113129
@Override
114130
public ResolvedTransform<ClassElement> resolve(ClassBuilder builder) {
115-
return new ResolvedTransformImpl<>(ce -> {
131+
return new ResolvedTransform<>(ce -> {
116132
if (ce instanceof MethodModel mm && filter.test(mm))
117133
builder.transformMethod(mm, transform);
118134
else
@@ -135,7 +151,7 @@ public record ClassFieldTransform(FieldTransform transform,
135151
implements UnresolvedClassTransform {
136152
@Override
137153
public ResolvedTransform<ClassElement> resolve(ClassBuilder builder) {
138-
return new ResolvedTransformImpl<>(ce -> {
154+
return new ResolvedTransform<>(ce -> {
139155
if (ce instanceof FieldModel fm && filter.test(fm))
140156
builder.transformField(fm, transform);
141157
else
@@ -155,7 +171,7 @@ public ClassTransform andThen(ClassTransform next) {
155171

156172
// MethodTransform
157173

158-
interface UnresolvedMethodTransform extends MethodTransform {
174+
interface UnresolvedMethodTransform extends MethodTransform, ResolvableTransform<MethodElement, MethodBuilder> {
159175
@Override
160176
default void accept(MethodBuilder builder, MethodElement element) {
161177
throw new UnsupportedOperationException("transforms must be resolved before running");
@@ -177,10 +193,10 @@ public record ChainedMethodTransform(MethodTransform t,
177193
implements TransformImpl.UnresolvedMethodTransform {
178194
@Override
179195
public ResolvedTransform<MethodElement> resolve(MethodBuilder builder) {
180-
ResolvedTransform<MethodElement> downstream = next.resolve(builder);
196+
ResolvedTransform<MethodElement> downstream = TransformImpl.resolve(next, builder);
181197
MethodBuilder chainedBuilder = new ChainedMethodBuilder(builder, downstream.consumer());
182-
ResolvedTransform<MethodElement> upstream = t.resolve(chainedBuilder);
183-
return new ResolvedTransformImpl<>(upstream.consumer(),
198+
ResolvedTransform<MethodElement> upstream = TransformImpl.resolve(t, chainedBuilder);
199+
return new ResolvedTransform<>(upstream.consumer(),
184200
chainRunnable(upstream.endHandler(), downstream.endHandler()),
185201
chainRunnable(upstream.startHandler(), downstream.startHandler()));
186202
}
@@ -190,15 +206,15 @@ public record SupplierMethodTransform(Supplier<MethodTransform> supplier)
190206
implements TransformImpl.UnresolvedMethodTransform {
191207
@Override
192208
public ResolvedTransform<MethodElement> resolve(MethodBuilder builder) {
193-
return supplier.get().resolve(builder);
209+
return TransformImpl.resolve(supplier.get(), builder);
194210
}
195211
}
196212

197213
public record MethodCodeTransform(CodeTransform xform)
198214
implements TransformImpl.UnresolvedMethodTransform {
199215
@Override
200216
public ResolvedTransform<MethodElement> resolve(MethodBuilder builder) {
201-
return new ResolvedTransformImpl<>(me -> {
217+
return new ResolvedTransform<>(me -> {
202218
if (me instanceof CodeModel cm) {
203219
builder.transformCode(cm, xform);
204220
}
@@ -219,7 +235,7 @@ public MethodTransform andThen(MethodTransform next) {
219235

220236
// FieldTransform
221237

222-
interface UnresolvedFieldTransform extends FieldTransform {
238+
interface UnresolvedFieldTransform extends FieldTransform, ResolvableTransform<FieldElement, FieldBuilder> {
223239
@Override
224240
default void accept(FieldBuilder builder, FieldElement element) {
225241
throw new UnsupportedOperationException("transforms must be resolved before running");
@@ -240,10 +256,10 @@ public record ChainedFieldTransform(FieldTransform t, FieldTransform next)
240256
implements UnresolvedFieldTransform {
241257
@Override
242258
public ResolvedTransform<FieldElement> resolve(FieldBuilder builder) {
243-
ResolvedTransform<FieldElement> downstream = next.resolve(builder);
259+
ResolvedTransform<FieldElement> downstream = TransformImpl.resolve(next, builder);
244260
FieldBuilder chainedBuilder = new ChainedFieldBuilder(builder, downstream.consumer());
245-
ResolvedTransform<FieldElement> upstream = t.resolve(chainedBuilder);
246-
return new ResolvedTransformImpl<>(upstream.consumer(),
261+
ResolvedTransform<FieldElement> upstream = TransformImpl.resolve(t, chainedBuilder);
262+
return new ResolvedTransform<>(upstream.consumer(),
247263
chainRunnable(upstream.endHandler(), downstream.endHandler()),
248264
chainRunnable(upstream.startHandler(), downstream.startHandler()));
249265
}
@@ -253,13 +269,13 @@ public record SupplierFieldTransform(Supplier<FieldTransform> supplier)
253269
implements UnresolvedFieldTransform {
254270
@Override
255271
public ResolvedTransform<FieldElement> resolve(FieldBuilder builder) {
256-
return supplier.get().resolve(builder);
272+
return TransformImpl.resolve(supplier.get(), builder);
257273
}
258274
}
259275

260276
// CodeTransform
261277

262-
interface UnresolvedCodeTransform extends CodeTransform {
278+
interface UnresolvedCodeTransform extends CodeTransform, ResolvableTransform<CodeElement, CodeBuilder> {
263279
@Override
264280
default void accept(CodeBuilder builder, CodeElement element) {
265281
throw new UnsupportedOperationException("transforms must be resolved before running");
@@ -280,10 +296,10 @@ public record ChainedCodeTransform(CodeTransform t, CodeTransform next)
280296
implements UnresolvedCodeTransform {
281297
@Override
282298
public ResolvedTransform<CodeElement> resolve(CodeBuilder builder) {
283-
ResolvedTransform<CodeElement> downstream = next.resolve(builder);
299+
ResolvedTransform<CodeElement> downstream = TransformImpl.resolve(next, builder);
284300
CodeBuilder chainedBuilder = new ChainedCodeBuilder(builder, downstream.consumer());
285-
ResolvedTransform<CodeElement> upstream = t.resolve(chainedBuilder);
286-
return new ResolvedTransformImpl<>(upstream.consumer(),
301+
ResolvedTransform<CodeElement> upstream = TransformImpl.resolve(t, chainedBuilder);
302+
return new ResolvedTransform<>(upstream.consumer(),
287303
chainRunnable(upstream.endHandler(), downstream.endHandler()),
288304
chainRunnable(upstream.startHandler(), downstream.startHandler()));
289305
}
@@ -293,7 +309,7 @@ public record SupplierCodeTransform(Supplier<CodeTransform> supplier)
293309
implements UnresolvedCodeTransform {
294310
@Override
295311
public ResolvedTransform<CodeElement> resolve(CodeBuilder builder) {
296-
return supplier.get().resolve(builder);
312+
return TransformImpl.resolve(supplier.get(), builder);
297313
}
298314
}
299315
}

0 commit comments

Comments
 (0)
Please sign in to comment.