Beispiel #1
0
 protected internal XamlValueConverter <TConverterBase> GetValueConverter <TConverterBase> (Type converterType, XamlType targetType)
     where TConverterBase : class
 {
     return(new XamlValueConverter <TConverterBase> (converterType, targetType));
 }
Beispiel #2
0
        protected internal XamlValueConverter <TConverterBase> GetValueConverter <TConverterBase>(Type converterType, XamlType targetType)
            where TConverterBase : class
        {
#if !HAS_TYPE_CONVERTER
            if (typeof(TConverterBase) == typeof(TypeConverter))
            {
                return(new XamlTypeValueConverter(converterType, targetType) as XamlValueConverter <TConverterBase>);
            }
#endif
            return(new XamlValueConverter <TConverterBase>(converterType, targetType));
        }
Beispiel #3
0
        // member element, implicit member, children via content property, or value
        IEnumerable <XamlXmlNodeInfo> ReadMemberElement(XamlType parentType, XamlType xt)
        {
            XamlMember xm       = null;
            var        name     = r.LocalName;
            int        idx      = name.IndexOf('.');
            string     typeName = null;

            if (idx >= 0)
            {
                typeName = name.Substring(0, idx);
                name     = name.Substring(idx + 1);
                // check if it is an attachable member first, either of this type or another type
                // Should this also check the namespace to find the correct type?
                if (typeName == xt.InternalXmlName)
                {
                    xm = xt.GetMember(name);
                }
                else
                {
                    xm = FindAttachableMember(r.Prefix, typeName, name);
                }
            }
            else
            {
                xm = (XamlMember)FindStandardDirective(name, AllowedMemberLocations.MemberElement);
                if (xm == null)
                {
                    // still not? could it be omitted as content property or items ?
                    if ((xm = GetExtraMember(xt)) != null)
                    {
                        // Note that this does not involve r.Read()
                        foreach (var ni in ReadMember(xt, xm))
                        {
                            yield return(ni);
                        }
                        yield break;
                    }
                }
            }
            if (xm == null)
            {
                // Current element could be for another member in the parent type (if exists)
                if (parentType != null &&
                    typeName != null &&
                    typeName == parentType.InternalXmlName &&
                    parentType.GetMember(name) != null)
                {
                    // stop the iteration and signal the caller to not read current element as an object. (It resolves conflicts between "start object for current collection's item" and "start member for the next member in the parent object".
                    yield return(Node(XamlNodeType.None, null));

                    yield break;
                }

                if (idx >= 0)
                {
                    // Unknown property.
                    xm = new XamlMember(name, xt, false);                     // FIXME: not sure if isAttachable is always false.
                }
                else
                {
                    // Unknown content member.
                    xm = XamlLanguage.UnknownContent;
                    foreach (var ni in ReadMember(xt, xm))
                    {
                        yield return(ni);
                    }
                    yield break;
                }
            }

            if (!r.IsEmptyElement)
            {
                r.Read();
                foreach (var ni in ReadMember(xt, xm))
                {
                    yield return(ni);
                }
                r.MoveToContent();
                r.ReadEndElement();
            }
            else
            {
                r.Read();
            }
        }
Beispiel #4
0
 protected XamlDuplicateMemberException(SerializationInfo info, StreamingContext context)
     : base(info, context)
 {
     DuplicateMember = (XamlMember)info.GetValue("member", typeof(XamlMember));
     ParentType      = (XamlType)info.GetValue("type", typeof(XamlType));
 }
Beispiel #5
0
        private static XamlType GetXamlType(Type type)
        {
            XamlType result = s_schemaContext.Value.GetXamlType(type);

            return(result);
        }
 public virtual void WriteStartObject(XamlMarkupExtensionWriter writer, XamlType type)
 {
     writer.failed = true;
 }
