This repository has been archived by the owner on Jul 17, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Allow jpyinterpreter to create annotations on classes, fields a…
…nd methods - Fields annotations are created using Annotated in type hints - Method annotations are created using Annotated in a method's return type hints - Class annotations are created using a decorator which stores the annotation in a dict - Changed values in type hint dictionary from PythonLikeType to TypeHint - TypeHint is a record containing the type and any Java annotations - Java annotations are stored as instances of AnnotationMetadata, a record containing the annotation type and value of its attributes
- Loading branch information
1 parent
4349d20
commit 6282186
Showing
12 changed files
with
416 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
jpyinterpreter/src/main/java/ai/timefold/jpyinterpreter/AnnotationMetadata.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package ai.timefold.jpyinterpreter; | ||
|
||
import java.lang.annotation.Annotation; | ||
import java.lang.reflect.Array; | ||
import java.util.Map; | ||
|
||
import org.objectweb.asm.AnnotationVisitor; | ||
import org.objectweb.asm.ClassVisitor; | ||
import org.objectweb.asm.FieldVisitor; | ||
import org.objectweb.asm.MethodVisitor; | ||
import org.objectweb.asm.Type; | ||
|
||
public record AnnotationMetadata(Class<? extends Annotation> annotationType, Map<String, Object> annotationValueMap) { | ||
public void addAnnotationTo(ClassVisitor classVisitor) { | ||
visitAnnotation(classVisitor.visitAnnotation(Type.getDescriptor(annotationType), true)); | ||
} | ||
|
||
public void addAnnotationTo(FieldVisitor fieldVisitor) { | ||
visitAnnotation(fieldVisitor.visitAnnotation(Type.getDescriptor(annotationType), true)); | ||
} | ||
|
||
public void addAnnotationTo(MethodVisitor methodVisitor) { | ||
visitAnnotation(methodVisitor.visitAnnotation(Type.getDescriptor(annotationType), true)); | ||
} | ||
|
||
private void visitAnnotation(AnnotationVisitor annotationVisitor) { | ||
for (var entry : annotationValueMap.entrySet()) { | ||
var annotationAttributeName = entry.getKey(); | ||
var annotationAttributeValue = entry.getValue(); | ||
|
||
visitAnnotationAttribute(annotationVisitor, annotationAttributeName, annotationAttributeValue); | ||
} | ||
annotationVisitor.visitEnd(); | ||
} | ||
|
||
private void visitAnnotationAttribute(AnnotationVisitor annotationVisitor, String attributeName, Object attributeValue) { | ||
if (attributeValue instanceof Number | ||
|| attributeValue instanceof Boolean | ||
|| attributeValue instanceof Character | ||
|| attributeValue instanceof String) { | ||
annotationVisitor.visit(attributeName, attributeValue); | ||
return; | ||
} | ||
|
||
if (attributeValue instanceof Class<?> clazz) { | ||
annotationVisitor.visit(attributeName, Type.getType(clazz)); | ||
return; | ||
} | ||
|
||
if (attributeValue instanceof AnnotationMetadata annotationMetadata) { | ||
annotationMetadata.visitAnnotation( | ||
annotationVisitor.visitAnnotation(attributeName, Type.getDescriptor(annotationMetadata.annotationType))); | ||
return; | ||
} | ||
|
||
if (attributeValue instanceof Enum<?> enumValue) { | ||
annotationVisitor.visitEnum(attributeName, Type.getDescriptor(enumValue.getClass()), | ||
enumValue.name()); | ||
return; | ||
} | ||
|
||
if (attributeValue.getClass().isArray()) { | ||
var arrayAnnotationVisitor = annotationVisitor.visitArray(attributeName); | ||
var arrayLength = Array.getLength(attributeValue); | ||
for (int i = 0; i < arrayLength; i++) { | ||
visitAnnotationAttribute(arrayAnnotationVisitor, attributeName, Array.get(attributeValue, i)); | ||
} | ||
arrayAnnotationVisitor.visitEnd(); | ||
return; | ||
} | ||
throw new IllegalArgumentException("Annotation of type %s has an illegal value %s for attribute %s." | ||
.formatted(annotationType, attributeValue, attributeName)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
jpyinterpreter/src/main/java/ai/timefold/jpyinterpreter/TypeHint.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package ai.timefold.jpyinterpreter; | ||
|
||
import java.util.List; | ||
|
||
import ai.timefold.jpyinterpreter.types.PythonLikeType; | ||
|
||
public record TypeHint(PythonLikeType type, List<AnnotationMetadata> annotationList) { | ||
public static TypeHint withoutAnnotations(PythonLikeType type) { | ||
return new TypeHint(type, List.of()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.