예제 #1
0
        public Declarations GetDeclarations(DataType dt, CppType type)
        {
            var baseTypes       = new HashSet <DataType>();
            var fieldTypes      = new HashSet <DataType>();
            var hIncludes       = new HashSet <string>();
            var hDeclarations   = new HashSet <string>();
            var hTypes          = new HashSet <DataType>();
            var incIncludes     = new HashSet <string>();
            var incTypes        = new HashSet <DataType>();
            var cppTypes        = new HashSet <DataType>();
            var cppIncludes     = new HashSet <string>();
            var cppDeclarations = new HashSet <string>();

            Resolve(dt, baseTypes, fieldTypes, hTypes, incTypes, cppTypes);

            foreach (var t in type.Dependencies)
            {
                Add(cppTypes, t);
            }
            foreach (var t in type.PrecalcedTypes)
            {
                Add(cppTypes, t);
            }
            foreach (var m in type.MethodTypes)
            {
                foreach (var t in m.Dependencies)
                {
                    Add(cppTypes, t);
                }
                foreach (var t in m.PrecalcedTypes)
                {
                    Add(cppTypes, t);
                }
            }

            if (_backend.HasForwardDeclaration(dt))
            {
                hDeclarations.Add(_backend.GetForwardDeclaration(dt));
            }

            foreach (var e in fieldTypes)
            {
                if (e.IsStruct && !_backend.IsOpaque(e))
                {
                    baseTypes.Add(e.MasterDefinition);
                }
                else
                {
                    hTypes.Add(e.MasterDefinition);
                }
            }

            foreach (var e in baseTypes)
            {
                hIncludes.Add(_backend.GetIncludeFilename(e));
                hTypes.Remove(e.MasterDefinition);
                incTypes.Remove(e.MasterDefinition);
                cppTypes.Add(e.MasterDefinition);
            }

            foreach (var e in hTypes)
            {
                hDeclarations.Add(_backend.GetForwardDeclaration(e));
                cppTypes.Add(e.MasterDefinition);
            }

            foreach (var e in incTypes)
            {
                incIncludes.Add(_backend.GetIncludeFilename(e));
            }
            foreach (var e in cppTypes)
            {
                cppIncludes.Add(_backend.GetIncludeFilename(e));
            }

            if (hIncludes.Count == 0)
            {
                hIncludes.Add("Uno.h");
            }

            foreach (var e in _env.GetSet(dt, "Header.Declaration"))
            {
                hDeclarations.Add(e.Trim());
            }
            foreach (var e in _env.GetSet(dt, "Header.Include"))
            {
                hIncludes.Add(e.Trim());
            }
            foreach (var e in _env.GetSet(dt, "Header.Import"))
            {
                hDeclarations.Add("#import <" + e.Trim() + ">");
            }

            foreach (var e in _env.GetSet(dt, "Source.Declaration"))
            {
                cppDeclarations.Add(e.Trim());
            }
            foreach (var e in _env.GetSet(dt, "Source.Include"))
            {
                cppIncludes.Add(e.Trim());
            }
            foreach (var e in _env.GetSet(dt, "Source.Import"))
            {
                cppDeclarations.Add("#import <" + e.Trim() + ">");
            }

            SourceValue val;

            if (_env.TryGetValue(dt, "ForwardDeclaration", out val))
            {
                hDeclarations.Add(val.String.Trim());
            }
            if (_env.TryGetValue(dt, "Include", out val))
            {
                hIncludes.Add(val.String.Trim());
            }

            foreach (var e in hIncludes)
            {
                cppIncludes.Remove(e);
                incIncludes.Remove(e);
            }
            foreach (var e in incIncludes)
            {
                cppIncludes.Remove(e);
            }

            foreach (var e in hIncludes)
            {
                hDeclarations.Add("#include <" + e + ">");
            }
            foreach (var e in cppIncludes)
            {
                cppDeclarations.Add("#include <" + e + ">");
            }

            hDeclarations.Remove(null);
            cppDeclarations.Remove(null);
            incIncludes.Remove(null);

            var inlineDeclarations = incIncludes.ToArray();

            for (int i = 0; i < inlineDeclarations.Length; i++)
            {
                inlineDeclarations[i] = "#include <" + inlineDeclarations[i] + ">";
            }

            var result = new Declarations
            {
                Header = hDeclarations.ToArray(),
                Source = cppDeclarations.ToArray(),
                Inline = inlineDeclarations,
            };

            Array.Sort(result.Header);
            Array.Sort(result.Source);
            Array.Sort(result.Inline);
            return(result);
        }
