static void MarkBaseMethod(this JavaClass cls, JavaMethod method) { JavaClass k = cls; while (true) { k = k.ResolvedExtends != null ? (JavaClass)k.ResolvedExtends.ReferencedType : null; if (k == null) { break; } // first we collect base method candidates by name (which is absolutely required!) var candidates = k.Members.OfType <JavaMethod> ().Where(_ => _.Name == method.Name); // Then we find exact parameter type matches. // No need to check returns. We only care about Java. var candidate = candidates.FirstOrDefault(c => method.IsImplementing(c, cls.GenericInheritanceMapping)); if (candidate != null) { method.BaseMethod = new JavaMethodReference(candidate); for (int i = 0; i < candidate.Parameters.Count; i++) { if (candidate.Parameters [i].ResolvedType.ReferencedTypeParameter != null && method.Parameters [i].ResolvedType.ReferencedTypeParameter == null) { method.Parameters [i].InstantiatedGenericArgumentName = candidate.Parameters [i].ResolvedType.ReferencedTypeParameter.Name; } } break; } } }
internal static bool TryLoadCommonElement(this JavaType type, XmlReader reader) { if (reader.LocalName == "implements") { var implements = new JavaImplements(); implements.Load(reader); type.Implements.Add(implements); } else if (reader.LocalName == "typeParameters") { var tp = new JavaTypeParameters(type); tp.Load(reader); type.TypeParameters = tp; } else if (reader.LocalName == "field") { var field = new JavaField(type); field.Load(reader); type.Members.Add(field); } else if (reader.LocalName == "method") { var method = new JavaMethod(type); method.Load(reader); type.Members.Add(method); } else { return(false); } return(true); }
public static void Resolve(this JavaMethod m) { m.ResolveMethodBase(); if (m.Return == null) { return; } m.ResolvedReturnType = m.GetApi().Parse(m.Return, m.Parent?.TypeParameters, m.TypeParameters); }
public static void Resolve(this JavaMethod m) { if (m.TypeParameters != null) { m.TypeParameters.Resolve(m.GetApi(), m.Parent.TypeParameters); } m.ResolveMethodBase(m.TypeParameters); m.ResolvedReturnType = m.GetApi().Parse(m.Return, m.Parent.TypeParameters, m.TypeParameters); }
static void Save(this JavaMethod method, XmlWriter writer) { Func <JavaMethod, bool> check = _ => _.BaseMethod?.Method?.Parent?.Visibility == "public" && !method.Static && method.Parameters.All(p => p.InstantiatedGenericArgumentName == null); // skip synthetic methods, that's what jar2xml does. // However, jar2xml is based on Java reflection and it generates synthetic methods // that actually needs to be generated in the output XML (they are not marked as // "synthetic" either by asm or java reflection), when: // - the synthetic method is actually from non-public ancestor class // (e.g. FileBackupHelperBase.writeNewStateDescription()) // For such case, it does not skip generation. if (method.ExtendedSynthetic && (method.BaseMethod == null || check(method))) { return; } // Here we skip most of the overriding methods of a virtual method, unless // - the method visibility or final-ity has changed: protected Object#clone() is often // overriden as public. In that case, we need a "new" method. // - the method is covariant. In that case we need another overload. // - they differ in "abstract" or "final" method attribute. // - the derived method is static. // - the base method is in the NON-public class. // - none of the arguments are type parameters. // - finally, it is the synthetic method already checked above. if (method.BaseMethod != null && method.BaseMethod.Method != null && !method.BaseMethod.Method.Abstract && method.BaseMethod.Method.Visibility == method.Visibility && method.BaseMethod.Method.Abstract == method.Abstract && method.BaseMethod.Method.Final == method.Final && !method.ExtendedSynthetic && check(method)) { return; } SaveCommon(method, writer, "method", XmlConvert.ToString(method.Abstract), XmlConvert.ToString(method.Native), method.GetVisibleReturnTypeName(), XmlConvert.ToString(method.Synchronized), null, null, null, null, null, method.TypeParameters, method.Parameters, method.Exceptions, method.ExtendedBridge, method.ExtendedJniReturn, method.ExtendedSynthetic, method.ReturnNotNull); }
public static void Load(this JavaMethod method, XmlReader reader) { method.Abstract = XmlConvert.ToBoolean(XmlUtil.GetRequiredAttribute(reader, "abstract")); method.Native = XmlConvert.ToBoolean(XmlUtil.GetRequiredAttribute(reader, "native")); method.Return = XmlUtil.GetRequiredAttribute(reader, "return"); method.Synchronized = XmlConvert.ToBoolean(XmlUtil.GetRequiredAttribute(reader, "synchronized")); XmlUtil.CheckExtraneousAttributes("method", reader, "deprecated", "final", "name", "static", "visibility", "jni-signature", "jni-return", "synthetic", "bridge", "abstract", "native", "return", "synchronized"); method.LoadMethodBase("method", reader); }
// It should detect implementation method for: // - equivalent implementation // - generic instantiation // - TODO: variance // - TODO?: array indicator fixup ("T..." should match "T[]") public static bool IsImplementing (this JavaMethod derived, JavaMethod basis, IDictionary<JavaTypeReference,JavaTypeReference> genericInstantiation) { if (genericInstantiation == null) throw new ArgumentNullException ("genericInstantiation"); if (basis.Name != derived.Name) return false; if (basis.Parameters.Count != derived.Parameters.Count) return false; if (basis.Parameters.Zip (derived.Parameters, (bp, dp) => dp.IsParameterAssignableTo (bp, derived, basis, genericInstantiation)).All (v => v)) return true; return false; }
static void Load(this JavaType type, GenBase gen) { type.IsReferenceOnly = true; type.Name = gen.JavaSimpleName; type.ExtendedJniSignature = gen.JniName; type.Deprecated = gen.DeprecatedComment; type.Visibility = gen.RawVisibility; type.Implements = gen.Interfaces.Select(_ => new JavaImplements() { Name = _.JavaName, ExtendedJniType = _.JniName, }).ToArray(); if (gen.TypeParameters != null && gen.TypeParameters.Any()) { type.TypeParameters = new JavaTypeParameters(type); type.TypeParameters.Load(gen.TypeParameters); } foreach (var f in gen.Fields.Where(_ => _.IsAcw)) { var fld = new JavaField(type); fld.Load(f); type.Members.Add(fld); } foreach (var p in gen.Properties) { if (p.Getter != null && p.Getter.IsAcw) { var getter = new JavaMethod(type); getter.Load(p.Getter); type.Members.Add(getter); } if (p.Setter != null && p.Setter.IsAcw) { var setter = new JavaMethod(type); setter.Load(p.Setter); type.Members.Add(setter); } } foreach (var m in gen.Methods.Where(_ => _.IsAcw)) { var method = new JavaMethod(type); method.Load(m); type.Members.Add(method); } }
static bool IsParameterAssignableTo (this JavaParameter dp, JavaParameter bp, JavaMethod derived, JavaMethod basis, IDictionary<JavaTypeReference,JavaTypeReference> genericInstantiation) { // If type names are equivalent, they simply match... except that the generic type parameter names match. // Generic type arguments need more check, so do not examine them just by name. // // FIXME: It is likely that this check should NOT result in "this method is not an override", // but rather like "this method is an override, but it should be still generated in the resulting XML". // For example, this results in that java.util.EnumMap#put() is NOT an override of // java.util.AbstractMap#put(), it is an override, not just that it is still generated in the XML. if (bp.ResolvedType.ReferencedTypeParameter != null && dp.ResolvedType.ReferencedTypeParameter != null && bp.ResolvedType.ReferencedTypeParameter.ToString () != dp.ResolvedType.ReferencedTypeParameter.ToString ()) return false; if (bp.Type == dp.Type) return true; if (bp.ResolvedType.ArrayPart != bp.ResolvedType.ArrayPart) return false; // if base is type with generic type parameters and derived is without any generic args, that's OK. // java.lang.Class should match java.lang.Class<T>. if (bp.ResolvedType.ReferencedType != null && dp.ResolvedType.ReferencedType != null && bp.ResolvedType.ReferencedType.FullName == dp.ResolvedType.ReferencedType.FullName && dp.ResolvedType.TypeParameters == null) return true; // generic instantiation check. var baseGTP = bp.ResolvedType.ReferencedTypeParameter; if (baseGTP != null) { if (baseGTP.Parent.ParentMethod != null && baseGTP.IsConformantType (dp.ResolvedType)) return true; var k = genericInstantiation.Keys.FirstOrDefault (tr => bp.ResolvedType.Equals (tr)); if (k == null) // the specified generic type parameter is not part of // the mappings e.g. non-instantiated ones. return false; if (genericInstantiation [k].Equals (dp.ResolvedType)) // the specified generic type parameter exactly matches // whatever specified at the derived method. return true; } // FIXME: implement variance check. return false; }
static void Load(this JavaMethod method, Method gm) { ((JavaMethodBase)method).Load(gm); if (gm.RetVal.RawJavaType == "System.Boolean") { throw new Exception(method.Parent.FullName + "." + gm.JavaName); } method.Final = gm.IsFinal; method.Name = gm.JavaName; method.Static = gm.IsStatic; //method.ExtendedJniSignature = gm.JniSignature; if (gm.GenericArguments != null && gm.GenericArguments.Any()) { method.TypeParameters = new JavaTypeParameters(method); method.TypeParameters.Load(gm.GenericArguments); } method.Abstract = gm.IsAbstract; method.Return = gm.RetVal.RawJavaType; // FIXME: get ExtendedJniReturn? }
public JavaMethodReference(JavaMethod candidate) { this.Method = candidate; }
public JavaTypeParameters(JavaMethod parent) { ParentMethod = parent; TypeParameters = new List <JavaTypeParameter> (); }
public static JavaTypeReference GetVisibleNonSpecialReturnType(this JavaMethod method) { return(GetVisibleNonSpecialType(method, method.ResolvedReturnType)); }
public static string GetVisibleReturnTypeName(this JavaMethod method) { var r = GetVisibleNonSpecialReturnType(method); return(r != null?r.ToString() : method.Return); }