Inheritance: CiSymbol
Example #1
0
 void Write(CiType type)
 {
     Write(" : ");
     if (type is CiStringType)
     {
         Write("String");
     }
     else if (type == CiBoolType.Value)
     {
         Write("Boolean");
     }
     else if (type == CiByteType.Value || type is CiEnum)
     {
         Write("int");
     }
     else if (type is CiArrayType)
     {
         Write(((CiArrayType)type).ElementType == CiByteType.Value ? "ByteArray" : "Array");
     }
     else if (type is CiDelegate)
     {
         Write("Function");
     }
     else
     {
         Write(type.Name);
     }
 }
Example #2
0
        void Write(CiType type)
        {
            StringBuilder sb        = new StringBuilder();
            bool          haveConst = false;

            while (type is CiArrayType)
            {
                sb.Insert(0, "[]");
                if (!haveConst)
                {
                    CiArrayPtrType ptr = type as CiArrayPtrType;
                    if (ptr != null && ptr.Writability != PtrWritability.ReadWrite)
                    {
                        sb.Insert(0, ")");
                        haveConst = true;
                    }
                }
                type = ((CiArrayType)type).ElementType;
            }
            if (haveConst)
            {
                Write("const(");
            }
            WriteBaseType(type.BaseType);
            Write(sb.ToString());
        }
Example #3
0
 protected TypeCode GetTypeCode(CiType type, bool promote)
 {
     if (type is CiNumericType)
     {
         if (type is CiIntegerType integer)
         {
             return(GetIntegerTypeCode(integer, promote));
         }
         if (type == CiSystem.DoubleType)
         {
             return(TypeCode.Double);
         }
         if (type == CiSystem.FloatType || type == CiSystem.FloatIntType)
         {
             return(TypeCode.Single);
         }
         throw new NotImplementedException(type.ToString());
     }
     else if (type == CiSystem.BoolType)
     {
         return(TypeCode.Boolean);
     }
     else if (type == CiSystem.NullType)
     {
         return(TypeCode.Empty);
     }
     else if (type is CiStringType)
     {
         return(TypeCode.String);
     }
     return(TypeCode.Object);
 }
Example #4
0
        protected override void WriteNew(CiType type)
        {
            CiClassStorageType classType = type as CiClassStorageType;

            if (classType != null)
            {
                Write("new ");
                Write(classType.Class.Name);
                Write("()");
            }
            else
            {
                CiArrayStorageType arrayType = (CiArrayStorageType)type;
                if (arrayType.ElementType == CiByteType.Value)
                {
                    Write("new ByteArray()");
                }
                else
                {
                    Write("new Array(");
                    if (arrayType.LengthExpr != null)
                    {
                        Write(arrayType.LengthExpr);
                    }
                    else
                    {
                        Write(arrayType.Length);
                    }
                    Write(')');
                }
            }
        }
Example #5
0
        public override bool IsAssignableFrom(CiType right)
        {
            if (right == CiSystem.NullType)
            {
                return(true);
            }
            CiClass klass = right as CiClass;

            if (klass == null)
            {
                if (!(right is CiClassPtrType ptr))
                {
                    return(false);
                }
                klass = ptr.Class;
            }
            while (klass != Class)
            {
                klass = klass.Parent as CiClass;
                if (klass == null)
                {
                    return(false);
                }
            }
            // TODO: modifiers
            return(true);
        }
Example #6
0
        protected override void Write(CiType type, bool promote)
        {
            switch (type)
            {
            case null:
                Write("void");
                break;

            case CiIntegerType integer:
                Write(GetTypeCode(integer, promote));
                break;

            case CiStringType _:
                Write("string");
                break;

            case CiListType list:
                Write("System.Collections.Generic.List<");
                Write(list.ElementType, false);
                Write('>');
                break;

            case CiArrayType array:
                Write(array.ElementType, false);
                Write("[]");
                break;

            default:
                Write(type.Name);
                break;
            }
        }
Example #7
0
 public CiMethod(CiCallType callType, CiType type, string name, params CiVar[] parameters)
 {
     this.CallType = callType;
     this.Type     = type;
     this.Name     = name;
     this.Parameters.AddRange(parameters);
 }
