private TypeReference(string originalString, TypeReferenceResolver resolveThunk) { if (resolveThunk == null) { throw new ArgumentNullException("resolveThunk"); } _resolveThunk = new CacheTypeReferenceResolver(resolveThunk); _originalString = originalString; }
public void PrepareForCompletion( TypeReferenceResolver typeReferenceResolver, Func <ISchema> schemaResolver, List <FieldMiddleware> globalComponents, IsOfTypeFallback?isOfType) { _typeReferenceResolver = typeReferenceResolver; _schemaResolver = schemaResolver; GlobalComponents = globalComponents; IsOfType = isOfType; }
public static IXamlIlAvaloniaPropertyNode CreateNode(AstTransformationContext context, string propertyName, IXamlAstTypeReference selectorTypeReference, IXamlLineInfo lineInfo) { XamlAstNamePropertyReference forgedReference; var parser = new PropertyParser(); var parsedPropertyName = parser.Parse(new CharacterReader(propertyName.AsSpan())); if (parsedPropertyName.owner == null) { forgedReference = new XamlAstNamePropertyReference(lineInfo, selectorTypeReference, propertyName, selectorTypeReference); } else { var xmlOwner = parsedPropertyName.ns; if (xmlOwner != null) { xmlOwner += ":"; } xmlOwner += parsedPropertyName.owner; var tref = TypeReferenceResolver.ResolveType(context, xmlOwner, false, lineInfo, true); var propertyFieldName = parsedPropertyName.name + "Property"; var found = tref.Type.GetAllFields() .FirstOrDefault(f => f.IsStatic && f.IsPublic && f.Name == propertyFieldName); if (found == null) { throw new XamlX.XamlParseException( $"Unable to find {propertyFieldName} field on type {tref.Type.GetFullName()}", lineInfo); } return(new XamlIlAvaloniaPropertyFieldNode(context.GetAvaloniaTypes(), lineInfo, found)); } var clrProperty = ((XamlAstClrProperty) new PropertyReferenceResolver().Transform(context, forgedReference)); return(new XamlIlAvaloniaPropertyNode(lineInfo, context.Configuration.TypeSystem.GetType("Avalonia.AvaloniaProperty"), clrProperty)); }
public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { if (!(node is XamlAstObjectNode on && on.Type.GetClrType().FullName == "Avalonia.Styling.ControlTheme")) { return(node); } // Check if we've already transformed this node. if (context.ParentNodes().FirstOrDefault() is AvaloniaXamlIlTargetTypeMetadataNode) { return(node); } var targetTypeNode = on.Children.OfType <XamlAstXamlPropertyValueNode>() .FirstOrDefault(p => p.Property.GetClrProperty().Name == "TargetType") ?? throw new XamlParseException("ControlTheme must have a TargetType.", node); IXamlType targetType; if (targetTypeNode.Values[0] is XamlTypeExtensionNode extension) { targetType = extension.Value.GetClrType(); } else if (targetTypeNode.Values[0] is XamlAstTextNode text) { targetType = TypeReferenceResolver.ResolveType(context, text.Text, false, text, true).GetClrType(); } else { throw new XamlParseException("Could not determine TargetType for ControlTheme.", targetTypeNode); } return(new AvaloniaXamlIlTargetTypeMetadataNode(on, new XamlAstClrTypeReference(targetTypeNode, targetType, false), AvaloniaXamlIlTargetTypeMetadataNode.ScopeTypes.Style)); }
private static BindingExpressionGrammar.INode ConvertLongFormPropertiesToBindingExpressionNode( AstTransformationContext context, XamlAstObjectNode binding) { BindingExpressionGrammar.INode convertedNode = null; var syntheticCompiledBindingProperties = binding.Children.OfType <XamlAstXamlPropertyValueNode>() .Where(v => v.Property is AvaloniaSyntheticCompiledBindingProperty) .ToList(); var elementNameProperty = syntheticCompiledBindingProperties .FirstOrDefault(v => v.Property is AvaloniaSyntheticCompiledBindingProperty prop && prop.Name == SyntheticCompiledBindingPropertyName.ElementName); var sourceProperty = syntheticCompiledBindingProperties .FirstOrDefault(v => v.Property is AvaloniaSyntheticCompiledBindingProperty prop && prop.Name == SyntheticCompiledBindingPropertyName.Source); var relativeSourceProperty = syntheticCompiledBindingProperties .FirstOrDefault(v => v.Property is AvaloniaSyntheticCompiledBindingProperty prop && prop.Name == SyntheticCompiledBindingPropertyName.RelativeSource); if (elementNameProperty?.Values[0] is XamlAstTextNode elementName) { convertedNode = new BindingExpressionGrammar.NameNode { Name = elementName.Text }; } else if (elementNameProperty != null) { throw new XamlParseException($"Invalid ElementName '{elementNameProperty.Values[0]}'.", elementNameProperty.Values[0]); } if (sourceProperty?.Values[0] != null) { if (convertedNode != null) { throw new XamlParseException("Only one of ElementName, Source, or RelativeSource specified as a binding source. Only one property is allowed.", binding); } convertedNode = new RawSourceBindingExpressionNode(sourceProperty?.Values[0]); } if (GetRelativeSourceObjectFromAssignment( context, relativeSourceProperty, out var relativeSourceObject)) { if (convertedNode != null) { throw new XamlParseException("Only one of ElementName, Source, or RelativeSource specified as a binding source. Only one property is allowed.", binding); } var mode = relativeSourceObject.Children .OfType <XamlAstXamlPropertyValueNode>() .FirstOrDefault(x => x.Property.GetClrProperty().Name == "Mode") ?.Values[0] is XamlAstTextNode modeAssignedValue ? modeAssignedValue.Text : null; if (relativeSourceObject.Arguments.Count == 0 && mode == null) { mode = "FindAncestor"; } if (mode == "FindAncestor") { var ancestorLevel = relativeSourceObject.Children .OfType <XamlAstXamlPropertyValueNode>() .FirstOrDefault(x => x.Property.GetClrProperty().Name == "FindAncestor") ?.Values[0] is XamlAstTextNode ancestorLevelText?int.Parse(ancestorLevelText.Text) - 1 : 0; var treeType = relativeSourceObject.Children .OfType <XamlAstXamlPropertyValueNode>() .FirstOrDefault(x => x.Property.GetClrProperty().Name == "Tree") ?.Values[0] is XamlAstTextNode treeTypeValue ? treeTypeValue.Text : "Visual"; var ancestorTypeName = relativeSourceObject.Children .OfType <XamlAstXamlPropertyValueNode>() .FirstOrDefault(x => x.Property.GetClrProperty().Name == "AncestorType") ?.Values[0] as XamlAstTextNode; IXamlType ancestorType = null; if (ancestorTypeName is null) { if (treeType == "Visual") { throw new XamlParseException("AncestorType must be set for RelativeSourceMode.FindAncestor when searching the visual tree.", relativeSourceObject); } else if (treeType == "Logical") { var styledElementType = context.GetAvaloniaTypes().StyledElement; ancestorType = context .ParentNodes() .OfType <XamlAstObjectNode>() .Where(x => styledElementType.IsAssignableFrom(x.Type.GetClrType())) .ElementAtOrDefault(ancestorLevel) ?.Type.GetClrType(); if (ancestorType is null) { throw new XamlX.XamlParseException("Unable to resolve implicit ancestor type based on XAML tree.", relativeSourceObject); } } } else { ancestorType = TypeReferenceResolver.ResolveType( context, ancestorTypeName.Text, false, ancestorTypeName, true).GetClrType(); } if (treeType == "Visual") { convertedNode = new VisualAncestorBindingExpressionNode { Type = ancestorType, Level = ancestorLevel }; } else if (treeType == "Logical") { convertedNode = new LogicalAncestorBindingExpressionNode { Type = ancestorType, Level = ancestorLevel }; } else { throw new XamlParseException($"Unknown tree type '{treeType}'.", binding); } } else if (mode == "DataContext") { convertedNode = null; } else if (mode == "Self") { convertedNode = new BindingExpressionGrammar.SelfNode(); } else if (mode == "TemplatedParent") { var parentType = context.ParentNodes().OfType <AvaloniaXamlIlTargetTypeMetadataNode>() .FirstOrDefault(x => x.ScopeType == AvaloniaXamlIlTargetTypeMetadataNode.ScopeTypes.ControlTemplate) ?.TargetType.GetClrType(); if (parentType is null) { throw new XamlParseException("A binding with a TemplatedParent RelativeSource has to be in a ControlTemplate.", binding); } convertedNode = new TemplatedParentBindingExpressionNode { Type = parentType }; } else { throw new XamlParseException($"Unknown RelativeSource mode '{mode}'.", binding); } } if (elementNameProperty != null) { binding.Children.Remove(elementNameProperty); } if (sourceProperty != null) { binding.Children.Remove(sourceProperty); } if (relativeSourceProperty != null) { binding.Children.Remove(relativeSourceProperty); } return(convertedNode); }
public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { if (context.ParentNodes().FirstOrDefault() is AvaloniaXamlIlDataContextTypeMetadataNode) { // We've already resolved the data context type for this node. return(node); } if (node is XamlAstConstructableObjectNode on) { AvaloniaXamlIlDataContextTypeMetadataNode inferredDataContextTypeNode = null; AvaloniaXamlIlDataContextTypeMetadataNode directiveDataContextTypeNode = null; bool isDataTemplate = on.Type.GetClrType().Equals(context.GetAvaloniaTypes().DataTemplate); for (int i = 0; i < on.Children.Count; ++i) { var child = on.Children[i]; if (child is XamlAstXmlDirective directive) { if (directive.Namespace == XamlNamespaces.Xaml2006 && directive.Name == "DataType" && directive.Values.Count == 1) { on.Children.RemoveAt(i); i--; if (directive.Values[0] is XamlAstTextNode text) { directiveDataContextTypeNode = new AvaloniaXamlIlDataContextTypeMetadataNode(on, TypeReferenceResolver.ResolveType(context, text.Text, isMarkupExtension: false, text, strict: true).Type); } else { throw new XamlX.XamlParseException("x:DataType should be set to a type name.", directive.Values[0]); } } } else if (child is XamlPropertyAssignmentNode pa) { if (pa.Property.Name == "DataContext" && pa.Property.DeclaringType.Equals(context.GetAvaloniaTypes().StyledElement) && pa.Values[0] is XamlMarkupExtensionNode ext && ext.Value is XamlAstConstructableObjectNode obj) { inferredDataContextTypeNode = ParseDataContext(context, on, obj); } else if (isDataTemplate && pa.Property.Name == "DataType" && pa.Values[0] is XamlTypeExtensionNode dataTypeNode) { inferredDataContextTypeNode = new AvaloniaXamlIlDataContextTypeMetadataNode(on, dataTypeNode.Value.GetClrType()); } } } // If there is no x:DataType directive, // do more specialized inference if (directiveDataContextTypeNode is null) { if (isDataTemplate && inferredDataContextTypeNode is null) { // Infer data type from collection binding on a control that displays items. var parentObject = context.ParentNodes().OfType <XamlAstConstructableObjectNode>().FirstOrDefault(); if (parentObject != null && context.GetAvaloniaTypes().IItemsPresenterHost.IsDirectlyAssignableFrom(parentObject.Type.GetClrType())) { inferredDataContextTypeNode = InferDataContextOfPresentedItem(context, on, parentObject); } else { inferredDataContextTypeNode = new AvaloniaXamlIlUninferrableDataContextMetadataNode(on); } } } return(directiveDataContextTypeNode ?? inferredDataContextTypeNode ?? node); }
public MetadataSystem(MetadataReader reader) { _reader = reader; _entryPoint = new Lazy <MethodDefinition>(() => GetMethodDefinition(_reader.EntryPoint.RID)); _assembly = new Lazy <AssemblyDefinition>(() => AssemblyDefinitionResolver.Resolve(_reader.AssemblyTable.Row, this)); _module = new Lazy <ModuleDefinition>(() => ModuleDefinitionResolver.Resolve(_reader.ModuleTable.Row, this)); _assemblyRefs = new Lazy <AssemblyReference[]>(() => _reader.AssemblyRefTable .Select((row, id) => AssemblyReferenceResolver.Resolve((uint)(id + 1), row, this)) .ToArray(_reader.AssemblyRefTable.Length)); _types = new Lazy <TypeDefinition[]>(() => _reader.TypeDefTable .Select((row, id) => TypeDefinitionResolver.Resolve((uint)(id + 1), row, this)) .ToArray(_reader.TypeDefTable.Length)); _methods = new Lazy <MethodDefinition[]>(() => _types.Value.SelectMany(type => type.Methods) .ToArray(_reader.MethodTable.Length)); _fields = new Lazy <FieldDefinition[]>(() => _types.Value.SelectMany(type => type.Fields) .ToArray(_reader.FieldTable.Length)); _typeRefLookup = new Lazy <ILookup <MetadataToken, TypeReference> >(() => _reader.TypeRefTable.ToLookup(row => row.ResolutionScope, row => TypeReferenceResolver.Resolve(row, this))); _memberRefLookup = new Lazy <ILookup <MetadataToken, IMemberReference> >(() => _reader.MemberRefTable.ToLookup(row => row.Class, row => MemberReferenceResolver.Resolve(row, this))); _attributeLookup = new Lazy <ILookup <MetadataToken, CustomAttribute> >(() => _reader.CustomAttributeTable.ToLookup(row => row.Parent, row => CustomAttributeResolver.Resolve(row, this))); _typeRefs = new Lazy <TypeReference[]>(() => _typeRefLookup.Value.SelectMany(items => items) .ToArray(_reader.TypeRefTable.Length)); _memberRefs = new Lazy <IMemberReference[]>(() => _memberRefLookup.Value.SelectMany(items => items) .ToArray(_reader.MemberRefTable.Length)); _attributes = new Lazy <CustomAttribute[]>(() => _attributeLookup.Value.SelectMany(items => items) .ToArray(_reader.CustomAttributeTable.Length)); _enclosingTypeMapping = new Lazy <Dictionary <MetadataToken, ITypeInfo> >(() => _reader.NestedClassTable.ToDictionary( row => row.NestedClass, row => GetTypeInfo(row.EnclosingClass))); }
public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { if (node is XamlAstXamlPropertyValueNode pv && pv.Values.Count == 1 && pv.Values[0] is XamlAstTextNode text && pv.Property.GetClrProperty().Getter?.ReturnType .Equals(context.GetAvaloniaTypes().PropertyPath) == true ) { var parentScope = context.ParentNodes().OfType <AvaloniaXamlIlTargetTypeMetadataNode>() .FirstOrDefault(); if (parentScope == null) { throw new XamlX.XamlParseException("No target type scope found for property path", text); } if (parentScope.ScopeType != AvaloniaXamlIlTargetTypeMetadataNode.ScopeTypes.Style) { throw new XamlX.XamlParseException("PropertyPath is currently only valid for styles", pv); } IEnumerable <PropertyPathGrammar.ISyntax> parsed; try { parsed = PropertyPathGrammar.Parse(text.Text); } catch (Exception e) { throw new XamlX.XamlParseException("Unable to parse PropertyPath: " + e.Message, text); } var elements = new List <IXamlIlPropertyPathElementNode>(); IXamlType currentType = parentScope.TargetType.GetClrType(); var expectProperty = true; var expectCast = true; var expectTraversal = false; var types = context.GetAvaloniaTypes(); IXamlType GetType(string ns, string name) { return(TypeReferenceResolver.ResolveType(context, $"{ns}:{name}", false, text, true).GetClrType()); } void HandleProperty(string name, string typeNamespace, string typeName) { if (!expectProperty || currentType == null) { throw new XamlX.XamlParseException("Unexpected property node", text); } var propertySearchType = typeName != null?GetType(typeNamespace, typeName) : currentType; IXamlIlPropertyPathElementNode prop = null; var avaloniaPropertyFieldName = name + "Property"; var avaloniaPropertyField = propertySearchType.GetAllFields().FirstOrDefault(f => f.IsStatic && f.IsPublic && f.Name == avaloniaPropertyFieldName); if (avaloniaPropertyField != null) { prop = new XamlIlAvaloniaPropertyPropertyPathElementNode(avaloniaPropertyField, XamlIlAvaloniaPropertyHelper.GetAvaloniaPropertyType(avaloniaPropertyField, types, text)); } else { var clrProperty = propertySearchType.GetAllProperties().FirstOrDefault(p => p.Name == name); prop = new XamlIClrPropertyPathElementNode(clrProperty); } if (prop == null) { throw new XamlX.XamlParseException( $"Unable to resolve property {name} on type {propertySearchType.GetFqn()}", text); } currentType = prop.Type; elements.Add(prop); expectProperty = false; expectTraversal = expectCast = true; } foreach (var ge in parsed) { if (ge is PropertyPathGrammar.ChildTraversalSyntax) { if (!expectTraversal) { throw new XamlX.XamlParseException("Unexpected child traversal .", text); } elements.Add(new XamlIlChildTraversalPropertyPathElementNode()); expectTraversal = expectCast = false; expectProperty = true; } else if (ge is PropertyPathGrammar.EnsureTypeSyntax ets) { if (!expectCast) { throw new XamlX.XamlParseException("Unexpected cast node", text); } currentType = GetType(ets.TypeNamespace, ets.TypeName); elements.Add(new XamlIlCastPropertyPathElementNode(currentType, true)); expectProperty = false; expectCast = expectTraversal = true; } else if (ge is PropertyPathGrammar.CastTypeSyntax cts) { if (!expectCast) { throw new XamlX.XamlParseException("Unexpected cast node", text); } //TODO: Check if cast can be done currentType = GetType(cts.TypeNamespace, cts.TypeName); elements.Add(new XamlIlCastPropertyPathElementNode(currentType, false)); expectProperty = false; expectCast = expectTraversal = true; } else if (ge is PropertyPathGrammar.PropertySyntax ps) { HandleProperty(ps.Name, null, null); } else if (ge is PropertyPathGrammar.TypeQualifiedPropertySyntax tqps) { HandleProperty(tqps.Name, tqps.TypeNamespace, tqps.TypeName); } else { throw new XamlX.XamlParseException("Unexpected node " + ge, text); } } var propertyPathNode = new XamlIlPropertyPathNode(text, elements, types); if (propertyPathNode.Type == null) { throw new XamlX.XamlParseException("Unexpected end of the property path", text); } pv.Values[0] = propertyPathNode; } return(node); }
public static bool TryConvertValue(AstTransformationContext context, IXamlAstValueNode node, IXamlType type, XamlAstClrProperty propertyContext, out IXamlAstValueNode rv) { rv = null; var cfg = context.Configuration; // Since we are doing a conversion anyway, it makes sense to check for the underlying nullable type if (type.GenericTypeDefinition?.Equals(cfg.WellKnownTypes.NullableT) == true) { type = type.GenericArguments[0]; } if (cfg.CustomValueConverter?.Invoke(context, node, type, out rv) == true) { return(true); } var nodeType = node.Type.GetClrType(); // Implicit type converters if (!nodeType.Equals(cfg.WellKnownTypes.String)) { return(false); } if (node is XamlAstTextNode tn) { if (type.IsEnum) { if (TypeSystemHelpers.TryGetEnumValueNode(type, tn.Text, tn, out var enumConstantNode)) { rv = enumConstantNode; return(true); } } // Well known types if (TypeSystemHelpers.ParseConstantIfTypeAllows(tn.Text, type, tn, out var constantNode)) { rv = constantNode; return(true); } if (type.FullName == "System.Type") { var resolvedType = TypeReferenceResolver.ResolveType(context, tn.Text, false, tn, true); rv = new XamlTypeExtensionNode(tn, resolvedType, type); return(true); } if (cfg.WellKnownTypes.Delegate.IsAssignableFrom(type)) { var invoke = type.FindMethod(m => m.Name == "Invoke"); var rootType = context.RootObject.Type.GetClrType(); var handler = rootType.FindMethod(tn.Text, invoke.ReturnType, false, invoke.Parameters.ToArray()); if (handler != null) { rv = new XamlLoadMethodDelegateNode(tn, context.RootObject, type, handler); return(true); } } } IXamlAstValueNode CreateInvariantCulture() => new XamlStaticOrTargetedReturnMethodCallNode(node, cfg.WellKnownTypes.CultureInfo.Methods.First(x => x.IsPublic && x.IsStatic && x.Name == "get_InvariantCulture"), null); var candidates = type.Methods.Where(m => m.Name == "Parse" && m.ReturnType.Equals(type) && m.Parameters.Count > 0 && m.Parameters[0].Equals(cfg.WellKnownTypes.String)).ToList(); // Types with parse method var parser = candidates.FirstOrDefault(m => m.Parameters.Count == 2 && ( m.Parameters[1].Equals(cfg.WellKnownTypes.CultureInfo) || m.Parameters[1].Equals(cfg.WellKnownTypes.IFormatProvider) ) ) ?? candidates.FirstOrDefault(m => m.Parameters.Count == 1); if (parser != null) { var args = new List <IXamlAstValueNode> { node }; if (parser.Parameters.Count == 2) { args.Add(CreateInvariantCulture()); } rv = new XamlStaticOrTargetedReturnMethodCallNode(node, parser, args); return(true); } if (cfg.TypeMappings.TypeDescriptorContext != null) { IXamlType converterType = null; if (propertyContext?.TypeConverters.TryGetValue(type, out converterType) != true) { var typeConverterAttribute = cfg.GetCustomAttribute(type, cfg.TypeMappings.TypeConverterAttributes).FirstOrDefault(); if (typeConverterAttribute != null) { converterType = TryGetTypeConverterFromCustomAttribute(cfg, typeConverterAttribute); } } if (converterType != null) { var converterMethod = converterType.FindMethod("ConvertFrom", cfg.WellKnownTypes.Object, false, cfg.TypeMappings.TypeDescriptorContext, cfg.WellKnownTypes.CultureInfo, cfg.WellKnownTypes.Object); rv = new XamlAstNeedsParentStackValueNode(node, new XamlAstRuntimeCastNode(node, new XamlStaticOrTargetedReturnMethodCallNode(node, converterMethod, new[] { new XamlAstNewClrObjectNode(node, new XamlAstClrTypeReference(node, converterType, false), null, new List <IXamlAstValueNode>()), new XamlAstContextLocalNode(node, cfg.TypeMappings.TypeDescriptorContext), CreateInvariantCulture(), node }), new XamlAstClrTypeReference(node, type, false))); return(true); } } return(false); }
public static TypeReference Resolve(TypeDefinition typeDef) { var resolver = new TypeReferenceResolver(typeDef); return(new TypeReference(resolver)); }
public TypeReference ResolveTypeReference(TypeDefinition newType, string targetTypeName = null) { return(TypeReferenceResolver.Resolve(ref ReservedTypeNames, ref AddedTypeReferences, mainModule, newType, targetTypeName)); }
public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { if (!(node is XamlAstObjectNode on && on.Type.GetClrType().FullName == "Avalonia.Styling.Style")) { return(node); } var pn = on.Children.OfType <XamlAstXamlPropertyValueNode>() .FirstOrDefault(p => p.Property.GetClrProperty().Name == "Selector"); if (pn == null) { return(node); } if (pn.Values.Count != 1) { throw new XamlParseException("Selector property should should have exactly one value", node); } if (pn.Values[0] is XamlIlSelectorNode) { //Deja vu. I've just been in this place before return(node); } if (!(pn.Values[0] is XamlAstTextNode tn)) { throw new XamlParseException("Selector property should be a text node", node); } var selectorType = pn.Property.GetClrProperty().Getter.ReturnType; var initialNode = new XamlIlSelectorInitialNode(node, selectorType); XamlIlSelectorNode Create(IEnumerable <SelectorGrammar.ISyntax> syntax, Func <string, string, XamlAstClrTypeReference> typeResolver) { XamlIlSelectorNode result = initialNode; XamlIlOrSelectorNode results = null; foreach (var i in syntax) { switch (i) { case SelectorGrammar.OfTypeSyntax ofType: result = new XamlIlTypeSelector(result, typeResolver(ofType.Xmlns, ofType.TypeName).Type, true); break; case SelectorGrammar.IsSyntax @is: result = new XamlIlTypeSelector(result, typeResolver(@is.Xmlns, @is.TypeName).Type, false); break; case SelectorGrammar.ClassSyntax @class: result = new XamlIlStringSelector(result, XamlIlStringSelector.SelectorType.Class, @class.Class); break; case SelectorGrammar.NameSyntax name: result = new XamlIlStringSelector(result, XamlIlStringSelector.SelectorType.Name, name.Name); break; case SelectorGrammar.PropertySyntax property: { var type = result?.TargetType; if (type == null) { throw new XamlParseException("Property selectors must be applied to a type.", node); } var targetProperty = type.GetAllProperties().FirstOrDefault(p => p.Name == property.Property); if (targetProperty == null) { throw new XamlParseException($"Cannot find '{property.Property}' on '{type}", node); } if (!XamlTransformHelpers.TryGetCorrectlyTypedValue(context, new XamlAstTextNode(node, property.Value, context.Configuration.WellKnownTypes.String), targetProperty.PropertyType, out var typedValue)) { throw new XamlParseException( $"Cannot convert '{property.Value}' to '{targetProperty.PropertyType.GetFqn()}", node); } result = new XamlIlPropertyEqualsSelector(result, targetProperty, typedValue); break; } case SelectorGrammar.ChildSyntax child: result = new XamlIlCombinatorSelector(result, XamlIlCombinatorSelector.SelectorType.Child); break; case SelectorGrammar.DescendantSyntax descendant: result = new XamlIlCombinatorSelector(result, XamlIlCombinatorSelector.SelectorType.Descendant); break; case SelectorGrammar.TemplateSyntax template: result = new XamlIlCombinatorSelector(result, XamlIlCombinatorSelector.SelectorType.Template); break; case SelectorGrammar.NotSyntax not: result = new XamlIlNotSelector(result, Create(not.Argument, typeResolver)); break; case SelectorGrammar.NthChildSyntax nth: result = new XamlIlNthChildSelector(result, nth.Step, nth.Offset, XamlIlNthChildSelector.SelectorType.NthChild); break; case SelectorGrammar.NthLastChildSyntax nth: result = new XamlIlNthChildSelector(result, nth.Step, nth.Offset, XamlIlNthChildSelector.SelectorType.NthLastChild); break; case SelectorGrammar.CommaSyntax comma: if (results == null) { results = new XamlIlOrSelectorNode(node, selectorType); } results.Add(result); result = initialNode; break; default: throw new XamlParseException($"Unsupported selector grammar '{i.GetType()}'.", node); } } if (results != null && result != null) { results.Add(result); } return(results ?? result); } IEnumerable <SelectorGrammar.ISyntax> parsed; try { parsed = SelectorGrammar.Parse(tn.Text); } catch (Exception e) { throw new XamlParseException("Unable to parse selector: " + e.Message, node); } var selector = Create(parsed, (p, n) => TypeReferenceResolver.ResolveType(context, $"{p}:{n}", true, node, true)); pn.Values[0] = selector; return(new AvaloniaXamlIlTargetTypeMetadataNode(on, new XamlAstClrTypeReference(selector, selector.TargetType, false), AvaloniaXamlIlTargetTypeMetadataNode.ScopeTypes.Style)); }
public CacheTypeReferenceResolver(TypeReferenceResolver inner) { _inner = inner; }
internal virtual void InitializeContext( IDescriptorContext context, TypeReferenceResolver typeReferenceResolver) { }