예제 #2
0
파일: CppType.cs 프로젝트: mortend/uno
        internal CppType(
            IEnvironment env,
            CppBackend backend,
            DataType dt)
        {
            EmitTypeObject = !env.HasProperty(dt, "TypeOfFunction");
            IsOpaque       = backend.IsOpaque(dt);
            ReflectedName  = dt.IsIntrinsic ? dt.QualifiedName : dt.ToString();
            StructName     = backend.GetStaticName(dt, dt);
            TypeOfFunction = StructName + "_typeof";
            TypeOfType     = StructName + "_type";

            if (dt.IsGenericMethodType)
            {
                TypeOfType = "uClassType";
                return;
            }

            EmitTypeOfDeclaration = true;

            switch (dt.TypeType)
            {
            case TypeType.Class:
            case TypeType.Struct:
            {
                foreach (var m in dt.Methods)
                {
                    AddClassMethod(env, m);
                }
                foreach (var m in dt.Properties)
                {
                    AddClassMethod(env, m.GetMethod);
                    AddClassMethod(env, m.SetMethod);
                }
                foreach (var m in dt.Events)
                {
                    AddClassMethod(env, m.AddMethod);
                    AddClassMethod(env, m.RemoveMethod);
                }

                foreach (var f in Functions)
                {
                    if (f.IsConstructor ||
                        !f.IsStatic && !f.IsVirtualBase ||
                        f.IsVirtual && (
                            backend.IsTemplate(f.DeclaringType) ||
                            f.DeclaringType.Base == null
                            ))
                    {
                        continue;
                    }

                    StaticMethods.Add(f);
                }

                Fields.AddRange(dt.EnumerateFields());

                for (var bt = dt.Base; bt != null; bt = bt.Base)
                {
                    foreach (var f in bt.EnumerateFields())
                    {
                        if (!f.IsStatic)
                        {
                            FlattenedFields.Add(f);
                        }
                    }
                }
                InheritedFieldCount = FlattenedFields.Count;

                foreach (var f in Fields)
                {
                    if (!f.IsStatic)
                    {
                        FlattenedFields.Add(f);
                    }
                }
                // Strategically add static fields last
                foreach (var f in Fields)
                {
                    if (f.IsStatic)
                    {
                        FlattenedFields.Add(f);
                    }
                }

                // Early out unless reflection is enabled
                if (!backend.EnableReflection || (!backend.EnableDebugDumps && !dt.IsPublic))
                {
                    break;
                }

                foreach (var f in dt.EnumerateFunctions())
                {
                    var prototype = f.Prototype;

                    if (!prototype.IsPublic || env.GetBool(f, "IsIntrinsic"))
                    {
                        continue;
                    }
                    switch (prototype.MemberType)
                    {
                    case MemberType.Cast:
                    case MemberType.Operator:
                    case MemberType.Finalizer:
                        continue;

                    case MemberType.Constructor:
                    {
                        if (prototype.IsStatic || f.ReturnType.IsVoid)
                        {
                            continue;
                        }

                        break;
                    }

                    case MemberType.Method:
                    {
                        var method = (Method)prototype;
                        if (method.ImplementedMethod != null ||
                            method.OverriddenMethod != null ||
                            method.IsGenerated && method.DeclaringMember == null)
                        {
                            continue;
                        }

                        break;
                    }
                    }

                    ReflectedFunctions.Add(f);
                }

                foreach (var f in backend.EnableDebugDumps ? dt.EnumerateFields() : dt.Fields)
                {
                    var prototype = f.Prototype;

                    if (!backend.EnableDebugDumps && (!prototype.IsPublic || prototype.IsGenerated))
                    {
                        continue;
                    }

                    ReflectedFields.Add(f);
                }

                break;
            }

            case TypeType.Interface:
            {
                foreach (var m in dt.Methods)
                {
                    AddInterfaceMethod(m);
                }
                foreach (var m in dt.Properties)
                {
                    AddInterfaceMethod(m.GetMethod);
                    AddInterfaceMethod(m.SetMethod);
                }
                foreach (var m in dt.Events)
                {
                    AddInterfaceMethod(m.AddMethod);
                    AddInterfaceMethod(m.RemoveMethod);
                }

                // Early out unless reflection is enabled
                if (!backend.EnableReflection || !dt.IsPublic)
                {
                    break;
                }

                ReflectedFunctions.AddRange(dt.EnumerateFunctions());
                break;
            }
            }

            // Clear fields on structs where TypeName is overridden,
            // to avoid invalid offsetof() in generated code.
            if (dt.IsStruct && env.HasProperty(dt, "TypeName"))
            {
                FlattenedFields.Clear();
                ReflectedFields.Clear();
            }

            EmitTypeStruct = EmitTypeObject && (
                VTable.Any(x => x.OverriddenMethod == null) ||
                dt.Base == null && dt.Interfaces.Length > 0 ||
                dt.Base != null && dt.Interfaces.Length > dt.Base.Interfaces.Length
                );

            if (!EmitTypeStruct)
            {
                TypeOfType = dt.IsValueType
                    ? "uStructType"
                    : backend.GetTypeOfType(dt.Base, dt);
            }

            Functions.Sort();
            ReflectedFields.Sort();
            ReflectedFunctions.Sort();
            InstanceMethods.Sort();
            VTable.Sort();
        }