Skip to content

Commit 2a51c98

Browse files
committed
refactor: introduce ClassGenerationParams
1 parent a27a706 commit 2a51c98

File tree

8 files changed

+80
-66
lines changed

8 files changed

+80
-66
lines changed

src/main/java/es/nachobrito/jsonschema/compiler/domain/Compiler.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static java.lang.classfile.ClassFile.ACC_PUBLIC;
2121
import static java.lang.constant.ClassDesc.of;
2222

23+
import es.nachobrito.jsonschema.compiler.domain.generator.ClassGenerationParams;
2324
import es.nachobrito.jsonschema.compiler.domain.generator.ModelGenerator;
2425
import es.nachobrito.jsonschema.compiler.domain.runtimeconfiguration.RuntimeConfiguration;
2526
import es.nachobrito.jsonschema.compiler.domain.schemareader.SchemaReaderFactory;
@@ -85,7 +86,7 @@ private void writeRecord(
8586
classBuilder.withFlags(ACC_PUBLIC | ACC_FINAL).withSuperclass(of("java.lang.Record"));
8687

8788
var classDesc = of(className);
88-
ModelGenerator.of(runtimeConfiguration, classDesc, classBuilder, properties)
89-
.forEach(ModelGenerator::generatePart);
89+
var params = new ClassGenerationParams(classDesc, classBuilder, properties);
90+
ModelGenerator.of(runtimeConfiguration, params).forEach(ModelGenerator::generatePart);
9091
}
9192
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2024 Nacho Brito
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+
17+
package es.nachobrito.jsonschema.compiler.domain.generator;
18+
19+
import es.nachobrito.jsonschema.compiler.domain.Property;
20+
import java.lang.classfile.ClassBuilder;
21+
import java.lang.constant.ClassDesc;
22+
import java.util.SortedMap;
23+
24+
public record ClassGenerationParams(
25+
ClassDesc classDesc, ClassBuilder classBuilder, SortedMap<String, Property> properties) {}

src/main/java/es/nachobrito/jsonschema/compiler/domain/generator/ConstructorGenerator.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,15 @@
3535

