public override void WriteProperty(XamlPropertyNode xamlPropertyNode) { MemberInfo memberInfo = xamlPropertyNode.PropInfo; if (xamlPropertyNode.AttributeUsage == BamlAttributeUsage.RuntimeName && memberInfo != null) { // NOTE: Error if local element has runtime Name specified. Change this to // a warning in the future when that feature is available. if (_compiler.LocalAssembly == memberInfo.ReflectedType.Assembly && !xamlPropertyNode.IsDefinitionName) { ThrowException(SRID.LocalNamePropertyNotAllowed, memberInfo.ReflectedType.Name, MarkupCompiler.DefinitionNSPrefix, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } string attributeValue = xamlPropertyNode.Value; if (!_pass2) { Debug.Assert(_name == null && _nameField == null, "Name has already been set"); _nameField = _compiler.AddNameField(attributeValue, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); _name = attributeValue; } if (_nameField != null || _compiler.IsRootNameScope) { WriteConnectionId(); } } if (memberInfo != null && memberInfo.Name.Equals(STARTUPURI) && KnownTypes.Types[(int)KnownElements.Application].IsAssignableFrom(memberInfo.DeclaringType)) { // if Application.StartupUri property then don't bamlize, but gen code since // this is better for perf as Application is not a DO. if (!_pass2) { _compiler.AddApplicationProperty(memberInfo, xamlPropertyNode.Value, xamlPropertyNode.LineNumber); } } else { _compiler.IsBamlNeeded = true; base.WriteProperty(xamlPropertyNode); } }
private MemberInfo GetCLRPropertyInfo(XamlPropertyNode xamlPropertyNode, ref string member) { // Strip off namespace prefix from the event or property name and // map this to an xmlnamespace. Also extract the class name, if present string prefix = string.Empty; string target = member; string propertyName = member; int dotIndex = member.LastIndexOf('.'); if (-1 != dotIndex) { target = propertyName.Substring(0, dotIndex); member = propertyName.Substring(dotIndex+1); } int colonIndex = target.IndexOf(':'); if (-1 != colonIndex) { // If using .net then match against the class. prefix = target.Substring(0, colonIndex); if (-1 == dotIndex) { member = target.Substring(colonIndex+1); } } string xmlNamespace = TokenReader.XmlReader.LookupNamespace(prefix); Type targetType = null; // Get the type associated with the property or event from the XamlTypeMapper and // use this to resolve the property or event into an EventInfo, PropertyInfo // or MethodInfo if (-1 != dotIndex) { targetType = XamlTypeMapper.GetTypeFromBaseString(target, ParserContext, false); } else if (_setterTargetNameOrConditionSourceName != null) { targetType = _IDTypes[_setterTargetNameOrConditionSourceName] as Type; if (targetType == null #if PBTCOMPILER && !IsLocalPass1 #endif ) { ThrowException(SRID.TemplateNoTriggerTarget, _setterTargetNameOrConditionSourceName, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } } else { targetType = TargetType; } MemberInfo memberInfo = null; if (targetType != null) { string objectName = propertyName; memberInfo = XamlTypeMapper.GetClrInfo( false, targetType, xmlNamespace, member, ref objectName) as MemberInfo; } if (memberInfo != null) { PropertyInfo pi = memberInfo as PropertyInfo; if (pi != null) { // For trigger condition only allow if public or internal getter if (_inSetterDepth < 0 && _styleModeStack.Mode == StyleMode.TriggerBase) { if (!XamlTypeMapper.IsAllowedPropertyGet(pi)) { ThrowException(SRID.ParserCantSetTriggerCondition, pi.Name, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } } else // for general Setters check prop setters { if (!XamlTypeMapper.IsAllowedPropertySet(pi)) { ThrowException(SRID.ParserCantSetAttribute, "Property Setter", pi.Name, "set", xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } } } } // local properties will be added to the baml in pass2 of the compilation. // so don't throw now. else #if PBTCOMPILER if (!IsLocalPass1) #endif { if (targetType != null) { ThrowException(SRID.TemplateNoProp, member, targetType.FullName, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } else { ThrowException(SRID.TemplateNoTarget, member, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } } return memberInfo; }
private MemberInfo GetDependencyPropertyInfo(XamlPropertyNode xamlPropertyNode) { string member = xamlPropertyNode.Value; MemberInfo dpInfo = GetCLRPropertyInfo(xamlPropertyNode, ref member); if (dpInfo != null) { // Note: Should we enforce that all DP fields should end with a // "Property" or "PropertyKey" postfix here? if (BamlRecordWriter != null) { short typeId; short propertyId = MapTable.GetAttributeOrTypeId(BamlRecordWriter.BinaryWriter, dpInfo.DeclaringType, member, out typeId); if (propertyId < 0) { xamlPropertyNode.ValueId = propertyId; xamlPropertyNode.MemberName = null; } else { xamlPropertyNode.ValueId = typeId; xamlPropertyNode.MemberName = member; } } } return dpInfo; }
/// <summary> /// Handle property node when within a Triggers section. Return true if this /// node is fully handled and needs no further processing. /// </summary> private bool WritePropertyForTriggers(XamlPropertyNode xamlPropertyNode) { if (_inSetterDepth >= 0) { if (xamlPropertyNode.PropName == XamlTemplateSerializer.SetterValueAttributeName) { _setterOrTriggerValueNode = xamlPropertyNode; // Delay writing out the Value attribute until WriteEndAttributes if this is a // normal property node. If this is a property node that was created from complex // syntax, then the WriteEndAttributes has already occurred, so process the // node now. if (xamlPropertyNode.ComplexAsSimple) { ProcessPropertyValueNode(); } return true; } else if (xamlPropertyNode.PropName == XamlTemplateSerializer.SetterPropertyAttributeName) { // Property names should be trimmed since whitespace is not significant // and can affect name resolution (See Windows bug 1035621) xamlPropertyNode.SetValue(xamlPropertyNode.Value.Trim()); _setterOrTriggerPropertyNode = xamlPropertyNode; // return now as Setter.TargetName might not have been set yet and we need that for resolving // the property name. So this is done in WriteEndattributes. return true; } else if (xamlPropertyNode.PropName == XamlTemplateSerializer.SetterTargetAttributeName) { _setterTargetNameOrConditionSourceName = xamlPropertyNode.Value; } } else { if (xamlPropertyNode.PropName == XamlTemplateSerializer.PropertyTriggerValuePropertyName) { // DataTrigger doesn't have a "Property" property so value has to be written directly. // This check filters out if "Property" was actually set vs. not present at all for // other Triggers. Type t = (Type)_elementTypeStack.Peek(); if (!KnownTypes.Types[(int)KnownElements.DataTrigger].IsAssignableFrom(t)) { _setterOrTriggerValueNode = xamlPropertyNode; // Delay writing out the Value attribute until WriteEndAttributes if this is a // normal property node. If this is a property node that was created from complex // syntax, then the WriteEndAttributes has already occurred, so process the // node now. if (xamlPropertyNode.ComplexAsSimple) { ProcessPropertyValueNode(); } return true; } } else if (xamlPropertyNode.PropName == XamlTemplateSerializer.PropertyTriggerPropertyName) { // Property names should be trimmed since whitespace is not significant // and can affect name resolution (See Windows bug 1035621) xamlPropertyNode.SetValue(xamlPropertyNode.Value.Trim()); _setterOrTriggerPropertyNode = xamlPropertyNode; // return now as Trigger.SourceName might not have been set yet and we need that for resolving // the property name. So this is done in WriteEndattributes. return true; } else if (xamlPropertyNode.PropName == XamlTemplateSerializer.PropertyTriggerSourceName) { _setterTargetNameOrConditionSourceName = xamlPropertyNode.Value; } } return false; }
/// <summary> /// Write a Property, which has the form in markup of property="value". /// </summary> /// <remarks> /// When in a VisualTree, only DependencyProperties can be set directly on /// a FrameworkElementFactory. This method checks the state of parsing and /// with throw an exception if a clr property is set on a FrameworkElementFactory. /// </remarks> public override void WriteProperty(XamlPropertyNode xamlPropertyNode) { StyleMode mode = _styleModeStack.Mode; if (mode == StyleMode.TriggerBase && WritePropertyForTriggers(xamlPropertyNode)) { return; } // If we are on the DataTemplate tag itself, and we encounter a DataType property, // this can be used as the key when placing this template in a ResourceDictionary. // In that case, remember what the property value is so that we can // later update the defer key held by the baml writer. if (mode == StyleMode.Base && xamlPropertyNode.PropName == XamlTemplateSerializer.DataTypePropertyName) { #if PBTCOMPILER // Treat DataType="some string" as a key in a resource dictionary. // Generate a sequence of baml records to describe the key. if (InDeferLoadedSection && !_defNameFound) { base.WriteKeyElementStart(new XamlElementStartNode( xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition, xamlPropertyNode.Depth, _templateKeyType.Assembly.FullName, _templateKeyType.FullName, _templateKeyType, null)); base.WriteConstructorParametersStart(new XamlConstructorParametersStartNode( xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition, xamlPropertyNode.Depth)); base.WriteText(new XamlTextNode( xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition, xamlPropertyNode.Depth, xamlPropertyNode.Value, null)); base.WriteConstructorParametersEnd(new XamlConstructorParametersEndNode( xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition, xamlPropertyNode.Depth)); base.WriteKeyElementEnd(new XamlElementEndNode( xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition, xamlPropertyNode.Depth)); } #endif } #if PBTCOMPILER else if (mode == StyleMode.DataTypeProperty && InDeferLoadedSection && !_defNameFound) { // We have to treat DataType="{x:Type SomeType}" as a key in a // resource dictionary, if one is present. This means generating // a series of baml records to use as the key for the defer loaded // body of the Style. base.WriteProperty(xamlPropertyNode); } #endif xamlPropertyNode.DefaultTargetType = TargetType; base.WriteProperty(xamlPropertyNode); // If the property being written identifies a Runtime name, then remember // the name and the type associated with it. This may be needed for // Setter value and property resolutions later on. if (xamlPropertyNode.AttributeUsage == BamlAttributeUsage.RuntimeName) { if (_IDTypes.ContainsKey(xamlPropertyNode.Value)) { ThrowException(SRID.TemplateDupName, xamlPropertyNode.Value, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } else { _IDTypes[xamlPropertyNode.Value] = _elementTypeStack.Peek() as Type; } } }
/// <summary> /// Write an Event Connector and call the controlling compiler parser to generate event hookup code. /// </summary> public override void WriteClrEvent(XamlClrEventNode xamlClrEventNode) { if (_previousXamlParser != null) { Debug.Assert(_styleModeStack.Mode == StyleMode.VisualTree); // if this event token is not owned by this TemplateXamlParser, then just chain // the WriteClrEvent call to the controlling parser. Ulimately, this will // reach the markup compiler that will deal with this info as appropriate. bool isOriginatingEvent = xamlClrEventNode.IsOriginatingEvent; if (isOriginatingEvent) { // set up additional state on event node for the markup compiler to use. Debug.Assert(!xamlClrEventNode.IsStyleSetterEvent); xamlClrEventNode.IsTemplateEvent = true; xamlClrEventNode.IsSameScope = _isSameScope; // any intermediary controlling parsers need to get out of the way so that // the markup compiler can ultimately do its thing. xamlClrEventNode.IsOriginatingEvent = false; // Store away the type of the element we're currently in. E.g. // in <Button Click="OnClicked"/>, this will be typeof(Button). // In the case of regular CLR events, this type is the same as that // which can be found in xamlClrEventNode.EventMember. But in the // case of attached events, EventMember is the class that holds // the attached event, and the compiler needs to know the type of // the listener. xamlClrEventNode.ListenerType = (Type) _elementTypeStack.Peek(); } _previousXamlParser.WriteClrEvent(xamlClrEventNode); if (isOriginatingEvent) { if (!String.IsNullOrEmpty(xamlClrEventNode.LocalAssemblyName)) { // if this event is a local event need to generate baml for it now XamlPropertyNode xamlPropertyNode = new XamlPropertyNode(xamlClrEventNode.LineNumber, xamlClrEventNode.LinePosition, xamlClrEventNode.Depth, null, xamlClrEventNode.LocalAssemblyName, xamlClrEventNode.EventMember.ReflectedType.FullName, xamlClrEventNode.EventName, xamlClrEventNode.Value, BamlAttributeUsage.Default, false); base.WriteProperty(xamlPropertyNode); } else { // write out a connectionId to the baml stream only if a // new event scope was encountered if (!_isSameScope) { base.WriteConnectionId(xamlClrEventNode.ConnectionId); } // We have just finished processing the start of a new event scope. // So specifiy start of this new scope. _isSameScope = true; } } } }
/// <summary> /// override of WriteDynamicEvent /// </summary> public override void WriteClrEvent(XamlClrEventNode xamlClrEventNode) { bool isStyleEvent = (xamlClrEventNode.IsStyleSetterEvent || xamlClrEventNode.IsTemplateEvent); bool localEvent = _compiler.LocalAssembly == xamlClrEventNode.EventMember.ReflectedType.Assembly; if (isStyleEvent) { if (localEvent) { // validate the event handler name per CLS grammar for identifiers _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value); xamlClrEventNode.LocalAssemblyName = _compiler.AssemblyName; // Pass2 should always be true here as otherwise localEvent will be false, but just being paranoid here. if (_pass2) { XamlTypeMapper.HasInternals = true; } } else { if (!xamlClrEventNode.IsSameScope) { _connectionId++; } xamlClrEventNode.ConnectionId = _connectionId; if (!_pass2) { _compiler.ConnectStyleEvent(xamlClrEventNode); } } return; } bool appEvent = KnownTypes.Types[(int)KnownElements.Application].IsAssignableFrom(xamlClrEventNode.EventMember.DeclaringType); if (!appEvent) { if (!_pass2) { // validate the event handler name per CLS grammar for identifiers _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value); if (_events == null) _events = new ArrayList(); _events.Add(new MarkupCompiler.MarkupEventInfo(xamlClrEventNode.Value, xamlClrEventNode.EventName, xamlClrEventNode.EventMember, xamlClrEventNode.LineNumber)); } // if not local event ... if (!localEvent) { WriteConnectionId(); } } else if (!_pass2) { // Since Application is not an Element it doesn't implement IComponentConnector and // so needs to add events directly. MarkupCompiler.MarkupEventInfo mei = new MarkupCompiler.MarkupEventInfo(xamlClrEventNode.Value, xamlClrEventNode.EventName, xamlClrEventNode.EventMember, xamlClrEventNode.LineNumber); _compiler.AddApplicationEvent(mei); } if (_pass2) { // if local event, add Baml Attribute Record for local event if (localEvent) { // validate the event handler name per C# grammar for identifiers _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value); XamlPropertyNode xamlPropertyNode = new XamlPropertyNode(xamlClrEventNode.LineNumber, xamlClrEventNode.LinePosition, xamlClrEventNode.Depth, xamlClrEventNode.EventMember, _compiler.AssemblyName, xamlClrEventNode.EventMember.ReflectedType.FullName, xamlClrEventNode.EventName, xamlClrEventNode.Value, BamlAttributeUsage.Default, false); XamlTypeMapper.HasInternals = true; base.WriteProperty(xamlPropertyNode); } } }
/// <summary> /// Write an Event Connector and call the controlling compiler parser to generate event hookup code. /// </summary> public override void WriteClrEvent(XamlClrEventNode xamlClrEventNode) { if (_previousXamlParser != null) { if (_styleModeStack.Mode != StyleMode.Setters) { ThrowException(SRID.StyleTargetNoEvents, xamlClrEventNode.EventName, xamlClrEventNode.LineNumber, xamlClrEventNode.LinePosition); } // if this event token is not owned by this StyleXamlParser, then just chain // the WriteClrEvent call to the controlling parser. Ulimately, this will // reach the markup compiler that will deal with this info as appropriate. bool isOriginatingEvent = xamlClrEventNode.IsOriginatingEvent; if (isOriginatingEvent) { // set up additional state on event node for the markup compiler to use. Debug.Assert(!xamlClrEventNode.IsTemplateEvent && _inEventSetter); xamlClrEventNode.IsStyleSetterEvent = _inEventSetter; xamlClrEventNode.IsSameScope = _isSameScope; // any intermediary controlling parsers need to get out of the way so that // the markup compiler can ultimately do its thing. xamlClrEventNode.IsOriginatingEvent = false; } _previousXamlParser.WriteClrEvent(xamlClrEventNode); if (isOriginatingEvent) { if (!String.IsNullOrEmpty(xamlClrEventNode.LocalAssemblyName)) { // if this event is a local event need to generate baml for it now string assemblyName = KnownTypes.Types[(int)KnownElements.EventSetter].Assembly.FullName; base.WriteElementStart(new XamlElementStartNode(XamlNodeType.ElementStart, xamlClrEventNode.LineNumber, xamlClrEventNode.LinePosition, xamlClrEventNode.Depth, assemblyName, KnownTypes.Types[(int)KnownElements.EventSetter].FullName, KnownTypes.Types[(int)KnownElements.EventSetter], null /*serializerType*/, false /*isEmptyElement*/, false /*needsDictionaryKey*/, false /*isInjected*/)); XamlPropertyNode xamlPropertyNode = new XamlPropertyNode(xamlClrEventNode.LineNumber, xamlClrEventNode.LinePosition, xamlClrEventNode.Depth, null, xamlClrEventNode.LocalAssemblyName, xamlClrEventNode.EventMember.ReflectedType.FullName, xamlClrEventNode.EventName, xamlClrEventNode.Value, BamlAttributeUsage.Default, false); base.WriteProperty(xamlPropertyNode); base.WriteElementEnd(new XamlElementEndNode(xamlClrEventNode.LineNumber, xamlClrEventNode.LinePosition, xamlClrEventNode.Depth)); } else { // write out a connectionId to the baml stream only if a // new event scope was encountered if (!_isSameScope) { base.WriteConnectionId(xamlClrEventNode.ConnectionId); } // We have just finished processing the start of a new event scope. // So specifiy start of this new scope. _isSameScope = true; } } } }
internal void WriteBaseProperty(XamlPropertyNode xamlPropertyNode) { if (BamlRecordWriter != null) { BamlRecordWriter.BaseWriteProperty(xamlPropertyNode); } }
/// <summary> /// Write a Property, which has the form in markup of property="value". /// </summary> /// <remarks> /// Note that for DependencyProperties, the assemblyName, TypeFullName, PropIdName /// refer to DependencyProperty field /// that the property was found on. This may be different from the ownerType /// of the propId if the property was registered as an alias so if the /// callback is persisting we want to persist the information that the propId /// was found on in case the alias is a private or internal field. /// </remarks> public virtual void WriteProperty(XamlPropertyNode xamlPropertyNode) { if (BamlRecordWriter != null) { BamlRecordWriter.WriteProperty(xamlPropertyNode); } }
/// <summary> /// Represent a single property for a MarkupExtension as a complex property. /// </summary> private void CompileProperty( ArrayList xamlNodes, string name, string value, Type parentType, string parentTypeNamespaceUri, AttributeData data, int lineNumber, int linePosition, int depth) { RemoveEscapes(ref name); RemoveEscapes(ref value); int nameIndex = name.IndexOf(':'); string localName = (nameIndex < 0) ? name : name.Substring(nameIndex+1); string prefix = (nameIndex < 0) ? String.Empty : name.Substring(0, nameIndex); string attribNamespaceURI = ResolveAttributeNamespaceURI(prefix, localName, parentTypeNamespaceUri); object dynamicObject; string assemblyName; string typeFullName; Type declaringType; string dynamicObjectName; if (String.IsNullOrEmpty(attribNamespaceURI)) { ThrowException(SRID.ParserPrefixNSProperty, prefix, name, lineNumber, linePosition); } AttributeContext attributeContext = GetAttributeContext( parentType, parentTypeNamespaceUri, attribNamespaceURI, localName, out dynamicObject, out assemblyName, out typeFullName, out declaringType, out dynamicObjectName); if (attributeContext != AttributeContext.Property) { ThrowException(SRID.ParserMarkupExtensionUnknownAttr, localName, parentType.FullName, lineNumber, linePosition); } MemberInfo info = dynamicObject as MemberInfo; Debug.Assert(null != info, "No property or method info for field Name"); if (data != null && data.IsSimple) { if (data.IsTypeExtension) { string typeValueFullName = value; // set this to original value for error reporting if reqd. string typeValueAssemblyFullName = null; Type typeValue = _parserContext.XamlTypeMapper.GetTypeFromBaseString(value, _parserContext, true); if (typeValue != null) { typeValueFullName = typeValue.FullName; typeValueAssemblyFullName = typeValue.Assembly.FullName; } XamlPropertyWithTypeNode xamlPropertyWithTypeNode = new XamlPropertyWithTypeNode(data.LineNumber, data.LinePosition, data.Depth, dynamicObject, assemblyName, typeFullName, localName, typeValueFullName, typeValueAssemblyFullName, typeValue, string.Empty, string.Empty); xamlNodes.Add(xamlPropertyWithTypeNode); } else { XamlPropertyWithExtensionNode xamlPropertyWithExtensionNode = new XamlPropertyWithExtensionNode(data.LineNumber, data.LinePosition, data.Depth, dynamicObject, assemblyName, typeFullName, localName, value, data.ExtensionTypeId, data.IsValueNestedExtension, data.IsValueTypeExtension); xamlNodes.Add(xamlPropertyWithExtensionNode); } } else { XamlPropertyNode xamlPropertyNode = new XamlPropertyNode(lineNumber, linePosition, depth, dynamicObject, assemblyName, typeFullName, dynamicObjectName, value, BamlAttributeUsage.Default, true); xamlNodes.Add(xamlPropertyNode); } }
// Write a property baml record. If the type of this property supports // custom serialization or type conversion, then write out a special property // record. Otherwise write out a 'normal' record, which will cause type // converter resolution to happen at load time. internal virtual void WriteProperty(XamlPropertyNode xamlProperty) { short attributeId = MapTable.AddAttributeInfoMap(BinaryWriter, xamlProperty.AssemblyName, xamlProperty.TypeFullName, xamlProperty.PropDeclaringType, xamlProperty.PropName, xamlProperty.PropValidType, xamlProperty.AttributeUsage); if (xamlProperty.AssemblyName != string.Empty && xamlProperty.TypeFullName != string.Empty) { short converterOrSerializerTypeId; Type converterOrSerializerType; bool isCustomSerializer = MapTable.GetCustomSerializerOrConverter( BinaryWriter, xamlProperty.ValueDeclaringType, xamlProperty.ValuePropertyType, xamlProperty.ValuePropertyMember, xamlProperty.ValuePropertyName, out converterOrSerializerTypeId, out converterOrSerializerType); if (converterOrSerializerType != null) { if (isCustomSerializer) { BamlPropertyCustomWriteInfoRecord bamlPropertyCustom = (BamlPropertyCustomWriteInfoRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyCustom); bamlPropertyCustom.AttributeId = attributeId; bamlPropertyCustom.Value = xamlProperty.Value; bamlPropertyCustom.ValueType = xamlProperty.ValuePropertyType; bamlPropertyCustom.SerializerTypeId = converterOrSerializerTypeId; bamlPropertyCustom.SerializerType = converterOrSerializerType; bamlPropertyCustom.TypeContext = TypeConvertContext; if (converterOrSerializerTypeId == (short)KnownElements.DependencyPropertyConverter) { // if ValueId\MemberName have alredy been resolved, just write it out. if (xamlProperty.HasValueId) { bamlPropertyCustom.ValueId = xamlProperty.ValueId; bamlPropertyCustom.ValueMemberName = xamlProperty.MemberName; } else { // else try to resolve the DP value of this property now string dpName; // get the ownerType and name of the DP value Type ownerType = _xamlTypeMapper.GetDependencyPropertyOwnerAndName(xamlProperty.Value, ParserContext, xamlProperty.DefaultTargetType, out dpName); short typeId; // get the known property Id or TypeId of the owner of the DP value short propertyId = MapTable.GetAttributeOrTypeId(BinaryWriter, ownerType, dpName, out typeId); // write it out as appropriate. if (propertyId < 0) { bamlPropertyCustom.ValueId = propertyId; bamlPropertyCustom.ValueMemberName = null; } else { bamlPropertyCustom.ValueId = typeId; bamlPropertyCustom.ValueMemberName = dpName; } } } WriteAndReleaseRecord(bamlPropertyCustom, xamlProperty); } else { BamlPropertyWithConverterRecord bamlPropertyWithConverter = (BamlPropertyWithConverterRecord)BamlRecordManager.GetWriteRecord( BamlRecordType.PropertyWithConverter); bamlPropertyWithConverter.AttributeId = attributeId; bamlPropertyWithConverter.Value = xamlProperty.Value; bamlPropertyWithConverter.ConverterTypeId = converterOrSerializerTypeId; WriteAndReleaseRecord(bamlPropertyWithConverter, xamlProperty); } return; } } BaseWriteProperty(xamlProperty); }
// Write out property to BAML record, with the property value as a string. // This is used if the value cannot stream itself out directly, or if we // are creating a tree directly and not storing BAML to a file. internal void BaseWriteProperty(XamlPropertyNode xamlProperty) { short attributeId = MapTable.AddAttributeInfoMap(BinaryWriter, xamlProperty.AssemblyName, xamlProperty.TypeFullName, xamlProperty.PropDeclaringType, xamlProperty.PropName, xamlProperty.PropValidType, xamlProperty.AttributeUsage); BamlPropertyRecord bamlClrProperty = (BamlPropertyRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.Property); bamlClrProperty.AttributeId = attributeId; bamlClrProperty.Value = xamlProperty.Value; WriteAndReleaseRecord(bamlClrProperty, xamlProperty); }
/// <summary> /// Write a Property, which has the form in markup of property="value". /// </summary> public override void WriteProperty(XamlPropertyNode xamlPropertyNode) { StyleMode mode = _styleModeStack.Mode; Debug.Assert (mode != StyleMode.Base || xamlPropertyNode.PropName != XamlStyleSerializer.TargetTypePropertyName, "TargetType should be handled by WritePropertyWithType"); if (mode == StyleMode.TargetTypeProperty && xamlPropertyNode.PropName == "TypeName") { // Remember the TargetType name so that the event setter parsing could use it // to resolve non-qualified event names _styleTargetTypeString = xamlPropertyNode.Value; } // When compiling, native DependencyProperties may not have a static setter, // so all we can resolve is the associated PropertyInfo. In this case, we // will check to see if there is a static field named PropName+Property and // assume that this will be a DependencyProperty that can be resolved at // runtime. If there is no property with this naming pattern, then it can't // resolve at runtime, so complain now. Note that this is only done in the // compile case, since a cheaper check is done in the StyleBamlRecordReader // for the xaml-to-tree case. if (mode == StyleMode.Setters || mode == StyleMode.TriggerBase) { if (_inSetterDepth >= 0 && !_inEventSetter) { // Trigger Setters processed here. if (xamlPropertyNode.PropName == XamlStyleSerializer.SetterValueAttributeName) { _setterOrTriggerValueNode = xamlPropertyNode; // Delay writing out the Value attribute until WriteEndAttributes if this is a // normal property node. If this is a property node that was created from complex // syntax, then the WriteEndAttributes has already occurred, so process the // node now. if (xamlPropertyNode.ComplexAsSimple) { ProcessPropertyValueNode(); } return; } else if (xamlPropertyNode.PropName == XamlStyleSerializer.SetterPropertyAttributeName) { // Property names should be trimmed since whitespace is not significant // and can affect name resolution (See Windows bug 1035621) xamlPropertyNode.SetValue(xamlPropertyNode.Value.Trim()); _setterOrTriggerPropertyInfo = GetDependencyPropertyInfo(xamlPropertyNode); } else if (xamlPropertyNode.PropName == XamlTemplateSerializer.SetterTargetAttributeName) { ThrowException(SRID.TargetNameNotSupportedForStyleSetters, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } } else if (_inSetterDepth < 0 && !_inEventSetter) { // Setters & Trigger Conditions processed here. if (xamlPropertyNode.PropName == XamlStyleSerializer.PropertyTriggerValuePropertyName) { _setterOrTriggerValueNode = xamlPropertyNode; // Delay writing out the Value attribute until WriteEndAttributes if this is a // normal property node. If this is a property node that was created from complex // syntax, then the WriteEndAttributes has already occurred, so process the // node now. if (xamlPropertyNode.ComplexAsSimple) { ProcessPropertyValueNode(); } return; } else if (xamlPropertyNode.PropName == XamlStyleSerializer.PropertyTriggerPropertyName) { // Property names should be trimmed since whitespace is not significant // and can affect name resolution. xamlPropertyNode.SetValue(xamlPropertyNode.Value.Trim()); _setterOrTriggerPropertyInfo = GetDependencyPropertyInfo(xamlPropertyNode); } else if (xamlPropertyNode.PropName == XamlStyleSerializer.PropertyTriggerSourceName) { ThrowException(SRID.SourceNameNotSupportedForStyleTriggers, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } else if (xamlPropertyNode.PropName == XamlTemplateSerializer.SetterTargetAttributeName) { ThrowException(SRID.TargetNameNotSupportedForStyleSetters, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } } #if PBTCOMPILER else if (_inEventSetter) { // Check for EventSetter properties. These aren't really stored as properties but // resolved at the EventSetter end tag as events by the compiler if (xamlPropertyNode.PropName == XamlStyleSerializer.SetterEventAttributeName) { _event = xamlPropertyNode.Value; } else if (xamlPropertyNode.PropName == XamlStyleSerializer.SetterHandlerAttributeName) { _handler = xamlPropertyNode.Value; } #if HANDLEDEVENTSTOO else if (xamlPropertyNode.PropName == XamlStyleSerializer.SetterHandledEventsTooAttributeName) { _handledEventsToo = Boolean.Parse(xamlPropertyNode.Value); } #endif return; } #endif } base.WriteProperty(xamlPropertyNode); }
/// <summary> /// override of WriteDynamicEvent /// </summary> public override void WriteClrEvent(XamlClrEventNode xamlClrEventNode) { bool isStyleEvent = (xamlClrEventNode.IsStyleSetterEvent || xamlClrEventNode.IsTemplateEvent); bool localEvent = _compiler.LocalAssembly == xamlClrEventNode.EventMember.ReflectedType.Assembly; if (isStyleEvent) { if (localEvent) { // validate the event handler name per CLS grammar for identifiers _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value); xamlClrEventNode.LocalAssemblyName = _compiler.AssemblyName; // Pass2 should always be true here as otherwise localEvent will be false, but just being paranoid here. if (_pass2) { XamlTypeMapper.HasInternals = true; } } else { if (!xamlClrEventNode.IsSameScope) { _connectionId++; } xamlClrEventNode.ConnectionId = _connectionId; if (!_pass2) { _compiler.ConnectStyleEvent(xamlClrEventNode); } } return; } bool appEvent = KnownTypes.Types[(int)KnownElements.Application].IsAssignableFrom(xamlClrEventNode.EventMember.DeclaringType); if (!appEvent) { if (!_pass2) { // validate the event handler name per CLS grammar for identifiers _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value); if (_events == null) { _events = new ArrayList(); } _events.Add(new MarkupCompiler.MarkupEventInfo(xamlClrEventNode.Value, xamlClrEventNode.EventName, xamlClrEventNode.EventMember, xamlClrEventNode.LineNumber)); } // if not local event ... if (!localEvent) { WriteConnectionId(); } } else if (!_pass2) { // Since Application is not an Element it doesn't implement IComponentConnector and // so needs to add events directly. MarkupCompiler.MarkupEventInfo mei = new MarkupCompiler.MarkupEventInfo(xamlClrEventNode.Value, xamlClrEventNode.EventName, xamlClrEventNode.EventMember, xamlClrEventNode.LineNumber); _compiler.AddApplicationEvent(mei); } if (_pass2) { // if local event, add Baml Attribute Record for local event if (localEvent) { // validate the event handler name per C# grammar for identifiers _compiler.ValidateEventHandlerName(xamlClrEventNode.EventName, xamlClrEventNode.Value); XamlPropertyNode xamlPropertyNode = new XamlPropertyNode(xamlClrEventNode.LineNumber, xamlClrEventNode.LinePosition, xamlClrEventNode.Depth, xamlClrEventNode.EventMember, _compiler.AssemblyName, xamlClrEventNode.EventMember.ReflectedType.FullName, xamlClrEventNode.EventName, xamlClrEventNode.Value, BamlAttributeUsage.Default, false); XamlTypeMapper.HasInternals = true; base.WriteProperty(xamlPropertyNode); } } }
internal override ParserAction LoadNode(XamlNode tokenNode) { switch (tokenNode.TokenType) { case XamlNodeType.DocumentStart: { // A single ParserHooks might be used to parse multiple bamls. // We need to clear the comments list at the begining of each baml. _commentList.Clear(); _currentComment = new LocalizationComment(); return(ParserAction.Normal); } case XamlNodeType.DefAttribute: { XamlDefAttributeNode node = (XamlDefAttributeNode)tokenNode; if (node.Name == XamlReaderHelper.DefinitionUid) { _currentComment.Uid = node.Value; } return(ParserAction.Normal); } case XamlNodeType.Property: { XamlPropertyNode node = (XamlPropertyNode)tokenNode; // When this parer hook is invoked, comments is always output to a seperate file. if (LocComments.IsLocCommentsProperty(node.TypeFullName, node.PropName)) { // try parse the value. Exception will be thrown if not valid. LocComments.ParsePropertyComments(node.Value); _currentComment.Comments = node.Value; return(ParserAction.Skip); // skips outputing this node to baml } if (_directivesToFile == LocalizationDirectivesToLocFile.All && LocComments.IsLocLocalizabilityProperty(node.TypeFullName, node.PropName)) { // try parse the value. Exception will be thrown if not valid. LocComments.ParsePropertyLocalizabilityAttributes(node.Value); _currentComment.Attributes = node.Value; return(ParserAction.Skip); // skips outputing this node to baml } return(ParserAction.Normal); } case XamlNodeType.EndAttributes: { FlushCommentToList(ref _currentComment); return(ParserAction.Normal); } case XamlNodeType.DocumentEnd: { // // When reaching document end, we output all the comments we have collected // so far into a localization comment file. If the parsing was aborted in // MarkupCompilePass1, we would not out the incomplete set of comments because // it will not reach document end. // if (_commentList.Count > 0) { string absoluteOutputPath = _compiler.TargetPath + _compiler.SourceFileInfo.RelativeSourceFilePath + SharedStrings.LocExtension; MemoryStream memStream = new MemoryStream(); // TaskFileService.WriteFile adds BOM for UTF8 Encoding, thus don't add here // when creating XmlTextWriter. using (XmlTextWriter writer = new XmlTextWriter(memStream, new UTF8Encoding(false))) { // output XML for each piece of comment writer.Formatting = Formatting.Indented; writer.WriteStartElement(LocComments.LocResourcesElement); writer.WriteAttributeString(LocComments.LocFileNameAttribute, _compiler.SourceFileInfo.RelativeSourceFilePath); foreach (LocalizationComment comment in _commentList) { writer.WriteStartElement(LocComments.LocCommentsElement); writer.WriteAttributeString(LocComments.LocCommentIDAttribute, comment.Uid); if (comment.Attributes != null) { writer.WriteAttributeString(LocComments.LocLocalizabilityAttribute, comment.Attributes); } if (comment.Comments != null) { writer.WriteAttributeString(LocComments.LocCommentsAttribute, comment.Comments); } writer.WriteEndElement(); } writer.WriteEndElement(); writer.Flush(); _compiler.TaskFileService.WriteFile(memStream.ToArray(), absoluteOutputPath); } } return(ParserAction.Normal); } default: { return(ParserAction.Normal); } } }