예제 #1
0
        private void MyStruct_AddWithMethod(CsEnumItem enumItem, bool isFirst)
        {
            if (isFirst)
            {
                var          cw            = new CsCodeWriter();
                const string maskVariable  = "value";
                const string modifiedValue = "current";
                cw.SingleLineIf("add", $"return {modifiedValue} | {maskVariable};",
                                $"return {modifiedValue} & ~{maskVariable};");
                var m = ExtensionsClass
                        .AddMethod(SetOrClearMethod, MyEnumTypeName)
                        .WithBody(cw)
                        .WithStatic();
                m.AddAggressiveInlining(ExtensionsClass);
                m.AddParam(modifiedValue, MyEnumTypeName).UseThis = true;
                m.AddParam(maskVariable, MyEnumTypeName);
                m.AddParam("add", "bool");
            }

            {
                var mask = GetMask(MyEnum, enumItem.EnumName);
                var cw   = CsCodeWriter.Create <SingleTaskEnumsGenerator>();
                cw.WriteLine($"{flagsPropertyName} = {flagsPropertyName}.{SetOrClearMethod}({mask}, value);");
                cw.WriteLine("return this;");
                var m = MyStruct.AddMethod("With" + enumItem.EnumName, OptionsClassName)
                        .WithBody(cw);
                m.AddParam("value", "bool").ConstValue = "true";
                m.Description = enumItem.Description;
            }
        }
예제 #2
0
 public void Append(CsEnumItem enumItem)
 {
     enumItem.EncodedValue = Value.ToInv();
     _target.Items.Add(enumItem);
     _target.UnderlyingType = GetUnderlyingType();
     Value *= 2;
 }
예제 #3
0
        /// <summary>
        /// Maps a C++ Enum to a C# enum.
        /// </summary>
        /// <param name="newEnum">the C# enum.</param>
        private void Process(CsEnum newEnum)
        {
            var cppEnum = (CppEnum)newEnum.CppElement;

            // Get tag from C++ enum
            var tag = cppEnum.GetTagOrDefault <MappingRule>();

            // Determine enum type. Default is int
            string typeName = cppEnum.GetTypeNameWithMapping();

            switch (typeName)
            {
            case "byte":
                newEnum.Type   = typeof(byte);
                newEnum.SizeOf = 1;
                break;

            case "short":
                newEnum.Type   = typeof(short);
                newEnum.SizeOf = 1;
                break;

            case "int":
                newEnum.Type   = typeof(int);
                newEnum.SizeOf = 4;
                break;

            default:
                Logger.Error("Invalid type [{0}] for enum [{1}]. Types supported are : int, byte, short", typeName, cppEnum);
                break;
            }

            // Find Root Name of this enum
            // All enum items should start with the same root name and the root name should be at least 4 chars
            string rootName        = cppEnum.Name;
            string rootNameFound   = null;
            bool   isRootNameFound = false;

            for (int i = rootName.Length; i >= 4 && !isRootNameFound; i--)
            {
                rootNameFound = rootName.Substring(0, i);

                isRootNameFound = true;
                foreach (var cppEnumItem in cppEnum.EnumItems)
                {
                    if (!cppEnumItem.Name.StartsWith(rootNameFound))
                    {
                        isRootNameFound = false;
                        break;
                    }
                }
            }
            if (isRootNameFound)
            {
                rootName = rootNameFound;
            }

            // Create enum items for enum
            foreach (var cppEnumItem in cppEnum.EnumItems)
            {
                string enumName  = NamingRules.Rename(cppEnumItem, rootName);
                string enumValue = cppEnumItem.Value;

                var csharpEnumItem = new CsEnumItem(enumName, enumValue)
                {
                    CppElement = cppEnumItem
                };

                newEnum.Add(csharpEnumItem);

                if (cppEnumItem.Name != "None")
                {
                    Manager.BindType(cppEnumItem.Name, csharpEnumItem);
                }
            }

            bool tryToAddNone = tag.EnumHasNone.HasValue ? tag.EnumHasNone.Value : false;

            // If C++ enum name is ending with FLAG OR FLAGS
            // Then tag this enum as flags and add None if necessary
            if (cppEnum.Name.EndsWith("FLAG") || cppEnum.Name.EndsWith("FLAGS"))
            {
                newEnum.IsFlag = true;

                if (!tag.EnumHasNone.HasValue)
                {
                    tryToAddNone = !newEnum.Items.Cast <CsEnumItem>().Any(item => item.Name == "None");
                }
            }

            // Add None value
            if (tryToAddNone)
            {
                var csharpEnumItem = new CsEnumItem("None", "0");
                csharpEnumItem.CppElement = new CppElement {
                    Description = "None."
                };
                newEnum.Add(csharpEnumItem);
            }
        }
예제 #4
0
        private static string GetEnumCondition(string variableName, CsEnum csEnum, CsEnumItem enumItem)
        {
            var mask = GetMask(csEnum, enumItem);

            return($"({variableName} & {mask}) != 0");
        }
