Пример #1
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            var asIntValue = false;
            var isEnum     = Type != null && Type.TypeKind == TypeKind.Enum;

            if (isEnum)
            {
                object value = null;
                switch (this.Value.Discriminator)
                {
                case ConstantValueTypeDiscriminator.Null:
                    break;

                case ConstantValueTypeDiscriminator.SByte:
                    value = this.Value.SByteValue;
                    break;

                case ConstantValueTypeDiscriminator.Byte:
                    value = this.Value.ByteValue;
                    break;

                case ConstantValueTypeDiscriminator.Int16:
                    value = this.Value.Int16Value;
                    break;

                case ConstantValueTypeDiscriminator.UInt16:
                    value = this.Value.UInt16Value;
                    break;

                case ConstantValueTypeDiscriminator.Char:
                    value = this.Value.CharValue;
                    break;

                case ConstantValueTypeDiscriminator.Int32:
                    value = this.Value.Int32Value;
                    break;

                case ConstantValueTypeDiscriminator.UInt32:
                    value = this.Value.UInt32Value;
                    break;

                case ConstantValueTypeDiscriminator.Int64:
                    value = this.Value.Int64Value;
                    break;

                case ConstantValueTypeDiscriminator.UInt64:
                    value = this.Value.UInt64Value;
                    break;

                case ConstantValueTypeDiscriminator.Single:
                    value = this.Value.SingleValue;
                    break;

                case ConstantValueTypeDiscriminator.Double:
                    value = this.Value.DoubleValue;
                    break;

                case ConstantValueTypeDiscriminator.String:
                    value = this.Value.StringValue;
                    break;

                case ConstantValueTypeDiscriminator.Boolean:
                    value = this.Value.BooleanValue;
                    break;

                default:
                    throw new NotSupportedException();
                }

                var field = Type.GetMembers().OfType <IFieldSymbol>().FirstOrDefault(f => f.HasConstantValue && f.ConstantValue.Equals(value));
                if (field != null)
                {
                    c.WriteNamespace(Type.ContainingNamespace, containingNamespace: MethodOwner?.ContainingNamespace);
                    c.WriteFieldAccessAsStaticField(field, enumAsConst: true);
                    return;
                }
                else
                {
                    // treat it as flags (fallback scenario)
                    asIntValue = true;
                }
            }

            if (asIntValue)
            {
                c.TextSpan("(");
                c.WriteType(Type, containingNamespace: MethodOwner?.ContainingNamespace);
                c.TextSpan(")");
            }

            var discriminator = this.Value.Discriminator;

            switch (discriminator)
            {
            case ConstantValueTypeDiscriminator.Null:
                c.TextSpan("nullptr");
                break;

            case ConstantValueTypeDiscriminator.SByte:
                if (sbyte.MaxValue == this.Value.SByteValue)
                {
                    c.TextSpan("std::numeric_limits<int8_t>::max()");
                }
                else if (sbyte.MinValue == this.Value.SByteValue)
                {
                    c.TextSpan("std::numeric_limits<int8_t>::min()");
                }
                else
                {
                    c.TextSpan("(int8_t)");
                    c.TextSpan(this.Value.SByteValue.ToString());
                }

                break;

            case ConstantValueTypeDiscriminator.Byte:
                if (byte.MaxValue == this.Value.ByteValue)
                {
                    c.TextSpan("std::numeric_limits<uint8_t>::max()");
                }
                else if (byte.MinValue == this.Value.ByteValue)
                {
                    c.TextSpan("std::numeric_limits<uint8_t>::min()");
                }
                else
                {
                    c.TextSpan("(uint8_t)");
                    c.TextSpan(this.Value.ByteValue.ToString());
                }

                break;

            case ConstantValueTypeDiscriminator.Int16:
                if (short.MaxValue == this.Value.Int16Value)
                {
                    c.TextSpan("std::numeric_limits<int16_t>::max()");
                }
                else if (short.MinValue == this.Value.Int16Value)
                {
                    c.TextSpan("std::numeric_limits<int16_t>::min()");
                }
                else
                {
                    c.TextSpan("(int16_t)");
                    c.TextSpan(this.Value.Int16Value.ToString());
                }

                break;

            case ConstantValueTypeDiscriminator.UInt16:
                if (ushort.MaxValue == this.Value.UInt16Value)
                {
                    c.TextSpan("std::numeric_limits<uint16_t>::max()");
                }
                else if (ushort.MinValue == this.Value.UInt16Value)
                {
                    c.TextSpan("std::numeric_limits<uint16_t>::min()");
                }
                else
                {
                    c.TextSpan("(uint16_t)");
                    c.TextSpan(this.Value.UInt16Value.ToString());
                }
                break;

            case ConstantValueTypeDiscriminator.Char:
                c.TextSpan(string.Format("u'{0}'", UnicodeChar(this.Value.CharValue)));
                break;

            case ConstantValueTypeDiscriminator.Int32:
                if (int.MaxValue == this.Value.Int32Value)
                {
                    c.TextSpan("std::numeric_limits<int32_t>::max()");
                }
                else if (int.MinValue == this.Value.Int32Value)
                {
                    c.TextSpan("std::numeric_limits<int32_t>::min()");
                }
                else
                {
                    c.TextSpan(this.Value.Int32Value.ToString());
                }

                break;

            case ConstantValueTypeDiscriminator.UInt32:
                if (uint.MaxValue == this.Value.UInt32Value)
                {
                    c.TextSpan("std::numeric_limits<uint32_t>::max()");
                }
                else if (uint.MinValue == this.Value.UInt32Value)
                {
                    c.TextSpan("std::numeric_limits<uint32_t>::min()");
                }
                else
                {
                    c.TextSpan(this.Value.UInt32Value.ToString());
                    c.TextSpan("U");
                }

                break;

            case ConstantValueTypeDiscriminator.Int64:
                if (long.MaxValue == this.Value.Int64Value)
                {
                    c.TextSpan("std::numeric_limits<int64_t>::max()");
                }
                else if (long.MinValue == this.Value.Int64Value)
                {
                    c.TextSpan("std::numeric_limits<int64_t>::min()");
                }
                else
                {
                    c.TextSpan("(int64_t)");
                    c.TextSpan(this.Value.Int64Value.ToString());
                    c.TextSpan("LL");
                }

                break;

            case ConstantValueTypeDiscriminator.UInt64:

                if (ulong.MaxValue == this.Value.UInt64Value)
                {
                    c.TextSpan("std::numeric_limits<uint64_t>::max()");
                }
                else if (ulong.MinValue == this.Value.UInt64Value)
                {
                    c.TextSpan("std::numeric_limits<uint64_t>::min()");
                }
                else
                {
                    c.TextSpan("(uint64_t)");
                    c.TextSpan(this.Value.UInt64Value.ToString());
                    c.TextSpan("ULL");
                }

                break;

            case ConstantValueTypeDiscriminator.Single:
                if (float.IsPositiveInfinity(this.Value.SingleValue))
                {
                    c.TextSpan("std::numeric_limits<float>::infinity()");
                }
                else if (float.IsNegativeInfinity(this.Value.SingleValue))
                {
                    c.TextSpan("-std::numeric_limits<float>::infinity()");
                }
                else if (float.IsNaN(this.Value.SingleValue))
                {
                    c.TextSpan("std::numeric_limits<float>::quiet_NaN()");
                }
                else if (float.MaxValue == this.Value.SingleValue)
                {
                    c.TextSpan("std::numeric_limits<float>::max()");
                }
                else if (float.MinValue == this.Value.SingleValue)
                {
                    c.TextSpan("std::numeric_limits<float>::min()");
                }
                else
                {
                    var line = this.Value.SingleValue.ToString();
                    c.TextSpan(line.IndexOf('.') != -1 || line.IndexOf('E') != -1 ? line : string.Concat(line, ".0"));
                    c.TextSpan("f");
                }

                break;

            case ConstantValueTypeDiscriminator.Double:
                if (double.IsPositiveInfinity(this.Value.DoubleValue))
                {
                    c.TextSpan("std::numeric_limits<double>::infinity()");
                }
                else if (double.IsNegativeInfinity(this.Value.DoubleValue))
                {
                    c.TextSpan("-std::numeric_limits<double>::infinity()");
                }
                else if (double.IsNaN(this.Value.DoubleValue))
                {
                    c.TextSpan("std::numeric_limits<double>::quiet_NaN()");
                }
                else if (double.MaxValue == this.Value.DoubleValue)
                {
                    c.TextSpan("std::numeric_limits<double>::max()");
                }
                else if (double.MinValue == this.Value.DoubleValue)
                {
                    c.TextSpan("std::numeric_limits<double>::min()");
                }
                else
                {
                    var line = this.Value.DoubleValue.ToString();
                    c.TextSpan(line.IndexOf('.') != -1 || line.IndexOf('E') != -1 ? line : string.Concat(line, ".0"));
                }

                break;

            case ConstantValueTypeDiscriminator.String:
                c.TextSpan(string.Format("u\"{0}\"", UnicodeString(this.Value.StringValue)));
                if (!CppConstString)
                {
                    c.TextSpan("_s");
                }

                break;

            case ConstantValueTypeDiscriminator.Boolean:
                c.TextSpan(this.Value.BooleanValue.ToString().ToLowerInvariant());
                break;

            default:
                throw new NotSupportedException();
            }
        }