Beispiel #7
0
        IEnumerable <XamlNodeInfo> GetNodes(XamlMember xm, XamlObject xobj, XamlType overrideMemberType = null, bool partOfPositionalParameters = false, XamlNodeInfo node = null)
        {
            //If the item is invisible for the serialization then we must just skip it and return empty nodes info
            if (!xobj.Type.ShouldSerialize(xobj.Value))
            {
                yield break;
            }

            object val;

            // Value - only for non-top-level node (thus xm != null)
            if (xm != null)
            {
                // collection items: each item is exposed as a standalone object that has StartObject, EndObject and contents.
                if (ReferenceEquals(xm, XamlLanguage.Items))
                {
                    foreach (var xn in GetItemsNodes(xm, xobj))
                    {
                        yield return(xn);
                    }
                    yield break;
                }

                // Arguments: each argument is written as a standalone object
                if (ReferenceEquals(xm, XamlLanguage.Arguments))
                {
                    var xarg = new XamlObject();
                    foreach (var argm in xobj.Type.GetSortedConstructorArguments())
                    {
                        var argv = argm.Invoker.GetValue(xobj.Value);
                        xarg.Set(argm.Type, argv);
                        foreach (var cn in GetNodes(null, xarg))
                        {
                            yield return(cn);
                        }
                    }
                    yield break;
                }

                // PositionalParameters: items are from constructor arguments, written as Value node sequentially. Note that not all of them are in simple string value. Also, null values are not written as NullExtension
                if (ReferenceEquals(xm, XamlLanguage.PositionalParameters))
                {
                    var xarg = new XamlObject();
                    foreach (var argm in xobj.Type.GetSortedConstructorArguments())
                    {
                        foreach (var cn in GetNodes(argm, xarg.Set(argm.Type, xobj.GetMemberValue(argm)), null, true))
                        {
                            yield return(cn);
                        }
                    }
                    yield break;
                }
                node = node ?? new XamlNodeInfo();

                if (ReferenceEquals(xm, XamlLanguage.Initialization))
                {
                    yield return(node.Set(TypeExtensionMethods.GetStringValue(xobj.Type, xm, xobj.Value, value_serializer_ctx)));

                    yield break;
                }

                val = xobj.Value;
                if (xm.DeferringLoader != null)
                {
                    foreach (var xn in GetDeferredNodes(xm, val))
                    {
                        yield return(xn);
                    }
                    yield break;
                }

                // don't serialize default values if one is explicitly specified using the DefaultValueAttribute
                if (!partOfPositionalParameters)
                {
                    if (xm.Invoker.IsDefaultValue(val))
                    {
                        yield break;
                    }
                    if (settings.IgnoreDefaultValues && xm.DefaultValue == null)
                    {
                        if (xm.Type?.UnderlyingType?.GetTypeInfo().IsValueType == true)
                        {
                            if (Equals(val, Activator.CreateInstance(xm.Type.UnderlyingType)))
                            {
                                yield break;
                            }
                        }
                        else if (ReferenceEquals(val, null))
                        {
                            yield break;
                        }
                    }
                }

                // overrideMemberType is (so far) used for XamlLanguage.Key.
                var xtt = overrideMemberType ?? xm.Type;
                if (!xtt.IsMarkupExtension &&                 // this condition is to not serialize MarkupExtension whose type has TypeConverterAttribute (e.g. StaticExtension) as a string.
                    (xtt.IsContentValue(value_serializer_ctx) || xm.IsContentValue(value_serializer_ctx)))
                {
                    // though null value is special: it is written as a standalone object.

                    if (val == null)
                    {
                        if (!partOfPositionalParameters)
                        {
                            foreach (var xn in GetNodes(null, null_object, node: node))
                            {
                                yield return(xn);
                            }
                        }
                        else
                        {
                            yield return(node.Set(String.Empty));
                        }
                    }
                    else if (!NameResolver.IsCollectingReferences)                     // for perf, getting string value can be expensive
                    {
                        yield return(node.Set(TypeExtensionMethods.GetStringValue(xtt, xm, val, value_serializer_ctx)));
                    }
                    else if (val is Type)
                    {
                        LookupType((Type)val);
                    }
                    //new XamlTypeName(xtt.SchemaContext.GetXamlType((Type)val)).ToString(value_serializer_ctx?.GetService(typeof(INamespacePrefixLookup)) as INamespacePrefixLookup);
                    yield break;
                }

                // collection items: return GetObject and Items.
                if ((xm.Type.IsCollection || xm.Type.IsDictionary) && !xm.IsWritePublic)
                {
                    yield return(XamlNodeInfo.GetObject);

                    // Write Items member only when there are items (i.e. do not write it if it is empty).
                    var itemsValue = xobj.GetMemberObjectValue(XamlLanguage.Items);
                    var en         = GetItemsNodes(XamlLanguage.Items, itemsValue).GetEnumerator();
                    if (en.MoveNext())
                    {
                        yield return(node.Set(XamlNodeType.StartMember, XamlLanguage.Items));

                        do
                        {
                            yield return(en.Current);
                        } while (en.MoveNext());
                        yield return(XamlNodeInfo.EndMember);
                    }
                    yield return(XamlNodeInfo.EndObject);

                    yield break;
                }
                if (xm.Type.IsXData)
                {
                    var sw = new StringWriter();
                    var xw = XmlWriter.Create(sw, new XmlWriterSettings {
                        OmitXmlDeclaration = true, ConformanceLevel = ConformanceLevel.Auto
                    });
#if NETSTANDARD1_0
                    if (!ReflectionHelpers.IXmlSerializableType?.GetTypeInfo().IsAssignableFrom(val?.GetType().GetTypeInfo()) ?? false)
                    {
                        yield break;                         // do not output anything
                    }
                    ReflectionHelpers.IXmlSerializableWriteXmlMethod?.Invoke(val, new object[] { xw });
#else
                    var val3 = val as IXmlSerializable;
                    if (val3 == null)
                    {
                        yield break;                         // do not output anything
                    }
                    val3.WriteXml(xw);
#endif
                    xw.Dispose();
                    var obj = new XData {
                        Text = sw.ToString()
                    };
                    foreach (var xn in GetNodes(null, new XamlObject(XamlLanguage.XData, obj), node: node))
                    {
                        yield return(xn);
                    }
                    yield break;
                }
            }
            else
            {
                node = node ?? new XamlNodeInfo();
                val  = xobj.Value;
            }
            // Object - could become Reference
            if (val != null && !ReferenceEquals(xobj.Type, XamlLanguage.Reference))
            {
                if (xm != null && !xm.IsReadOnly && !IsPublicOrVisible(val.GetType()))
                {
                    throw new XamlObjectReaderException($"Cannot read from internal type {xobj.Type}");
                }

                if (!xobj.Type.IsContentValue(value_serializer_ctx))
                {
                    string refName = NameResolver.GetReferenceName(xobj, val);
                    if (refName != null)
                    {
                        // The target object is already retrieved, so we don't return the same object again.
                        NameResolver.SaveAsReferenced(val);                         // Record it as named object.
                        // Then return Reference object instead.

                        var xref = new XamlObject(XamlLanguage.Reference, new Reference(refName));
                        yield return(node.Set(XamlNodeType.StartObject, xref));

                        yield return(node.Set(XamlNodeType.StartMember, XamlLanguage.PositionalParameters));

                        yield return(node.Set(refName));

                        yield return(XamlNodeInfo.EndMember);

                        yield return(XamlNodeInfo.EndObject);

                        yield break;
                    }
                    else
                    {
                        // The object appeared in the xaml tree for the first time. So we store the reference with a unique name so that it could be referenced later.
                        NameResolver.SetNamedObject(val, true);                         // probably fullyInitialized is always true here.
                    }
                }

                yield return(node.Set(XamlNodeType.StartObject, xobj));

                // If this object is referenced and there is no [RuntimeNameProperty] member, then return Name property in addition.
                if (!NameResolver.IsCollectingReferences && xobj.Type.GetAliasedProperty(XamlLanguage.Name) == null)
                {
                    string name = NameResolver.GetReferencedName(xobj, val);
                    if (name != null)
                    {
                        yield return(node.Set(XamlNodeType.StartMember, XamlLanguage.Name));

                        yield return(node.Set(name));

                        yield return(XamlNodeInfo.EndMember);
                    }
                }
            }
            else
            {
                yield return(node.Set(XamlNodeType.StartObject, xobj));
            }

            // get all object member nodes
            var xce       = GetNodeMembers(xobj, value_serializer_ctx).GetEnumerator();
            var xobject   = new XamlObject();
            var startNode = new XamlNodeInfo();
            while (xce.MoveNext())
            {
                var xnm = xce.Current;

                var en = GetNodes(xnm.Member, xnm.GetValue(xobject), node: node).GetEnumerator();
                if (en.MoveNext())
                {
                    if (!xnm.Member.IsWritePublic && xnm.Member.Type != null && (xnm.Member.Type.IsCollection || xnm.Member.Type.IsDictionary))
                    {
                        // if we are a collection or dictionary without a setter, check to see if its empty first
                        var node1 = en.Current.Copy();                         // getObject
                        if (!en.MoveNext())
                        {
                            continue;
                        }
                        var node2 = en.Current.Copy();              // possibly endObject
                        if (!en.MoveNext())                         // we have one more, so it's not empty!
                        {
                            continue;
                        }

                        // if we have three nodes, then it isn't empty

                        yield return(startNode.Set(XamlNodeType.StartMember, xnm.Member));

                        yield return(node1);

                        yield return(node2);
                    }
                    else
                    {
                        yield return(startNode.Set(XamlNodeType.StartMember, xnm.Member));
                    }

                    do
                    {
                        yield return(en.Current);
                    } while (en.MoveNext());
                    yield return(XamlNodeInfo.EndMember);
                }
            }

            yield return(XamlNodeInfo.EndObject);
        }
 public override void WriteStartObject(XamlType type)
 {
     source.Enqueue(new XamlNodeInfo(XamlNodeType.StartObject, new XamlObject(type, null)));
 }
 public override void WriteStartObject(XamlType xamlType)
 {
     this.ThrowIsDisposed();
     this._addDelegate(XamlNodeType.StartObject, xamlType);
 }