예제 #5
0
        private bool CreateEnumAndConversionMethods()
        {
            var parts = _item.OwnerClasses;
            var conflictsCodeMethod = Extensions_CheckConflictsCode(_item);

            var optionsToStringCode = new CsCodeWriter();

            optionsToStringCode.WriteLine("// generator : " + GetType().Name);
            if (!string.IsNullOrEmpty(conflictsCodeMethod))
            {
                optionsToStringCode.WriteLine($"{conflictsCodeMethod}({valueVariable});");
            }
            var fb = new EnumFlagsBuilder(MyEnum);

            fb.AddFlagsAttribute(MyNamespace);

            var enumSource = from q in _item.Options.Values
                             where string.IsNullOrEmpty(q.Parameter?.Value)
                             select q;
            var generate = false;

            foreach (var option in enumSource)
            {
                generate = true;
                var enumItem = new CsEnumItem(option.GetCsName())
                {
                    Description = option.FullDescription,
                };
                var stringValue = GetStringValue(preferLongNameVariable, option, ExtensionsClass);
                optionsToStringCode.WriteDescriptionComment(option);
                var condition = GetEnumCondition(valueVariable, MyEnum, enumItem);
                optionsToStringCode.SingleLineIf(condition, $"yield return {stringValue};");
                MyStruct_AddWithMethod(enumItem, fb.Value == 1);

                fb.Append(enumItem);

                {
                    apps.Add((w, r) =>
                    {
                        var stringValue = GetStringValue(preferLongNameVariable, option, ExtensionsClass);
                        w.WriteDescriptionComment(option);
                        var condition = GetEnumCondition(flagsPropertyName, MyEnum, enumItem);
                        w.SingleLineIf(condition, $"yield return {stringValue};");
                    });
                }
            }

            if (!generate)
            {
                return(false);
            }
            {
                var m = ExtensionsClass
                        .AddMethod("OptionsToString", MyNamespace.GetTypeName <IEnumerable <string> >())
                        .WithStatic()
                        .WithBody(optionsToStringCode);
                m.AddParam(valueVariable, MyEnumTypeName).UseThis = true;
                m.AddParam <OptionPreference>(preferLongNameVariable, ExtensionsClass).ConstValue =
                    ExtensionsClass.GetEnumValueCode(OptionPreference.Short);
            }

            AddEnumToOutput(parts, MyNamespace, MyEnum);
            return(true);
        }
예제 #6
0
        /// <summary>
        /// Maps a C++ Enum to a C# enum.
        /// </summary>
        /// <param name="newEnum">the C# enum.</param>
        public override void Process(CsEnum newEnum)
        {
            var cppEnum = (CppEnum)newEnum.CppElement;

            // Determine enum type. Default is int
            var typeName = cppEnum.GetTypeNameWithMapping();

            switch (typeName)
            {
            case "byte":
                newEnum.UnderlyingType = typeRegistry.ImportType(typeof(byte));
                break;

            case "short":
                newEnum.UnderlyingType = typeRegistry.ImportType(typeof(short));
                break;

            case "ushort":
                newEnum.UnderlyingType = typeRegistry.ImportType(typeof(ushort));
                break;

            case "int":
                newEnum.UnderlyingType = typeRegistry.ImportType(typeof(int));
                break;

            case "uint":
                newEnum.UnderlyingType = typeRegistry.ImportType(typeof(uint));
                break;

            default:
                Logger.Error(LoggingCodes.InvalidUnderlyingType, "Invalid type [{0}] for enum [{1}]. Types supported are : int, byte, short", typeName, cppEnum);
                break;
            }

            // Find Root Name of this enum
            // All enum items should start with the same root name and the root name should be at least 4 chars
            string rootName        = cppEnum.Name;
            string rootNameFound   = null;
            bool   isRootNameFound = false;

            for (int i = rootName.Length; i >= 4 && !isRootNameFound; i--)
            {
                rootNameFound = rootName.Substring(0, i);

                isRootNameFound = true;
                foreach (var cppEnumItem in cppEnum.EnumItems)
                {
                    if (!cppEnumItem.Name.StartsWith(rootNameFound))
                    {
                        isRootNameFound = false;
                        break;
                    }
                }
            }
            if (isRootNameFound)
            {
                rootName = rootNameFound;
            }

            // Create enum items for enum
            foreach (var cppEnumItem in cppEnum.EnumItems)
            {
                string enumName  = NamingRules.Rename(cppEnumItem, rootName);
                string enumValue = cppEnumItem.Value;

                var csharpEnumItem = new CsEnumItem(enumName, enumValue)
                {
                    CppElement = cppEnumItem
                };

                newEnum.Add(csharpEnumItem);
            }

            var rule = cppEnum.GetMappingRule();

            bool tryToAddNone = rule.EnumHasNone ?? false;

            // If C++ enum name is ending with FLAG OR FLAGS
            // Then tag this enum as flags and add None if necessary
            if (cppEnum.Name.EndsWith("FLAG") || cppEnum.Name.EndsWith("FLAGS"))
            {
                newEnum.IsFlag = true;

                if (!rule.EnumHasNone.HasValue)
                {
                    tryToAddNone = !newEnum.EnumItems.Any(item => item.Name == "None");
                }
            }

            // Add None value
            if (tryToAddNone)
            {
                var csharpEnumItem = new CsEnumItem("None", "0")
                {
                    CppElementName = "None",
                    Description    = "None"
                };
                newEnum.Add(csharpEnumItem);
            }
        }