|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Markup;
using System.Xaml.MS.Impl;
using System.Xaml.Schema;
using System.Xml.Serialization;
namespace System.Xaml
{
public static class XamlLanguage
{
public const string Xaml2006Namespace = "http://schemas.microsoft.com/winfx/2006/xaml";
public const string Xml1998Namespace = "http://www.w3.org/XML/1998/namespace";
internal const string SWMNamespace = "System.Windows.Markup";
internal const string PreferredPrefix = "x";
private const string x_AsyncRecords = "AsyncRecords";
private const string x_Arguments = "Arguments";
private const string x_Class = "Class";
private const string x_ClassModifier = "ClassModifier";
private const string x_Code = "Code";
private const string x_ConnectionId = "ConnectionId";
private const string x_FactoryMethod = "FactoryMethod";
private const string x_FieldModifier = "FieldModifier";
private const string x_Initialization = "_Initialization";
private const string x_Items = "_Items";
private const string x_Key = "Key";
private const string x_Members = "Members";
private const string x_ClassAttributes = "ClassAttributes";
private const string x_Name = "Name";
private const string x_PositionalParameters = "_PositionalParameters";
private const string x_Shared = "Shared";
private const string x_Subclass = "Subclass";
private const string x_SynchronousMode = "SynchronousMode";
private const string x_TypeArguments = "TypeArguments";
private const string x_Uid = "Uid";
private const string x_UnknownContent = "_UnknownContent";
private const string xml_Space = "space";
private const string xml_Lang = "lang";
private const string xml_Base = "base";
private static ReadOnlyCollection<string> s_xamlNamespaces =
new ReadOnlyCollection<string>(new string[] { Xaml2006Namespace });
private static ReadOnlyCollection<string> s_xmlNamespaces =
new ReadOnlyCollection<string>(new string[] { Xml1998Namespace });
private static Lazy<XamlSchemaContext> s_schemaContext =
new Lazy<XamlSchemaContext>(GetSchemaContext);
private static Lazy<XamlType> s_array =
new Lazy<XamlType>(() => GetXamlType(typeof(ArrayExtension)));
private static Lazy<XamlType> s_null =
new Lazy<XamlType>(() => GetXamlType(typeof(NullExtension)));
private static Lazy<XamlType> s_reference =
new Lazy<XamlType>(() => GetXamlType(typeof(Reference)));
private static Lazy<XamlType> s_static =
new Lazy<XamlType>(() => GetXamlType(typeof(StaticExtension)));
private static Lazy<XamlType> s_type =
new Lazy<XamlType>(() => GetXamlType(typeof(TypeExtension)));
private static Lazy<XamlType> s_string =
new Lazy<XamlType>(() => GetXamlType(typeof(string)));
private static Lazy<XamlType> s_double =
new Lazy<XamlType>(() => GetXamlType(typeof(double)));
private static Lazy<XamlType> s_int32 =
new Lazy<XamlType>(() => GetXamlType(typeof(int)));
private static Lazy<XamlType> s_boolean =
new Lazy<XamlType>(() => GetXamlType(typeof(bool)));
private static Lazy<XamlType> s_member =
new Lazy<XamlType>(() => GetXamlType(typeof(MemberDefinition)));
private static Lazy<XamlType> s_property =
new Lazy<XamlType>(() => GetXamlType(typeof(PropertyDefinition)));
private static Lazy<XamlType> s_xDataHolder =
new Lazy<XamlType>(() => GetXamlType(typeof(XData)));
// These aren't language built-ins, but we need them because they're used as the type of directives
private static Lazy<XamlType> s_object =
new Lazy<XamlType>(() => GetXamlType(typeof(object)));
private static Lazy<XamlType> s_listOfObject =
new Lazy<XamlType>(() => GetXamlType(typeof(List<object>)));
private static Lazy<XamlType> s_listOfMembers =
new Lazy<XamlType>(() => GetXamlType(typeof(List<MemberDefinition>)));
private static Lazy<XamlType> s_listOfAttributes =
new Lazy<XamlType>(() => GetXamlType(typeof(List<Attribute>)));
// These aren't language built-ins, but we use them in schema
private static Lazy<XamlType> s_markupExtension =
new Lazy<XamlType>(() => GetXamlType(typeof(MarkupExtension)));
private static Lazy<XamlType> s_iNameScope =
new Lazy<XamlType>(() => GetXamlType(typeof(INameScope)));
private static Lazy<XamlType> s_iXmlSerializable =
new Lazy<XamlType>(() => GetXamlType(typeof(IXmlSerializable)), true);
// This isn't a language built-in, but we use it in ObjectWriter
private static Lazy<XamlType> s_positionalParameterDescriptor =
new Lazy<XamlType>(() => GetXamlType(typeof(PositionalParameterDescriptor)), true);
private static Lazy<XamlType> s_char =
new Lazy<XamlType>(() => GetXamlType(typeof(Char)), true);
private static Lazy<XamlType> s_single =
new Lazy<XamlType>(() => GetXamlType(typeof(Single)), true);
private static Lazy<XamlType> s_byte =
new Lazy<XamlType>(() => GetXamlType(typeof(Byte)), true);
private static Lazy<XamlType> s_int16 =
new Lazy<XamlType>(() => GetXamlType(typeof(Int16)), true);
private static Lazy<XamlType> s_int64 =
new Lazy<XamlType>(() => GetXamlType(typeof(Int64)), true);
private static Lazy<XamlType> s_decimal =
new Lazy<XamlType>(() => GetXamlType(typeof(Decimal)), true);
private static Lazy<XamlType> s_uri =
new Lazy<XamlType>(() => GetXamlType(typeof(Uri)), true);
private static Lazy<XamlType> s_timespan =
new Lazy<XamlType>(() => GetXamlType(typeof(TimeSpan)), true);
private static Lazy<ReadOnlyCollection<XamlType>> s_allTypes =
new Lazy<ReadOnlyCollection<XamlType>>(GetAllTypes);
private static Lazy<XamlDirective> s_asyncRecords =
new Lazy<XamlDirective>(() => GetXamlDirective(x_AsyncRecords,
String, BuiltInValueConverter.Int32, AllowedMemberLocations.Attribute), true);
private static Lazy<XamlDirective> s_arguments =
new Lazy<XamlDirective>(() => GetXamlDirective(x_Arguments,
s_listOfObject.Value, null, AllowedMemberLocations.Any), true);
private static Lazy<XamlDirective> s_class =
new Lazy<XamlDirective>(() => GetXamlDirective(x_Class));
private static Lazy<XamlDirective> s_classModifier =
new Lazy<XamlDirective>(() => GetXamlDirective(x_ClassModifier));
private static Lazy<XamlDirective> s_code =
new Lazy<XamlDirective>(() => GetXamlDirective(x_Code));
private static Lazy<XamlDirective> s_connectionId =
new Lazy<XamlDirective>(() => GetXamlDirective(x_ConnectionId,
s_string.Value, BuiltInValueConverter.Int32, AllowedMemberLocations.Any), true);
private static Lazy<XamlDirective> s_factoryMethod =
new Lazy<XamlDirective>(() => GetXamlDirective(x_FactoryMethod,
s_string.Value, BuiltInValueConverter.String, AllowedMemberLocations.Any), true);
private static Lazy<XamlDirective> s_fieldModifier =
new Lazy<XamlDirective>(() => GetXamlDirective(x_FieldModifier));
private static Lazy<XamlDirective> s_items =
new Lazy<XamlDirective>(() => GetXamlDirective(x_Items,
s_listOfObject.Value, null, AllowedMemberLocations.Any), true);
private static Lazy<XamlDirective> s_initialization =
new Lazy<XamlDirective>(() => GetXamlDirective(x_Initialization,
s_object.Value, null, AllowedMemberLocations.Any), true);
private static Lazy<XamlDirective> s_key =
new Lazy<XamlDirective>(() => GetXamlDirective(x_Key,
s_object.Value, BuiltInValueConverter.String, AllowedMemberLocations.Any), true);
private static Lazy<XamlDirective> s_members =
new Lazy<XamlDirective>(() => GetXamlDirective(x_Members,
s_listOfMembers.Value, null, AllowedMemberLocations.MemberElement), true);
private static Lazy<XamlDirective> s_classAttributes =
new Lazy<XamlDirective>(() => GetXamlDirective(x_ClassAttributes,
s_listOfAttributes.Value, null, AllowedMemberLocations.MemberElement), true);
private static Lazy<XamlDirective> s_name =
new Lazy<XamlDirective>(() => GetXamlDirective(x_Name));
private static Lazy<XamlDirective> s_positionalParameters =
new Lazy<XamlDirective>(() => GetXamlDirective(x_PositionalParameters,
s_listOfObject.Value, null, AllowedMemberLocations.Any), true);
private static Lazy<XamlDirective> s_shared =
new Lazy<XamlDirective>(() => GetXamlDirective(x_Shared), true);
private static Lazy<XamlDirective> s_subclass =
new Lazy<XamlDirective>(() => GetXamlDirective(x_Subclass), true);
private static Lazy<XamlDirective> s_synchronousMode =
new Lazy<XamlDirective>(() => GetXamlDirective(x_SynchronousMode));
private static Lazy<XamlDirective> s_typeArguments =
new Lazy<XamlDirective>(() => GetXamlDirective(x_TypeArguments));
private static Lazy<XamlDirective> s_uid =
new Lazy<XamlDirective>(() => GetXamlDirective(x_Uid));
private static Lazy<XamlDirective> s_unknownContent =
new Lazy<XamlDirective>(() => GetXamlDirective(x_UnknownContent, AllowedMemberLocations.MemberElement, MemberReflector.UnknownReflector), true);
private static Lazy<XamlDirective> s_base =
new Lazy<XamlDirective>(() => GetXmlDirective(xml_Base));
private static Lazy<XamlDirective> s_lang =
new Lazy<XamlDirective>(() => GetXmlDirective(xml_Lang));
private static Lazy<XamlDirective> s_space =
new Lazy<XamlDirective>(() => GetXmlDirective(xml_Space));
private static Lazy<ReadOnlyCollection<XamlDirective>> s_allDirectives =
new Lazy<ReadOnlyCollection<XamlDirective>>(GetAllDirectives);
public static IList<string> XamlNamespaces { get { return s_xamlNamespaces; } }
public static IList<string> XmlNamespaces { get { return s_xmlNamespaces; } }
public static XamlType Array { get { return s_array.Value; } }
public static XamlType Member { get { return s_member.Value; } }
public static XamlType Null { get { return s_null.Value; } }
public static XamlType Property { get { return s_property.Value; } }
public static XamlType Reference { get { return s_reference.Value; } }
public static XamlType Static { get { return s_static.Value; } }
public static XamlType Type { get { return s_type.Value; } }
public static XamlType String { get { return s_string.Value; } }
public static XamlType Double { get { return s_double.Value; } }
public static XamlType Int32 { get { return s_int32.Value; } }
public static XamlType Boolean { get { return s_boolean.Value; } }
public static XamlType XData { get { return s_xDataHolder.Value; } }
public static XamlType Object { get { return s_object.Value; } }
public static XamlType Char { get { return s_char.Value; } }
public static XamlType Single { get { return s_single.Value; } }
public static XamlType Byte { get { return s_byte.Value; } }
public static XamlType Int16 { get { return s_int16.Value; } }
public static XamlType Int64 { get { return s_int64.Value; } }
public static XamlType Decimal { get { return s_decimal.Value; } }
public static XamlType Uri { get { return s_uri.Value; } }
public static XamlType TimeSpan { get { return s_timespan.Value; } }
public static ReadOnlyCollection<XamlType> AllTypes { get { return s_allTypes.Value; } }
public static XamlDirective Arguments { get { return s_arguments.Value; } }
public static XamlDirective AsyncRecords { get { return s_asyncRecords.Value; } }
public static XamlDirective Class { get { return s_class.Value; } }
public static XamlDirective ClassModifier { get { return s_classModifier.Value; } }
public static XamlDirective Code { get { return s_code.Value; } }
public static XamlDirective ConnectionId { get { return s_connectionId.Value; } }
public static XamlDirective FactoryMethod { get { return s_factoryMethod.Value; } }
public static XamlDirective FieldModifier { get { return s_fieldModifier.Value; } }
public static XamlDirective Items { get { return s_items.Value; } }
public static XamlDirective Initialization { get { return s_initialization.Value; } }
public static XamlDirective Key { get { return s_key.Value; } }
public static XamlDirective Members { get { return s_members.Value; } }
public static XamlDirective ClassAttributes { get { return s_classAttributes.Value; } }
public static XamlDirective Name { get { return s_name.Value; } }
public static XamlDirective PositionalParameters { get { return s_positionalParameters.Value; } }
public static XamlDirective Shared { get { return s_shared.Value; } }
public static XamlDirective Subclass { get { return s_subclass.Value; } }
public static XamlDirective SynchronousMode { get { return s_synchronousMode.Value; } }
public static XamlDirective TypeArguments { get { return s_typeArguments.Value; } }
public static XamlDirective Uid { get { return s_uid.Value; } }
public static XamlDirective UnknownContent { get { return s_unknownContent.Value; } }
public static XamlDirective Base { get { return s_base.Value; } }
public static XamlDirective Lang { get { return s_lang.Value; } }
// This isn't a node stream directive, we should get rid of it
public static XamlDirective Space { get { return s_space.Value; } }
public static ReadOnlyCollection<XamlDirective> AllDirectives { get { return s_allDirectives.Value; } }
internal static XamlType MarkupExtension { get { return s_markupExtension.Value; } }
internal static XamlType INameScope { get { return s_iNameScope.Value; } }
internal static XamlType PositionalParameterDescriptor { get { return s_positionalParameterDescriptor.Value; } }
// Careful: accessing this faults in System.Xml
internal static XamlType IXmlSerializable { get { return s_iXmlSerializable.Value; } }
internal static string TypeAlias(Type type)
{
if (type.Equals(typeof(MemberDefinition)))
{
return KnownStrings.Member;
}
if (type.Equals(typeof(PropertyDefinition)))
{
return KnownStrings.Property;
}
return null;
}
internal static XamlDirective LookupXamlDirective(string name)
{
switch (name)
{
case x_AsyncRecords:
return AsyncRecords;
case x_Arguments:
return Arguments;
case x_Class:
return Class;
case x_ClassModifier:
return ClassModifier;
case x_Code:
return Code;
case x_ConnectionId:
return ConnectionId;
case x_FactoryMethod:
return FactoryMethod;
case x_FieldModifier:
return FieldModifier;
case x_Initialization:
return Initialization;
case x_Items:
return Items;
case x_Key:
return Key;
case x_Members:
return Members;
case x_ClassAttributes:
return ClassAttributes;
case x_Name:
return Name;
case x_PositionalParameters:
return PositionalParameters;
case x_Shared:
return Shared;
case x_Subclass:
return Subclass;
case x_SynchronousMode:
return SynchronousMode;
case x_TypeArguments:
return TypeArguments;
case x_Uid:
return Uid;
case x_UnknownContent:
return UnknownContent;
default:
return null;
}
}
internal static XamlType LookupXamlType(string typeNamespace, string typeName)
{
if (XamlNamespaces.Contains(typeNamespace))
{
switch (typeName)
{
case "Array":
case "ArrayExtension":
return Array;
case "Member":
return Member;
case "Null":
case "NullExtension":
return Null;
case "Property":
return Property;
case "Reference":
case "ReferenceExtension":
return Reference;
case "Static":
case "StaticExtension":
return Static;
case "Type":
case "TypeExtension":
return Type;
case "String":
return String;
case "Double":
return Double;
case "Int16":
return Int16;
case "Int32":
return Int32;
case "Int64":
return Int64;
case "Boolean":
return Boolean;
case "XData":
return XData;
case "Object":
return Object;
case "Char":
return Char;
case "Single":
return Single;
case "Byte":
return Byte;
case "Decimal":
return Decimal;
case "Uri":
return Uri;
case "TimeSpan":
return TimeSpan;
default:
return null;
}
}
return null;
}
// The XAML names of MemberDefinition and PropertyDefinition don't match their CLR type names.
// LookupXamlType will still find them in the XAML namespace, but they won't be found through
// clr-namespace lookup. This method handles that special case.
internal static Type LookupClrNamespaceType(AssemblyNamespacePair nsPair, string typeName)
{
if (nsPair.ClrNamespace == SWMNamespace && nsPair.Assembly == typeof(XamlLanguage).Assembly)
{
switch (typeName)
{
case "Member":
return typeof(MemberDefinition);
case "Property":
return typeof(PropertyDefinition);
default:
return null;
}
}
return null;
}
internal static XamlDirective LookupXmlDirective(string name)
{
switch (name)
{
case xml_Base:
return Base;
case xml_Lang:
return Lang;
case xml_Space:
return Space;
default:
return null;
}
}
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);
}
private static ReadOnlyCollection<XamlDirective> GetAllDirectives()
{
XamlDirective[] result = new XamlDirective[]
{ Arguments, AsyncRecords, Class, Code, ClassModifier, ConnectionId, FactoryMethod, FieldModifier,
Key, Initialization, Items, Members, ClassAttributes, Name, PositionalParameters, Shared, Subclass,
SynchronousMode, TypeArguments, Uid, UnknownContent, Base, Lang, Space};
return new ReadOnlyCollection<XamlDirective>(result);
}
private static XamlSchemaContext GetSchemaContext()
{
// System.Xaml and WindowsBase
Assembly[] assemblies = new Assembly[]
{ typeof(XamlLanguage).Assembly, typeof(MarkupExtension).Assembly };
XamlSchemaContextSettings settings =
new XamlSchemaContextSettings { SupportMarkupExtensionsWithDuplicateArity = true };
XamlSchemaContext result = new XamlSchemaContext(assemblies, settings);
return result;
}
private static XamlDirective GetXamlDirective(string name)
{
return GetXamlDirective(name, String, BuiltInValueConverter.String, AllowedMemberLocations.Attribute);
}
private static XamlDirective GetXamlDirective(string name, AllowedMemberLocations allowedLocation, MemberReflector reflector)
{
XamlDirective result = new XamlDirective(s_xamlNamespaces, name, allowedLocation, reflector);
return result;
}
private static XamlDirective GetXamlDirective(string name, XamlType xamlType,
XamlValueConverter<TypeConverter> typeConverter, AllowedMemberLocations allowedLocation)
{
XamlDirective result = new XamlDirective(s_xamlNamespaces, name, allowedLocation, new MemberReflector(xamlType, typeConverter));
return result;
}
private static XamlDirective GetXmlDirective(string name)
{
XamlDirective result = new XamlDirective(s_xmlNamespaces, name, AllowedMemberLocations.Attribute, new MemberReflector(String, BuiltInValueConverter.String));
return result;
}
private static XamlType GetXamlType(Type type)
{
XamlType result = s_schemaContext.Value.GetXamlType(type);
return result;
}
}
}
|