Example #8
0
        protected override void WriteNewStorage(CiType type)
        {
            switch (type)
            {
            case CiListType list:
                Write("new List");
                WriteElementType(list);
                Write("()");
                break;

            case CiStackType stack:
                Write("new Stack");
                WriteElementType(stack);
                Write("()");
                break;

            case CiHashSetType set:
                Write("new HashSet");
                WriteElementType(set);
                Write("()");
                break;

            case CiDictionaryType dict:
                Write("new ");
                Write(dict);
                Write("()");
                break;

            default:
                base.WriteNewStorage(type);
                break;
            }
        }
Example #9
0
        public override bool IsAssignableFrom(CiType right)
        {
            if (right == CiSystem.NullType)
            {
                return(true);
            }
            if (!(right is CiArrayType array) || !array.ElementType.Equals(this.ElementType))
            {
                return(false);
            }
            switch (this.Modifier)
            {
            case CiToken.EndOfFile:
                return(true);

            case CiToken.ExclamationMark:
                return(!(array is CiArrayPtrType ptr) || ptr.Modifier != CiToken.EndOfFile);

            case CiToken.Hash:
                return(array is CiArrayPtrType dynamicPtr && dynamicPtr.Modifier == CiToken.Hash);

            default:
                throw new NotImplementedException(this.Modifier.ToString());
            }
        }
Example #10
0
        void Write(CiField field)
        {
            Write(field.Documentation);
            Write("this.");
            WriteCamelCase(field.Name);
            CiType type = field.Type;

            if (type == CiBoolType.Value)
            {
                Write(" = false");
            }
            else if (type == CiByteType.Value || type == CiIntType.Value)
            {
                Write(" = 0");
            }
            else if (type is CiEnum)
            {
                Write(" = ");
                WriteConst(((CiEnum)type).Values[0]);
            }
            else if (!WriteInit(type))
            {
                Write(" = null");
            }
            WriteLine(";");
        }
Example #11
0
 protected override string ToString(CiType type)
 {
     if (type == CiBoolType.Value)
     {
         return("cibool");
     }
     return(type.Name);
 }
Example #12
0
 public CiMethod(CiType returnType, string name, params CiParam[] paramz)
 {
     this.Name      = name;
     this.CallType  = CiCallType.Normal;
     this.Signature = new CiDelegate {
         Name = name, ReturnType = returnType, Params = paramz
     };
 }
Example #13
0
 protected void WriteCoercedLiterals(CiType type, CiExpr[] exprs)
 {
     for (int i = 0; i < exprs.Length; i++)
     {
         WriteComma(i);
         WriteCoercedLiteral(type, ((CiLiteral)exprs[i]).Value);
     }
 }
Example #14
0
 protected override void WriteCoercedLiteral(CiType type, CiExpr literal)
 {
     literal.Accept(this, CiPriority.Argument);
     if (type == CiSystem.FloatType)
     {
         Write('f');
     }
 }
Example #15
0
 protected override void WriteStaticCast(CiType type, CiExpr expr)
 {
     Write("static_cast<");
     Write(type, false);
     Write(">(");
     GetStaticCastInner(type, expr).Accept(this, CiPriority.Statement);
     Write(')');
 }
Example #16
0
        public override CiExpr Visit(CiAggregateInitializer expr, CiPriority parent)
        {
            CiType type = ((CiArrayStorageType)expr.Type).ElementType;

            Write("[ ");
            WriteCoercedLiterals(type, expr.Items);
            Write(" ]");
            return(expr);
        }
Example #17
0
 protected override void WriteNewArray(CiType elementType, CiExpr lengthExpr, CiPriority parent)
 {
     Include("memory");
     Write("std::make_shared<");
     Write(elementType, false);
     Write("[]>(");
     lengthExpr.Accept(this, CiPriority.Statement);
     Write(')');
 }
Example #18
0
 protected override void WriteNewArray(CiType elementType, CiExpr lengthExpr, CiPriority parent)
 {
     Write("new ");
     if (elementType is CiNumericType numeric)
     {
         Write(GetArrayElementType(numeric));
     }
     WriteCall("Array", lengthExpr);
 }
Example #19
0
 void Write(CiType type)
 {
     WriteBaseType(type.BaseType);
     for (int i = 0; i < type.ArrayLevel; i++)
     {
         Write("[]");
     }
     Write(' ');
 }