Beispiel #10
0
        IEnumerable <XamlXmlNodeInfo> ReadCollectionItems(XamlType parentType, XamlMember xm)
        {
            bool GetNextElementTrim()
            {
                if (r.NodeType == XmlNodeType.Element)
                {
                    var sti = GetStartTagInfo();
                    var xt  = sctx.GetXamlType(sti.TypeName);
                    return(xt.TrimSurroundingWhitespace);
                }

                return(true);
            }

            XamlTypeName previous = null;

            r.MoveToContent();

            while (r.NodeType != XmlNodeType.EndElement)
            {
                switch (r.NodeType)
                {
                case XmlNodeType.Text:
                    var text = r.Value;
                    r.Read();

                    var trimStart = previous == null ||
                                    sctx.GetXamlType(previous).TrimSurroundingWhitespace;
                    var trimEnd = r.NodeType == XmlNodeType.EndElement ||
                                  GetNextElementTrim();

                    yield return(Node(XamlNodeType.Value, NormalizeWhitespace(text, trimStart, trimEnd)));

                    break;

                case XmlNodeType.Element:
                    if (parentType != null && (r.LocalName.IndexOf('.') > 0 || parentType.GetMember(r.LocalName) != null))
                    {
                        yield return(Node(XamlNodeType.None, null));

                        yield break;
                    }

                    var sti = GetStartTagInfo();
                    previous = sti.TypeName;

                    foreach (var x in ReadObjectElement(parentType, xm))
                    {
                        yield return(x);
                    }
                    break;

                case XmlNodeType.Whitespace:
                    r.Read();
                    if (previous != null &&
                        parentType.IsWhitespaceSignificantCollection &&
                        !sctx.GetXamlType(previous).TrimSurroundingWhitespace)
                    {
                        if (r.NodeType != XmlNodeType.EndElement)
                        {
                            yield return(Node(XamlNodeType.Value, " "));
                        }
                    }
                    break;

                default:
                    throw new XamlParseException(String.Format("Text or Element is expected, but got {0}", r.NodeType));
                }
            }
        }
Beispiel #11
0
 public XamlDuplicateMemberException(XamlMember member, XamlType type)
     : base(SR.Get(SRID.DuplicateMemberSet, (member != null) ? member.Name : null, (type != null) ? type.Name : null))
 {
     DuplicateMember = member;
     ParentType      = type;
 }
Beispiel #12
0
 public SpecialTypeName(string name, XamlType type)
 {
     Name = name;
     Type = type;
 }
