IXamlIlType LookupConverter(IXamlIlType type)
 {
     foreach (var p in _converters)
     {
         if (p.Key.Equals(type))
         {
             return(p.Value);
         }
     }
     if (type.GenericTypeDefinition?.Equals(_avaloniaList) == true)
     {
         return(_avaloniaListConverter.MakeGenericType(type.GenericArguments[0]));
     }
     return(null);
 }
示例#2
0
        public XamlIlContext(IXamlIlType definition, IXamlIlType constructedType,
                             Action <XamlIlContext, IXamlIlEmitter> factory)
        {
            ContextType = definition.MakeGenericType(constructedType);

            IXamlIlField Get(string s) =>
            ContextType.Fields.FirstOrDefault(f => f.Name == s);

            IXamlIlMethod GetMethod(string s) =>
            ContextType.Methods.FirstOrDefault(f => f.Name == s);

            RootObjectField        = Get(XamlIlContextDefinition.RootObjectFieldName);
            ParentListField        = Get(XamlIlContextDefinition.ParentListFieldName);
            PropertyTargetObject   = Get(XamlIlContextDefinition.ProvideTargetObjectName);
            PropertyTargetProperty = Get(XamlIlContextDefinition.ProvideTargetPropertyName);
            PushParentMethod       = GetMethod(XamlIlContextDefinition.PushParentMethodName);
            PopParentMethod        = GetMethod(XamlIlContextDefinition.PopParentMethodName);
            Constructor            = ContextType.Constructors.First();
            Factory = il => factory(this, il);
        }
        public static IXamlIlType ResolveType(XamlIlAstTransformationContext context,
                                              string xmlns, string name, List <XamlIlAstXmlTypeReference> typeArguments, IXamlIlLineInfo lineInfo,
                                              bool strict)
        {
            var targs = typeArguments
                        .Select(ta => ResolveType(context, ta.XmlNamespace, ta.Name, ta.GenericArguments, lineInfo, strict))
                        .ToList();

            IXamlIlType Attempt(Func <string, IXamlIlType> cb, string xname)
            {
                var suffix = (typeArguments.Count != 0) ? ("`" + typeArguments.Count) : "";

                return(cb(xname + "Extension" + suffix) ?? cb(xname + suffix));
            }

            IXamlIlType found = null;

            // Try to resolve from system
            if (xmlns == XamlNamespaces.Xaml2006)
            {
                found = context.Configuration.TypeSystem.FindType("System." + name);
            }


            if (found == null)
            {
                var resolvedNamespaces = XamlIlNamespaceInfoHelper.TryResolve(context.Configuration, xmlns);
                if (resolvedNamespaces?.Count > 0)
                {
                    found = Attempt(formedName =>
                    {
                        foreach (var resolvedNs in resolvedNamespaces)
                        {
                            var rname = resolvedNs.ClrNamespace + "." + formedName;
                            IXamlIlType subRes;
                            if (resolvedNs.Assembly != null)
                            {
                                subRes = resolvedNs.Assembly.FindType(rname);
                            }
                            else
                            {
                                subRes = context.Configuration.TypeSystem.FindType(rname, resolvedNs.AssemblyName);
                            }
                            if (subRes != null)
                            {
                                return(subRes);
                            }
                        }

                        return(null);
                    }, name);
                }
            }

            if (typeArguments.Count != 0)
            {
                found = found?.MakeGenericType(targs);
            }
            if (found != null)
            {
                return(found);
            }
            if (strict)
            {
                throw new XamlIlParseException(
                          $"Unable to resolve type {name} from namespace {xmlns}", lineInfo);
            }
            return(null);
        }
示例#4
0
 public static IXamlIlType MakeGenericType(this IXamlIlType type, params IXamlIlType[] typeArguments)
 => type.MakeGenericType(typeArguments);
        IXamlIlType ResolveType(XamlIlAstTransformationContext context,
                                string xmlns, string name, List <XamlIlAstXmlTypeReference> typeArguments, IXamlIlLineInfo lineInfo)
        {
            var targs = typeArguments
                        .Select(ta => ResolveType(context, ta.XmlNamespace, ta.Name, ta.GenericArguments, lineInfo))
                        .ToList();


            const string clrNamespace       = "clr-namespace:";
            const string assemblyNamePrefix = ";assembly=";

            IXamlIlType Attempt(Func <string, IXamlIlType> cb, string xname)
            {
                var suffix = (typeArguments.Count != 0) ? ("`" + typeArguments.Count) : "";

                return(cb(xname + suffix) ?? cb(xname + "Extension" + suffix));
            }

            IXamlIlType found = null;

            // Try to resolve from system
            if (xmlns == XamlNamespaces.Xaml2006)
            {
                found = context.Configuration.TypeSystem.FindType("System." + name);
            }

            // Try registered xmlns
            if (found == null && context.Configuration.XmlnsMappings.Namespaces.TryGetValue(xmlns, out var lst))
            {
                foreach (var pair in lst)
                {
                    found = Attempt(pair.asm.FindType, pair.ns + "." + name);
                    if (found != null)
                    {
                        break;
                    }
                }
            }

            // Try to resolve from clr-namespace
            if (found == null && xmlns.StartsWith(clrNamespace))
            {
                var ns = xmlns.Substring(clrNamespace.Length);

                // We are completely ignoring `;assembly=` part because of type forwarding shenanigans with
                // netstandard and .NET Core

                var indexOfAssemblyPrefix = ns.IndexOf(assemblyNamePrefix, StringComparison.Ordinal);
                if (indexOfAssemblyPrefix != -1)
                {
                    ns = ns.Substring(0, indexOfAssemblyPrefix);
                }

                found = Attempt(context.Configuration.TypeSystem.FindType, $"{ns}.{name}");
            }
            if (typeArguments.Count != 0)
            {
                found = found?.MakeGenericType(targs);
            }
            if (found != null)
            {
                return(found);
            }
            if (context.StrictMode)
            {
                throw new XamlIlParseException(
                          $"Unable to resolve type {name} from namespace {xmlns}", lineInfo);
            }
            return(null);
        }