3636
record ConstructorGenerator(
3737
RuntimeConfiguration runtimeConfiguration,
38-
ClassDesc classDesc,
39-
ClassBuilder classBuilder,
40-
SortedMap<String, Property> properties)
38+
ClassGenerationParams params
39+
)
4140
implements ModelGenerator {
4241
@Override
4342
public void generatePart() {
4443
var propertyTypes =
45-
properties.values().stream().map(Property::type).toArray(ClassDesc[]::new);
44+
params.properties().values().stream().map(Property::type).toArray(ClassDesc[]::new);
4645

47-
classBuilder.withMethod(
46+
params.classBuilder().withMethod(
4847
INIT_NAME,
4948
MethodTypeDesc.of(CD_void, propertyTypes),
5049
ACC_PUBLIC,
@@ -55,20 +54,20 @@ public void generatePart() {
5554
codeBuilder
5655
.aload(0)
5756
.invokespecial(of("java.lang.Record"), INIT_NAME, MethodTypeDesc.of(CD_void));
58-
// Set properties:
57+
// Set params.properties():
5958
int index = 1;
60-
for (var entry : properties.entrySet()) {
59+
for (var entry : params.properties().entrySet()) {
6160
codeBuilder
6261
.aload(0)
6362
.aload(index++)
6463
.putfield(
65-
classDesc, entry.getValue().formattedName(), entry.getValue().type());
64+
params.classDesc(), entry.getValue().formattedName(), entry.getValue().type());
6665
}
6766
codeBuilder.return_();
6867
});
6968
if (runtimeConfiguration.withJacksonAnnotations()) {
7069
var annotations =
71-
properties.values().stream()
70+
params.properties().values().stream()
7271
.map(
7372
property ->
7473
List.of(

src/main/java/es/nachobrito/jsonschema/compiler/domain/generator/EqualsGenerator.java

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,11 @@
3232
import java.util.SortedMap;
3333

3434
record EqualsGenerator(
35-
RuntimeConfiguration runtimeConfiguration,
36-
ClassDesc classDesc,
37-
ClassBuilder classBuilder,
38-
SortedMap<String, Property> properties)
35+
RuntimeConfiguration runtimeConfiguration,ClassGenerationParams params)
3936
implements ModelGenerator {
4037
@Override
4138
public void generatePart() {
42-
classBuilder.withMethodBody(
39+
params.classBuilder().withMethodBody(
4340
"equals",
4441
MethodTypeDesc.of(CD_boolean, CD_Object),
4542
ACC_PUBLIC | ACC_FINAL,
@@ -53,14 +50,14 @@ public void generatePart() {
5350
.if_null(returnFalse)
5451
// if (!(o instanceof *ThisClass*)) return false;
5552
.aload(1)
56-
.instanceof_(classDesc)
53+
.instanceof_(params.classDesc())
5754
.ifeq(returnFalse)
5855
// if (o == this) return true;
5956
.aload(0)
6057
.aload(1)
6158
.if_acmpeq(returnTrue);
6259

63-
properties
60+
params.properties()
6461
.entrySet()
6562
.forEach(
6663
entry -> {
@@ -98,10 +95,10 @@ private void compareProperty(
9895
return;
9996
}
10097
cob.aload(0)
101-
.getfield(classDesc, propertyName, propertyDesc)
98+
.getfield(params.classDesc(), propertyName, propertyDesc)
10299
.aload(1)
103-
.checkcast(classDesc)
104-
.getfield(classDesc, propertyName, propertyDesc)
100+
.checkcast(params.classDesc())
101+
.getfield(params.classDesc(), propertyName, propertyDesc)
105102
.invokestatic(
106103
ClassDesc.of(Objects.class.getName()),
107104
"equals",
@@ -112,10 +109,10 @@ private void compareProperty(
112109
private void compareArray(
113110
String propertyName, ClassDesc propertyDesc, CodeBuilder cob, Label returnFalse) {
114111
cob.aload(0)
115-
.getfield(classDesc, propertyName, propertyDesc)
112+
.getfield(params.classDesc(), propertyName, propertyDesc)
116113
.aload(1)
117-
.checkcast(classDesc)
118-
.getfield(classDesc, propertyName, propertyDesc)
114+
.checkcast(params.classDesc())
115+
.getfield(params.classDesc(), propertyName, propertyDesc)
119116
.invokestatic(
120117
ClassDesc.of(Objects.class.getName()),
121118
"deepEquals",
@@ -126,10 +123,10 @@ private void compareArray(
126123
private void comparePrimitive(
127124
String propertyName, ClassDesc propertyDesc, CodeBuilder cob, Label returnFalse) {
128125
cob.aload(0)
129-
.getfield(classDesc, propertyName, propertyDesc)
126+
.getfield(params.classDesc(), propertyName, propertyDesc)
130127
.aload(1)
131-
.checkcast(classDesc)
132-
.getfield(classDesc, propertyName, propertyDesc)
128+
.checkcast(params.classDesc())
129+
.getfield(params.classDesc(), propertyName, propertyDesc)
133130
.if_icmpne(returnFalse);
134131
}
135132
}

src/main/java/es/nachobrito/jsonschema/compiler/domain/generator/HashCodeGenerator.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@
3131

3232
record HashCodeGenerator(
3333
RuntimeConfiguration runtimeConfiguration,
34-
ClassDesc classDesc,
35-
ClassBuilder classBuilder,
36-
SortedMap<String, Property> properties)
34+
ClassGenerationParams params)
3735
implements ModelGenerator {
3836

3937
/**
@@ -53,13 +51,13 @@ record HashCodeGenerator(
5351
*/
5452
@Override
5553
public void generatePart() {
56-
classBuilder.withMethodBody(
54+
params.classBuilder().withMethodBody(
5755
"hashCode",
5856
MethodTypeDesc.of(CD_int),
5957
ACC_PUBLIC | ACC_FINAL,
6058
cob -> {
6159
cob.ldc(1);
62-
properties
60+
params.properties()
6361
.entrySet()
6462
.forEach(
6563
entry -> {
@@ -83,20 +81,20 @@ private void loadFieldValue(String propertyName, ClassDesc propertyDesc, CodeBui
8381
return;
8482
}
8583
cob.aload(0)
86-
.getfield(classDesc, propertyName, propertyDesc)
84+
.getfield(params.classDesc(), propertyName, propertyDesc)
8785
.invokestatic(
8886
ClassDesc.of(Objects.class.getName()),
8987
"hashCode",
9088
MethodTypeDesc.of(CD_int, CD_Object));
9189
}
9290

9391
private void loadPrimitiveValue(String propertyName, ClassDesc propertyDesc, CodeBuilder cob) {
94-
cob.aload(0).getfield(classDesc, propertyName, propertyDesc);
92+
cob.aload(0).getfield(params.classDesc(), propertyName, propertyDesc);
9593
}
9694

9795
private void loadArrayValue(String propertyName, ClassDesc propertyDesc, CodeBuilder cob) {
9896
cob.aload(0)
99-
.getfield(classDesc, propertyName, propertyDesc)
97+
.getfield(params.classDesc(), propertyName, propertyDesc)
10098
.invokestatic(
10199
ClassDesc.of(Arrays.class.getName()),
102100
"deepHashcode",

src/main/java/es/nachobrito/jsonschema/compiler/domain/generator/ModelGenerator.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,13 @@ public interface ModelGenerator {
2727

2828
static Set<ModelGenerator> of(
2929
RuntimeConfiguration runtimeConfiguration,
30-
ClassDesc classDesc,
31-
ClassBuilder classBuilder,
32-
SortedMap<String, Property> properties) {
30+
ClassGenerationParams params) {
3331
return Set.of(
34-
new ConstructorGenerator(runtimeConfiguration, classDesc, classBuilder, properties),
35-
new PropertiesGenerator(runtimeConfiguration, classDesc, classBuilder, properties),
36-
new EqualsGenerator(runtimeConfiguration, classDesc, classBuilder, properties),
37-
new HashCodeGenerator(runtimeConfiguration, classDesc, classBuilder, properties),
38-
new ToStringGenerator(runtimeConfiguration, classDesc, classBuilder, properties));
32+
new ConstructorGenerator(runtimeConfiguration, params),
33+
new PropertiesGenerator(runtimeConfiguration, params),
34+
new EqualsGenerator(runtimeConfiguration, params),
35+
new HashCodeGenerator(runtimeConfiguration, params),
36+
new ToStringGenerator(runtimeConfiguration, params));
3937
}
4038

4139
void generatePart();

src/main/java/es/nachobrito/jsonschema/compiler/domain/generator/PropertiesGenerator.java

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,35 +32,33 @@
3232

3333
record PropertiesGenerator(
3434
RuntimeConfiguration runtimeConfiguration,
35-
ClassDesc classDesc,
36-
ClassBuilder classBuilder,
37-
SortedMap<String, Property> properties)
35+
ClassGenerationParams params)
3836
implements ModelGenerator {
3937
@Override
4038
public void generatePart() {
41-
properties
39+
params.properties()
4240
.entrySet()
43-
.forEach(entry -> buildProperty(classDesc, entry.getValue(), classBuilder));
41+
.forEach(entry -> buildProperty(entry.getValue()));
4442
}
4543

46-
private void buildProperty(ClassDesc className, Property property, ClassBuilder classBuilder) {
47-
buildField(property, classBuilder);
48-
buildAccessor(className, property, classBuilder);
44+
private void buildProperty(Property property) {
45+
buildField(property);
46+
buildAccessor(property);
4947
}
5048

51-
private void buildAccessor(ClassDesc classDesc, Property property, ClassBuilder classBuilder) {
49+
private void buildAccessor(Property property) {
5250
var name = property.formattedName();
5351
var type = property.type();
54-
classBuilder.withMethodBody(
52+
params.classBuilder().withMethodBody(
5553
name,
5654
MethodTypeDesc.of(type),
5755
ACC_PUBLIC,
58-
builder -> builder.aload(0).getfield(classDesc, name, type).areturn());
56+
builder -> builder.aload(0).getfield(params.classDesc(), name, type).areturn());
5957
}
6058

61-
private void buildField(Property property, ClassBuilder classBuilder) {
59+
private void buildField(Property property) {
6260

63-
classBuilder.withField(
61+
params.classBuilder().withField(
6462
property.formattedName(),
6563
property.type(),
6664
fieldBuilder -> {

src/main/java/es/nachobrito/jsonschema/compiler/domain/generator/ToStringGenerator.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,28 +31,26 @@
3131

3232
record ToStringGenerator(
3333
RuntimeConfiguration runtimeConfiguration,
34-
ClassDesc classDesc,
35-
ClassBuilder classBuilder,
36-
SortedMap<String, Property> properties)
34+
ClassGenerationParams params)
3735
implements ModelGenerator {
3836
@Override
3937
public void generatePart() {
4038
// loosely based on:
4139
// https://github.com/openjdk/babylon/blob/490332b12e479d8a0c164cb32dab1def982d8fce/hat/hat/src/main/java/hat/ifacemapper/ByteCodeGenerator.java#L36
4240
var nonArrayGetters =
43-
properties.entrySet().stream()
41+
params.properties().entrySet().stream()
4442
.filter(entry -> !entry.getValue().type().isArray())
4543
.map(
4644
entry ->
4745
MethodHandleDesc.ofField(
4846
DirectMethodHandleDesc.Kind.GETTER,
49-
classDesc,
47+
params.classDesc(),
5048
entry.getValue().formattedName(),
5149
entry.getValue().type()))
5250
.toList();
5351

5452
var recipe =
55-
properties.entrySet().stream()
53+
params.properties().entrySet().stream()
5654
.map(
5755
entry ->
5856
entry.getValue().type().isArray()
@@ -62,7 +60,7 @@ public void generatePart() {
6260
entry.getValue().type().arrayType().displayName(),
6361
"[]")
6462
: String.format("%s=\u0001", entry.getValue().formattedName()))
65-
.collect(Collectors.joining(", ", classDesc.displayName() + "[", "]"));
63+
.collect(Collectors.joining(", ", params.classDesc().displayName() + "[", "]"));
6664

6765
DirectMethodHandleDesc bootstrap =
6866
ofCallsiteBootstrap(
@@ -73,7 +71,7 @@ public void generatePart() {
7371
CD_Object.arrayType());
7472

7573
List<ClassDesc> getDescriptions =
76-
properties.values().stream().map(Property::type).filter(it -> !it.isArray()).toList();
74+
params.properties().values().stream().map(Property::type).filter(it -> !it.isArray()).toList();
7775

7876
DynamicCallSiteDesc desc =
7977
DynamicCallSiteDesc.of(
@@ -82,7 +80,7 @@ public void generatePart() {
8280
MethodTypeDesc.of(CD_String, getDescriptions), // String, g0, g1, ...
8381
recipe);
8482

85-
classBuilder.withMethodBody(
83+
params.classBuilder().withMethodBody(
8684
"toString",
8785
MethodTypeDesc.of(CD_String),
8886
ACC_PUBLIC | ACC_FINAL,
@@ -91,7 +89,7 @@ public void generatePart() {
9189
var name = nonArrayGetters.get(i).methodName();
9290
cob.aload(0);
9391
// Method gi:()?
94-
cob.invokevirtual(classDesc, name, MethodTypeDesc.of(getDescriptions.get(i)));
92+
cob.invokevirtual(params.classDesc(), name, MethodTypeDesc.of(getDescriptions.get(i)));
9593
}
9694
cob.invokedynamic(desc);
9795
cob.areturn();

0 commit comments

Comments
 (0)