Example #20
0
        public override CiExpr Visit(CiCollection expr, CiPriority parent)
        {
            CiType type = ((CiArrayStorageType)expr.Type).ElementType;

            Write("{ ");
            WriteCoercedLiterals(type, expr.Items);
            Write(" }");
            return(expr);
        }
Example #21
0
 bool WriteInit(CiType type)
 {
     if (type is CiClassStorageType || type is CiArrayStorageType)
     {
         Write(" = ");
         WriteNew(type);
         return(true);
     }
     return(false);
 }
Example #22
0
 protected void WriteCoerced(CiType type, CiExpr expr, CiPriority parent)
 {
     if (expr is CiCondExpr cond)
     {
         WriteCoerced(type, cond, parent);
     }
     else
     {
         WriteCoercedInternal(type, expr, parent);
     }
 }
Example #23
0
 void WriteBaseType(CiType type)
 {
     if (type is CiStringType)
     {
         Write("string");
     }
     else
     {
         Write(type.Name);
     }
 }
Example #24
0
 protected void WriteCoerced(CiType type, CiExpr expr, CiPriority parent)
 {
     if (expr is CiSelectExpr select)
     {
         WriteCoerced(type, select, parent);
     }
     else
     {
         WriteCoercedInternal(type, expr, parent);
     }
 }
Example #25
0
        protected override void WriteNew(CiType type)
        {
            Write("new ");
            WriteBaseType(type.BaseType);
            CiArrayStorageType arrayType = type as CiArrayStorageType;

            if (arrayType != null)
            {
                WriteInitializer(arrayType);
            }
        }
Example #26
0
 protected void WriteNewStorage(CiType type)
 {
     if (type is CiClass klass)
     {
         WriteNew(klass, CiPriority.Statement);
     }
     else if (type is CiArrayStorageType array)
     {
         WriteNewArray(array);
     }
 }
Example #27
0
 void WriteBaseType(CiType type)
 {
     if (type == CiSystem.MatchClass)
     {
         Include("regex");
         Write("std::cmatch");
     }
     else
     {
         Write(type.Name);
     }
 }
Example #28
0
 protected override void WriteNewArray(CiType elementType, CiExpr lengthExpr, CiPriority parent)
 {
     Write("new ");
     Write(elementType.BaseType, false);
     Write('[');
     lengthExpr.Accept(this, CiPriority.Statement);
     Write(']');
     while (elementType is CiArrayType array)
     {
         Write("[]");
         elementType = array.ElementType;
     }
 }
Example #29
0
File: GenTs.cs Project: pfusik/cito
 void WriteListType(CiType elementType)
 {
     if (elementType.IsPointer)
     {
         Write('(');
     }
     Write(elementType, false);
     if (elementType.IsPointer)
     {
         Write(')');
     }
     Write("[]");
 }
Example #30
0
        protected override void Write(CiType type, bool promote)
        {
            switch (type)
            {
            case CiIntegerType integer:
                Write(GetIntegerTypeCode(integer, promote));
                break;

            case CiStringType _:
                Write("string");
                break;

            case CiListType list:
                Write("List");
                WriteElementType(list);
                break;

            case CiStackType stack:
                Write("Stack");
                WriteElementType(stack);
                break;

            case CiHashSetType set:
                Write("HashSet");
                WriteElementType(set);
                break;

            case CiDictionaryType dict:
                Write(dict);
                break;

            case CiArrayType array:
                Write(array.ElementType, false);
                Write("[]");
                break;

            case CiClass klass:
                WriteClassName(klass);
                break;

            case CiClassPtrType classPtr:
                WriteClassName(classPtr.Class);
                break;

            default:
                Write(type.Name);
                break;
            }
        }
Example #31
0
File: CiTree.cs Project: epi/cito
 public override bool Equals(CiType obj)
 {
     CiArrayPtrType that = obj as CiArrayPtrType;
     return that != null && this.ElementType.Equals(that.ElementType);
 }
Example #32
0
File: GenJava.cs Project: epi/cito
 protected override void WriteNew(CiType type)
 {
     CiClassStorageType classType = type as CiClassStorageType;
     if (classType != null) {
     Write("new ");
     Write(classType.Class.Name);
     Write("()");
     }
     else {
     CiArrayStorageType arrayType = (CiArrayStorageType) type;
     Write("new ");
     WriteBaseType(arrayType.BaseType);
     WriteInitializer(arrayType);
     }
 }
