diff --git a/src/net/JNetReflector/InternalConst.cs b/src/net/JNetReflector/InternalConst.cs index 51a70acf67..25f75fdd61 100644 --- a/src/net/JNetReflector/InternalConst.cs +++ b/src/net/JNetReflector/InternalConst.cs @@ -106,6 +106,8 @@ public static string VersionPlaceHolder() public const string JavaLangListener = "Listener"; public const string JavaLangAdapter = "Adapter"; public const string ArrayTypeTrailer = "[]"; + public const string ArrayTypeMethodTrailer = "Array"; + public const string StreamTypeMethodTrailer = "Stream"; public const string PropertySuffix = "Property"; public const string ClassSuffix = "Class"; public const string FieldSuffix = "Field"; diff --git a/src/net/JNetReflector/InternalExtensions.cs b/src/net/JNetReflector/InternalExtensions.cs index cf223edb02..13161361a2 100644 --- a/src/net/JNetReflector/InternalExtensions.cs +++ b/src/net/JNetReflector/InternalExtensions.cs @@ -808,7 +808,7 @@ static string GetBound(this Java.Lang.Reflect.Type bound, bool usedInGenerics, b } else { - result = ToNetType(bound.TypeName, false, camel); + result = ToNetType(bound.TypeName, false, camel, JNetReflectorCore.UseDotNetNullable, JNetReflectorCore.UseDirectDotNetType); } return result; } @@ -841,7 +841,7 @@ static string GetGenerics(this Java.Lang.Reflect.Type entry, IList genAr } else { - retVal = ToNetType(entry.TypeName, false, camel); + retVal = ToNetType(entry.TypeName, false, camel, JNetReflectorCore.UseDotNetNullable, JNetReflectorCore.UseDirectDotNetType); } } return retVal; @@ -2021,12 +2021,45 @@ static bool IsJVMNativeType(string typeName) } } + public static bool IsJVMNativeRawOrBoxedType(this string typeName) + { + if (typeName == null) throw new ArgumentNullException(nameof(typeName)); + switch (typeName) + { + case "boolean": + case "byte": + case "char": + case "short": + case "int": + case "long": + case "float": + case "double": + case "java.lang.Boolean": + case "java.lang.Byte": + case "java.lang.Character": + case "java.lang.Short": + case "java.lang.Integer": + case "java.lang.Long": + case "java.lang.Float": + case "java.lang.Double": + return true; + default: return false; + } + } + + public static string JVMNativeRawOrBoxedToNetType(this string typeName) + { + if (typeName == null) throw new ArgumentNullException(nameof(typeName)); + var cName = ToNetType(typeName, false, false, false, true); + return cName; + } + public static string ToNetType(this Java.Lang.Reflect.Type type, bool camel) { if (type == null) throw new ArgumentNullException(nameof(type)); var cName = type.TypeName; cName = cName.Contains(SpecialNames.BeginGenericDeclaration) ? cName.Substring(0, cName.IndexOf(SpecialNames.BeginGenericDeclaration)) : cName; - cName = ToNetType(cName, false, camel); + cName = ToNetType(cName, false, camel, JNetReflectorCore.UseDotNetNullable, JNetReflectorCore.UseDirectDotNetType); return cName; } @@ -2035,15 +2068,15 @@ public static string ToNetType(this Class type, bool camel) if (type == null) throw new ArgumentNullException(nameof(type)); var cName = type.TypeName; cName = cName.Contains(SpecialNames.BeginGenericDeclaration) ? cName.Substring(0, cName.IndexOf(SpecialNames.BeginGenericDeclaration)) : cName; - cName = ToNetType(cName, false, camel); + cName = ToNetType(cName, false, camel, JNetReflectorCore.UseDotNetNullable, JNetReflectorCore.UseDirectDotNetType); return cName; } - static string ToNetType(string typeName, bool isFromArray, bool camel) + static string ToNetType(string typeName, bool isFromArray, bool camel, bool useNullable, bool useDirectDotNetType) { - if (typeName.EndsWith(SpecialNames.ArrayTypeTrailer)) return ToNetType(typeName.Remove(typeName.LastIndexOf(SpecialNames.ArrayTypeTrailer)), true, camel) + SpecialNames.ArrayTypeTrailer; + if (typeName.EndsWith(SpecialNames.ArrayTypeTrailer)) return ToNetType(typeName.Remove(typeName.LastIndexOf(SpecialNames.ArrayTypeTrailer)), true, camel, useNullable, useDirectDotNetType) + SpecialNames.ArrayTypeTrailer; - if (JNetReflectorCore.UseDotNetNullable) + if (useNullable) { switch (typeName) { @@ -2053,47 +2086,47 @@ static string ToNetType(string typeName, bool isFromArray, bool camel) case "boolean": return "bool"; case "java.lang.Boolean": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return isFromArray ? "bool" : "bool?"; case "byte": return "byte"; case "java.lang.Byte": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return isFromArray ? "byte" : "byte?"; case "char": return "char"; case "java.lang.Character": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return isFromArray ? "char" : "char?"; case "short": return "short"; case "java.lang.Short": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return isFromArray ? "short" : "short?"; case "int": return "int"; case "java.lang.Integer": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return isFromArray ? "int" : "int?"; case "long": return "long"; case "java.lang.Long": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return isFromArray ? "long" : "long?"; case "float": return "float"; case "java.lang.Float": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return isFromArray ? "float" : "float?"; case "double": return "double"; case "java.lang.Double": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return isFromArray ? "double" : "double?"; case "java.lang.Object": return "object"; case "java.lang.String": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return "string"; default: break; } @@ -2110,42 +2143,42 @@ static string ToNetType(string typeName, bool isFromArray, bool camel) case "boolean": return "bool"; case "java.lang.Boolean": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return "bool"; case "byte": return "byte"; case "java.lang.Byte": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return "byte"; case "char": return "char"; case "java.lang.Character": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return "char"; case "short": return "short"; case "java.lang.Short": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return "short"; case "int": return "int"; case "java.lang.Integer": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return "int"; case "long": return "long"; case "java.lang.Long": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return "long"; case "float": return "float"; case "java.lang.Float": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return "float"; case "double": return "double"; case "java.lang.Double": - if (!JNetReflectorCore.UseDirectDotNetType) break; + if (!useDirectDotNetType) break; return "double"; case "java.lang.Object": return "object"; diff --git a/src/net/JNetReflector/InternalMethods.cs b/src/net/JNetReflector/InternalMethods.cs index 00fca5710b..b38a4fa7c4 100644 --- a/src/net/JNetReflector/InternalMethods.cs +++ b/src/net/JNetReflector/InternalMethods.cs @@ -1430,6 +1430,7 @@ static string AnalyzeMethods(this Class classDefinition, IEnumerable clas string methodName = prop.Key; string modifier = string.Empty; + string streamReturnType = string.Empty; string returnType = string.Empty; Method getMethod = null; Method setMethod = null; @@ -1478,16 +1479,26 @@ static string AnalyzeMethods(this Class classDefinition, IEnumerable clas bool isGetDeprecated = false; bool isSetDeprecated = false; + StringBuilder streamExecutionStub = new StringBuilder(); StringBuilder executionStub = new StringBuilder(); if (getMethod != null) { string getSignature = getMethod.SignatureFromGenericString(); + string streamExecStub = string.Empty; string execStub = getMethod.IsStatic() ? AllPackageClasses.ClassStub.MethodStub.STATIC_EXECUTE : AllPackageClasses.ClassStub.MethodStub.INSTANCE_EXECUTE; if (!string.IsNullOrWhiteSpace(getSignature)) { execStub += AllPackageClasses.ClassStub.MethodStub.SIGNATURE_EXECUTE_TRAILER; } - if (isArrayReturnType) execStub += "Array"; + if (isArrayReturnType) + { + if (returnType.IsJVMNativeRawOrBoxedType()) + { + streamReturnType = returnType.JVMNativeRawOrBoxedToNetType(); + streamExecStub = execStub + SpecialNames.StreamTypeMethodTrailer; + } + execStub += SpecialNames.ArrayTypeMethodTrailer; + } if (JNetReflectorCore.ReflectDeprecated) isGetDeprecated = getMethod.IsDeprecated(); if (getMethod.IsReturnTypeAnException()) { @@ -1501,6 +1512,14 @@ static string AnalyzeMethods(this Class classDefinition, IEnumerable clas getMethod.IsVoid() || getMethod.IsObjectReturnType(isGeneric, JNetReflectorCore.UseCamel) ? string.Empty : $"<{returnType}>", getMethod.Name, string.IsNullOrWhiteSpace(getSignature) ? string.Empty : $", \"{getSignature}\""); + + if (!string.IsNullOrWhiteSpace(streamReturnType)) + { + streamExecutionStub.AppendFormat(execFormat, streamExecStub, + $">", + getMethod.Name, + string.IsNullOrWhiteSpace(getSignature) ? string.Empty : $", \"{getSignature}\""); + } } } @@ -1532,7 +1551,35 @@ static string AnalyzeMethods(this Class classDefinition, IEnumerable clas jPropDecoration.Append(AllPackageClasses.ClassStub.MethodStub.OBSOLETE_DECORATION); } - string singleProperty; + string singleProperty = string.Empty; + if (!string.IsNullOrWhiteSpace(streamReturnType)) + { + if (forInterface) + { + var execInterface = AllPackageClasses.ClassStub.PropertyStub.GET_INTERFACE_FORMAT; + + var template = Template.GetTemplate(Template.SingleInterfacePropertyTemplate); + singleProperty = template.Replace(AllPackageClasses.ClassStub.PropertyStub.DECORATION, jPropDecoration.ToString()) + .Replace(AllPackageClasses.ClassStub.PropertyStub.TYPE, $"MASES.JCOBridge.C2JBridge.JCOBridgeStream<{streamReturnType}>") + .Replace(AllPackageClasses.ClassStub.PropertyStub.NAME, methodName + SpecialNames.StreamTypeMethodTrailer) + .Replace(AllPackageClasses.ClassStub.PropertyStub.EXECUTION, execInterface) + .Replace(AllPackageClasses.ClassStub.PropertyStub.GET_HELP, getMethod != null ? getMethod.JavadocHrefUrl(JNetReflectorCore.UseCamel) : string.Empty) + .Replace(AllPackageClasses.ClassStub.PropertyStub.SET_HELP, string.Empty); + } + else + { + var template = Template.GetTemplate(Template.SinglePropertyTemplate); + singleProperty = template.Replace(AllPackageClasses.ClassStub.PropertyStub.DECORATION, jPropDecoration.ToString()) + .Replace(AllPackageClasses.ClassStub.PropertyStub.MODIFIER, modifier) + .Replace(AllPackageClasses.ClassStub.PropertyStub.TYPE, $"MASES.JCOBridge.C2JBridge.JCOBridgeStream<{streamReturnType}>") + .Replace(AllPackageClasses.ClassStub.PropertyStub.NAME, methodName + SpecialNames.StreamTypeMethodTrailer) + .Replace(AllPackageClasses.ClassStub.PropertyStub.EXECUTION, streamExecutionStub.ToString()) + .Replace(AllPackageClasses.ClassStub.PropertyStub.GET_HELP, getMethod != null ? getMethod.JavadocHrefUrl(JNetReflectorCore.UseCamel) : string.Empty) + .Replace(AllPackageClasses.ClassStub.PropertyStub.SET_HELP, string.Empty); + } + } + if (!string.IsNullOrWhiteSpace(singleProperty)) subClassBlock.AppendLine(singleProperty); + if (forInterface) { var execInterface = (getMethod != null ? AllPackageClasses.ClassStub.PropertyStub.GET_INTERFACE_FORMAT : string.Empty) + (setMethod != null ? AllPackageClasses.ClassStub.PropertyStub.SET_INTERFACE_FORMAT : string.Empty); @@ -1807,6 +1854,8 @@ static string AnalyzeMethods(this Class classDefinition, IEnumerable clas bool isArrayReturnType = false; + string streamReturnType = string.Empty; + string streamExecStub = string.Empty; string execStub = method.IsStatic() ? AllPackageClasses.ClassStub.MethodStub.STATIC_EXECUTE : AllPackageClasses.ClassStub.MethodStub.INSTANCE_EXECUTE; if (!string.IsNullOrWhiteSpace(signature)) { @@ -1815,7 +1864,12 @@ static string AnalyzeMethods(this Class classDefinition, IEnumerable clas if (returnType.EndsWith(SpecialNames.ArrayTypeTrailer)) { returnType = returnType.Substring(0, returnType.IndexOf(SpecialNames.ArrayTypeTrailer)); - execStub += "Array"; + if (returnType.IsJVMNativeRawOrBoxedType()) + { + streamReturnType = returnType.JVMNativeRawOrBoxedToNetType(); + streamExecStub = execStub + SpecialNames.StreamTypeMethodTrailer; + } + execStub += SpecialNames.ArrayTypeMethodTrailer; isArrayReturnType = true; } @@ -2519,6 +2573,8 @@ static string AnalyzeFields(this Class classDefinition, IEnumerable class ReportTrace(ReflectionTraceLevel.Debug, "Preparing field {0}", field.GenericString); bool isFinal = false; // disable usage to be compliant with HPA pooling field.IsFinal(); + string getStreamType; + string getStreamFunction; string getFunction; string getFormat; string setFormat; @@ -2539,7 +2595,12 @@ static string AnalyzeFields(this Class classDefinition, IEnumerable class if (fieldType.EndsWith(SpecialNames.ArrayTypeTrailer)) { fieldType = fieldType.Substring(0, fieldType.IndexOf(SpecialNames.ArrayTypeTrailer)); - getFunction += "Array"; + if (fieldType.IsJVMNativeRawOrBoxedType()) + { + getStreamType = fieldType.JVMNativeRawOrBoxedToNetType(); + getStreamFunction = getFunction + SpecialNames.StreamTypeMethodTrailer; + } + getFunction += SpecialNames.ArrayTypeMethodTrailer; isArrayReturnType = true; }