Beispiel #13
0
        IEnumerable <XamlNodeInfo> GetNodes(XamlMember xm, XamlObject xobj, XamlType overrideMemberType, bool partOfPositionalParameters)
        {
            // collection items: each item is exposed as a standalone object that has StartObject, EndObject and contents.
            if (xm == XamlLanguage.Items)
            {
                foreach (var xn in GetItemsNodes(xm, xobj))
                {
                    yield return(xn);
                }
                yield break;
            }

            // Arguments: each argument is written as a standalone object
            if (xm == XamlLanguage.Arguments)
            {
                foreach (var argm in xobj.Type.GetSortedConstructorArguments())
                {
                    var argv = argm.Invoker.GetValue(xobj.GetRawValue());
                    var xarg = new XamlObject(argm.Type, argv);
                    foreach (var cn in GetNodes(null, xarg))
                    {
                        yield return(cn);
                    }
                }
                yield break;
            }

            // PositionalParameters: items are from constructor arguments, written as Value node sequentially. Note that not all of them are in simple string value. Also, null values are not written as NullExtension
            if (xm == XamlLanguage.PositionalParameters)
            {
                foreach (var argm in xobj.Type.GetSortedConstructorArguments())
                {
                    foreach (var cn in GetNodes(argm, new XamlObject(argm.Type, xobj.GetMemberValue(argm)), null, true))
                    {
                        yield return(cn);
                    }
                }
                yield break;
            }

            if (xm == XamlLanguage.Initialization)
            {
                yield return(new XamlNodeInfo(TypeExtensionMethods.GetStringValue(xobj.Type, xm, xobj.GetRawValue(), value_serializer_ctx)));

                yield break;
            }

            // Value - only for non-top-level node (thus xm != null)
            if (xm != null)
            {
                // overrideMemberType is (so far) used for XamlLanguage.Key.
                var xtt = overrideMemberType ?? xm.Type;
                if (!xtt.IsMarkupExtension &&                 // this condition is to not serialize MarkupExtension whose type has TypeConverterAttribute (e.g. StaticExtension) as a string.
                    (xtt.IsContentValue(value_serializer_ctx) || xm.IsContentValue(value_serializer_ctx)))
                {
                    // though null value is special: it is written as a standalone object.
                    var val = xobj.GetRawValue();
                    if (val == null)
                    {
                        if (!partOfPositionalParameters)
                        {
                            foreach (var xn in GetNodes(null, null_object))
                            {
                                yield return(xn);
                            }
                        }
                        else
                        {
                            yield return(new XamlNodeInfo(String.Empty));
                        }
                    }
                    else
                    {
                        yield return(new XamlNodeInfo(TypeExtensionMethods.GetStringValue(xtt, xm, val, value_serializer_ctx)));
                    }
                    yield break;
                }
            }

            // collection items: return GetObject and Items.
            if (xm != null && xm.Type.IsCollection && !xm.IsWritePublic)
            {
                yield return(new XamlNodeInfo(XamlNodeType.GetObject, xobj));

                // Write Items member only when there are items (i.e. do not write it if it is empty).
                var xnm = new XamlNodeMember(xobj, XamlLanguage.Items);
                var en  = GetNodes(XamlLanguage.Items, xnm.Value).GetEnumerator();
                if (en.MoveNext())
                {
                    yield return(new XamlNodeInfo(XamlNodeType.StartMember, xnm));

                    do
                    {
                        yield return(en.Current);
                    } while (en.MoveNext());
                    yield return(new XamlNodeInfo(XamlNodeType.EndMember, xnm));
                }
                yield return(new XamlNodeInfo(XamlNodeType.EndObject, xobj));
            }
            else if (xm != null && xm.Type.IsXData)
            {
                var sw = new StringWriter();
                var xw = XmlWriter.Create(sw, new XmlWriterSettings()
                {
                    OmitXmlDeclaration = true, ConformanceLevel = ConformanceLevel.Auto
                });
                var val = xobj.GetRawValue() as IXmlSerializable;
                if (val == null)
                {
                    yield break;                     // do not output anything
                }
                val.WriteXml(xw);
                xw.Close();
                var obj = new XData()
                {
                    Text = sw.ToString()
                };
                foreach (var xn in GetNodes(null, new XamlObject(XamlLanguage.XData, obj)))
                {
                    yield return(xn);
                }
            }
            else
            {
                // Object - could become Reference
                var val = xobj.GetRawValue();
                if (!xobj.Type.IsContentValue(value_serializer_ctx) && val != null)
                {
                    string refName = NameResolver.GetName(val);
                    if (refName != null)
                    {
                        // The target object is already retrieved, so we don't return the same object again.
                        NameResolver.SaveAsReferenced(val);                          // Record it as named object.
                        // Then return Reference object instead.
                        foreach (var xn in GetNodes(null, new XamlObject(XamlLanguage.Reference, new Reference(refName))))
                        {
                            yield return(xn);
                        }
                        yield break;
                    }
                    else
                    {
                        // The object appeared in the xaml tree for the first time. So we store the reference with a unique name so that it could be referenced later.
                        refName = GetReferenceName(xobj);
                        if (NameResolver.IsCollectingReferences && NameResolver.Contains(refName))
                        {
                            throw new InvalidOperationException(String.Format("There is already an object of type {0} named as '{1}'. Object names must be unique.", val.GetType(), refName));
                        }
                        NameResolver.SetNamedObject(refName, val, true);                          // probably fullyInitialized is always true here.
                    }
                }
                yield return(new XamlNodeInfo(XamlNodeType.StartObject, xobj));

                // If this object is referenced and there is no [RuntimeNameProperty] member, then return Name property in addition.
                if (val != null && xobj.Type.GetAliasedProperty(XamlLanguage.Name) == null)
                {
                    string name = NameResolver.GetReferencedName(val);
                    if (name != null)
                    {
                        var sobj = new XamlObject(XamlLanguage.String, name);
                        foreach (var cn in GetMemberNodes(new XamlNodeMember(sobj, XamlLanguage.Name), new XamlNodeInfo [] { new XamlNodeInfo(name) }))
                        {
                            yield return(cn);
                        }
                    }
                }
                foreach (var xn in GetObjectMemberNodes(xobj))
                {
                    yield return(xn);
                }
                yield return(new XamlNodeInfo(XamlNodeType.EndObject, xobj));
            }
        }
 public XamlDuplicateMemberException(XamlMember member, XamlType type)
     : this(String.Format("duplicate member '{0}' in type '{1}'", member, type))
 {
     DuplicateMember = member;
     ParentType      = type;
 }
