Example #1
0
        public override object Serialize(IDesignerSerializationManager manager, object value)
        {
            if (manager == null)
            {
                throw new ArgumentNullException("manager");
            }
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            object obj2 = null;

            using (CodeDomSerializerBase.TraceScope("CollectionCodeDomSerializer::Serialize"))
            {
                CodeExpression     expression;
                ExpressionContext  context    = manager.Context[typeof(ExpressionContext)] as ExpressionContext;
                PropertyDescriptor descriptor = manager.Context[typeof(PropertyDescriptor)] as PropertyDescriptor;
                if (((context != null) && (context.PresetValue == value)) && ((descriptor != null) && (descriptor.PropertyType == context.ExpressionType)))
                {
                    expression = context.Expression;
                }
                else
                {
                    expression = null;
                    context    = null;
                    descriptor = null;
                }
                ICollection is2 = value as ICollection;
                if (is2 == null)
                {
                    return(obj2);
                }
                ICollection valuesToSerialize           = is2;
                InheritedPropertyDescriptor descriptor2 = descriptor as InheritedPropertyDescriptor;
                Type c    = (context == null) ? is2.GetType() : context.ExpressionType;
                bool flag = typeof(Array).IsAssignableFrom(c);
                if ((expression == null) && !flag)
                {
                    bool flag2;
                    expression = base.SerializeCreationExpression(manager, is2, out flag2);
                    if (flag2)
                    {
                        return(expression);
                    }
                }
                if ((expression == null) && !flag)
                {
                    return(obj2);
                }
                if ((descriptor2 != null) && !flag)
                {
                    valuesToSerialize = this.GetCollectionDelta(descriptor2.OriginalValue as ICollection, is2);
                }
                obj2 = this.SerializeCollection(manager, expression, c, is2, valuesToSerialize);
                if ((expression == null) || !this.ShouldClearCollection(manager, is2))
                {
                    return(obj2);
                }
                CodeStatementCollection statements = obj2 as CodeStatementCollection;
                if ((is2.Count > 0) && ((obj2 == null) || ((statements != null) && (statements.Count == 0))))
                {
                    return(null);
                }
                if (statements == null)
                {
                    statements = new CodeStatementCollection();
                    CodeStatement statement = obj2 as CodeStatement;
                    if (statement != null)
                    {
                        statements.Add(statement);
                    }
                    obj2 = statements;
                }
                if (statements != null)
                {
                    CodeMethodInvokeExpression expression2 = new CodeMethodInvokeExpression(expression, "Clear", new CodeExpression[0]);
                    CodeExpressionStatement    statement2  = new CodeExpressionStatement(expression2);
                    statements.Insert(0, statement2);
                }
            }
            return(obj2);
        }
        /// <include file='doc\CollectionCodeDomSerializer.uex' path='docs/doc[@for="CollectionCodeDomSerializer.SerializeViaAdd"]/*' />
        /// <devdoc>
        ///     Serializes the given collection by creating multiple calls to an Add method.
        /// </devdoc>
        private object SerializeViaAdd(
            IDesignerSerializationManager manager,
            CodePropertyReferenceExpression propRef,
            ICollection collection,
            MethodInfo addMethod,
            ParameterInfo parameter,
            object targetObject)
        {
            Debug.WriteLineIf(traceSerialization.TraceVerbose, "CollectionCodeDomSerializer::SerializeViaAdd");
            Debug.Indent();

            Debug.WriteLineIf(traceSerialization.TraceVerbose, "Collection: " + collection.GetType().Name);
            Debug.WriteLineIf(traceSerialization.TraceVerbose, "Elements: " + collection.Count.ToString());

            // Here we need to invoke Add once for each and every item in the collection. We can re-use the property
            // reference and method reference, but we will need to recreate the invoke statement each time.
            //
            CodeStatementCollection       statements = new CodeStatementCollection();
            CodeMethodReferenceExpression methodRef  = new CodeMethodReferenceExpression(propRef, addMethod.Name);

            MethodInfo clearMethod = collection.GetType().GetMethod("Clear", new Type[0]);

            if (clearMethod != null)
            {
                PropertyDescriptor clearProp = manager.Properties["ClearCollections"];
                if (clearProp != null)
                {
                    // insert code here to clear the collecion...
                    //
                    statements.Add(new CodeMethodInvokeExpression(propRef, "Clear"));
                }
            }

            bool isTargetInherited = false;
            InheritedPropertyDescriptor inheritedDesc = manager.Context[typeof(PropertyDescriptor)] as InheritedPropertyDescriptor;

            if (inheritedDesc != null)
            {
                isTargetInherited = true;
                collection        = GetCollectionDelta(inheritedDesc.OriginalValue as ICollection, collection);
                if (collection.Count == 0)
                {
                    Debug.Unindent();
                    return(statements);
                }
            }

            foreach (object o in collection)
            {
                // If this object is being privately inherited, it cannot be inside
                // this collection.
                //
                bool genCode = !(o is IComponent);
                if (!genCode)
                {
                    InheritanceAttribute ia = (InheritanceAttribute)TypeDescriptor.GetAttributes(o)[typeof(InheritanceAttribute)];
                    if (ia != null)
                    {
                        if (ia.InheritanceLevel == InheritanceLevel.InheritedReadOnly)
                        {
                            genCode = false;
                        }
                        else if (ia.InheritanceLevel == InheritanceLevel.Inherited && isTargetInherited)
                        {
                            genCode = false;
                        }
                        else
                        {
                            genCode = true;
                        }
                    }
                    else
                    {
                        genCode = true;
                    }
                }

                if (genCode)
                {
                    CodeMethodInvokeExpression statement = new CodeMethodInvokeExpression();
                    statement.Method = methodRef;

                    CodeValueExpression codeValue = new CodeValueExpression(null, o, parameter.ParameterType);
                    manager.Context.Push(codeValue);

                    CodeExpression serializedObj = null;

                    try {
                        serializedObj = SerializeToExpression(manager, o);
                    }
                    finally {
                        manager.Context.Pop();
                    }
                    if (serializedObj != null)
                    {
                        statement.Parameters.Add(serializedObj);
                        statements.Add(statement);
                    }
                }
            }

            Debug.Unindent();
            return(statements);
        }
        /// <include file='doc\CollectionCodeDomSerializer.uex' path='docs/doc[@for="CollectionCodeDomSerializer.SerializeViaAddRange"]/*' />
        /// <devdoc>
        ///     Serializes the given collection by creating an array and passing it to the AddRange method.
        /// </devdoc>
        private object SerializeViaAddRange(
            IDesignerSerializationManager manager,
            CodePropertyReferenceExpression propRef,
            ICollection collection,
            MethodInfo addRangeMethod,
            ParameterInfo parameter,
            object targetObject)
        {
            Debug.WriteLineIf(traceSerialization.TraceVerbose, "CollectionCodeDomSerializer::SerializeViaAddRange");
            Debug.Indent();

            Debug.WriteLineIf(traceSerialization.TraceVerbose, "Collection: " + collection.GetType().Name);
            Debug.WriteLineIf(traceSerialization.TraceVerbose, "Elements: " + collection.Count.ToString());


            CodeStatementCollection statements = new CodeStatementCollection();

            MethodInfo clearMethod = collection.GetType().GetMethod("Clear", new Type[0]);

            if (clearMethod != null)
            {
                PropertyDescriptor clearProp = manager.Properties["ClearCollections"];
                if (clearProp != null && clearProp.PropertyType == typeof(bool) && ((bool)clearProp.GetValue(manager) == true))
                {
                    // insert code here to clear the collecion...
                    //
                    statements.Add(new CodeMethodInvokeExpression(propRef, "Clear"));
                }
            }

            if (collection.Count == 0)
            {
                Debug.Unindent();
                return(statements);
            }

            // We must walk the collection looking for privately inherited objects.  If we find them,
            // we need to exclude them from the array.
            //
            ArrayList arrayList = new ArrayList(collection.Count);

            bool isTargetInherited = false;
            InheritedPropertyDescriptor inheritedDesc = manager.Context[typeof(PropertyDescriptor)] as InheritedPropertyDescriptor;

            if (inheritedDesc != null)
            {
                isTargetInherited = true;
                collection        = GetCollectionDelta(inheritedDesc.OriginalValue as ICollection, collection);
                if (collection.Count == 0)
                {
                    Debug.Unindent();
                    return(statements);
                }
            }

            CodeValueExpression codeValue = new CodeValueExpression(null, collection, parameter.ParameterType.GetElementType());

            manager.Context.Push(codeValue);

            try {
                foreach (object o in collection)
                {
                    // If this object is being privately inherited, it cannot be inside
                    // this collection.
                    //
                    bool genCode = !(o is IComponent);
                    if (!genCode)
                    {
                        InheritanceAttribute ia = (InheritanceAttribute)TypeDescriptor.GetAttributes(o)[typeof(InheritanceAttribute)];
                        if (ia != null)
                        {
                            if (ia.InheritanceLevel == InheritanceLevel.InheritedReadOnly)
                            {
                                genCode = false;
                            }
                            else if (ia.InheritanceLevel == InheritanceLevel.Inherited && isTargetInherited)
                            {
                                genCode = false;
                            }
                            else
                            {
                                genCode = true;
                            }
                        }
                        else
                        {
                            genCode = true;
                        }
                    }

                    if (genCode)
                    {
                        CodeExpression exp = SerializeToExpression(manager, o);
                        if (exp != null)
                        {
                            arrayList.Add(exp);
                        }
                    }
                }
            }
            finally {
                manager.Context.Pop();
            }

            if (arrayList.Count > 0)
            {
                // Now convert the array list into an array create expression.
                //
                CodeTypeReference elementTypeRef = new CodeTypeReference(parameter.ParameterType.GetElementType());

                // Now create an ArrayCreateExpression, and fill its initializers.
                //
                CodeArrayCreateExpression arrayCreate = new CodeArrayCreateExpression();
                arrayCreate.CreateType = elementTypeRef;

                foreach (CodeExpression exp in arrayList)
                {
                    arrayCreate.Initializers.Add(exp);
                }
                CodeMethodReferenceExpression methodRef    = new CodeMethodReferenceExpression(propRef, addRangeMethod.Name);
                CodeMethodInvokeExpression    methodInvoke = new CodeMethodInvokeExpression();
                methodInvoke.Method = methodRef;
                methodInvoke.Parameters.Add(arrayCreate);
                statements.Add(new CodeExpressionStatement(methodInvoke));
            }

            Debug.Unindent();
            return(statements);
        }
        /// <include file='doc\CollectionCodeDomSerializer.uex' path='docs/doc[@for="CollectionCodeDomSerializer.SerializeArray"]/*' />
        /// <devdoc>
        ///     Serializes the given array.
        /// </devdoc>
        private object SerializeArray(IDesignerSerializationManager manager, CodePropertyReferenceExpression propRef, Type asType, Array array, object targetObject)
        {
            object result = null;

            Debug.WriteLineIf(traceSerialization.TraceVerbose, "CollectionCodeDomSerializer::SerializeArray");
            Debug.Indent();

            if (array.Rank != 1)
            {
                Debug.WriteLineIf(traceSerialization.TraceError, "*** Cannot serialize arrays with rank > 1. ***");
                manager.ReportError(SR.GetString(SR.SerializerInvalidArrayRank, array.Rank.ToString()));
            }
            else
            {
                // For an array, we need an array create expression.  First, get the array type
                //
                Type elementType = null;

                if (asType != null)
                {
                    elementType = asType;
                }
                else
                {
                    elementType = array.GetType().GetElementType();
                }

                CodeTypeReference elementTypeRef = new CodeTypeReference(elementType);

                Debug.WriteLineIf(traceSerialization.TraceVerbose, "Array type: " + elementType.Name);
                Debug.WriteLineIf(traceSerialization.TraceVerbose, "Length:" + array.Length.ToString());

                // Now create an ArrayCreateExpression, and fill its initializers.
                //
                CodeArrayCreateExpression arrayCreate = new CodeArrayCreateExpression();
                arrayCreate.CreateType = elementTypeRef;
                bool arrayOk = true;

                ICollection collection = array;

                bool       isTargetInherited = false;
                IComponent comp = targetObject as IComponent;
                if (comp != null)
                {
                    InheritanceAttribute ia = (InheritanceAttribute)TypeDescriptor.GetAttributes(comp)[typeof(InheritanceAttribute)];
                    isTargetInherited = (ia != null && ia.InheritanceLevel == InheritanceLevel.Inherited);
                }

                if (isTargetInherited)
                {
                    InheritedPropertyDescriptor inheritedDesc = manager.Context[typeof(PropertyDescriptor)] as InheritedPropertyDescriptor;
                    if (inheritedDesc != null)
                    {
                        collection = GetCollectionDelta(inheritedDesc.OriginalValue as ICollection, array);
                    }
                }

                CodeValueExpression codeValue = new CodeValueExpression(null, collection, elementType);
                manager.Context.Push(codeValue);

                try {
                    foreach (object o in collection)
                    {
                        // If this object is being privately inherited, it cannot be inside
                        // this collection.  Since we're writing an entire array here, we
                        // cannot write any of it.
                        //
                        if (o is IComponent && TypeDescriptor.GetAttributes(o).Contains(InheritanceAttribute.InheritedReadOnly))
                        {
                            arrayOk = false;
                            break;
                        }

                        object expression = SerializeToExpression(manager, o);
                        if (expression is CodeExpression)
                        {
                            arrayCreate.Initializers.Add((CodeExpression)expression);
                        }
                        else
                        {
                            arrayOk = false;
                            break;
                        }
                    }
                }
                finally {
                    manager.Context.Pop();
                }

                // if we weren't given a property, we're done.  Otherwise, we must create an assign statement for
                // the property.
                //
                if (arrayOk)
                {
                    if (propRef != null)
                    {
                        result = new CodeAssignStatement(propRef, arrayCreate);
                    }
                    else
                    {
                        result = arrayCreate;
                    }
                }
            }

            Debug.Unindent();
            return(result);
        }