Exemple #1
0
 public bool ContainsMethod(Method method, bool check_ifaces, bool check_base_ifaces)
 {
     // background: bug #10123.
     // Visibility check was introduced - and required so far - to block "public overrides protected" methods
     // (which is allowed in Java but not in C#).
     // The problem is, it does not *always* result in error and generates callable code, and we depend on
     // that fact in several classes that implements some interface that requires "public Object clone()".
     //
     // This visibility inconsistency results in 1) error for abstract methods and 2) warning for virtual methods.
     // Hence, for abstract methods we dare to ignore visibility difference and treat it as override,
     // *then* C# compiler will report this inconsistency as error that users need to fix manually, but
     // with obvious message saying "it is because of visibility consistency",
     // not "abstract member not implemented" (it is *implemented* in different visibility and brings confusion).
     // For virtual methods, just check the visibility difference and treat as different method.
     // Regardless of whether it is actually an override or not, we just invoke Java method.
     if (jni_sig_hash.ContainsKey(method.JavaName + method.JniSignature))
     {
         var bm = jni_sig_hash [method.JavaName + method.JniSignature];
         if (bm.Visibility == method.Visibility || bm.IsAbstract)
         {
             return(true);
         }
     }
     if (check_ifaces)
     {
         foreach (ISymbol isym in Interfaces)
         {
             if ((isym is GenericSymbol ? (isym as GenericSymbol).Gen : isym) is InterfaceGen igen && igen.ContainsMethod(method, true))
             {
                 return(true);
             }
         }
     }
     return(BaseSymbol != null && BaseSymbol.ContainsMethod(method, check_base_ifaces, check_base_ifaces));
 }
Exemple #2
0
        protected virtual bool OnValidate(CodeGenerationOptions opt, GenericParameterDefinitionList type_params)
        {
            if (Name.Length > TypeNamePrefix.Length &&
                (Name [TypeNamePrefix.Length] == '.' || Char.IsDigit(Name [TypeNamePrefix.Length])))              // see bug #5111
            {
                return(false);
            }

            if (!support.ValidateNamespace())
            {
                return(false);
            }

            List <GenBase> valid_nests = new List <GenBase> ();

            foreach (GenBase gen in nested_types)
            {
                if (gen.Validate(opt, TypeParameters))
                {
                    valid_nests.Add(gen);
                }
            }
            nested_types = valid_nests;

            AdjustNestedTypeFullName(this);

            foreach (string iface_name in iface_names)
            {
                ISymbol isym = SymbolTable.Lookup(iface_name);
                if (isym != null && isym.Validate(opt, TypeParameters))
                {
                    ifaces.Add(isym);
                }
                else
                {
                    if (isym == null)
                    {
                        Report.Warning(0, Report.WarningGenBase + 0, "For type {0}, base interface {1} does not exist.", FullName, iface_name);
                    }
                    else
                    {
                        Report.Warning(0, Report.WarningGenBase + 0, "For type {0}, base interface {1} is invalid.", FullName, iface_name);
                    }
                    iface_validation_failed = true;
                }
            }

            List <Field> valid_fields = new List <Field> ();

            foreach (Field f in fields)
            {
                if (!f.Validate(opt, TypeParameters))
                {
                    continue;
                }
                valid_fields.Add(f);
            }
            fields = valid_fields;

            int method_cnt = methods.Count;

            methods = methods.Where(m => ValidateMethod(opt, m)).ToList();
            method_validation_failed = method_cnt != methods.Count;
            foreach (Method m in methods)
            {
                if (m.IsVirtual)
                {
                    has_virtual_methods = true;
                }
                if (m.Name == "HashCode" && m.Parameters.Count == 0)
                {
                    m.IsOverride = true;
                    m.Name       = "GetHashCode";
                }
                jni_sig_hash [m.JavaName + m.JniSignature] = m;
                if ((m.Name == "ToString" && m.Parameters.Count == 0) || (BaseSymbol != null && BaseSymbol.ContainsMethod(m, true)))
                {
                    m.IsOverride = true;
                }
            }
            return(true);
        }
Exemple #3
0
        public void Generate(StreamWriter sw, string indent, CodeGenerationOptions opt, GenBase type, bool generate_callbacks)
        {
            if (!IsValid)
            {
                return;
            }

            bool gen_as_formatted = IsReturnCharSequence;

            if (generate_callbacks && IsVirtual)
            {
                GenerateCallback(sw, indent, opt, type, null, gen_as_formatted);
            }

            string name_and_jnisig     = JavaName + JniSignature.Replace("java/lang/CharSequence", "java/lang/String");
            bool   gen_string_overload = !IsOverride && Parameters.HasCharSequence && !type.ContainsMethod(name_and_jnisig);

            string static_arg = IsStatic ? " static" : String.Empty;
            string virt_ov    = IsOverride ? " override" : IsVirtual ? " virtual" : String.Empty;
            string seal       = IsOverride && IsFinal ? " sealed" : null;
            string ret        = opt.GetOutputName(RetVal.FullName);

            GenerateIdField(sw, indent, opt);
            sw.WriteLine("{0}// Metadata.xml XPath method reference: path=\"{1}\"", indent, GetMetadataXPathReference(this.DeclaringType));
            if (Deprecated != null)
            {
                sw.WriteLine("{0}[Obsolete (@\"{1}\")]", indent, Deprecated.Replace("\"", "\"\""));
            }
            if (IsReturnEnumified)
            {
                sw.WriteLine("{0}[return:global::Android.Runtime.GeneratedEnum]", indent);
            }
            sw.WriteLine("{0}[Register (\"{1}\", \"{2}\", \"{3}\"{4})]",
                         indent, JavaName, JniSignature, IsVirtual ? ConnectorName : String.Empty, this.AdditionalAttributeString());
            GenerateCustomAttributes(sw, indent);
            sw.WriteLine("{0}{1}{2}{3}{4} unsafe {5} {6} ({7})", indent, Visibility, static_arg, virt_ov, seal, ret, AdjustedName, GenBase.GetSignature(this, opt));
            sw.WriteLine("{0}{{", indent);
            GenerateBody(sw, indent + "\t", opt);
            sw.WriteLine("{0}}}", indent);
            sw.WriteLine();

            if (gen_string_overload || gen_as_formatted)
            {
                GenerateStringOverload(sw, indent, opt);
            }

            GenerateAsyncWrapper(sw, indent, opt);
        }