예제 #1
0
        // A bit clumsy but better than full-blown reflection use or an open set of Create* methods for each
        // type we support now or in the future
        protected virtual T CreateHierarchyElement <T> (HierarchyBase parent) where T : HierarchyElement
        {
            Type          type = typeof(T);
            HierarchyBase ret  = null;

            if (type == typeof(HierarchyNamespace))
            {
                ret = new HierarchyNamespace(Context, parent as Hierarchy);
            }
            else if (type == typeof(HierarchyClass))
            {
                ret = new HierarchyClass(Context, parent as HierarchyNamespace);
            }
            else if (type == typeof(HierarchyImplements))
            {
                ret = new HierarchyImplements(Context, parent as HierarchyObject);
            }
            else if (type == typeof(HierarchyMethod))
            {
                ret = new HierarchyMethod(Context, parent as HierarchyObject);
            }
            else if (type == typeof(HierarchyConstructor))
            {
                ret = new HierarchyConstructor(Context, parent as HierarchyObject);
            }
            else if (type == typeof(HierarchyException))
            {
                ret = new HierarchyException(Context, parent as HierarchyMethod);
            }
            else if (type == typeof(HierarchyTypeParameter))
            {
                ret = new HierarchyTypeParameter(Context, parent as HierarchyElement);
            }
            else if (type == typeof(HierarchyTypeParameterGenericConstraint))
            {
                ret = new HierarchyTypeParameterGenericConstraint(Context, parent as HierarchyTypeParameter);
            }
            else if (type == typeof(HierarchyMethodParameter))
            {
                ret = new HierarchyMethodParameter(Context, parent as HierarchyMethod);
            }
            else if (type == typeof(HierarchyField))
            {
                ret = new HierarchyField(Context, parent as HierarchyObject);
            }
            else if (type == typeof(HierarchyInterface))
            {
                ret = new HierarchyInterface(Context, parent as HierarchyNamespace);
            }
            else if (type == typeof(HierarchyEnum))
            {
                ret = new HierarchyEnum(Context, parent as Hierarchy);
            }
            else
            {
                throw new InvalidOperationException($"Unsupported hierarchy element type {type}");
            }

            return(ret as T);
        }
예제 #2
0
 public HierarchyInterfaceInvoker(GeneratorContext context, HierarchyElement parent, HierarchyInterface invokedInterface) : base(context, parent)
 {
     InvokedInterface = invokedInterface ?? throw new ArgumentNullException(nameof(invokedInterface));
     Visibility       = ApiVisibility.Internal;
 }
예제 #3
0
 protected abstract InterfaceCodeGenerator GetInterfaceGenerator(HierarchyInterface iface);
예제 #4
0
 public abstract void AddMember(HierarchyInterface iface);
예제 #5
0
        public void Build(IList <ApiElement> rawElements)
        {
            if (rawElements == null || rawElements.Count == 0)
            {
                throw new ArgumentException("must be a non-empty collection", nameof(rawElements));
            }

            // Pass 1: build basic hierarchy (no class or interface nesting yet)
            Helpers.ForEachNotNull(rawElements, (ApiElement e) => {
                switch (e)
                {
                case ApiNameSpace ns:
                    Process(ns);
                    break;

                case ApiEnum enm:
                    Process(enm);
                    break;

                default:
                    Logger.Warning($"Unsupported top-level element type: {e.GetType ().FullName}");
                    break;
                }
            });

            HierarchyNamespace androidRuntime = namespaces?.Where(ns => String.Compare(DefaultInterfaceBaseTypeNamespace, ns?.FullName, StringComparison.OrdinalIgnoreCase) == 0).FirstOrDefault();

            if (androidRuntime == null)
            {
                Logger.Verbose("Creating Android.Runtime namespace (not found after parsing API description)");
                androidRuntime = CreateHierarchyElementInternal <HierarchyNamespace> (this);
                androidRuntime.Init();
                androidRuntime.IgnoreForCodeGeneration = true;
                androidRuntime.FullName        = DefaultInterfaceBaseTypeNamespace;
                androidRuntime.Name            = Helpers.GetBaseTypeName(androidRuntime.FullName);
                androidRuntime.ManagedName     = androidRuntime.Name;
                androidRuntime.FullManagedName = androidRuntime.FullName;
                Helpers.AddToList(androidRuntime, ref namespaces);
            }

            // IJavaObject is defined in Xamarin.Android's non-generated source and implmented by all
            // interfaces that don't derive from other interfaces
            HierarchyInterface iJavaLangObject = androidRuntime.Members?.OfType <HierarchyInterface> ().Where(iface => String.Compare(DefaultInterfaceBaseType, iface?.FullName, StringComparison.OrdinalIgnoreCase) == 0).FirstOrDefault();

            if (iJavaLangObject == null)
            {
                Logger.Verbose("Synthesizing Android.Runtime.IJavaObject interface (not found after parsing API description)");
                iJavaLangObject = CreateHierarchyElementInternal <HierarchyInterface> (androidRuntime);
                iJavaLangObject.Init();
                iJavaLangObject.FullName = DefaultInterfaceBaseType;
                iJavaLangObject.Name     = Helpers.GetBaseTypeName(iJavaLangObject.FullName);
                iJavaLangObject.IgnoreForCodeGeneration = true;
                iJavaLangObject.InvokerNotNeeded        = true;
                iJavaLangObject.UseGlobal = true;
                TypeIndex.Add(iJavaLangObject);
            }

            // Pass 2: nest classes, interfaces
            NestNamespaces();

            // Pass 3: generate managed names
            Helpers.ForEachNotNull(namespaces, (HierarchyNamespace ns) => GenerateManagedNames(ns));

            // TODO: fix generation of full managed names for enums
            Helpers.ForEachNotNull(enums, (HierarchyEnum enm) => GenerateManagedNames(enm));

            // Pass 4: nest enums (they need managed names)
            NestEnums();

            // Pass 5: generate and inject synthetic elements
            SynthesizeElements();

            // Pass 6: resolve base types since we have everything in place now
            ResolveBaseTypes();

            // Pass 7: sort class members
        }