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);
 }
示例#3
0
 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);
 }
示例#4
0
 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?
        }
示例#11
0
 public JavaMethodReference(JavaMethod candidate)
 {
     this.Method = candidate;
 }
示例#12
0
 public JavaTypeParameters(JavaMethod parent)
 {
     ParentMethod   = parent;
     TypeParameters = new List <JavaTypeParameter> ();
 }
示例#13
0
 public static JavaTypeReference GetVisibleNonSpecialReturnType(this JavaMethod method)
 {
     return(GetVisibleNonSpecialType(method, method.ResolvedReturnType));
 }
示例#14
0
        public static string GetVisibleReturnTypeName(this JavaMethod method)
        {
            var r = GetVisibleNonSpecialReturnType(method);

            return(r != null?r.ToString() : method.Return);
        }