Beispiel #15
0
        IEnumerable <XamlXmlNodeInfo> ReadMember(XamlType parentType, XamlMember xm)
        {
            yield return(Node(XamlNodeType.StartMember, xm));

            if (xm.IsEvent)
            {
                yield return(Node(XamlNodeType.Value, r.Value));

                r.Read();
            }
            else if (!xm.IsWritePublic)
            {
                if (xm.Type.IsXData)
                {
                    foreach (var ni in ReadXData())
                    {
                        yield return(ni);
                    }
                }
                else if (xm.Type.IsCollection)
                {
                    yield return(Node(XamlNodeType.GetObject, xm.Type));

                    yield return(Node(XamlNodeType.StartMember, XamlLanguage.Items));

                    foreach (var ni in ReadCollectionItems(parentType, XamlLanguage.Items))
                    {
                        yield return(ni);
                    }
                    yield return(Node(XamlNodeType.EndMember, XamlLanguage.Items));

                    yield return(Node(XamlNodeType.EndObject, xm.Type));
                }
                else
                {
                    throw new XamlParseException(String.Format("Read-only member '{0}' showed up in the source XML, and the xml contains element content that cannot be read.", xm.Name))
                          {
                              LineNumber = this.LineNumber, LinePosition = this.LinePosition
                          }
                };
            }
            else
            {
                if (xm.Type.IsCollection || xm.Type.IsDictionary)
                {
                    foreach (var ni in ReadCollectionItems(parentType, xm))
                    {
                        yield return(ni);
                    }
                }
                else
                {
                    foreach (var ni in ReadObjectElement(parentType, xm))
                    {
                        if (ni.NodeType == XamlNodeType.None)
                        {
                            throw new Exception("should not happen");
                        }
                        yield return(ni);
                    }
                }
            }

            yield return(Node(XamlNodeType.EndMember, xm));
        }
Beispiel #16
0
        // It expects that it is not invoked when there is no value to
        // assign.
        // When it is passed null, then it returns a default instance.
        // For example, passing null as Int32 results in 0.
        // But do not immediately try to instantiate with the type, since the type might be abstract.
        object GetCorrectlyTypedValue(XamlMember xm, XamlType xt, object value, bool fallbackToString = false)
        {
            try
            {
                if (value == null)
                {
                    if (xt.IsContentValue(service_provider)) // it is for collection/dictionary key and item
                    {
                        return(null);
                    }
                    else
                    {
                        return(xt.IsNullable ? null : xt.Invoker.CreateInstance(new object[0]));
                    }
                }
                if (ReferenceEquals(xt, null))
                {
                    return(value);
                }

                // Not sure if this is really required though...
                var vt = sctx.GetXamlType(value.GetType());
                if (vt.CanAssignTo(xt))
                {
                    return(value);
                }

                // FIXME: this could be generalized by some means, but I cannot find any.
                if (xt.UnderlyingType == typeof(XamlType) && value is string)
                {
                    value = ResolveTypeFromName((string)value);
                }

                // FIXME: this could be generalized by some means, but I cannot find any.
                if (xt.UnderlyingType == typeof(Type))
                {
                    value = new TypeExtension((string)value).ProvideValue(service_provider);
                }
                if (ReferenceEquals(xt, XamlLanguage.Type) && value is string)
                {
                    value = new TypeExtension((string)value);
                }

                if (IsAllowedType(xt, value))
                {
                    return(value);
                }

                var xtc = xm?.TypeConverter ?? xt.TypeConverter;
                if (xtc != null && value != null)
                {
                    var tc = xtc.ConverterInstance;
                    if (tc != null && tc.CanConvertFrom(service_provider, value.GetType()))
                    {
                        value = tc.ConvertFrom(service_provider, CultureInfo.InvariantCulture, value);
                    }
                    return(value);
                }
            }
            catch (Exception ex)
            {
                // For + ex.Message, the runtime should print InnerException message like .NET does.
                throw WithLineInfo(new XamlObjectWriterException(
                                       String.Format("Could not convert object \'{0}' (of type {1}) to {2}: ", value, value != null ? (object)value.GetType() : "(null)", xt) + ex.Message,
                                       ex));
            }

            return(fallbackToString ?
                   value :
                   throw WithLineInfo(new XamlObjectWriterException(
                                          String.Format("Value '{0}' (of type {1}) is not of or convertible to type {2} (member {3})", value, value != null ? (object)value.GetType() : "(null)", xt, xm),
                                          null)));
        }
 public override void WriteStartObject(XamlType type)
 {
     this.currentState.WriteStartObject(this, type);
 }
Beispiel #18
0
 public static IEnumerable <XamlMember> GetConstructorArguments(this XamlType type)
 {
     return(type.GetAllMembers().Where(m => m.UnderlyingMember != null && m.GetCustomAttributeProvider().GetCustomAttribute <ConstructorArgumentAttribute> (false) != null));
 }
 public override void WriteStartObject(XamlMarkupExtensionWriter writer, XamlType type)
 {
     writer.sb.Append(Delimiter);
     writer.currentState = InMember.State;
     writer.currentState.WriteStartObject(writer, type);
 }
