34 this.context = context ??
throw new ArgumentNullException(nameof(context));
47 internal void Write(Stream stream, RuntimeJavaType type,
bool includeNonPublicTypes,
bool includeNonPublicInterfaces,
bool includeNonPublicMembers,
bool includeParameterNames,
bool includeSerialVersionUID)
49 var name = type.Name.Replace(
'.',
'/');
53 super =
"java/lang/Object";
54 else if (type.BaseTypeWrapper !=
null)
55 super = type.BaseTypeWrapper.Name.Replace(
'.',
'/');
57 var builder =
new ClassFileBuilder(
new ClassFormatVersion(includeParameterNames ? (ushort)52 : (ushort)49, 0), (AccessFlag)type.Modifiers, name, super);
59 AddInterfaces(builder, type, includeNonPublicInterfaces);
60 AddMethods(builder, type, includeNonPublicMembers, includeParameterNames);
61 AddFields(builder, type, includeNonPublicMembers, includeSerialVersionUID);
62 AddInnerClassesAttribute(builder, type, name, includeNonPublicTypes);
63 AddSignatureAttribute(builder, type);
64 AddAssemblyAttribute(builder, type);
65 AddDeprecatedAttribute(builder, type);
66 AddRuntimeVisibleAnnotationsAttribute(builder, type);
67 AddRuntimeVisibleTypeAnnotationsAttribute(builder, type);
70 var blob =
new BlobBuilder();
71 builder.Serialize(blob);
72 blob.WriteContentTo(stream);
81 void AddInterfaces(ClassFileBuilder builder, RuntimeJavaType type,
bool includeNonPublicInterfaces)
83 foreach (var iface
in type.Interfaces)
84 if (iface.IsPublic || includeNonPublicInterfaces)
85 builder.AddInterface(iface.Name.Replace(
'.',
'/'));
95 void AddMethods(ClassFileBuilder builder, RuntimeJavaType type,
bool includeNonPublicMembers,
bool includeParameterNames)
97 foreach (var method
in type.GetMethods())
99 var accessFlags = (AccessFlag)method.Modifiers;
100 var attributes =
new AttributeTableBuilder(builder.Constants);
102 if (method.IsHideFromReflection ==
false && (method.IsPublic || method.IsProtected || includeNonPublicMembers))
108 if (method.Name ==
"<init>" || (type == context.JavaBase.TypeOfJavaLangInvokeMethodHandle && (method.Modifiers &
Modifiers.Native) == 0))
111 var codeBlob =
new BlobBuilder();
112 new CodeBuilder(codeBlob)
113 .New(builder.Constants.GetOrAddClass(
"java/lang/UnsatisfiedLinkError"))
115 .LoadConstant(builder.Constants.GetOrAddString(
"IKVM stubs can only be used on IKVM"))
116 .InvokeSpecial(builder.Constants.GetOrAddMethodref(
"java/lang/UnsatisfiedLinkError",
"<init>",
"(Ljava/lang/String;)V"))
119 attributes.Code(3, (ushort)(method.GetParameters().Length * 2 + 1), codeBlob, e => { },
new AttributeTableBuilder(builder.Constants));
123 if ((accessFlags & AccessFlag.Abstract) == 0)
124 accessFlags |= AccessFlag.Native;
126 if (method.IsOptionalAttributeAnnotationValue)
127 attributes.AnnotationDefault(e => EncodeAnnotationDefault(builder,
ref e, method.ReturnType));
130 var methodBase = method.GetMethod();
131 if (methodBase !=
null)
133 AddExceptionsAttribute(builder, type, method, attributes, methodBase);
134 AddDeprecatedAttribute(builder, type, method, attributes, methodBase);
135 AddAnnotationDefaultAttribute(builder, type, method, attributes, methodBase);
136 AddMethodParameters(builder, type, method, attributes, includeParameterNames);
139 AddSignatureAttribute(builder, type, method, attributes);
140 AddRuntimeVisibleAnnotationsAttribute(builder, type, method, attributes);
141 AddRuntimeVisibleTypeAnnotationsAttribute(builder, type, method, attributes);
142 AddRuntimeVisibleParameterAnnotationsAttribute(builder, type, method, attributes);
144 builder.AddMethod(accessFlags, method.Name, method.Signature.Replace(
'.',
'/'), attributes);
156 void AddFields(ClassFileBuilder builder, RuntimeJavaType type,
bool includeNonPublicMembers,
bool includeSerialVersionUID)
158 var hasSerialVersionUID =
false;
160 foreach (var field
in type.GetFields())
162 if (field.IsHideFromReflection ==
false)
164 var attributes =
new AttributeTableBuilder(builder.Constants);
166 var isSerialVersionUID = includeSerialVersionUID && field.IsSerialVersionUID;
167 hasSerialVersionUID |= isSerialVersionUID;
169 if (field.IsPublic || field.IsProtected || isSerialVersionUID || includeNonPublicMembers)
171 AddConstantValueAttribute(builder, type, field, attributes);
172 AddSignatureAttribute(builder, type, field, attributes);
173 AddDeprecatedAttribute(builder, type, field, attributes);
174 AddRuntimeVisibleAnnotationsAttribute(builder, type, field, attributes);
175 AddRuntimeVisibleTypeAnnotationsAttribute(builder, type, field, attributes);
176 builder.AddField((AccessFlag)field.Modifiers, field.Name, field.Signature.Replace(
'.',
'/'), attributes);
183 if (includeSerialVersionUID && hasSerialVersionUID ==
false && IsSerializable(type))
185 var fieldAttributes =
new AttributeTableBuilder(builder.Constants);
186 fieldAttributes.ConstantValue(SerialVersionUID.Compute(type));
187 builder.AddField(AccessFlag.Private | AccessFlag.Static | AccessFlag.Final,
"serialVersionUID",
"J", fieldAttributes);
196 void AddRuntimeVisibleTypeAnnotationsAttribute(ClassFileBuilder builder, RuntimeJavaType type)
198 var blob =
new BlobBuilder();
199 var encoder =
new TypeAnnotationTableEncoder(blob);
200 if (ImportTypeAnnotations(builder,
ref encoder, type, type.GetRawTypeAnnotations()))
201 builder.Attributes.Attribute(AttributeName.RuntimeVisibleTypeAnnotations, blob);
209 void AddRuntimeVisibleAnnotationsAttribute(ClassFileBuilder builder, RuntimeJavaType type)
211 var blob =
new BlobBuilder();
212 var encoder =
new AnnotationTableEncoder(blob);
213 if (EncodeAnnotations(builder,
ref encoder, type.TypeAsBaseType) ||
214 EncodeAnnotationsForType(builder,
ref encoder, type))
215 builder.Attributes.Attribute(AttributeName.RuntimeVisibleAnnotations, blob);
223 void AddDeprecatedAttribute(ClassFileBuilder builder, RuntimeJavaType type)
225 if (type.TypeAsBaseType.IsDefined(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).AsReflection(),
false))
226 builder.Attributes.Deprecated();
236 void AddInnerClassesAttribute(ClassFileBuilder builder, RuntimeJavaType javaType,
string name,
bool includeNonPublicTypes)
239 var blob =
new BlobBuilder();
240 var encoder =
new InnerClassTableEncoder(blob);
242 if (javaType.DeclaringTypeWrapper !=
null)
244 var innerName = name;
245 int idx = name.LastIndexOf(
'$');
247 innerName = innerName.Substring(idx + 1);
250 builder.Constants.GetOrAddClass(name),
251 builder.Constants.GetOrAddClass(javaType.DeclaringTypeWrapper.Name.Replace(
'.',
'/')),
252 builder.Constants.GetOrAddUtf8(innerName),
253 (AccessFlag)javaType.ReflectiveModifiers);
258 foreach (var innerType
in javaType.InnerClasses)
260 if (innerType.IsPublic || includeNonPublicTypes)
262 var namePart = innerType.Name;
263 namePart = namePart.Substring(namePart.LastIndexOf(
'$') + 1);
266 builder.Constants.GetOrAddClass(innerType.Name.Replace(
'.',
'/')),
267 builder.Constants.GetOrAddClass(name),
268 builder.Constants.GetOrAddUtf8(namePart),
269 (AccessFlag)innerType.ReflectiveModifiers);
276 builder.Attributes.Attribute(AttributeName.InnerClasses, blob);
284 void AddSignatureAttribute(ClassFileBuilder builder, RuntimeJavaType javaType)
286 var signature = javaType.GetGenericSignature();
287 if (signature !=
null)
288 builder.Attributes.Signature(signature);
296 void AddAssemblyAttribute(ClassFileBuilder builder, RuntimeJavaType javaType)
300 var assemblyAttributeBlob =
new BlobBuilder();
301 new ClassFormatWriter(assemblyAttributeBlob.ReserveBytes(ClassFormatWriter.U2).GetBytes()).WriteU2(builder.Constants.GetOrAddUtf8(GetAssemblyName(javaType)).Slot);
302 builder.Attributes.Encoder.Attribute(builder.Constants.GetOrAddUtf8(
"IKVM.NET.Assembly"), assemblyAttributeBlob);
313 void AddExceptionsAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder attributes,
MethodBase methodBase)
315 var
throws = context.AttributeHelper.GetThrows(methodBase);
318 var throwsArray = method.GetDeclaredExceptions();
319 if (throwsArray !=
null && throwsArray.Length > 0)
321 attributes.Exceptions(e =>
323 foreach (
string ex
in throwsArray)
324 e.Class(builder.Constants.GetOrAddClass(ex.Replace(
'.',
'/')));
330 if (
throws.classes !=
null ||
throws.types !=
null)
332 attributes.Exceptions(e =>
334 if (
throws.classes !=
null)
335 foreach (
string ex
in throws.classes)
336 e.Class(builder.Constants.GetOrAddClass(ex.Replace(
'.',
'/')));
338 if (
throws.types !=
null)
339 foreach (
Type ex
in throws.types)
340 e.Class(builder.Constants.GetOrAddClass(context.ClassLoaderFactory.GetJavaTypeFromType(ex).Name.Replace(
'.',
'/')));
355 void AddMethodParameters(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder attributes,
bool includeParameterNames)
357 if (includeParameterNames)
359 var mp = type.GetMethodParameters(method);
360 if (mp == MethodParametersEntry.Malformed)
362 attributes.MethodParameters(e => { });
366 attributes.MethodParameters(e =>
368 foreach (var i
in mp)
369 e.MethodParameter(builder.Constants.GetOrAddUtf8(i.name), i.accessFlags);
383 void AddAnnotationDefaultAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder attributes,
MethodBase methodBase)
385 var attr = GetAnnotationDefault(methodBase);
387 attributes.AnnotationDefault(e => EncodeAnnotationDefault(builder,
ref e, attr.ConstructorArguments[0]));
397 void AddSignatureAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder methodAttributes)
399 var signature = type.GetGenericMethodSignature(method);
400 if (signature !=
null)
401 methodAttributes.Signature(signature);
412 void AddDeprecatedAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder attributes,
MethodBase methodBase)
417 if (methodBase.IsDefined(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).AsReflection(),
false) && (!methodBase.Name.StartsWith(
"instancehelper_") || methodBase.DeclaringType.FullName !=
"java.lang.String" || GetObsoleteCount(methodBase) == 2))
418 attributes.Deprecated();
428 void AddRuntimeVisibleParameterAnnotationsAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder attributes)
430 var blob =
new BlobBuilder();
431 var encoder =
new ParameterAnnotationTableEncoder(blob);
432 if (EncodeParameterAnnotations(builder,
ref encoder, method.GetMethod()))
433 attributes.Attribute(AttributeName.RuntimeVisibleParameterAnnotations, blob);
443 void AddRuntimeVisibleTypeAnnotationsAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder attributes)
445 var blob =
new BlobBuilder();
446 var encoder =
new TypeAnnotationTableEncoder(blob);
447 if (ImportTypeAnnotations(builder,
ref encoder, type, type.GetMethodRawTypeAnnotations(method)))
448 attributes.Attribute(AttributeName.RuntimeVisibleTypeAnnotations, blob);
458 void AddRuntimeVisibleAnnotationsAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaMethod method, AttributeTableBuilder attributes)
460 var blob =
new BlobBuilder();
461 var encoder =
new AnnotationTableEncoder(blob);
462 if (EncodeAnnotations(builder,
ref encoder, method.GetMethod()))
463 attributes.Attribute(AttributeName.RuntimeVisibleAnnotations, blob);
474 void AddConstantValueAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaField field, AttributeTableBuilder attributes)
476 if (field.GetField() !=
null && field.GetField().IsLiteral && (field.FieldTypeWrapper.IsPrimitive || field.FieldTypeWrapper == context.JavaBase.TypeOfJavaLangString))
478 var constant = field.GetField().GetRawConstantValue();
479 if (field.GetField().FieldType.IsEnum)
480 constant = EnumHelper.GetPrimitiveValue(context, EnumHelper.GetUnderlyingType(field.GetField().FieldType), constant);
482 if (constant !=
null)
487 attributes.ConstantValue(i);
490 attributes.ConstantValue(s);
493 attributes.ConstantValue(c);
496 attributes.ConstantValue((
int)(sbyte)b);
499 attributes.ConstantValue(z);
502 attributes.ConstantValue(f);
505 attributes.ConstantValue(j);
508 attributes.ConstantValue(d);
511 attributes.ConstantValue(l);
514 throw new Exception();
527 void AddSignatureAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaField field, AttributeTableBuilder attributes)
529 var signature = type.GetGenericFieldSignature(field);
530 if (signature !=
null)
531 attributes.Signature(signature);
541 void AddDeprecatedAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaField field, AttributeTableBuilder attributes)
544 if (field.GetField() !=
null && field.GetField().IsDefined(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).AsReflection(),
false))
545 attributes.Deprecated();
555 void AddRuntimeVisibleTypeAnnotationsAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaField field, AttributeTableBuilder attributes)
557 var blob =
new BlobBuilder();
558 var encoder =
new TypeAnnotationTableEncoder(blob);
559 if (ImportTypeAnnotations(builder,
ref encoder, type, type.GetFieldRawTypeAnnotations(field)))
560 attributes.Attribute(AttributeName.RuntimeVisibleTypeAnnotations, blob);
570 void AddRuntimeVisibleAnnotationsAttribute(ClassFileBuilder builder, RuntimeJavaType type, RuntimeJavaField field, AttributeTableBuilder attributes)
572 var blob =
new BlobBuilder();
573 var encoder =
new AnnotationTableEncoder(blob);
574 if (EncodeAnnotations(builder,
ref encoder, field.GetField()))
575 attributes.Attribute(AttributeName.RuntimeVisibleAnnotations, blob);
584 bool EncodeAnnotations(ClassFileBuilder builder,
ref AnnotationTableEncoder encoder,
MemberInfo source)
588#if !FIRST_PASS && !EXPORTER
591 foreach (var cad
in CustomAttributeData.GetCustomAttributes(source))
593 var ann = GetAnnotation(cad);
596 EncodeAnnotation(builder,
ref encoder, ann);
612 bool EncodeParameterAnnotations(ClassFileBuilder builder,
ref ParameterAnnotationTableEncoder encoder,
MethodBase source)
616#if !FIRST_PASS && !EXPORTER
619 var parameters = source.GetParameters();
620 if (parameters.Length > 0)
622 for (
int i = 0; i < parameters.Length; i++)
624 encoder.ParameterAnnotation(e2 =>
626 foreach (var cad
in CustomAttributeData.GetCustomAttributes(parameters[i]))
628 var ann = GetAnnotation(cad);
631 EncodeAnnotation(builder,
ref e2, ann);
652 bool ImportTypeAnnotations(ClassFileBuilder builder,
ref TypeAnnotationTableEncoder encoder, RuntimeJavaType type,
byte[] typeAnnotations)
654#if !FIRST_PASS && !EXPORTER
655 if (typeAnnotations !=
null)
657 var reader =
new ClassFormatReader(typeAnnotations);
658 if (TypeAnnotationTable.TryRead(
ref reader, out var table) ==
false)
659 throw new Exception();
661 table.CopyTo(
new ConstantView(type.GetConstantPool()), builder.Constants,
ref encoder);
662 return table.Count > 0;
672 class ConstantView : IConstantView
675 readonly
object[] view;
681 public ConstantView(
object[] view)
686 public Constant Get(ConstantHandle handle)
688 return handle.Kind
switch
690 ConstantKind.Utf8 => Get((Utf8ConstantHandle)handle),
691 ConstantKind.Integer => Get((IntegerConstantHandle)handle),
692 ConstantKind.Float => Get((FloatConstantHandle)handle),
693 ConstantKind.Long => Get((LongConstantHandle)handle),
694 ConstantKind.Double => Get((DoubleConstantHandle)handle),
695 ConstantKind.Class => Get((ClassConstantHandle)handle),
696 ConstantKind.String => Get((StringConstantHandle)handle),
697 ConstantKind.Fieldref => Get((FieldrefConstantHandle)handle),
698 ConstantKind.Methodref => Get((MethodrefConstantHandle)handle),
699 ConstantKind.InterfaceMethodref => Get((InterfaceMethodrefConstantHandle)handle),
700 ConstantKind.NameAndType => Get((NameAndTypeConstantHandle)handle),
701 ConstantKind.MethodHandle => Get((MethodHandleConstantHandle)handle),
702 ConstantKind.MethodType => Get((MethodTypeConstantHandle)handle),
703 ConstantKind.Dynamic => Get((DynamicConstantHandle)handle),
704 ConstantKind.InvokeDynamic => Get((InvokeDynamicConstantHandle)handle),
705 ConstantKind.Module => Get((ModuleConstantHandle)handle),
706 ConstantKind.Package => Get((PackageConstantHandle)handle),
707 _ => Get((IntegerConstantHandle)handle),
711 public RefConstant Get(RefConstantHandle handle)
713 throw new NotImplementedException();
716 public Utf8Constant Get(Utf8ConstantHandle handle)
718 if (view[handle.Slot] is not
string s)
719 throw new Exception();
721 return new Utf8Constant(s);
724 public IntegerConstant Get(IntegerConstantHandle handle)
726 if (view[handle.Slot] is not
int i)
727 throw new Exception();
729 return new IntegerConstant(i);
732 public FloatConstant Get(FloatConstantHandle handle)
734 if (view[handle.Slot] is not
float f)
735 throw new Exception();
737 return new FloatConstant(f);
740 public LongConstant Get(LongConstantHandle handle)
742 if (view[handle.Slot] is not
long j)
743 throw new Exception();
745 return new LongConstant(j);
748 public DoubleConstant Get(DoubleConstantHandle handle)
750 if (view[handle.Slot] is not
double d)
751 throw new Exception();
753 return new DoubleConstant(d);
756 public ClassConstant Get(ClassConstantHandle handle)
758 throw new NotImplementedException();
761 public StringConstant Get(StringConstantHandle handle)
763 if (view[handle.Slot] is not
string s)
764 throw new Exception();
766 return new StringConstant(s);
769 public FieldrefConstant Get(FieldrefConstantHandle handle)
771 throw new NotImplementedException();
774 public MethodrefConstant Get(MethodrefConstantHandle handle)
776 throw new NotImplementedException();
779 public InterfaceMethodrefConstant Get(InterfaceMethodrefConstantHandle handle)
781 throw new NotImplementedException();
784 public NameAndTypeConstant Get(NameAndTypeConstantHandle handle)
786 throw new NotImplementedException();
789 public MethodHandleConstant Get(MethodHandleConstantHandle handle)
791 throw new NotImplementedException();
794 public MethodTypeConstant Get(MethodTypeConstantHandle handle)
796 throw new NotImplementedException();
799 public DynamicConstant Get(DynamicConstantHandle handle)
801 throw new NotImplementedException();
804 public InvokeDynamicConstant Get(InvokeDynamicConstantHandle handle)
806 throw new NotImplementedException();
809 public ModuleConstant Get(ModuleConstantHandle handle)
811 throw new NotImplementedException();
814 public PackageConstant Get(PackageConstantHandle handle)
816 throw new NotImplementedException();
821#if !FIRST_PASS && !EXPORTER
828 object[] GetAnnotation(CustomAttributeData cad)
831 if (cad.ConstructorArguments.Count == 1 && cad.ConstructorArguments[0].ArgumentType == typeof(
object[]) && (cad.Constructor.DeclaringType.BaseType == typeof(ikvm.@
internal.AnnotationAttributeBase) || cad.Constructor.DeclaringType == typeof(
DynamicAnnotationAttribute)))
833 return UnpackArray((IList<CustomAttributeTypedArgument>)cad.ConstructorArguments[0].Value);
836 if (cad.Constructor.DeclaringType.BaseType == typeof(ikvm.@
internal.AnnotationAttributeBase))
838 var annotationType = GetAnnotationInterface(cad);
839 if (annotationType !=
null)
842 var list =
new List<object>();
844 list.Add(
"L" + annotationType.Replace(
'.',
'/') +
";");
846 var parameters = cad.Constructor.GetParameters();
847 for (
int i = 0; i < parameters.Length; i++)
849 list.Add(parameters[i].
Name);
850 list.Add(GetAnnotationValue(cad.ConstructorArguments[i]));
853 foreach (var arg
in cad.NamedArguments)
855 list.Add(arg.MemberInfo.Name);
856 list.Add(GetAnnotationValue(arg.TypedValue));
859 return list.ToArray();
866 string GetAnnotationInterface(CustomAttributeData cad)
869 if (attr.Length == 1)
872 if (interfaces.Length == 1)
873 return interfaces[0];
885 object GetAnnotationValue(CustomAttributeTypedArgument arg)
888 if (arg.ArgumentType.IsEnum)
891 var tw = context.ClassLoaderFactory.GetJavaTypeFromType(arg.ArgumentType) ?? context.ClassLoaderFactory.GetJavaTypeFromType(arg.ArgumentType.DeclaringType);
896 if (arg.Value is
Type type)
902 if (arg.ArgumentType.IsArray)
904 var array = (IList<CustomAttributeTypedArgument>)arg.Value;
905 var arr =
new object[array.Count + 1];
907 for (
int i = 0; i < array.Count; i++)
908 arr[i + 1] = GetAnnotationValue(array[i]);
923 void EncodeAnnotation(ClassFileBuilder builder,
ref AnnotationTableEncoder encoder,
object[] annotation)
925 encoder.Annotation(e =>
927 e.Annotation(builder.Constants.GetOrAddUtf8((
string)annotation[1]), e2 =>
929 for (int i = 2; i < annotation.Length; i += 2)
930 e2.Element(builder.Constants.GetOrAddUtf8((string)annotation[i]), e3 => EncodeElementValue(builder, ref e3, annotation[i + 1]));
935 void EncodeElementValue(ClassFileBuilder builder,
ref ElementValueEncoder encoder,
object value)
937 if (value is
object[] v)
941 encoder.Enum(builder.Constants.GetOrAddUtf8(DecodeTypeName((
string)v[1])), builder.Constants.GetOrAddUtf8((
string)v[2]));
949 for (
int i = 1; i < v.Length; i++)
950 e.ElementValue(e2 => EncodeElementValue(builder,
ref e2, v[i]));
958 encoder.Class(builder.Constants.GetOrAddUtf8((
string)v[1]));
964 encoder.Annotation(e =>
966 e.Annotation(builder.Constants.GetOrAddUtf8(DecodeTypeName((
string)v[1])), e2 =>
968 for (
int i = 2; i < v.Length; i++)
969 e2.Element(builder.Constants.GetOrAddUtf8((
string)v[i]), e3 => EncodeElementValue(builder,
ref e3, v[i + 1]));
976 throw new InvalidOperationException();
981 encoder.Boolean(builder.Constants.GetOrAddInteger(z ? 1 : 0));
987 encoder.Byte(builder.Constants.GetOrAddInteger(unchecked((sbyte)b)));
993 encoder.Char(builder.Constants.GetOrAddInteger(c));
997 if (value is
short s)
999 encoder.Short(builder.Constants.GetOrAddInteger(s));
1005 encoder.Integer(builder.Constants.GetOrAddInteger(i));
1009 if (value is
long j)
1011 encoder.Long(builder.Constants.GetOrAddLong(j));
1015 if (value is
float f)
1017 encoder.Float(builder.Constants.GetOrAddFloat(f));
1021 if (value is
double d)
1023 encoder.Double(builder.Constants.GetOrAddDouble(d));
1027 if (value is
string S)
1029 encoder.String(builder.Constants.GetOrAddUtf8(S));
1033 throw new InvalidOperationException();
1036 static string EncodeTypeName(RuntimeJavaType tw)
1038 return tw.SigName.Replace(
'.',
'/');
1041 static string DecodeTypeName(
string typeName)
1043#if !FIRST_PASS && !EXPORTER
1044 int index = typeName.IndexOf(
',');
1051 typeName =
"L" +
java.
lang.Class.forName(typeName.Substring(1, typeName.Length - 2).Replace(
'/',
'.')).getName().Replace(
'.',
'/') +
";";
1065 object[] UnpackArray(IList<CustomAttributeTypedArgument> list)
1067 var arr =
new object[list.Count];
1068 for (
int i = 0; i < arr.Length; i++)
1069 arr[i] = list[i].Value is IList<CustomAttributeTypedArgument> l ? UnpackArray(l) : list[i].Value;
1077 return mb.__GetCustomAttributes(context.Resolver.ResolveCoreType(typeof(ObsoleteAttribute).FullName).AsReflection(),
false).Count;
1079 return mb.GetCustomAttributes(typeof(ObsoleteAttribute),
false).Length;
1083 CustomAttributeData GetAnnotationDefault(
MethodBase mb)
1086 var attr = CustomAttributeData.__GetCustomAttributes(mb, context.Resolver.ResolveRuntimeType(typeof(Attributes.AnnotationDefaultAttribute).FullName).AsReflection(),
false);
1087 return attr.Count == 1 ? attr[0] :
null;
1089 foreach (var cad
in CustomAttributeData.GetCustomAttributes(mb))
1090 if (cad.Constructor.DeclaringType == typeof(Attributes.AnnotationDefaultAttribute))
1097 string GetAssemblyName(RuntimeJavaType tw)
1099 var loader = tw.ClassLoader;
1100 var acl = loader as RuntimeAssemblyClassLoader;
1102 return acl.GetAssembly(tw).FullName;
1104 return ((RuntimeGenericClassLoader)loader).GetName();
1107 bool IsSerializable(RuntimeJavaType tw)
1109 if (tw.Name ==
"java.io.Serializable")
1114 foreach (var iface
in tw.Interfaces)
1115 if (IsSerializable(iface))
1118 tw = tw.BaseTypeWrapper;
1131 bool EncodeAnnotationsForType(ClassFileBuilder builder,
ref AnnotationTableEncoder encoder, RuntimeJavaType tw)
1133 if (tw is RuntimeManagedJavaType.AttributeAnnotationJavaTypeBase attributeAnnotation)
1136 builder.Constants.GetOrAddUtf8(
"Ljava/lang/annotation/Retention;"), e => e
1138 builder.Constants.GetOrAddUtf8(
"value"),
1139 builder.Constants.GetOrAddUtf8(
"Ljava/lang/annotation/RetentionPolicy;"),
1140 builder.Constants.GetOrAddUtf8(
"RUNTIME")));
1142 var validOn = attributeAnnotation.AttributeTargets;
1143 var elementTypes =
new List<string>();
1145 if ((validOn & (AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate | AttributeTargets.Assembly)) != 0)
1146 elementTypes.Add(
"TYPE");
1148 if ((validOn & AttributeTargets.Constructor) != 0)
1149 elementTypes.Add(
"CONSTRUCTOR");
1151 if ((validOn & AttributeTargets.Field) != 0)
1152 elementTypes.Add(
"FIELD");
1154 if ((validOn & (AttributeTargets.Method | AttributeTargets.ReturnValue)) != 0)
1155 elementTypes.Add(
"METHOD");
1157 if ((validOn & AttributeTargets.Parameter) != 0)
1158 elementTypes.Add(
"PARAMETER");
1161 builder.Constants.GetOrAddUtf8(
"Ljava/lang/annotation/Target;"), e => e
1163 builder.Constants.GetOrAddUtf8(
"value"), e2 => e2
1166 foreach (var elementType in elementTypes)
1167 e3.Enum(builder.Constants.GetOrAddUtf8(
"Ljava/lang/annotation/ElementType;"), builder.Constants.GetOrAddUtf8(elementType));
1170 if (IsRepeatableAnnotation(tw))
1173 builder.Constants.GetOrAddUtf8(
"Ljava/lang/annotation/Repeatable;"), e => e
1175 builder.Constants.GetOrAddUtf8(
"value"),
1176 builder.Constants.GetOrAddUtf8(
"L" + (tw.Name + RuntimeManagedJavaType.AttributeAnnotationMultipleSuffix).Replace(
'.',
'/') +
";")));
1185 bool IsRepeatableAnnotation(RuntimeJavaType tw)
1187 foreach (var nested
in tw.InnerClasses)
1188 if (nested.Name == tw.Name + RuntimeManagedJavaType.AttributeAnnotationMultipleSuffix)
1200 void EncodeAnnotationDefault(ClassFileBuilder builder,
ref ElementValueEncoder encoder, CustomAttributeTypedArgument value)
1202 EncodeElementValue(builder,
ref encoder, value);
1212 void EncodeAnnotationDefault(ClassFileBuilder builder,
ref ElementValueEncoder encoder, RuntimeJavaType type)
1214 if (type == context.PrimitiveJavaTypeFactory.BOOLEAN)
1216 encoder.Boolean(builder.Constants.GetOrAddInteger(0));
1218 else if (type == context.PrimitiveJavaTypeFactory.BYTE)
1220 encoder.Byte(builder.Constants.GetOrAddInteger(0));
1222 else if (type == context.PrimitiveJavaTypeFactory.CHAR)
1224 encoder.Char(builder.Constants.GetOrAddInteger(0));
1226 else if (type == context.PrimitiveJavaTypeFactory.SHORT)
1228 encoder.Short(builder.Constants.GetOrAddInteger(0));
1230 else if (type == context.PrimitiveJavaTypeFactory.INT)
1232 encoder.Integer(builder.Constants.GetOrAddInteger(0));
1234 else if (type == context.PrimitiveJavaTypeFactory.FLOAT)
1236 encoder.Float(builder.Constants.GetOrAddFloat(0));
1238 else if (type == context.PrimitiveJavaTypeFactory.LONG)
1240 encoder.Long(builder.Constants.GetOrAddLong(0));
1242 else if (type == context.PrimitiveJavaTypeFactory.DOUBLE)
1244 encoder.Double(builder.Constants.GetOrAddDouble(0));
1246 else if (type == context.JavaBase.TypeOfJavaLangString)
1248 encoder.String(builder.Constants.GetOrAddUtf8(
""));
1250 else if ((type.Modifiers &
Modifiers.Enum) != 0)
1252 encoder.Enum(builder.Constants.GetOrAddUtf8(
"L" + type.Name.Replace(
'.',
'/') +
";"), builder.Constants.GetOrAddUtf8(
"__unspecified"));
1254 else if (type == context.JavaBase.TypeOfJavaLangClass)
1256 encoder.Class(builder.Constants.GetOrAddUtf8(
"Likvm/internal/__unspecified;"));
1258 else if (type.IsArray)
1260 encoder.Array(e => { });
1264 throw new InvalidOperationException();
1274 void EncodeElementValue(ClassFileBuilder builder,
ref ElementValueTableEncoder encoder, CustomAttributeTypedArgument value)
1276 encoder.ElementValue(e => EncodeElementValue(builder,
ref e, value));
1285 void EncodeElementValue(ClassFileBuilder builder,
ref ElementValueEncoder encoder, CustomAttributeTypedArgument value)
1288 if (value.ArgumentType == context.Types.Boolean)
1290 encoder.Boolean(builder.Constants.GetOrAddInteger((
bool)value.Value ? 1 : 0));
1295 if (value.ArgumentType == context.Types.Byte)
1297 encoder.Byte(builder.Constants.GetOrAddInteger(unchecked((sbyte)(
byte)value.Value)));
1302 if (value.ArgumentType == context.Types.Char)
1304 encoder.Char(builder.Constants.GetOrAddInteger((
char)value.Value));
1309 if (value.ArgumentType == context.Types.Int16)
1311 encoder.Short(builder.Constants.GetOrAddInteger((
short)value.Value));
1316 if (value.ArgumentType == context.Types.Int32)
1318 encoder.Integer(builder.Constants.GetOrAddInteger((
int)value.Value));
1323 if (value.ArgumentType == context.Types.Single)
1325 encoder.Float(builder.Constants.GetOrAddFloat((
float)value.Value));
1330 if (value.ArgumentType == context.Types.Int64)
1332 encoder.Long(builder.Constants.GetOrAddLong((
long)value.Value));
1337 if (value.ArgumentType == context.Types.Double)
1339 encoder.Double(builder.Constants.GetOrAddDouble((
double)value.Value));
1344 if (value.ArgumentType == context.Types.String)
1346 encoder.String(builder.Constants.GetOrAddUtf8((
string)value.Value));
1351 if (value.ArgumentType == context.Types.Object.MakeArrayType())
1354 var data = (IReadOnlyList<CustomAttributeTypedArgument>)value.Value;
1355 var type = (byte)data[0].Value;
1362 for (
int i = 1; i < data.Count; i++)
1363 EncodeElementValue(builder,
ref e, data[i]);
1372 encoder.Class(builder.Constants.GetOrAddUtf8((
string)data[1].Value));
1379 encoder.Enum(builder.Constants.GetOrAddUtf8((
string)data[1].Value), builder.Constants.GetOrAddUtf8((
string)data[2].Value));
1386 encoder.Annotation(e =>
1388 e.Annotation(builder.Constants.GetOrAddUtf8((
string)data[1].Value), e2 =>
1390 for (int i = 2; i < data.Count; i += 2)
1391 e2.Element(builder.Constants.GetOrAddUtf8((string)data[i].Value), e3 => EncodeElementValue(builder, ref e3, data[i + 1]));
1398 Warning(
"Warning: incorrect annotation default element tag: " + type);
1402 Warning(
"Warning: incorrect annotation default element type: " + value.ArgumentType);
1413 Console.Error.WriteLine(message);