Example #33
0
File: GenJava.cs Project: epi/cito
 void WriteBaseType(CiType type)
 {
     if (type is CiStringType)
     Write("String");
     else if (type == CiBoolType.Value)
     Write("boolean");
     else if (type is CiEnum)
     Write("int");
     else
     Write(type.Name);
 }
Example #34
0
 static void CheckCopyPtr(CiType target, CiMaybeAssign source)
 {
     ICiPtrType tp = target as ICiPtrType;
     if (tp == null)
     return;
     CiCondExpr cond = source as CiCondExpr;
     if (cond != null) {
     CheckCopyPtr(target, cond.OnTrue);
     CheckCopyPtr(target, cond.OnFalse);
     return;
     }
     for (;;) {
     while (source is CiCoercion)
         source = ((CiCoercion) source).Inner;
     ICiPtrType sp = source.Type as ICiPtrType;
     if (sp != null) {
         tp.Sources.Add(sp);
         break;
     }
     if (source is CiFieldAccess)
         source = ((CiFieldAccess) source).Obj;
     else if (source is CiArrayAccess)
         source = ((CiArrayAccess) source).Array;
     else
         break;
     }
 }
Example #35
0
File: GenAs.cs Project: epi/cito
 void Write(CiType type)
 {
     Write(" : ");
     if (type is CiStringType)
     Write("String");
     else if (type == CiBoolType.Value)
     Write("Boolean");
     else if (type == CiByteType.Value || type is CiEnum)
     Write("int");
     else if (type is CiArrayType)
     Write(((CiArrayType) type).ElementType == CiByteType.Value ? "ByteArray" : "Array");
     else if (type is CiDelegate)
     Write("Function");
     else
     Write(type.Name);
 }
Example #36
0
File: GenC89.cs Project: epi/cito
 protected override string ToString(CiType type)
 {
     if (type == CiBoolType.Value)
     return "cibool";
     return type.Name;
 }
Example #37
0
 static object GetErrorValue(CiType type)
 {
     if (type == CiType.Void)
     return false;
     if (type == CiIntType.Value)
     return -1;
     if (type == CiStringPtrType.Value || type is CiClassPtrType || type is CiArrayPtrType)
     return null;
     throw new ResolveException("throw in a method of unsupported return type");
 }
Example #38
0
 object ResolveConstInitializer(ref CiType type, object value)
 {
     if (type is CiArrayType) {
     object[] array = value as object[];
     if (array == null)
         return value;
     CiType elementType = ((CiArrayType) type).ElementType;
     if (type is CiArrayStorageType) {
         int expected = ((CiArrayStorageType) type).Length;
         if (array.Length != expected)
             throw new ResolveException("Expected {0} array elements, got {1}", expected, array.Length);
     }
     else {
         type = new CiArrayStorageType { ElementType = elementType, Length = array.Length };
     }
     Array dest = Array.CreateInstance(elementType.DotNetType, array.Length);
     for (int i = 0; i < array.Length; i++)
         dest.SetValue(ResolveConstInitializer(ref elementType, array[i]), i);
     return dest;
     }
     if (value is CiExpr)
     return ResolveConstExpr((CiExpr) value, type);
     return value;
 }
Example #39
0
 object ResolveConstExpr(CiExpr expr, CiType type)
 {
     expr = Coerce(Resolve(expr), type);
     CiConstExpr ce = expr as CiConstExpr;
     if (ce == null)
     throw new ResolveException("{0} is not constant", expr);
     return ce.Value;
 }
Example #40
0
File: CiTree.cs Project: epi/cito
 public CiMethod(CiType returnType, string name, params CiParam[] paramz)
 {
     this.Name = name;
     this.CallType = CiCallType.Normal;
     this.Signature = new CiDelegate { Name = name, ReturnType = returnType, Params = paramz };
 }
Example #41
0
 protected abstract void WriteNew(CiType type);
Example #42
0
File: CiTree.cs Project: epi/cito
 public CiParam(CiType type, string name)
 {
     this.Type = type;
     this.Name = name;
 }
Example #43
0
File: CiTree.cs Project: epi/cito
 public override bool Equals(CiType obj)
 {
     CiStringStorageType that = obj as CiStringStorageType;
     return that != null && this.Length == that.Length;
 }
