| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971 |
- //
- // Author:
- // Jb Evain (jbevain@gmail.com)
- //
- // Copyright (c) 2008 - 2015 Jb Evain
- // Copyright (c) 2008 - 2011 Novell, Inc.
- //
- // Licensed under the MIT/X11 license.
- //
- using System;
- using System.Collections.Generic;
- using System.Threading;
- using ILRuntime.Mono.Collections.Generic;
- namespace ILRuntime.Mono.Cecil {
- sealed class TypeDefinitionProjection {
- public readonly TypeAttributes Attributes;
- public readonly string Name;
- public readonly TypeDefinitionTreatment Treatment;
- public readonly Collection<MethodDefinition> RedirectedMethods;
- public readonly Collection<KeyValuePair<InterfaceImplementation, InterfaceImplementation>> RedirectedInterfaces;
- public TypeDefinitionProjection(TypeDefinition type, TypeDefinitionTreatment treatment, Collection<MethodDefinition> redirectedMethods, Collection<KeyValuePair<InterfaceImplementation, InterfaceImplementation>> redirectedInterfaces)
- {
- Attributes = type.Attributes;
- Name = type.Name;
- Treatment = treatment;
- RedirectedMethods = redirectedMethods;
- RedirectedInterfaces = redirectedInterfaces;
- }
- }
- sealed class TypeReferenceProjection {
- public readonly string Name;
- public readonly string Namespace;
- public readonly IMetadataScope Scope;
- public readonly TypeReferenceTreatment Treatment;
- public TypeReferenceProjection (TypeReference type, TypeReferenceTreatment treatment)
- {
- Name = type.Name;
- Namespace = type.Namespace;
- Scope = type.Scope;
- Treatment = treatment;
- }
- }
- sealed class MethodDefinitionProjection {
- public readonly MethodAttributes Attributes;
- public readonly MethodImplAttributes ImplAttributes;
- public readonly string Name;
- public readonly MethodDefinitionTreatment Treatment;
- public MethodDefinitionProjection (MethodDefinition method, MethodDefinitionTreatment treatment)
- {
- Attributes = method.Attributes;
- ImplAttributes = method.ImplAttributes;
- Name = method.Name;
- Treatment = treatment;
- }
- }
- sealed class FieldDefinitionProjection {
- public readonly FieldAttributes Attributes;
- public readonly FieldDefinitionTreatment Treatment;
- public FieldDefinitionProjection (FieldDefinition field, FieldDefinitionTreatment treatment)
- {
- Attributes = field.Attributes;
- Treatment = treatment;
- }
- }
- sealed class CustomAttributeValueProjection {
- public readonly AttributeTargets Targets;
- public readonly CustomAttributeValueTreatment Treatment;
- public CustomAttributeValueProjection (AttributeTargets targets, CustomAttributeValueTreatment treatment)
- {
- Targets = targets;
- Treatment = treatment;
- }
- }
- sealed class WindowsRuntimeProjections {
- struct ProjectionInfo {
- public readonly string WinRTNamespace;
- public readonly string ClrNamespace;
- public readonly string ClrName;
- public readonly string ClrAssembly;
- public readonly bool Attribute;
- public ProjectionInfo (string winrt_namespace, string clr_namespace, string clr_name, string clr_assembly, bool attribute = false)
- {
- WinRTNamespace = winrt_namespace;
- ClrNamespace = clr_namespace;
- ClrName = clr_name;
- ClrAssembly = clr_assembly;
- Attribute = attribute;
- }
- }
- static readonly Version version = new Version (4, 0, 0, 0);
- static readonly byte[] contract_pk_token = {
- 0xB0, 0x3F, 0x5F, 0x7F, 0x11, 0xD5, 0x0A, 0x3A
- };
- static readonly byte[] contract_pk = {
- 0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00,
- 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
- 0x07, 0xD1, 0xFA, 0x57, 0xC4, 0xAE, 0xD9, 0xF0, 0xA3, 0x2E, 0x84, 0xAA, 0x0F, 0xAE, 0xFD, 0x0D,
- 0xE9, 0xE8, 0xFD, 0x6A, 0xEC, 0x8F, 0x87, 0xFB, 0x03, 0x76, 0x6C, 0x83, 0x4C, 0x99, 0x92, 0x1E,
- 0xB2, 0x3B, 0xE7, 0x9A, 0xD9, 0xD5, 0xDC, 0xC1, 0xDD, 0x9A, 0xD2, 0x36, 0x13, 0x21, 0x02, 0x90,
- 0x0B, 0x72, 0x3C, 0xF9, 0x80, 0x95, 0x7F, 0xC4, 0xE1, 0x77, 0x10, 0x8F, 0xC6, 0x07, 0x77, 0x4F,
- 0x29, 0xE8, 0x32, 0x0E, 0x92, 0xEA, 0x05, 0xEC, 0xE4, 0xE8, 0x21, 0xC0, 0xA5, 0xEF, 0xE8, 0xF1,
- 0x64, 0x5C, 0x4C, 0x0C, 0x93, 0xC1, 0xAB, 0x99, 0x28, 0x5D, 0x62, 0x2C, 0xAA, 0x65, 0x2C, 0x1D,
- 0xFA, 0xD6, 0x3D, 0x74, 0x5D, 0x6F, 0x2D, 0xE5, 0xF1, 0x7E, 0x5E, 0xAF, 0x0F, 0xC4, 0x96, 0x3D,
- 0x26, 0x1C, 0x8A, 0x12, 0x43, 0x65, 0x18, 0x20, 0x6D, 0xC0, 0x93, 0x34, 0x4D, 0x5A, 0xD2, 0x93
- };
- static Dictionary<string, ProjectionInfo> projections;
- static Dictionary<string, ProjectionInfo> Projections
- {
- get {
- if (projections != null)
- return projections;
- var new_projections = new Dictionary<string, ProjectionInfo> {
- { "AttributeTargets", new ProjectionInfo ("Windows.Foundation.Metadata", "System", "AttributeTargets", "System.Runtime") },
- { "AttributeUsageAttribute", new ProjectionInfo ("Windows.Foundation.Metadata", "System", "AttributeUsageAttribute", "System.Runtime", attribute: true) },
- { "Color", new ProjectionInfo ("Windows.UI", "Windows.UI", "Color", "System.Runtime.WindowsRuntime") },
- { "CornerRadius", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "CornerRadius", "System.Runtime.WindowsRuntime.UI.Xaml") },
- { "DateTime", new ProjectionInfo ("Windows.Foundation", "System", "DateTimeOffset", "System.Runtime") },
- { "Duration", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "Duration", "System.Runtime.WindowsRuntime.UI.Xaml") },
- { "DurationType", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "DurationType", "System.Runtime.WindowsRuntime.UI.Xaml") },
- { "EventHandler`1", new ProjectionInfo ("Windows.Foundation", "System", "EventHandler`1", "System.Runtime") },
- { "EventRegistrationToken", new ProjectionInfo ("Windows.Foundation", "System.Runtime.InteropServices.WindowsRuntime", "EventRegistrationToken", "System.Runtime.InteropServices.WindowsRuntime") },
- { "GeneratorPosition", new ProjectionInfo ("Windows.UI.Xaml.Controls.Primitives", "Windows.UI.Xaml.Controls.Primitives", "GeneratorPosition", "System.Runtime.WindowsRuntime.UI.Xaml") },
- { "GridLength", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "GridLength", "System.Runtime.WindowsRuntime.UI.Xaml") },
- { "GridUnitType", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "GridUnitType", "System.Runtime.WindowsRuntime.UI.Xaml") },
- { "HResult", new ProjectionInfo ("Windows.Foundation", "System", "Exception", "System.Runtime") },
- { "IBindableIterable", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections", "IEnumerable", "System.Runtime") },
- { "IBindableVector", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections", "IList", "System.Runtime") },
- { "IClosable", new ProjectionInfo ("Windows.Foundation", "System", "IDisposable", "System.Runtime") },
- { "ICommand", new ProjectionInfo ("Windows.UI.Xaml.Input", "System.Windows.Input", "ICommand", "System.ObjectModel") },
- { "IIterable`1", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IEnumerable`1", "System.Runtime") },
- { "IKeyValuePair`2", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "KeyValuePair`2", "System.Runtime") },
- { "IMapView`2", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IReadOnlyDictionary`2", "System.Runtime") },
- { "IMap`2", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IDictionary`2", "System.Runtime") },
- { "INotifyCollectionChanged", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "INotifyCollectionChanged", "System.ObjectModel") },
- { "INotifyPropertyChanged", new ProjectionInfo ("Windows.UI.Xaml.Data", "System.ComponentModel", "INotifyPropertyChanged", "System.ObjectModel") },
- { "IReference`1", new ProjectionInfo ("Windows.Foundation", "System", "Nullable`1", "System.Runtime") },
- { "IVectorView`1", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IReadOnlyList`1", "System.Runtime") },
- { "IVector`1", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IList`1", "System.Runtime") },
- { "KeyTime", new ProjectionInfo ("Windows.UI.Xaml.Media.Animation", "Windows.UI.Xaml.Media.Animation", "KeyTime", "System.Runtime.WindowsRuntime.UI.Xaml") },
- { "Matrix", new ProjectionInfo ("Windows.UI.Xaml.Media", "Windows.UI.Xaml.Media", "Matrix", "System.Runtime.WindowsRuntime.UI.Xaml") },
- { "Matrix3D", new ProjectionInfo ("Windows.UI.Xaml.Media.Media3D", "Windows.UI.Xaml.Media.Media3D", "Matrix3D", "System.Runtime.WindowsRuntime.UI.Xaml") },
- { "Matrix3x2", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Matrix3x2", "System.Numerics.Vectors") },
- { "Matrix4x4", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Matrix4x4", "System.Numerics.Vectors") },
- { "NotifyCollectionChangedAction", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "NotifyCollectionChangedAction", "System.ObjectModel") },
- { "NotifyCollectionChangedEventArgs", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "NotifyCollectionChangedEventArgs", "System.ObjectModel") },
- { "NotifyCollectionChangedEventHandler", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "NotifyCollectionChangedEventHandler", "System.ObjectModel") },
- { "Plane", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Plane", "System.Numerics.Vectors") },
- { "Point", new ProjectionInfo ("Windows.Foundation", "Windows.Foundation", "Point", "System.Runtime.WindowsRuntime") },
- { "PropertyChangedEventArgs", new ProjectionInfo ("Windows.UI.Xaml.Data", "System.ComponentModel", "PropertyChangedEventArgs", "System.ObjectModel") },
- { "PropertyChangedEventHandler", new ProjectionInfo ("Windows.UI.Xaml.Data", "System.ComponentModel", "PropertyChangedEventHandler", "System.ObjectModel") },
- { "Quaternion", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Quaternion", "System.Numerics.Vectors") },
- { "Rect", new ProjectionInfo ("Windows.Foundation", "Windows.Foundation", "Rect", "System.Runtime.WindowsRuntime") },
- { "RepeatBehavior", new ProjectionInfo ("Windows.UI.Xaml.Media.Animation", "Windows.UI.Xaml.Media.Animation", "RepeatBehavior", "System.Runtime.WindowsRuntime.UI.Xaml") },
- { "RepeatBehaviorType", new ProjectionInfo ("Windows.UI.Xaml.Media.Animation", "Windows.UI.Xaml.Media.Animation", "RepeatBehaviorType", "System.Runtime.WindowsRuntime.UI.Xaml") },
- { "Size", new ProjectionInfo ("Windows.Foundation", "Windows.Foundation", "Size", "System.Runtime.WindowsRuntime") },
- { "Thickness", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "Thickness", "System.Runtime.WindowsRuntime.UI.Xaml") },
- { "TimeSpan", new ProjectionInfo ("Windows.Foundation", "System", "TimeSpan", "System.Runtime") },
- { "TypeName", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System", "Type", "System.Runtime") },
- { "Uri", new ProjectionInfo ("Windows.Foundation", "System", "Uri", "System.Runtime") },
- { "Vector2", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector2", "System.Numerics.Vectors") },
- { "Vector3", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector3", "System.Numerics.Vectors") },
- { "Vector4", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector4", "System.Numerics.Vectors") },
- };
- Interlocked.CompareExchange (ref projections, new_projections, null);
- return projections;
- }
- }
- readonly ModuleDefinition module;
- Version corlib_version = new Version (255, 255, 255, 255);
- AssemblyNameReference[] virtual_references;
- AssemblyNameReference[] VirtualReferences {
- get {
- if (virtual_references == null) {
- // force module to read its assembly references. that will in turn initialize virtual_references
- Mixin.Read (module.AssemblyReferences);
- }
- return virtual_references;
- }
- }
- public WindowsRuntimeProjections (ModuleDefinition module)
- {
- this.module = module;
- }
- public static void Project (TypeDefinition type)
- {
- var treatment = TypeDefinitionTreatment.None;
- var metadata_kind = type.Module.MetadataKind;
- Collection<MethodDefinition> redirectedMethods = null;
- Collection<KeyValuePair<InterfaceImplementation, InterfaceImplementation>> redirectedInterfaces = null;
- if (type.IsWindowsRuntime) {
- if (metadata_kind == MetadataKind.WindowsMetadata) {
- treatment = GetWellKnownTypeDefinitionTreatment (type);
- if (treatment != TypeDefinitionTreatment.None) {
- ApplyProjection (type, new TypeDefinitionProjection (type, treatment, redirectedMethods, redirectedInterfaces));
- return;
- }
- var base_type = type.BaseType;
- if (base_type != null && IsAttribute (base_type)) {
- treatment = TypeDefinitionTreatment.NormalAttribute;
- } else {
- treatment = GenerateRedirectionInformation (type, out redirectedMethods, out redirectedInterfaces);
- }
- }
- else if (metadata_kind == MetadataKind.ManagedWindowsMetadata && NeedsWindowsRuntimePrefix (type))
- treatment = TypeDefinitionTreatment.PrefixWindowsRuntimeName;
- if (treatment == TypeDefinitionTreatment.PrefixWindowsRuntimeName || treatment == TypeDefinitionTreatment.NormalType)
- if (!type.IsInterface && HasAttribute (type, "Windows.UI.Xaml", "TreatAsAbstractComposableClassAttribute"))
- treatment |= TypeDefinitionTreatment.Abstract;
- }
- else if (metadata_kind == MetadataKind.ManagedWindowsMetadata && IsClrImplementationType (type))
- treatment = TypeDefinitionTreatment.UnmangleWindowsRuntimeName;
- if (treatment != TypeDefinitionTreatment.None)
- ApplyProjection (type, new TypeDefinitionProjection (type, treatment, redirectedMethods, redirectedInterfaces));
- }
- static TypeDefinitionTreatment GetWellKnownTypeDefinitionTreatment (TypeDefinition type)
- {
- ProjectionInfo info;
- if (!Projections.TryGetValue (type.Name, out info))
- return TypeDefinitionTreatment.None;
- var treatment = info.Attribute ? TypeDefinitionTreatment.RedirectToClrAttribute : TypeDefinitionTreatment.RedirectToClrType;
- if (type.Namespace == info.ClrNamespace)
- return treatment;
- if (type.Namespace == info.WinRTNamespace)
- return treatment | TypeDefinitionTreatment.Internal;
- return TypeDefinitionTreatment.None;
- }
- private static TypeDefinitionTreatment GenerateRedirectionInformation (TypeDefinition type, out Collection<MethodDefinition> redirectedMethods, out Collection<KeyValuePair<InterfaceImplementation, InterfaceImplementation>> redirectedInterfaces)
- {
- bool implementsProjectedInterface = false;
- redirectedMethods = null;
- redirectedInterfaces = null;
- foreach (var implementedInterface in type.Interfaces) {
- if (IsRedirectedType (implementedInterface.InterfaceType)) {
- implementsProjectedInterface = true;
- break;
- }
- }
- if (!implementsProjectedInterface)
- return TypeDefinitionTreatment.NormalType;
- var allImplementedInterfaces = new HashSet<TypeReference> (new TypeReferenceEqualityComparer ());
- redirectedMethods = new Collection<MethodDefinition> ();
- redirectedInterfaces = new Collection<KeyValuePair<InterfaceImplementation, InterfaceImplementation>> ();
- foreach (var @interface in type.Interfaces) {
- var interfaceType = @interface.InterfaceType;
- if (IsRedirectedType (interfaceType)) {
- allImplementedInterfaces.Add (interfaceType);
- CollectImplementedInterfaces (interfaceType, allImplementedInterfaces);
- }
- }
- foreach (var implementedInterface in type.Interfaces) {
- var interfaceType = implementedInterface.InterfaceType;
- if (IsRedirectedType (implementedInterface.InterfaceType)) {
- var etype = interfaceType.GetElementType ();
- var unprojectedType = new TypeReference (etype.Namespace, etype.Name, etype.Module, etype.Scope) {
- DeclaringType = etype.DeclaringType,
- projection = etype.projection
- };
- RemoveProjection (unprojectedType);
- var genericInstanceType = interfaceType as GenericInstanceType;
- if (genericInstanceType != null) {
- var genericUnprojectedType = new GenericInstanceType (unprojectedType);
- foreach (var genericArgument in genericInstanceType.GenericArguments)
- genericUnprojectedType.GenericArguments.Add (genericArgument);
- unprojectedType = genericUnprojectedType;
- }
- var unprojectedInterface = new InterfaceImplementation (unprojectedType);
- redirectedInterfaces.Add (new KeyValuePair<InterfaceImplementation, InterfaceImplementation> (implementedInterface, unprojectedInterface));
- }
- }
- // Interfaces don't inherit methods of the interfaces they implement
- if (!type.IsInterface) {
- foreach (var implementedInterface in allImplementedInterfaces) {
- RedirectInterfaceMethods (implementedInterface, redirectedMethods);
- }
- }
- return TypeDefinitionTreatment.RedirectImplementedMethods;
- }
- private static void CollectImplementedInterfaces (TypeReference type, HashSet<TypeReference> results)
- {
- var typeResolver = TypeResolver.For (type);
- var typeDef = type.Resolve ();
- foreach (var implementedInterface in typeDef.Interfaces) {
- var interfaceType = typeResolver.Resolve (implementedInterface.InterfaceType);
- results.Add (interfaceType);
- CollectImplementedInterfaces (interfaceType, results);
- }
- }
- private static void RedirectInterfaceMethods (TypeReference interfaceType, Collection<MethodDefinition> redirectedMethods)
- {
- var typeResolver = TypeResolver.For (interfaceType);
- var typeDef = interfaceType.Resolve ();
- foreach (var method in typeDef.Methods) {
- var redirectedMethod = new MethodDefinition (method.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot, typeResolver.Resolve (method.ReturnType));
- redirectedMethod.ImplAttributes = MethodImplAttributes.Runtime;
- foreach (var parameter in method.Parameters) {
- redirectedMethod.Parameters.Add (new ParameterDefinition (parameter.Name, parameter.Attributes, typeResolver.Resolve (parameter.ParameterType)));
- }
- redirectedMethod.Overrides.Add (typeResolver.Resolve (method));
- redirectedMethods.Add (redirectedMethod);
- }
- }
- private static bool IsRedirectedType (TypeReference type)
- {
- var typeRefProjection = type.GetElementType ().projection as TypeReferenceProjection;
- return typeRefProjection != null && typeRefProjection.Treatment == TypeReferenceTreatment.UseProjectionInfo;
- }
- static bool NeedsWindowsRuntimePrefix (TypeDefinition type)
- {
- if ((type.Attributes & (TypeAttributes.VisibilityMask | TypeAttributes.Interface)) != TypeAttributes.Public)
- return false;
- var base_type = type.BaseType;
- if (base_type == null || base_type.MetadataToken.TokenType != TokenType.TypeRef)
- return false;
- if (base_type.Namespace == "System")
- switch (base_type.Name)
- {
- case "Attribute":
- case "MulticastDelegate":
- case "ValueType":
- return false;
- }
- return true;
- }
- static bool IsClrImplementationType (TypeDefinition type)
- {
- if ((type.Attributes & (TypeAttributes.VisibilityMask | TypeAttributes.SpecialName)) != TypeAttributes.SpecialName)
- return false;
- return type.Name.StartsWith ("<CLR>");
- }
- public static void ApplyProjection (TypeDefinition type, TypeDefinitionProjection projection)
- {
- if (projection == null)
- return;
- var treatment = projection.Treatment;
- switch (treatment & TypeDefinitionTreatment.KindMask) {
- case TypeDefinitionTreatment.NormalType:
- type.Attributes |= TypeAttributes.WindowsRuntime | TypeAttributes.Import;
- break;
- case TypeDefinitionTreatment.NormalAttribute:
- type.Attributes |= TypeAttributes.WindowsRuntime | TypeAttributes.Sealed;
- break;
- case TypeDefinitionTreatment.UnmangleWindowsRuntimeName:
- type.Attributes = type.Attributes & ~TypeAttributes.SpecialName | TypeAttributes.Public;
- type.Name = type.Name.Substring ("<CLR>".Length);
- break;
- case TypeDefinitionTreatment.PrefixWindowsRuntimeName:
- type.Attributes = type.Attributes & ~TypeAttributes.Public | TypeAttributes.Import;
- type.Name = "<WinRT>" + type.Name;
- break;
- case TypeDefinitionTreatment.RedirectToClrType:
- type.Attributes = type.Attributes & ~TypeAttributes.Public | TypeAttributes.Import;
- break;
- case TypeDefinitionTreatment.RedirectToClrAttribute:
- type.Attributes = type.Attributes & ~TypeAttributes.Public;
- break;
- case TypeDefinitionTreatment.RedirectImplementedMethods: {
- type.Attributes |= TypeAttributes.WindowsRuntime | TypeAttributes.Import;
- foreach (var redirectedInterfacePair in projection.RedirectedInterfaces) {
- type.Interfaces.Add (redirectedInterfacePair.Value);
- foreach (var customAttribute in redirectedInterfacePair.Key.CustomAttributes)
- redirectedInterfacePair.Value.CustomAttributes.Add (customAttribute);
- redirectedInterfacePair.Key.CustomAttributes.Clear ();
- foreach (var method in type.Methods) {
- foreach (var @override in method.Overrides) {
- if (TypeReferenceEqualityComparer.AreEqual (@override.DeclaringType, redirectedInterfacePair.Key.InterfaceType)) {
- @override.DeclaringType = redirectedInterfacePair.Value.InterfaceType;
- }
- }
- }
- }
- foreach (var method in projection.RedirectedMethods) {
- type.Methods.Add (method);
- }
- }
- break;
- }
- if ((treatment & TypeDefinitionTreatment.Abstract) != 0)
- type.Attributes |= TypeAttributes.Abstract;
- if ((treatment & TypeDefinitionTreatment.Internal) != 0)
- type.Attributes &= ~TypeAttributes.Public;
- type.WindowsRuntimeProjection = projection;
- }
- public static TypeDefinitionProjection RemoveProjection (TypeDefinition type)
- {
- if (!type.IsWindowsRuntimeProjection)
- return null;
- var projection = type.WindowsRuntimeProjection;
- type.WindowsRuntimeProjection = null;
- type.Attributes = projection.Attributes;
- type.Name = projection.Name;
- if (projection.Treatment == TypeDefinitionTreatment.RedirectImplementedMethods) {
- foreach (var method in projection.RedirectedMethods) {
- type.Methods.Remove (method);
- }
- foreach (var redirectedInterfacePair in projection.RedirectedInterfaces) {
- foreach (var method in type.Methods) {
- foreach (var @override in method.Overrides) {
- if (TypeReferenceEqualityComparer.AreEqual (@override.DeclaringType, redirectedInterfacePair.Value.InterfaceType)) {
- @override.DeclaringType = redirectedInterfacePair.Key.InterfaceType;
- }
- }
- }
- foreach (var customAttribute in redirectedInterfacePair.Value.CustomAttributes)
- redirectedInterfacePair.Key.CustomAttributes.Add (customAttribute);
- redirectedInterfacePair.Value.CustomAttributes.Clear ();
- type.Interfaces.Remove (redirectedInterfacePair.Value);
- }
- }
- return projection;
- }
- public static void Project (TypeReference type)
- {
- TypeReferenceTreatment treatment;
- ProjectionInfo info;
- if (Projections.TryGetValue (type.Name, out info) && info.WinRTNamespace == type.Namespace)
- treatment = TypeReferenceTreatment.UseProjectionInfo;
- else
- treatment = GetSpecialTypeReferenceTreatment (type);
- if (treatment != TypeReferenceTreatment.None)
- ApplyProjection (type, new TypeReferenceProjection (type, treatment));
- }
- static TypeReferenceTreatment GetSpecialTypeReferenceTreatment (TypeReference type)
- {
- if (type.Namespace == "System") {
- if (type.Name == "MulticastDelegate")
- return TypeReferenceTreatment.SystemDelegate;
- if (type.Name == "Attribute")
- return TypeReferenceTreatment.SystemAttribute;
- }
- return TypeReferenceTreatment.None;
- }
- static bool IsAttribute (TypeReference type)
- {
- if (type.MetadataToken.TokenType != TokenType.TypeRef)
- return false;
- return type.Name == "Attribute" && type.Namespace == "System";
- }
- static bool IsEnum (TypeReference type)
- {
- if (type.MetadataToken.TokenType != TokenType.TypeRef)
- return false;
- return type.Name == "Enum" && type.Namespace == "System";
- }
- public static void ApplyProjection (TypeReference type, TypeReferenceProjection projection)
- {
- if (projection == null)
- return;
- switch (projection.Treatment)
- {
- case TypeReferenceTreatment.SystemDelegate:
- case TypeReferenceTreatment.SystemAttribute:
- type.Scope = type.Module.Projections.GetAssemblyReference ("System.Runtime");
- break;
- case TypeReferenceTreatment.UseProjectionInfo:
- var info = Projections [type.Name];
- type.Name = info.ClrName;
- type.Namespace = info.ClrNamespace;
- type.Scope = type.Module.Projections.GetAssemblyReference (info.ClrAssembly);
- break;
- }
- type.WindowsRuntimeProjection = projection;
- }
- public static TypeReferenceProjection RemoveProjection (TypeReference type)
- {
- if (!type.IsWindowsRuntimeProjection)
- return null;
- var projection = type.WindowsRuntimeProjection;
- type.WindowsRuntimeProjection = null;
- type.Name = projection.Name;
- type.Namespace = projection.Namespace;
- type.Scope = projection.Scope;
- return projection;
- }
- public static void Project (MethodDefinition method)
- {
- var treatment = MethodDefinitionTreatment.None;
- var other = false;
- var declaring_type = method.DeclaringType;
- if (declaring_type.IsWindowsRuntime)
- {
- if (IsClrImplementationType (declaring_type))
- treatment = MethodDefinitionTreatment.None;
- else if (declaring_type.IsNested)
- treatment = MethodDefinitionTreatment.None;
- else if (declaring_type.IsInterface)
- treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.InternalCall;
- else if (declaring_type.Module.MetadataKind == MetadataKind.ManagedWindowsMetadata && !method.IsPublic)
- treatment = MethodDefinitionTreatment.None;
- else
- {
- other = true;
- var base_type = declaring_type.BaseType;
- if (base_type != null && base_type.MetadataToken.TokenType == TokenType.TypeRef)
- {
- switch (GetSpecialTypeReferenceTreatment(base_type))
- {
- case TypeReferenceTreatment.SystemDelegate:
- treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.Public;
- other = false;
- break;
- case TypeReferenceTreatment.SystemAttribute:
- treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.InternalCall;
- other = false;
- break;
- }
- }
- }
- }
- if (other)
- {
- var seen_redirected = false;
- var seen_non_redirected = false;
- foreach (var @override in method.Overrides) {
- if (@override.MetadataToken.TokenType == TokenType.MemberRef && ImplementsRedirectedInterface (@override)) {
- seen_redirected = true;
- } else {
- seen_non_redirected = true;
- }
- }
- if (seen_redirected && !seen_non_redirected) {
- treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.InternalCall | MethodDefinitionTreatment.Private;
- other = false;
- }
- }
- if (other)
- treatment |= GetMethodDefinitionTreatmentFromCustomAttributes(method);
- if (treatment != MethodDefinitionTreatment.None)
- ApplyProjection (method, new MethodDefinitionProjection (method, treatment));
- }
- static MethodDefinitionTreatment GetMethodDefinitionTreatmentFromCustomAttributes(MethodDefinition method)
- {
- var treatment = MethodDefinitionTreatment.None;
- foreach (var attribute in method.CustomAttributes)
- {
- var type = attribute.AttributeType;
- if (type.Namespace != "Windows.UI.Xaml")
- continue;
- if (type.Name == "TreatAsPublicMethodAttribute")
- treatment |= MethodDefinitionTreatment.Public;
- else if (type.Name == "TreatAsAbstractMethodAttribute")
- treatment |= MethodDefinitionTreatment.Abstract;
- }
- return treatment;
- }
- public static void ApplyProjection (MethodDefinition method, MethodDefinitionProjection projection)
- {
- if (projection == null)
- return;
- var treatment = projection.Treatment;
- if ((treatment & MethodDefinitionTreatment.Abstract) != 0)
- method.Attributes |= MethodAttributes.Abstract;
- if ((treatment & MethodDefinitionTreatment.Private) != 0)
- method.Attributes = (method.Attributes & ~MethodAttributes.MemberAccessMask) | MethodAttributes.Private;
- if ((treatment & MethodDefinitionTreatment.Public) != 0)
- method.Attributes = (method.Attributes & ~MethodAttributes.MemberAccessMask) | MethodAttributes.Public;
- if ((treatment & MethodDefinitionTreatment.Runtime) != 0)
- method.ImplAttributes |= MethodImplAttributes.Runtime;
- if ((treatment & MethodDefinitionTreatment.InternalCall) != 0)
- method.ImplAttributes |= MethodImplAttributes.InternalCall;
- method.WindowsRuntimeProjection = projection;
- }
- public static MethodDefinitionProjection RemoveProjection (MethodDefinition method)
- {
- if (!method.IsWindowsRuntimeProjection)
- return null;
- var projection = method.WindowsRuntimeProjection;
- method.WindowsRuntimeProjection = null;
- method.Attributes = projection.Attributes;
- method.ImplAttributes = projection.ImplAttributes;
- method.Name = projection.Name;
- return projection;
- }
- public static void Project (FieldDefinition field)
- {
- var treatment = FieldDefinitionTreatment.None;
- var declaring_type = field.DeclaringType;
- if (declaring_type.Module.MetadataKind == MetadataKind.WindowsMetadata && field.IsRuntimeSpecialName && field.Name == "value__") {
- var base_type = declaring_type.BaseType;
- if (base_type != null && IsEnum (base_type))
- treatment = FieldDefinitionTreatment.Public;
- }
- if (treatment != FieldDefinitionTreatment.None)
- ApplyProjection (field, new FieldDefinitionProjection (field, treatment));
- }
- public static void ApplyProjection (FieldDefinition field, FieldDefinitionProjection projection)
- {
- if (projection == null)
- return;
- if (projection.Treatment == FieldDefinitionTreatment.Public)
- field.Attributes = (field.Attributes & ~FieldAttributes.FieldAccessMask) | FieldAttributes.Public;
- field.WindowsRuntimeProjection = projection;
- }
- public static FieldDefinitionProjection RemoveProjection (FieldDefinition field)
- {
- if (!field.IsWindowsRuntimeProjection)
- return null;
- var projection = field.WindowsRuntimeProjection;
- field.WindowsRuntimeProjection = null;
- field.Attributes = projection.Attributes;
- return projection;
- }
- static bool ImplementsRedirectedInterface (MemberReference member)
- {
- var declaring_type = member.DeclaringType;
- TypeReference type;
- switch (declaring_type.MetadataToken.TokenType) {
- case TokenType.TypeRef:
- type = declaring_type;
- break;
- case TokenType.TypeSpec:
- if (!declaring_type.IsGenericInstance)
- return false;
- type = ((TypeSpecification) declaring_type).ElementType;
- if (type.MetadataType != MetadataType.Class || type.MetadataToken.TokenType != TokenType.TypeRef)
- return false;
- break;
- default:
- return false;
- }
- var projection = RemoveProjection (type);
- var found = false;
- ProjectionInfo info;
- if (Projections.TryGetValue (type.Name, out info) && type.Namespace == info.WinRTNamespace) {
- found = true;
- }
- ApplyProjection (type, projection);
- return found;
- }
- public void AddVirtualReferences (Collection<AssemblyNameReference> references)
- {
- var corlib = GetCoreLibrary (references);
- corlib_version = corlib.Version;
- corlib.Version = version;
- if (virtual_references == null) {
- var winrt_references = GetAssemblyReferences (corlib);
- Interlocked.CompareExchange (ref virtual_references, winrt_references, null);
- }
- foreach (var reference in virtual_references)
- references.Add (reference);
- }
- public void RemoveVirtualReferences (Collection<AssemblyNameReference> references)
- {
- var corlib = GetCoreLibrary (references);
- corlib.Version = corlib_version;
- foreach (var reference in VirtualReferences)
- references.Remove (reference);
- }
- static AssemblyNameReference[] GetAssemblyReferences (AssemblyNameReference corlib)
- {
- var system_runtime = new AssemblyNameReference ("System.Runtime", version);
- var system_runtime_interopservices_windowsruntime = new AssemblyNameReference ("System.Runtime.InteropServices.WindowsRuntime", version);
- var system_objectmodel = new AssemblyNameReference ("System.ObjectModel", version);
- var system_runtime_windowsruntime = new AssemblyNameReference ("System.Runtime.WindowsRuntime", version);
- var system_runtime_windowsruntime_ui_xaml = new AssemblyNameReference ("System.Runtime.WindowsRuntime.UI.Xaml", version);
- var system_numerics_vectors = new AssemblyNameReference ("System.Numerics.Vectors", version);
- if (corlib.HasPublicKey) {
- system_runtime_windowsruntime.PublicKey =
- system_runtime_windowsruntime_ui_xaml.PublicKey = corlib.PublicKey;
- system_runtime.PublicKey =
- system_runtime_interopservices_windowsruntime.PublicKey =
- system_objectmodel.PublicKey =
- system_numerics_vectors.PublicKey = contract_pk;
- }
- else {
- system_runtime_windowsruntime.PublicKeyToken =
- system_runtime_windowsruntime_ui_xaml.PublicKeyToken = corlib.PublicKeyToken;
- system_runtime.PublicKeyToken =
- system_runtime_interopservices_windowsruntime.PublicKeyToken =
- system_objectmodel.PublicKeyToken =
- system_numerics_vectors.PublicKeyToken = contract_pk_token;
- }
- return new[] {
- system_runtime,
- system_runtime_interopservices_windowsruntime,
- system_objectmodel,
- system_runtime_windowsruntime,
- system_runtime_windowsruntime_ui_xaml,
- system_numerics_vectors,
- };
- }
- static AssemblyNameReference GetCoreLibrary (Collection<AssemblyNameReference> references)
- {
- foreach (var reference in references)
- if (reference.Name == "mscorlib")
- return reference;
- throw new BadImageFormatException ("Missing mscorlib reference in AssemblyRef table.");
- }
- AssemblyNameReference GetAssemblyReference (string name)
- {
- foreach (var assembly in VirtualReferences)
- if (assembly.Name == name)
- return assembly;
- throw new Exception ();
- }
- public static void Project (ICustomAttributeProvider owner, CustomAttribute attribute)
- {
- if (!IsWindowsAttributeUsageAttribute (owner, attribute))
- return;
- var treatment = CustomAttributeValueTreatment.None;
- var type = (TypeDefinition) owner;
- if (type.Namespace == "Windows.Foundation.Metadata") {
- if (type.Name == "VersionAttribute")
- treatment = CustomAttributeValueTreatment.VersionAttribute;
- else if (type.Name == "DeprecatedAttribute")
- treatment = CustomAttributeValueTreatment.DeprecatedAttribute;
- }
- if (treatment == CustomAttributeValueTreatment.None) {
- var multiple = HasAttribute (type, "Windows.Foundation.Metadata", "AllowMultipleAttribute");
- treatment = multiple ? CustomAttributeValueTreatment.AllowMultiple : CustomAttributeValueTreatment.AllowSingle;
- }
- if (treatment != CustomAttributeValueTreatment.None) {
- var attribute_targets = (AttributeTargets) attribute.ConstructorArguments [0].Value;
- ApplyProjection (attribute, new CustomAttributeValueProjection (attribute_targets, treatment));
- }
- }
- static bool IsWindowsAttributeUsageAttribute (ICustomAttributeProvider owner, CustomAttribute attribute)
- {
- if (owner.MetadataToken.TokenType != TokenType.TypeDef)
- return false;
- var constructor = attribute.Constructor;
- if (constructor.MetadataToken.TokenType != TokenType.MemberRef)
- return false;
- var declaring_type = constructor.DeclaringType;
- if (declaring_type.MetadataToken.TokenType != TokenType.TypeRef)
- return false;
- // declaring type is already projected
- return declaring_type.Name == "AttributeUsageAttribute" && declaring_type.Namespace == /*"Windows.Foundation.Metadata"*/"System";
- }
- static bool HasAttribute (TypeDefinition type, string @namespace, string name)
- {
- foreach (var attribute in type.CustomAttributes) {
- var attribute_type = attribute.AttributeType;
- if (attribute_type.Name == name && attribute_type.Namespace == @namespace)
- return true;
- }
- return false;
- }
- public static void ApplyProjection (CustomAttribute attribute, CustomAttributeValueProjection projection)
- {
- if (projection == null)
- return;
- bool version_or_deprecated;
- bool multiple;
- switch (projection.Treatment) {
- case CustomAttributeValueTreatment.AllowSingle:
- version_or_deprecated = false;
- multiple = false;
- break;
- case CustomAttributeValueTreatment.AllowMultiple:
- version_or_deprecated = false;
- multiple = true;
- break;
- case CustomAttributeValueTreatment.VersionAttribute:
- case CustomAttributeValueTreatment.DeprecatedAttribute:
- version_or_deprecated = true;
- multiple = true;
- break;
- default:
- throw new ArgumentException ();
- }
- var attribute_targets = (AttributeTargets) attribute.ConstructorArguments [0].Value;
- if (version_or_deprecated)
- attribute_targets |= AttributeTargets.Constructor | AttributeTargets.Property;
- attribute.ConstructorArguments [0] = new CustomAttributeArgument (attribute.ConstructorArguments [0].Type, attribute_targets);
- attribute.Properties.Add (new CustomAttributeNamedArgument ("AllowMultiple", new CustomAttributeArgument (attribute.Module.TypeSystem.Boolean, multiple)));
- attribute.projection = projection;
- }
- public static CustomAttributeValueProjection RemoveProjection (CustomAttribute attribute)
- {
- if (attribute.projection == null)
- return null;
- var projection = attribute.projection;
- attribute.projection = null;
- attribute.ConstructorArguments [0] = new CustomAttributeArgument (attribute.ConstructorArguments [0].Type, projection.Targets);
- attribute.Properties.Clear ();
- return projection;
- }
- }
- }
|