@@ -56,6 +56,8 @@ public class PythonClassTranslator {
5656 // $ is illegal in variables/methods in Python
5757 public static String TYPE_FIELD_NAME = "$TYPE" ;
5858 public static String CPYTHON_TYPE_FIELD_NAME = "$CPYTHON_TYPE" ;
59+ private static String JAVA_FIELD_PREFIX = "$field$" ;
60+ private static String JAVA_METHOD_PREFIX = "$method$" ;
5961
6062 public static PythonLikeType translatePythonClass (PythonCompiledClass pythonCompiledClass ) {
6163 String maybeClassName =
@@ -144,6 +146,10 @@ public static PythonLikeType translatePythonClass(PythonCompiledClass pythonComp
144146 classWriter .visit (Opcodes .V11 , Modifier .PUBLIC , internalClassName , null ,
145147 superClassType .getJavaTypeInternalName (), interfaces );
146148
149+ for (var annotation : pythonCompiledClass .annotations ) {
150+ annotation .addAnnotationTo (classWriter );
151+ }
152+
147153 pythonCompiledClass .staticAttributeNameToObject .forEach (pythonLikeType ::$setAttribute );
148154
149155 classWriter .visitField (Modifier .PUBLIC | Modifier .STATIC , TYPE_FIELD_NAME , Type .getDescriptor (PythonLikeType .class ),
@@ -157,15 +163,28 @@ public static PythonLikeType translatePythonClass(PythonCompiledClass pythonComp
157163 pythonLikeType .$setAttribute (staticAttributeEntry .getKey (), staticAttributeEntry .getValue ());
158164 }
159165
166+ for (var attributeName : pythonCompiledClass .typeAnnotations .keySet ()) {
167+ if (pythonLikeType .$getAttributeOrNull (attributeName ) == null ) {
168+ instanceAttributeSet .add (attributeName );
169+ }
170+ }
171+
160172 Map <String , PythonLikeType > attributeNameToTypeMap = new HashMap <>();
161173 for (String attributeName : instanceAttributeSet ) {
162- PythonLikeType type = pythonCompiledClass .typeAnnotations .getOrDefault (attributeName , BuiltinTypes .BASE_TYPE );
174+ var typeHint = pythonCompiledClass .typeAnnotations .getOrDefault (attributeName ,
175+ TypeHint .withoutAnnotations (BuiltinTypes .BASE_TYPE ));
176+ PythonLikeType type = typeHint .type ();
163177 if (type == null ) { // null might be in __annotations__
164178 type = BuiltinTypes .BASE_TYPE ;
165179 }
166180 String javaFieldTypeDescriptor = 'L' + type .getJavaTypeInternalName () + ';' ;
167181 attributeNameToTypeMap .put (attributeName , type );
168- classWriter .visitField (Modifier .PUBLIC , getJavaFieldName (attributeName ), javaFieldTypeDescriptor , null , null );
182+ var fieldVisitor = classWriter .visitField (Modifier .PUBLIC , getJavaFieldName (attributeName ), javaFieldTypeDescriptor ,
183+ null , null );
184+ for (var annotation : typeHint .annotationList ()) {
185+ annotation .addAnnotationTo (fieldVisitor );
186+ }
187+ fieldVisitor .visitEnd ();
169188 FieldDescriptor fieldDescriptor =
170189 new FieldDescriptor (attributeName , getJavaFieldName (attributeName ), internalClassName ,
171190 javaFieldTypeDescriptor , type , true );
@@ -264,7 +283,7 @@ public static PythonLikeType translatePythonClass(PythonCompiledClass pythonComp
264283 pythonLikeType .$setAttribute ("__module__" , PythonString .valueOf (pythonCompiledClass .module ));
265284
266285 PythonLikeDict annotations = new PythonLikeDict ();
267- pythonCompiledClass .typeAnnotations .forEach ((name , type ) -> annotations .put (PythonString .valueOf (name ), type ));
286+ pythonCompiledClass .typeAnnotations .forEach ((name , type ) -> annotations .put (PythonString .valueOf (name ), type . type () ));
268287 pythonLikeType .$setAttribute ("__annotations__" , annotations );
269288
270289 PythonLikeTuple mro = new PythonLikeTuple ();
@@ -347,19 +366,19 @@ public static void setSelfStaticInstances(PythonCompiledClass pythonCompiledClas
347366 }
348367
349368 public static String getJavaFieldName (String pythonFieldName ) {
350- return "$field$" + pythonFieldName ;
369+ return JAVA_FIELD_PREFIX + pythonFieldName ;
351370 }
352371
353372 public static String getPythonFieldName (String javaFieldName ) {
354- return javaFieldName .substring ("$field$" .length ());
373+ return javaFieldName .substring (JAVA_FIELD_PREFIX .length ());
355374 }
356375
357376 public static String getJavaMethodName (String pythonMethodName ) {
358- return "$method$" + pythonMethodName ;
377+ return JAVA_METHOD_PREFIX + pythonMethodName ;
359378 }
360379
361380 public static String getPythonMethodName (String javaMethodName ) {
362- return javaMethodName .substring ("$method$" .length ());
381+ return javaMethodName .substring (JAVA_METHOD_PREFIX .length ());
363382 }
364383
365384 private static Class <?> createBytecodeForMethodAndSetOnClass (String className , PythonLikeType pythonLikeType ,
@@ -673,6 +692,15 @@ private static PythonLikeFunction createConstructor(String classInternalName,
673692 }
674693 }
675694
695+ private static void addAnnotationsToMethod (PythonCompiledFunction function , MethodVisitor methodVisitor ) {
696+ var returnTypeHint = function .typeAnnotations .get ("return" );
697+ if (returnTypeHint != null ) {
698+ for (var annotation : returnTypeHint .annotationList ()) {
699+ annotation .addAnnotationTo (methodVisitor );
700+ }
701+ }
702+ }
703+
676704 private static void createInstanceMethod (PythonLikeType pythonLikeType , ClassWriter classWriter , String internalClassName ,
677705 String methodName , PythonCompiledFunction function ) {
678706 InterfaceDeclaration interfaceDeclaration = getInterfaceForInstancePythonFunction (internalClassName , function );
@@ -693,7 +721,8 @@ private static void createInstanceMethod(PythonLikeType pythonLikeType, ClassWri
693721 MethodVisitor methodVisitor =
694722 classWriter .visitMethod (Modifier .PUBLIC , javaMethodName , javaMethodDescriptor , null , null );
695723
696- createMethodBody (internalClassName , javaMethodName , javaParameterTypes , interfaceDeclaration .methodDescriptor , function ,
724+ createInstanceOrStaticMethodBody (internalClassName , javaMethodName , javaParameterTypes ,
725+ interfaceDeclaration .methodDescriptor , function ,
697726 interfaceDeclaration .interfaceName , interfaceDescriptor , methodVisitor );
698727
699728 pythonLikeType .addMethod (methodName ,
@@ -722,7 +751,9 @@ private static void createStaticMethod(PythonLikeType pythonLikeType, ClassWrite
722751 for (int i = 0 ; i < function .totalArgCount (); i ++) {
723752 javaParameterTypes [i ] = Type .getType ('L' + parameterPythonTypeList .get (i ).getJavaTypeInternalName () + ';' );
724753 }
725- createMethodBody (internalClassName , javaMethodName , javaParameterTypes , interfaceDeclaration .methodDescriptor , function ,
754+
755+ createInstanceOrStaticMethodBody (internalClassName , javaMethodName , javaParameterTypes ,
756+ interfaceDeclaration .methodDescriptor , function ,
726757 interfaceDeclaration .interfaceName , interfaceDescriptor , methodVisitor );
727758
728759 pythonLikeType .addMethod (methodName ,
@@ -746,8 +777,10 @@ private static void createClassMethod(PythonLikeType pythonLikeType, ClassWriter
746777 classWriter .visitMethod (Modifier .PUBLIC | Modifier .STATIC , javaMethodName , javaMethodDescriptor , null , null );
747778
748779 for (int i = 0 ; i < function .getParameterTypes ().size (); i ++) {
749- methodVisitor .visitParameter ("parameter" + i , 0 );
780+ methodVisitor .visitParameter (function . co_varnames . get ( i ) , 0 );
750781 }
782+
783+ addAnnotationsToMethod (function , methodVisitor );
751784 methodVisitor .visitCode ();
752785
753786 methodVisitor .visitFieldInsn (Opcodes .GETSTATIC , internalClassName , javaMethodName , interfaceDescriptor );
@@ -775,13 +808,15 @@ private static void createClassMethod(PythonLikeType pythonLikeType, ClassWriter
775808 parameterTypes ));
776809 }
777810
778- private static void createMethodBody (String internalClassName , String javaMethodName , Type [] javaParameterTypes ,
811+ private static void createInstanceOrStaticMethodBody (String internalClassName , String javaMethodName ,
812+ Type [] javaParameterTypes ,
779813 String methodDescriptorString ,
780814 PythonCompiledFunction function , String interfaceInternalName , String interfaceDescriptor ,
781815 MethodVisitor methodVisitor ) {
782816 for (int i = 0 ; i < javaParameterTypes .length ; i ++) {
783- methodVisitor .visitParameter ("parameter" + i , 0 );
817+ methodVisitor .visitParameter (function . co_varnames . get ( i ) , 0 );
784818 }
819+ addAnnotationsToMethod (function , methodVisitor );
785820 methodVisitor .visitCode ();
786821
787822 methodVisitor .visitFieldInsn (Opcodes .GETSTATIC , internalClassName , javaMethodName , interfaceDescriptor );
0 commit comments