Example #44
0
File: CiTree.cs Project: epi/cito
 public virtual bool Equals(CiType obj)
 {
     return this == obj;
 }
Example #45
0
 CiMaybeAssign Coerce(CiMaybeAssign expr, CiType expected)
 {
     CiType got = expr.Type;
     if (expected.Equals(got))
     return expr;
     if (expected == CiIntType.Value && got == CiByteType.Value) {
     CiConstExpr konst = expr as CiConstExpr;
     if (konst != null)
         return new CiConstExpr((object) (int) (byte) konst.Value);
     CiCondExpr cond = expr as CiCondExpr;
     if (cond != null && (cond.OnTrue is CiConstExpr || cond.OnFalse is CiConstExpr)) {
         // avoid ((foo ? 1 : 0) & 0xff) in Java
         return Coerce(cond, expected);
     }
     if (expr is CiArrayAccess) {
         CiConstAccess ca = ((CiArrayAccess) expr).Array as CiConstAccess;
         if (ca != null && ca.Const.Is7Bit)
             return expr;
     }
     return new CiCoercion { ResultType = expected, Inner = expr };
     }
     if (expected == CiByteType.Value && got == CiIntType.Value) {
     CiConstExpr konst = expr as CiConstExpr;
     if (konst != null)
         return new CiConstExpr((object) (byte) (int) konst.Value);
     return new CiCoercion { ResultType = expected, Inner = expr };
     }
     if (expected == CiStringPtrType.Value && (got == CiType.Null || got is CiStringType))
     return expr;
     if (expected is CiStringStorageType && got is CiStringType)
     return expr;
     if (expected is CiClassType) {
     if (got == CiType.Null)
         return expr;
     if (Extends(got, ((CiClassType) expected).Class)) {
         if (expr is CiCondExpr) {
             // C doesn't like &(cond ? foo : bar)
             return Coerce((CiCondExpr) expr, expected);
         }
         return new CiCoercion { ResultType = expected, Inner = expr };
     }
     }
     if (expected is CiArrayPtrType) {
     if (got == CiType.Null)
         return expr;
     CiArrayType gotArray = got as CiArrayType;
     if (got != null && ((CiArrayPtrType) expected).ElementType.Equals(gotArray.ElementType))
         return new CiCoercion { ResultType = expected, Inner = expr };
     }
     throw new ResolveException("Expected {0}, got {1}", expected, got);
 }
Example #46
0
 CiType Resolve(CiType type)
 {
     return type.Accept(this);
 }
Example #47
0
 CiCondExpr Coerce(CiCondExpr expr, CiType expected)
 {
     return new CiCondExpr {
     Cond = expr.Cond,
     ResultType = expected,
     OnTrue = Coerce(expr.OnTrue, expected),
     OnFalse = Coerce(expr.OnFalse, expected)
     };
 }
Example #48
0
File: CiParser.cs Project: epi/cito
 CiType ParseArrayType(CiType baseType)
 {
     if (Eat(CiToken.LeftBracket)) {
     if (Eat(CiToken.RightBracket))
         return new CiArrayPtrType { ElementType = ParseArrayType(baseType) };
     CiExpr len = ParseExpr();
     Expect(CiToken.RightBracket);
     return new CiArrayStorageType {
         LengthExpr = len,
         ElementType = ParseArrayType(baseType)
     };
     }
     return baseType;
 }
Example #49
0
 void CheckCreatable(CiType type)
 {
     CiClass storageClass = type.StorageClass;
     if (storageClass != null && storageClass.IsAbstract)
     throw new ResolveException("Cannot create instances of an abstract class {0}", storageClass.Name);
 }
Example #50
0
File: CiParser.cs Project: epi/cito
 object ParseConstInitializer(CiType type)
 {
     if (type is CiArrayType) {
     Expect(CiToken.LeftBrace);
     CiType elementType = ((CiArrayType) type).ElementType;
     List<object> list = new List<object>();
     if (!See(CiToken.RightBrace)) {
         do
             list.Add(ParseConstInitializer(elementType));
         while (Eat(CiToken.Comma));
     }
     Expect(CiToken.RightBrace);
     return list.ToArray();
     }
     return ParseExpr();
 }
Example #51
0
 static bool Extends(CiType type, CiClass baseClass)
 {
     if (!(type is CiClassType))
     return false;
     CiClass klass = ((CiClassType) type).Class;
     while (klass != baseClass) {
     // TODO: resolve, make sure no loops
     klass = klass.BaseClass;
     if (klass == null)
         return false;
     }
     return true;
 }