Beispiel #20
0
 internal static ICustomAttributeProvider GetCustomAttributeProvider(this XamlType type)
 {
     return(type.UnderlyingType);
 }
Beispiel #21
0
 public XamlDuplicateMemberException(XamlMember member, XamlType type)
     : this(String.Format("'{0}' property has already been set on '{1}'.", member?.Name, type?.Name))
 {
     DuplicateMember = member;
     ParentType      = type;
 }
Beispiel #22
0
        void ReadStartTypeOrContentGetObject()
        {
            string name         = r.LocalName;
            string ns           = r.NamespaceURI;
            string typeArgNames = null;

            var members = new List <Pair> ();
            var atts    = ProcessAttributes(members);

            // check TypeArguments to resolve Type, and remove them from the list. They don't appear as a node.
            var l = new List <Pair> ();

            foreach (var p in members)
            {
                if (p.Key == XamlLanguage.TypeArguments)
                {
                    typeArgNames = p.Value;
                    l.Add(p);
                    break;
                }
            }
            foreach (var p in l)
            {
                members.Remove(p);
            }

            XamlType             xt;
            IList <XamlTypeName> typeArgs = typeArgNames == null ? null : XamlTypeName.ParseList(typeArgNames, xaml_namespace_resolver);
            var xtn = new XamlTypeName(ns, name, typeArgs);

            xt = sctx.GetXamlType(xtn);
            if (xt == null)
            {
                // creates name-only XamlType. Also, it does not seem that it does not store this XamlType to XamlSchemaContext (Try GetXamlType(xtn) after reading such xaml node, it will return null).
                xt = new XamlType(ns, name, typeArgs == null ? null : typeArgs.Select <XamlTypeName, XamlType> (xxtn => sctx.GetXamlType(xxtn)).ToArray(), sctx);
            }

            if (current_member != null && !xt.CanAssignTo(current_member.Type))
            {
                var pxt = types.Count > 0 ? types.Peek() : null;
                if (pxt != null && pxt.ContentProperty == current_member)
                {
                    SetGetObject();
                    return;
                }

                // It could still be GetObject if current_member
                // is not a directive and current type is not
                // a markup extension.
                // (I'm not very sure about the condition;
                // it could be more complex.)
                // seealso: bug #682131
                if (!get_flags.Peek() &&
                    !(current_member is XamlDirective) &&
                    !xt.IsMarkupExtension)
                {
                    SetGetObject();
                    return;
                }
            }

            types.Push(xt);
            get_flags.Push(false);
            current = xt;

            if (!r.IsEmptyElement)
            {
                r.Read();
                do
                {
                    r.MoveToContent();
                    switch (r.NodeType)
                    {
                    case XmlNodeType.Element:
                    // FIXME: parse type arguments etc.
                    case XmlNodeType.EndElement:
                        break;

                    default:
                        // this value is for Initialization, or Content property value
                        if (xt.ContentProperty != null)
                        {
                            members.Add(new Pair(xt.ContentProperty, r.Value));
                        }
                        else
                        {
                            members.Add(new Pair(XamlLanguage.Initialization, r.Value));
                        }
                        r.Read();
                        continue;
                    }
                    break;
                } while (true);
            }
            else
            {
                is_empty_object = true;
            }

            foreach (var p in atts)
            {
                int    idx    = p.Key.IndexOf(':');
                string prefix = idx > 0 ? p.Key.Substring(0, idx) : String.Empty;
                string aname  = idx > 0 ? p.Key.Substring(idx + 1) : p.Key;
                idx = aname.IndexOf('.');
                if (idx > 0)
                {
                    string apns   = prefix.Length > 0 ? r.LookupNamespace(prefix) : r.NamespaceURI;
                    var    apname = aname.Substring(0, idx);
                    var    axtn   = new XamlTypeName(apns, apname, null);
                    var    at     = sctx.GetXamlType(axtn);
                    var    am     = at.GetAttachableMember(aname.Substring(idx + 1));
                    if (am != null)
                    {
                        members.Add(new Pair(am, p.Value));
                    }
                    // ignore unknown attribute
                }
                var xm = xt.GetMember(aname);
                if (xm != null)
                {
                    members.Add(new Pair(xm, p.Value));
                }
                // ignore unknown attribute
            }

            node_type = XamlNodeType.StartObject;
            inside_object_not_member = true;

            // The next Read() results are likely directives.
            stored_member_enumerator = members.GetEnumerator();
        }
Beispiel #23
0
 private static ReadOnlyCollection <XamlType> GetAllTypes()
 {
     XamlType[] result = new XamlType[] { Array, Member, Null, Property, Reference, Static, Type, String, Double, Int16, Int32, Int64, Boolean, XData, Object, Char, Single, Byte, Decimal, Uri, TimeSpan };
     return(new ReadOnlyCollection <XamlType>(result));
 }
Beispiel #24
0
 public XamlMember(string name, XamlType declaringType, bool isAttachable)
 {
     _name          = name ?? throw new ArgumentNullException(nameof(name));
     _declaringType = declaringType ?? throw new ArgumentNullException(nameof(declaringType));
     _memberType    = isAttachable ? MemberType.Attachable : MemberType.Instance;
 }
Beispiel #25
0
 public override void WriteStartObject(XamlType xamlType)
 {
     this.WriteObject(xamlType, false, "WriteStartObject");
 }
