Skip to content

Commit c7b7924

Browse files
authored
Merge pull request #1 from mmhelloworld/feature/idrisjvm-35
idrisjvm-35 Add initial annotation support
2 parents 7c52fde + 3cee2c7 commit c7b7924

File tree

4 files changed

+199
-11
lines changed

4 files changed

+199
-11
lines changed

jvm-assembler-server/pom.xml

+5
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@
115115
<groupId>org.ow2.asm</groupId>
116116
<artifactId>asm-all</artifactId>
117117
</dependency>
118+
119+
<dependency>
120+
<groupId>org.projectlombok</groupId>
121+
<artifactId>lombok</artifactId>
122+
</dependency>
118123
</dependencies>
119124

120125

jvm-assembler-server/src/main/java/com/mmhelloworld/jvmassembler/server/Asm.java

+137-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import com.fasterxml.jackson.annotation.JsonProperty;
55
import com.fasterxml.jackson.annotation.JsonSubTypes;
66
import com.fasterxml.jackson.annotation.JsonTypeInfo;
7+
import lombok.ToString;
8+
9+
import java.util.List;
710

811
@JsonTypeInfo(
912
use = JsonTypeInfo.Id.NAME,
@@ -16,6 +19,7 @@
1619
@JsonSubTypes.Type(value = Asm.Aconstnull.class, name = "Aconstnull"),
1720
@JsonSubTypes.Type(value = Asm.Aload.class, name = "Aload"),
1821
@JsonSubTypes.Type(value = Asm.Anewarray.class, name = "Anewarray"),
22+
@JsonSubTypes.Type(value = Asm.Annotation.class, name = "Annotation"),
1923
@JsonSubTypes.Type(value = Asm.Astore.class, name = "Astore"),
2024
@JsonSubTypes.Type(value = Asm.Areturn.class, name = "Areturn"),
2125
@JsonSubTypes.Type(value = Asm.Checkcast.class, name = "Checkcast"),
@@ -107,6 +111,7 @@ public enum AsmType {
107111
Aconstnull,
108112
Aload,
109113
Anewarray,
114+
Annotation,
110115
Astore,
111116
Areturn,
112117
Checkcast,
@@ -301,19 +306,22 @@ public static class ClassCodeStart extends Asm {
301306
private final String sig;
302307
private final String parent;
303308
private final String[] interfaces;
309+
private final List<Annotation> annotations;
304310

305311
public ClassCodeStart(@JsonProperty("version") final int version,
306312
@JsonProperty("acc") final int acc,
307313
@JsonProperty("name") final String name,
308314
@JsonProperty("sig") final String sig,
309315
@JsonProperty("parent") final String parent,
310-
@JsonProperty("interfaces") final String[] interfaces) {
316+
@JsonProperty("interfaces") final String[] interfaces,
317+
@JsonProperty("annotations") final List<Annotation> annotations) {
311318
this.version = version;
312319
this.acc = acc;
313320
this.name = name;
314321
this.sig = sig;
315322
this.parent = parent;
316323
this.interfaces = interfaces;
324+
this.annotations = annotations;
317325
}
318326

319327
public int getVersion() {
@@ -339,6 +347,10 @@ public String getParent() {
339347
public String[] getInterfaces() {
340348
return interfaces;
341349
}
350+
351+
public List<Annotation> getAnnotations() {
352+
return annotations;
353+
}
342354
}
343355

344356
public static class ClassCodeEnd extends Asm {
@@ -360,19 +372,25 @@ public static class CreateMethod extends Asm {
360372
private final String desc;
361373
private final String sig;
362374
private final String[] excs;
375+
private final List<Annotation> anns;
376+
private final List<List<Annotation>> paramAnns;
363377

364378
public CreateMethod(@JsonProperty("acc") final int acc,
365379
@JsonProperty("cname") final String cname,
366380
@JsonProperty("fname") final String fname,
367381
@JsonProperty("desc") final String desc,
368382
@JsonProperty("sig") final String sig,
369-
@JsonProperty("excs") final String[] excs) {
383+
@JsonProperty("excs") final String[] excs,
384+
@JsonProperty("anns") final List<Annotation> anns,
385+
@JsonProperty("paramAnns") final List<List<Annotation>> paramAnns) {
370386
this.acc = acc;
371387
this.cname = cname;
372388
this.fname = fname;
373389
this.desc = desc;
374390
this.sig = sig;
375391
this.excs = excs;
392+
this.anns = anns;
393+
this.paramAnns = paramAnns;
376394
}
377395

378396
public int getAcc() {
@@ -398,6 +416,14 @@ public String getSig() {
398416
public String[] getExcs() {
399417
return excs;
400418
}
419+
420+
public List<Annotation> getAnns() {
421+
return anns;
422+
}
423+
424+
public List<List<Annotation>> getParamAnns() {
425+
return paramAnns;
426+
}
401427
}
402428

403429
public static class CreateField extends Asm {
@@ -1057,4 +1083,113 @@ public int getN() {
10571083
return n;
10581084
}
10591085
}
1086+
1087+
@ToString
1088+
public static class Annotation extends Asm {
1089+
private final String name;
1090+
private final List<AnnotationProperty> properties;
1091+
1092+
public Annotation(@JsonProperty("name") final String name,
1093+
@JsonProperty("props") final List<AnnotationProperty> properties) {
1094+
this.name = name;
1095+
this.properties = properties;
1096+
}
1097+
1098+
public String getName() {
1099+
return name;
1100+
}
1101+
1102+
public List<AnnotationProperty> getProperties() {
1103+
return properties;
1104+
}
1105+
}
1106+
1107+
@ToString
1108+
public static class AnnotationProperty {
1109+
private final String name;
1110+
private final AnnotationValue value;
1111+
1112+
public AnnotationProperty(@JsonProperty("name") final String name,
1113+
@JsonProperty("value") final AnnotationValue value) {
1114+
this.name = name;
1115+
this.value = value;
1116+
}
1117+
1118+
public AnnotationValue getValue() {
1119+
return value;
1120+
}
1121+
1122+
public String getName() {
1123+
return name;
1124+
}
1125+
}
1126+
1127+
@JsonTypeInfo(
1128+
use = JsonTypeInfo.Id.NAME,
1129+
include = JsonTypeInfo.As.PROPERTY,
1130+
property = "type",
1131+
visible = true)
1132+
@JsonSubTypes({
1133+
@JsonSubTypes.Type(value = AnnotationValue.AnnString.class, name = "AnnString"),
1134+
@JsonSubTypes.Type(value = AnnotationValue.AnnInt.class, name = "AnnInt"),
1135+
@JsonSubTypes.Type(value = AnnotationValue.AnnArray.class, name = "AnnArray")
1136+
})
1137+
public static abstract class AnnotationValue {
1138+
private AnnotationValueType type;
1139+
1140+
private AnnotationValue() {}
1141+
1142+
public AnnotationValueType getType() {
1143+
return type;
1144+
}
1145+
1146+
public void setType(final AnnotationValueType type) {
1147+
this.type = type;
1148+
}
1149+
1150+
public enum AnnotationValueType {
1151+
AnnString,
1152+
AnnInt,
1153+
AnnArray
1154+
}
1155+
1156+
@ToString
1157+
public static class AnnString extends AnnotationValue {
1158+
private final String value;
1159+
1160+
public AnnString(@JsonProperty("value") final String value) {
1161+
this.value = value;
1162+
}
1163+
1164+
public String getValue() {
1165+
return value;
1166+
}
1167+
}
1168+
1169+
@ToString
1170+
public static class AnnInt extends AnnotationValue {
1171+
private final int value;
1172+
1173+
public AnnInt(@JsonProperty("value") final int value) {
1174+
this.value = value;
1175+
}
1176+
1177+
public int getValue() {
1178+
return value;
1179+
}
1180+
}
1181+
1182+
@ToString
1183+
public static class AnnArray extends AnnotationValue {
1184+
private final List<AnnotationValue> values;
1185+
1186+
public AnnArray(@JsonProperty("values") final List<AnnotationValue> values) {
1187+
this.values = values;
1188+
}
1189+
1190+
public List<AnnotationValue> getValues() {
1191+
return values;
1192+
}
1193+
}
1194+
}
10601195
}

jvm-assembler-server/src/main/java/com/mmhelloworld/jvmassembler/server/AssemblerResource.java

+50-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package com.mmhelloworld.jvmassembler.server;
22

33
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.mmhelloworld.jvmassembler.server.Asm.AnnotationValue;
5+
import com.mmhelloworld.jvmassembler.server.Asm.AnnotationValue.AnnotationValueType;
6+
import org.objectweb.asm.AnnotationVisitor;
47
import org.objectweb.asm.ClassWriter;
58
import org.objectweb.asm.FieldVisitor;
69
import org.objectweb.asm.Handle;
@@ -21,6 +24,7 @@
2124
import java.io.OutputStream;
2225
import java.util.Arrays;
2326
import java.util.HashMap;
27+
import java.util.List;
2428
import java.util.Map;
2529

2630
import static org.objectweb.asm.ClassWriter.COMPUTE_MAXS;
@@ -136,14 +140,7 @@ public AssemblerResponse assemble(CreateBytecode request) throws JsonProcessingE
136140
mv.visitTypeInsn(CHECKCAST, checkcast.getDesc());
137141
break;
138142
case ClassCodeStart:
139-
Asm.ClassCodeStart classCodeStart = (Asm.ClassCodeStart) asm;
140-
cw.visit(classCodeStart.getVersion(),
141-
classCodeStart.getAcc(),
142-
classCodeStart.getName(),
143-
classCodeStart.getSig(),
144-
classCodeStart.getParent(),
145-
classCodeStart.getInterfaces());
146-
cws.put(classCodeStart.getName(), cw);
143+
handleClassCodeStart(cws, cw, (Asm.ClassCodeStart) asm);
147144
break;
148145
case ClassCodeEnd:
149146
cw.visitEnd();
@@ -190,12 +187,14 @@ public AssemblerResponse assemble(CreateBytecode request) throws JsonProcessingE
190187
createDefaultConstructor(classWriter);
191188
return classWriter;
192189
});
190+
List<Asm.Annotation> anns = createMethod.getAnns();
193191
mv = cw.visitMethod(
194192
createMethod.getAcc(),
195193
createMethod.getFname(),
196194
createMethod.getDesc(),
197195
createMethod.getSig(),
198196
createMethod.getExcs());
197+
handleCreateMethod(mv, createMethod);
199198
break;
200199
case Dadd:
201200
mv.visitInsn(DADD);
@@ -391,7 +390,7 @@ public AssemblerResponse assemble(CreateBytecode request) throws JsonProcessingE
391390
mv.visitLdcInsn(((Asm.LdcString) asm).getVal());
392391
break;
393392
case LdcType:
394-
mv.visitLdcInsn(Type.getType(((Asm.LdcType)asm).getVal()));
393+
mv.visitLdcInsn(Type.getType(((Asm.LdcType) asm).getVal()));
395394
break;
396395
case Ldiv:
397396
mv.visitInsn(LDIV);
@@ -464,6 +463,48 @@ public AssemblerResponse assemble(CreateBytecode request) throws JsonProcessingE
464463
return new AssemblerResponse(isSuccess, error);
465464
}
466465

466+
private void handleCreateMethod(final MethodVisitor mv, final Asm.CreateMethod createMethod) {
467+
createMethod.getAnns().forEach(annotation -> {
468+
final AnnotationVisitor av = mv.visitAnnotation(annotation.getName(), true);
469+
annotation.getProperties().forEach(prop -> addPropertyToAnnotation(av, prop));
470+
});
471+
}
472+
473+
private void handleClassCodeStart(final Map<String, ClassWriter> cws,
474+
final ClassWriter cw,
475+
final Asm.ClassCodeStart classCodeStart) {
476+
cw.visit(classCodeStart.getVersion(),
477+
classCodeStart.getAcc(),
478+
classCodeStart.getName(),
479+
classCodeStart.getSig(),
480+
classCodeStart.getParent(),
481+
classCodeStart.getInterfaces());
482+
cws.put(classCodeStart.getName(), cw);
483+
484+
final List<Asm.Annotation> annotations = classCodeStart.getAnnotations();
485+
annotations.forEach(annotation -> {
486+
AnnotationVisitor av = cw.visitAnnotation(annotation.getName(), true);
487+
annotation.getProperties().forEach(prop -> addPropertyToAnnotation(av, prop));
488+
av.visitEnd();
489+
});
490+
}
491+
492+
private void addPropertyToAnnotation(final AnnotationVisitor av, final Asm.AnnotationProperty prop) {
493+
final AnnotationValueType propType = prop.getValue().getType();
494+
switch (propType) {
495+
case AnnString:
496+
AnnotationValue.AnnString annStr = (AnnotationValue.AnnString) prop.getValue();
497+
av.visit(prop.getName(), annStr.getValue());
498+
break;
499+
case AnnInt:
500+
AnnotationValue.AnnInt annInt = (AnnotationValue.AnnInt) prop.getValue();
501+
av.visit(prop.getName(), annInt.getValue());
502+
break;
503+
case AnnArray:
504+
break;
505+
}
506+
}
507+
467508
private MethodVisitor createDefaultConstructor(final ClassWriter cw) {
468509
final MethodVisitor mv;
469510
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);

pom.xml

+7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<jetty.version>9.3.11.v20160721</jetty.version>
1919
<asm.version>5.1</asm.version>
2020
<joptsimple.version>5.0.2</joptsimple.version>
21+
<lombok.version>1.16.12</lombok.version>
2122
</properties>
2223

2324
<build>
@@ -104,6 +105,12 @@
104105
<version>${joptsimple.version}</version>
105106
</dependency>
106107

108+
<dependency>
109+
<groupId>org.projectlombok</groupId>
110+
<artifactId>lombok</artifactId>
111+
<version>${lombok.version}</version>
112+
</dependency>
113+
107114
</dependencies>
108115
</dependencyManagement>
109116

0 commit comments

Comments
 (0)