Example #52
0
File: GenD.cs Project: epi/cito
 protected override void WriteNew(CiType type)
 {
     Write("new ");
     WriteBaseType(type.BaseType);
     CiArrayStorageType arrayType = type as CiArrayStorageType;
     if (arrayType != null)
     WriteInitializer(arrayType);
 }
Example #53
0
File: GenAs.cs Project: epi/cito
 protected override void WriteNew(CiType type)
 {
     CiClassStorageType classType = type as CiClassStorageType;
     if (classType != null) {
     Write("new ");
     Write(classType.Class.Name);
     Write("()");
     }
     else {
     CiArrayStorageType arrayType = (CiArrayStorageType) type;
     if (arrayType.ElementType == CiByteType.Value)
         Write("new ByteArray()");
     else {
         Write("new Array(");
         if (arrayType.LengthExpr != null)
             Write(arrayType.LengthExpr);
         else
             Write(arrayType.Length);
         Write(')');
     }
     }
 }
Example #54
0
File: GenD.cs Project: epi/cito
 void Write(CiType type)
 {
     StringBuilder sb = new StringBuilder();
     bool haveConst = false;
     while (type is CiArrayType) {
     sb.Insert(0, "[]");
     if (!haveConst) {
         CiArrayPtrType ptr = type as CiArrayPtrType;
         if (ptr != null && ptr.Writability != PtrWritability.ReadWrite) {
             sb.Insert(0, ")");
             haveConst = true;
         }
     }
     type = ((CiArrayType) type).ElementType;
     }
     if (haveConst)
     Write("const(");
     WriteBaseType(type.BaseType);
     Write(sb.ToString());
 }
Example #55
0
File: GenC.cs Project: epi/cito
        string ToString(CiType type, string s)
        {
            StringBuilder sb = new StringBuilder(s);
            bool needParens = false;
            while (type is CiArrayType) {
            CiArrayStorageType stg = type as CiArrayStorageType;
            if (stg != null) {
                if (needParens) {
                    sb.Insert(0, '(');
                    sb.Append(')');
                    needParens = false;
                }
                sb.Append('[');
                sb.Append(stg.Length);
                sb.Append(']');
            }
            else {
                InsertPtr(sb, ((CiArrayPtrType) type).Writability);
                needParens = true;
            }
            type = ((CiArrayType) type).ElementType;
            }

            if (type is CiByteType)
            sb.Insert(0, "unsigned char ");
            else if (type is CiStringPtrType)
            sb.Insert(0, "const char *");
            else if (type is CiStringStorageType) {
            if (needParens) {
                sb.Insert(0, '(');
                sb.Append(')');
            }
            sb.Insert(0, "char ");
            sb.Append('[');
            sb.Append(((CiStringStorageType) type).Length + 1);
            sb.Append(']');
            }
            else {
            if (type is CiClassPtrType)
                InsertPtr(sb, ((CiClassPtrType) type).Writability);
            sb.Insert(0, ' ');
            sb.Insert(0, ToString(type));
            }
            return sb.ToString();
        }
Example #56
0
File: GenCs.cs Project: epi/cito
 void WriteBaseType(CiType type)
 {
     if (type is CiStringType)
     Write("string");
     else
     Write(type.Name);
 }
Example #57
0
File: GenJava.cs Project: epi/cito
 void Write(CiType type)
 {
     WriteBaseType(type.BaseType);
     for (int i = 0; i < type.ArrayLevel; i++)
     Write("[]");
     Write(' ');
 }
Example #58
0
 CiExpr Coerce(CiExpr expr, CiType expected)
 {
     return (CiExpr) Coerce((CiMaybeAssign) expr, expected);
 }
Example #59
0
File: GenJava.cs Project: epi/cito
 bool WriteInit(CiType type)
 {
     if (type is CiClassStorageType || type is CiArrayStorageType) {
     Write(" = ");
     WriteNew(type);
     return true;
     }
     return false;
 }
Example #60
0
File: CiTree.cs Project: epi/cito
 public override bool Equals(CiType obj)
 {
     CiClassStorageType that = obj as CiClassStorageType;
     return that != null && this.Class == that.Class;
 }