Beispiel #26
0
        // Note that it could return invalid (None) node to tell the caller that it is not really an object element.
        IEnumerable <XamlXmlNodeInfo> ReadObjectElement(XamlType parentType, XamlMember currentMember)
        {
            var theReader = r;

            if (r.NodeType != XmlNodeType.Element)
            {
                //throw new XamlParseException (String.Format ("Element is expected, but got {0}", r.NodeType));
                yield return(Node(XamlNodeType.Value, r.Value));

                yield break;
            }

            if (r.MoveToFirstAttribute())
            {
                do
                {
                    if (r.NamespaceURI == XamlLanguage.Xmlns2000Namespace)
                    {
                        yield return(Node(XamlNodeType.NamespaceDeclaration, new NamespaceDeclaration(r.Value, r.Prefix == "xmlns" ? r.LocalName : String.Empty)));
                    }
                } while (r.MoveToNextAttribute());
                r.MoveToElement();
            }

            var sti = GetStartTagInfo();

            var xt = sctx.GetXamlType(sti.TypeName);

            if (xt == null)
            {
                // Current element could be for another member in the parent type (if exists)
                if (parentType != null && (r.LocalName.IndexOf('.') > 0 || parentType.GetMember(r.LocalName) != null))
                {
                    // stop the iteration and signal the caller to not read current element as an object. (It resolves conflicts between "start object for current collection's item" and "start member for the next member in the parent object".
                    yield return(Node(XamlNodeType.None, null));

                    yield break;
                }

                // creates name-only XamlType. Also, it does not seem that it does not store this XamlType to XamlSchemaContext (Try GetXamlType(xtn) after reading such xaml node, it will return null).
                xt = new XamlType(sti.Namespace, sti.Name, sti.TypeName.TypeArguments == null ? null : sti.TypeName.TypeArguments.Select <XamlTypeName, XamlType> (xxtn => sctx.GetXamlType(xxtn)).ToArray(), sctx);
            }

            bool isGetObject = false;

            if (currentMember != null && !xt.CanAssignTo(currentMember.Type))
            {
                if (currentMember.DeclaringType != null && currentMember.DeclaringType.ContentProperty == currentMember)
                {
                    isGetObject = true;
                }

                // It could still be GetObject if current_member
                // is not a directive and current type is not
                // a markup extension.
                // (I'm not very sure about the condition;
                // it could be more complex.)
                // seealso: bug #682131
                else if (!(currentMember is XamlDirective) &&
                         !xt.IsMarkupExtension)
                {
                    isGetObject = true;
                }
            }

            if (isGetObject)
            {
                yield return(Node(XamlNodeType.GetObject, currentMember.Type));

                foreach (var ni in ReadMembers(parentType, currentMember.Type))
                {
                    yield return(ni);
                }
                yield return(Node(XamlNodeType.EndObject, currentMember.Type));

                yield break;
            }
            // else

            yield return(Node(XamlNodeType.StartObject, xt));

            // process attribute members (including MarkupExtensions)
            ProcessAttributesToMember(sctx, sti, xt);

            foreach (var pair in sti.Members)
            {
                yield return(Node(XamlNodeType.StartMember, pair.Key));

                // Try markup extension
                // FIXME: is this rule correct?
                var v = pair.Value;
                if (!String.IsNullOrEmpty(v) && v [0] == '{')
                {
                    var pai = ParsedMarkupExtensionInfo.Parse(v, xaml_namespace_resolver, sctx);
                    yield return(Node(XamlNodeType.StartObject, pai.Type));

                    foreach (var xepair in pai.Arguments)
                    {
                        yield return(Node(XamlNodeType.StartMember, xepair.Key));

                        if (xepair.Value is List <string> )
                        {
                            foreach (var s in (List <string>)xepair.Value)
                            {
                                yield return(Node(XamlNodeType.Value, s));
                            }
                        }
                        else
                        {
                            yield return(Node(XamlNodeType.Value, xepair.Value));
                        }
                        yield return(Node(XamlNodeType.EndMember, xepair.Key));
                    }
                    yield return(Node(XamlNodeType.EndObject, pai.Type));
                }
                else
                {
                    yield return(Node(XamlNodeType.Value, pair.Value));
                }

                yield return(Node(XamlNodeType.EndMember, pair.Key));
            }

            // process content members
            if (!r.IsEmptyElement)
            {
                r.Read();
                foreach (var ni in ReadMembers(parentType, xt))
                {
                    yield return(ni);
                }
                r.ReadEndElement();
            }
            else
            {
                r.Read();                  // consume empty element.
            }
            yield return(Node(XamlNodeType.EndObject, xt));
        }
Beispiel #27
0
        // Note that it could return invalid (None) node to tell the caller that it is not really an object element.
        IEnumerable <XamlXmlNodeInfo> ReadObjectElement(XamlType parentType, XamlMember currentMember)
        {
            if (r.NodeType == XmlNodeType.Whitespace)
            {
                r.MoveToContent();
            }

            if (r.NodeType == XmlNodeType.EndElement)
            {
                yield break;
            }

            if (r.NodeType != XmlNodeType.Element)
            {
                throw new XamlParseException(String.Format("Element is expected, but got {0}", r.NodeType));
            }

            if (r.MoveToFirstAttribute())
            {
                do
                {
                    if (r.NamespaceURI == XamlLanguage.Xmlns2000Namespace)
                    {
                        yield return(Node(XamlNodeType.NamespaceDeclaration, new NamespaceDeclaration(ResolveLocalNamespace(r.Value), r.Prefix == "xmlns" ? r.LocalName : String.Empty)));
                    }
                } while (r.MoveToNextAttribute());
                r.MoveToElement();
            }

            var sti = GetStartTagInfo();

            var xt = sctx.GetXamlType(sti.TypeName);

            if (ReferenceEquals(xt, null))
            {
                // Current element could be for another member in the parent type (if exists)
                if (parentType != null && (r.LocalName.IndexOf('.') > 0 || parentType.GetMember(r.LocalName) != null))
                {
                    // stop the iteration and signal the caller to not read current element as an object. (It resolves conflicts between "start object for current collection's item" and "start member for the next member in the parent object".
                    yield return(Node(XamlNodeType.None, null));

                    yield break;
                }

                // creates name-only XamlType. Also, it does not seem that it does not store this XamlType to XamlSchemaContext (Try GetXamlType(xtn) after reading such xaml node, it will return null).
                xt = new XamlType(sti.Namespace, sti.Name, sti.TypeName.TypeArguments?.Select(xxtn => sctx.GetXamlType(xxtn)).ToArray(), sctx);
            }

            // It could still be GetObject if current_member is not defer-loaded, it
            // is not a directive, and current type is not
            // a markup extension.
            // (I'm not very sure about the condition;
            // it could be more complex.)
            // seealso: bug #682131
            if (!ReferenceEquals(currentMember, null) &&
                ReferenceEquals(currentMember.DeferringLoader, null) &&
                !xt.CanAssignTo(currentMember.Type) &&
                !ReferenceEquals(xt, XamlLanguage.Reference) &&
                (
                    currentMember.DeclaringType?.ContentProperty == currentMember ||
                    (!currentMember.IsDirective && !xt.IsMarkupExtension)
                )
                )
            {
                yield return(Node(XamlNodeType.GetObject, currentMember.Type));

                foreach (var ni in ReadMembers(parentType, currentMember.Type))
                {
                    yield return(ni);
                }
                yield return(Node(XamlNodeType.EndObject, currentMember.Type));

                yield break;
            }


            yield return(Node(XamlNodeType.StartObject, xt));

            // process attribute members (including MarkupExtensions)
            ProcessAttributesToMember(sti, xt);

            for (int i = 0; i < sti.Members.Count; i++)
            {
                var memberInfo = sti.Members[i];
                yield return(Node(XamlNodeType.StartMember, memberInfo.Member, memberInfo.LineInfo));

                // Try markup extension
                // FIXME: is this rule correct?
                var v = memberInfo.Value;
                if (!string.IsNullOrEmpty(v) && v[0] == '{')
                {
                    if (v.Length >= 2 && v[1] == '}')
                    {
                        // escaped value with {} at the beginning of the string
                        yield return(Node(XamlNodeType.Value, v.Substring(2)));
                    }
                    else
                    {
                        var pai = new ParsedMarkupExtensionInfo(v, xaml_namespace_resolver, sctx);
                        pai.Parse();
                        foreach (var node in ReadMarkup(pai))
                        {
                            yield return(node);
                        }
                    }
                }
                else
                {
                    yield return(Node(XamlNodeType.Value, v, memberInfo.LineInfo));
                }

                yield return(Node(XamlNodeType.EndMember, memberInfo.Member, memberInfo.LineInfo));
            }

            // process content members
            if (!r.IsEmptyElement)
            {
                r.Read();
                foreach (var ni in ReadMembers(parentType, xt))
                {
                    yield return(ni);
                }
                r.ReadEndElement();
            }
            else
            {
                r.Read();                  // consume empty element.
            }
            yield return(Node(XamlNodeType.EndObject, xt));
        }
Beispiel #28
0
        // member element, implicit member, children via content property, or value
        IEnumerable <XamlXmlNodeInfo> ReadMemberElement(XamlType parentType, XamlType xt)
        {
            XamlMember xm   = null;
            var        name = r.LocalName;
            int        idx  = name.IndexOf('.');

            // FIXME: it skips strict type name check, as it could result in MarkupExtension mismatch (could be still checked, though)
            if (idx >= 0 /* && name.Substring (0, idx) == xt.Name*/)
            {
                name = name.Substring(idx + 1);
                xm   = xt.GetMember(name);
            }
            else
            {
                xm = (XamlMember)FindStandardDirective(name, AllowedMemberLocations.MemberElement) ??
                     // not a standard directive? then try attachable
                     xt.GetAttachableMember(name) ??
                     // still not? then try ordinal member
                     xt.GetMember(name);
                if (xm == null)
                {
                    // still not? could it be omitted as content property or items ?
                    if ((xm = GetExtraMember(xt)) != null)
                    {
                        // Note that this does not involve r.Read()
                        foreach (var ni in ReadMember(xt, xm))
                        {
                            yield return(ni);
                        }
                        yield break;
                    }
                }
            }
            if (xm == null)
            {
                // Current element could be for another member in the parent type (if exists)
                if (parentType != null && parentType.GetMember(name) != null)
                {
                    // stop the iteration and signal the caller to not read current element as an object. (It resolves conflicts between "start object for current collection's item" and "start member for the next member in the parent object".
                    yield return(Node(XamlNodeType.None, null));

                    yield break;
                }

                // ok, then create unknown member.
                xm = new XamlMember(name, xt, false);                  // FIXME: not sure if isAttachable is always false.
            }

            if (!r.IsEmptyElement)
            {
                r.Read();
                foreach (var ni in ReadMember(xt, xm))
                {
                    yield return(ni);
                }
                r.MoveToContent();
                r.ReadEndElement();
            }
            else
            {
                r.Read();
            }
        }
Beispiel #29
0
 public XamlScannerFrame(System.Xaml.XamlType xamlType, string ns)
 {
     this.XamlType      = xamlType;
     this.TypeNamespace = ns;
 }
Beispiel #30
0
 public XamlObject(XamlType type, object instance)
 {
     Type  = type;
     Value = instance;
 }