private void GetLocalizabilityForElementNode( BamlStartElementNode node, out LocalizabilityAttribute localizability, out string formattingTag ) { localizability = null; formattingTag = null; // get the names we need string assemblyName = node.AssemblyName; string className = node.TypeFullName; // query the resolver ElementLocalizability result = _resolver.GetElementLocalizability( assemblyName, className ); LocalizabilityGroup comment = null; comment = _resolver.GetLocalizabilityComment(node, BamlConst.ContentSuffix); if (comment != null) { localizability = comment.Override(result.Attribute); } else { localizability = result.Attribute; } formattingTag = result.FormattingTag; }
// Token: 0x06006EB7 RID: 28343 RVA: 0x001FD064 File Offset: 0x001FB264 private bool TryFormatElementContent(BamlLocalizableResourceKey key, BamlStartElementNode node, out string content) { content = string.Empty; LocalizabilityAttribute localizabilityAttribute; string text; this.GetLocalizabilityForElementNode(node, out localizabilityAttribute, out text); localizabilityAttribute = this.CombineAndPropagateInheritanceValues(node, localizabilityAttribute); if (text != null && localizabilityAttribute.Category != LocalizationCategory.NeverLocalize && localizabilityAttribute.Category != LocalizationCategory.Ignore && localizabilityAttribute.Modifiability == Modifiability.Modifiable && localizabilityAttribute.Readability == Readability.Readable) { StringBuilder stringBuilder = new StringBuilder(); if (node.Uid != null) { stringBuilder.AppendFormat(TypeConverterHelper.InvariantEnglishUS, "<{0} {1}=\"{2}\">", new object[] { text, "Uid", BamlResourceContentUtil.EscapeString(node.Uid) }); } else { stringBuilder.AppendFormat(TypeConverterHelper.InvariantEnglishUS, "<{0}>", new object[] { text }); } string value; bool flag = this.TryGetContent(key, node, out value); if (flag) { stringBuilder.Append(value); stringBuilder.AppendFormat(TypeConverterHelper.InvariantEnglishUS, "</{0}>", new object[] { text }); node.Formatted = true; content = stringBuilder.ToString(); } return(flag); } bool result = true; if (node.Uid != null) { content = string.Format(TypeConverterHelper.InvariantEnglishUS, "{0}{1}{2}", new object[] { '#', BamlResourceContentUtil.EscapeString(node.Uid), ';' }); } else { this._resolver.RaiseErrorNotifyEvent(new BamlLocalizerErrorNotifyEventArgs(key, BamlLocalizerError.UidMissingOnChildElement)); result = false; } return(result); }
// Token: 0x06006EB6 RID: 28342 RVA: 0x001FCF00 File Offset: 0x001FB100 internal bool TryGetContent(BamlLocalizableResourceKey key, BamlTreeNode currentNode, out string content) { content = string.Empty; BamlNodeType nodeType = currentNode.NodeType; if (nodeType == BamlNodeType.StartElement) { BamlStartElementNode bamlStartElementNode = (BamlStartElementNode)currentNode; if (bamlStartElementNode.Content == null) { StringBuilder stringBuilder = new StringBuilder(); foreach (BamlTreeNode bamlTreeNode in bamlStartElementNode.Children) { nodeType = bamlTreeNode.NodeType; if (nodeType != BamlNodeType.StartElement) { if (nodeType == BamlNodeType.Text) { stringBuilder.Append(BamlResourceContentUtil.EscapeString(((BamlTextNode)bamlTreeNode).Content)); } } else { string value; if (!this.TryFormatElementContent(key, (BamlStartElementNode)bamlTreeNode, out value)) { return(false); } stringBuilder.Append(value); } } bamlStartElementNode.Content = stringBuilder.ToString(); } content = bamlStartElementNode.Content; return(true); } if (nodeType == BamlNodeType.Property) { bool result = true; BamlPropertyNode bamlPropertyNode = (BamlPropertyNode)currentNode; content = BamlResourceContentUtil.EscapeString(bamlPropertyNode.Value); string text = content; string text2; string text3; if (MarkupExtensionParser.GetMarkupExtensionTypeAndArgs(ref text, out text2, out text3)) { LocalizabilityGroup localizabilityComment = this._resolver.GetLocalizabilityComment(bamlPropertyNode.Parent as BamlStartElementNode, bamlPropertyNode.PropertyName); result = (localizabilityComment != null && localizabilityComment.Readability == Readability.Readable); } return(result); } if (nodeType != BamlNodeType.LiteralContent) { return(true); } content = BamlResourceContentUtil.EscapeString(((BamlLiteralContentNode)currentNode).Content); return(true); }
internal override BamlTreeNode Copy() { BamlStartElementNode node = new BamlStartElementNode(_assemblyName, _typeFullName, _isInjected, _useTypeConverter); node._content = _content; node._uid = _uid; node._inheritableAttribute = _inheritableAttribute; return(node); }
// Token: 0x06008D42 RID: 36162 RVA: 0x00259018 File Offset: 0x00257218 internal BamlStartElementNode MapUidToBamlTreeElementNode(string uid) { BamlStartElementNode bamlStartElementNode = this._originalMap.MapUidToBamlTreeElementNode(uid, this._tree); if (bamlStartElementNode == null && this._uidToNewBamlNodeIndexMap.Contains(uid)) { bamlStartElementNode = (this._tree[(int)this._uidToNewBamlNodeIndexMap[uid]] as BamlStartElementNode); } return(bamlStartElementNode); }
// Token: 0x06006E27 RID: 28199 RVA: 0x001FB688 File Offset: 0x001F9888 internal string GetStringComment(BamlStartElementNode node, string localName) { InternalBamlLocalizabilityResolver.ElementComments elementComments = this.LookupCommentForElement(node); for (int i = 0; i < elementComments.LocalizationComments.Length; i++) { if (elementComments.LocalizationComments[i].PropertyName == localName) { return((string)elementComments.LocalizationComments[i].Value); } } return(null); }
// Token: 0x06006E21 RID: 28193 RVA: 0x001FB3C4 File Offset: 0x001F95C4 internal static BamlLocalizableResourceKey GetKey(BamlTreeNode node) { BamlLocalizableResourceKey result = null; BamlNodeType nodeType = node.NodeType; if (nodeType != BamlNodeType.StartElement) { if (nodeType != BamlNodeType.Property) { if (nodeType == BamlNodeType.LiteralContent) { BamlLiteralContentNode bamlLiteralContentNode = (BamlLiteralContentNode)node; BamlStartElementNode bamlStartElementNode = (BamlStartElementNode)node.Parent; if (bamlStartElementNode.Uid != null) { result = new BamlLocalizableResourceKey(bamlStartElementNode.Uid, bamlStartElementNode.TypeFullName, "$LiteralContent", bamlStartElementNode.AssemblyName); } } } else { BamlPropertyNode bamlPropertyNode = (BamlPropertyNode)node; BamlStartElementNode bamlStartElementNode2 = (BamlStartElementNode)bamlPropertyNode.Parent; if (bamlStartElementNode2.Uid != null) { string uid; if (bamlPropertyNode.Index <= 0) { uid = bamlStartElementNode2.Uid; } else { uid = string.Format(TypeConverterHelper.InvariantEnglishUS, "{0}.{1}_{2}", new object[] { bamlStartElementNode2.Uid, bamlPropertyNode.PropertyName, bamlPropertyNode.Index }); } result = new BamlLocalizableResourceKey(uid, bamlPropertyNode.OwnerTypeFullName, bamlPropertyNode.PropertyName, bamlPropertyNode.AssemblyName); } } } else { BamlStartElementNode bamlStartElementNode3 = (BamlStartElementNode)node; if (bamlStartElementNode3.Uid != null) { result = new BamlLocalizableResourceKey(bamlStartElementNode3.Uid, bamlStartElementNode3.TypeFullName, "$Content", bamlStartElementNode3.AssemblyName); } } return(result); }
// Token: 0x06006E31 RID: 28209 RVA: 0x001FBBD4 File Offset: 0x001F9DD4 private void SetLocalizationComments(BamlStartElementNode node, InternalBamlLocalizabilityResolver.ElementComments comments, string stringComment) { if (!string.IsNullOrEmpty(stringComment)) { try { comments.LocalizationComments = LocComments.ParsePropertyComments(stringComment); } catch (FormatException) { this.RaiseErrorNotifyEvent(new BamlLocalizerErrorNotifyEventArgs(BamlTreeMap.GetKey(node), BamlLocalizerError.InvalidLocalizationComments)); } } }
internal BamlStartElementNode MapUidToBamlTreeElementNode(string uid) { BamlStartElementNode node = _originalMap.MapUidToBamlTreeElementNode(uid, _tree); if (node == null) { // find it in the new nodes if (_uidToNewBamlNodeIndexMap.Contains(uid)) { node = _tree[(int)_uidToNewBamlNodeIndexMap[uid]] as BamlStartElementNode; } } return(node); }
/// <remarks> /// Try to add the matching ContentPropertyNode to the newly constructed element /// </remarks> private static void TryAddContentPropertyToNewElement( BamlTreeUpdateMap bamlTreeMap, BamlStartElementNode bamlNode ) { string contentProperty = bamlTreeMap.GetContentProperty(bamlNode.AssemblyName, bamlNode.TypeFullName); if (!string.IsNullOrEmpty(contentProperty)) { bamlNode.AddChild( new BamlContentPropertyNode( bamlNode.AssemblyName, bamlNode.TypeFullName, contentProperty ) ); } }
// Grab the comments on a BamlTreeNode for the value. internal LocalizabilityGroup GetLocalizabilityComment( BamlStartElementNode node, string localName ) { // get all the comments declares on this node ElementComments comment = LookupCommentForElement(node); for (int i = 0; i < comment.LocalizationAttributes.Length; i++) { if (comment.LocalizationAttributes[i].PropertyName == localName) { return((LocalizabilityGroup)comment.LocalizationAttributes[i].Value); } } return(null); }
internal string GetStringComment( BamlStartElementNode node, string localName ) { // get all the comments declares on this node ElementComments comment = LookupCommentForElement(node); for (int i = 0; i < comment.LocalizationComments.Length; i++) { if (comment.LocalizationComments[i].PropertyName == localName) { return((string)comment.LocalizationComments[i].Value); } } return(null); }
//---------------------------------- // private method //---------------------------------- /// <summary> /// Serialize the tree out to the stream. /// </summary> private void SerializeImp( BamlLocalizer localizer, BamlTree tree, Stream output ) { Debug.Assert(output != null, "The output stream given is null"); Debug.Assert(tree != null && tree.Root != null, "The tree to be serialized is null."); _writer = new BamlWriter(output); _bamlTreeStack = new Stack <BamlTreeNode>(); // intialize the stack. _bamlTreeStack.Push(tree.Root); while (_bamlTreeStack.Count > 0) { BamlTreeNode currentNode = _bamlTreeStack.Pop(); if (!currentNode.Visited) { // Mark this node so that it won't be serialized again. currentNode.Visited = true; currentNode.Serialize(_writer); PushChildrenToStack(currentNode.Children); } else { BamlStartElementNode elementNode = currentNode as BamlStartElementNode; Debug.Assert(elementNode != null); if (elementNode != null) { localizer.RaiseErrorNotifyEvent( new BamlLocalizerErrorNotifyEventArgs( BamlTreeMap.GetKey(elementNode), BamlLocalizerError.DuplicateElement ) ); } } } // do not close stream as we don't own it. }
// Token: 0x06006EB8 RID: 28344 RVA: 0x001FD1C4 File Offset: 0x001FB3C4 private void GetLocalizabilityForElementNode(BamlStartElementNode node, out LocalizabilityAttribute localizability, out string formattingTag) { localizability = null; formattingTag = null; string assemblyName = node.AssemblyName; string typeFullName = node.TypeFullName; ElementLocalizability elementLocalizability = this._resolver.GetElementLocalizability(assemblyName, typeFullName); LocalizabilityGroup localizabilityComment = this._resolver.GetLocalizabilityComment(node, "$Content"); if (localizabilityComment != null) { localizability = localizabilityComment.Override(elementLocalizability.Attribute); } else { localizability = elementLocalizability.Attribute; } formattingTag = elementLocalizability.FormattingTag; }
private void SetLocalizationAttributes( BamlStartElementNode node, ElementComments comments, string attributes ) { if (!string.IsNullOrEmpty(attributes)) { try { comments.LocalizationAttributes = LocComments.ParsePropertyLocalizabilityAttributes(attributes); } catch (FormatException) { RaiseErrorNotifyEvent( new BamlLocalizerErrorNotifyEventArgs( BamlTreeMap.GetKey(node), BamlLocalizerError.InvalidLocalizationAttributes ) ); } } }
// Token: 0x06006EAB RID: 28331 RVA: 0x001FC55C File Offset: 0x001FA75C private static void CreateMissingBamlTreeNode(BamlLocalizationDictionary dictionary, BamlTreeUpdater.BamlTreeUpdateMap treeMap) { BamlLocalizationDictionaryEnumerator enumerator = dictionary.GetEnumerator(); while (enumerator.MoveNext()) { BamlLocalizableResourceKey key = enumerator.Key; BamlLocalizableResource value = enumerator.Value; if (treeMap.MapKeyToBamlTreeNode(key) == null) { if (key.PropertyName == "$Content") { if (treeMap.MapUidToBamlTreeElementNode(key.Uid) == null) { BamlStartElementNode bamlStartElementNode = new BamlStartElementNode(treeMap.Resolver.ResolveAssemblyFromClass(key.ClassName), key.ClassName, false, false); bamlStartElementNode.AddChild(new BamlDefAttributeNode("Uid", key.Uid)); BamlTreeUpdater.TryAddContentPropertyToNewElement(treeMap, bamlStartElementNode); bamlStartElementNode.AddChild(new BamlEndElementNode()); treeMap.AddBamlTreeNode(key.Uid, key, bamlStartElementNode); } } else { BamlTreeNode node; if (key.PropertyName == "$LiteralContent") { node = new BamlLiteralContentNode(value.Content); } else { node = new BamlPropertyNode(treeMap.Resolver.ResolveAssemblyFromClass(key.ClassName), key.ClassName, key.PropertyName, value.Content, BamlAttributeUsage.Default); } treeMap.AddBamlTreeNode(null, key, node); } } } }
// Token: 0x06006E19 RID: 28185 RVA: 0x001FB070 File Offset: 0x001F9270 private void SerializeImp(BamlLocalizer localizer, BamlTree tree, Stream output) { this._writer = new BamlWriter(output); this._bamlTreeStack = new Stack <BamlTreeNode>(); this._bamlTreeStack.Push(tree.Root); while (this._bamlTreeStack.Count > 0) { BamlTreeNode bamlTreeNode = this._bamlTreeStack.Pop(); if (!bamlTreeNode.Visited) { bamlTreeNode.Visited = true; bamlTreeNode.Serialize(this._writer); this.PushChildrenToStack(bamlTreeNode.Children); } else { BamlStartElementNode bamlStartElementNode = bamlTreeNode as BamlStartElementNode; if (bamlStartElementNode != null) { localizer.RaiseErrorNotifyEvent(new BamlLocalizerErrorNotifyEventArgs(BamlTreeMap.GetKey(bamlStartElementNode), BamlLocalizerError.DuplicateElement)); } } } }
private ElementComments LookupCommentForElement(BamlStartElementNode node) { Debug.Assert(node.NodeType == BamlNodeType.StartElement); if (node.Uid == null) { return(new ElementComments()); // return empty comments for null Uid } for (int i = 0; i < _comments.Length; i++) { if (_comments[i] != null && _comments[i].ElementId == node.Uid) { return(_comments[i]); } } ElementComments comment = new ElementComments(); comment.ElementId = node.Uid; if (_commentsDocument != null) { // select the xmlNode containing the comments XmlElement element = FindElementByID(_commentsDocument, node.Uid); if (element != null) { // parse the comments string locAttribute = element.GetAttribute(LocComments.LocLocalizabilityAttribute); SetLocalizationAttributes(node, comment, locAttribute); locAttribute = element.GetAttribute(LocComments.LocCommentsAttribute); SetLocalizationComments(node, comment, locAttribute); } } if (node.Children != null) { // // The baml itself might contain comments too // Grab the missing comments from Baml if there is any. // for (int i = 0; i < node.Children.Count && (comment.LocalizationComments.Length == 0 || comment.LocalizationAttributes.Length == 0); i++) { BamlTreeNode child = (BamlTreeNode)node.Children[i]; if (child.NodeType == BamlNodeType.Property) { BamlPropertyNode propertyNode = (BamlPropertyNode)child; if (LocComments.IsLocCommentsProperty(propertyNode.OwnerTypeFullName, propertyNode.PropertyName) && comment.LocalizationComments.Length == 0) { // grab comments from Baml SetLocalizationComments(node, comment, propertyNode.Value); } else if (LocComments.IsLocLocalizabilityProperty(propertyNode.OwnerTypeFullName, propertyNode.PropertyName) && comment.LocalizationAttributes.Length == 0) { // grab comments from Baml SetLocalizationAttributes(node, comment, propertyNode.Value); } } } } // cached it _comments[_commentsIndex] = comment; _commentsIndex = (_commentsIndex + 1) % _comments.Length; return(comment); }
internal string GetStringComment( BamlStartElementNode node, string localName ) { // get all the comments declares on this node ElementComments comment = LookupCommentForElement(node); for (int i = 0; i < comment.LocalizationComments.Length; i++) { if (comment.LocalizationComments[i].PropertyName == localName) { return (string) comment.LocalizationComments[i].Value; } } return null; }
// Token: 0x06006EB1 RID: 28337 RVA: 0x001FCAE4 File Offset: 0x001FACE4 private static bool GetBamlTreeNodeFromXmlNode(BamlLocalizableResourceKey key, XmlNode node, BamlTreeUpdater.BamlTreeUpdateMap bamlTreeMap, IList <BamlTreeNode> newChildrenList) { if (node.NodeType == XmlNodeType.Text) { return(BamlTreeUpdater.GetBamlTreeNodeFromText(key, node.Value, bamlTreeMap, newChildrenList)); } if (node.NodeType != XmlNodeType.Element) { return(true); } XmlElement xmlElement = node as XmlElement; string text = bamlTreeMap.Resolver.ResolveFormattingTagToClass(xmlElement.Name); bool flag = string.IsNullOrEmpty(text); string text2 = null; if (!flag) { text2 = bamlTreeMap.Resolver.ResolveAssemblyFromClass(text); flag = string.IsNullOrEmpty(text2); } if (flag) { bamlTreeMap.Resolver.RaiseErrorNotifyEvent(new BamlLocalizerErrorNotifyEventArgs(key, BamlLocalizerError.UnknownFormattingTag)); return(false); } string text3 = null; if (xmlElement.HasAttributes) { text3 = xmlElement.GetAttribute("Uid"); if (!string.IsNullOrEmpty(text3)) { text3 = BamlResourceContentUtil.UnescapeString(text3); } } BamlStartElementNode bamlStartElementNode = null; if (text3 != null) { bamlStartElementNode = bamlTreeMap.MapUidToBamlTreeElementNode(text3); } if (bamlStartElementNode == null) { bamlStartElementNode = new BamlStartElementNode(text2, text, false, false); if (text3 != null) { bamlTreeMap.AddBamlTreeNode(text3, new BamlLocalizableResourceKey(text3, text, "$Content", text2), bamlStartElementNode); bamlStartElementNode.AddChild(new BamlDefAttributeNode("Uid", text3)); } BamlTreeUpdater.TryAddContentPropertyToNewElement(bamlTreeMap, bamlStartElementNode); bamlStartElementNode.AddChild(new BamlEndElementNode()); } else if (bamlStartElementNode.TypeFullName != text) { bamlTreeMap.Resolver.RaiseErrorNotifyEvent(new BamlLocalizerErrorNotifyEventArgs(key, BamlLocalizerError.DuplicateUid)); return(false); } newChildrenList.Add(bamlStartElementNode); bool flag2 = true; if (xmlElement.HasChildNodes) { IList <BamlTreeNode> list = new List <BamlTreeNode>(); int num = 0; while (num < xmlElement.ChildNodes.Count && flag2) { flag2 = BamlTreeUpdater.GetBamlTreeNodeFromXmlNode(key, xmlElement.ChildNodes[num], bamlTreeMap, list); num++; } if (flag2) { BamlTreeUpdater.MergeChildrenList(key, bamlTreeMap, bamlStartElementNode, list); } } return(flag2); }
/// <summary> /// Combine inheritable attributes, and propegate it down the tree. /// </summary> /// <param name="node">current node</param> /// <param name="localizabilityFromSource">localizability defined in source code</param> /// <returns> /// The LocalizabilityAttribute to used for this node. It is not the same as the /// inheritable attributes of the node when the node is set to Ignore. /// </returns> /// <remarks>We always walk the baml tree in depth-first order</remarks> private LocalizabilityAttribute CombineAndPropagateInheritanceValues( ILocalizabilityInheritable node, LocalizabilityAttribute localizabilityFromSource ) { if (node == null) { return(localizabilityFromSource); } // If this node's inheritable localizability has been constructed, we can skip it // This can happen when recursively format the content if (node.InheritableAttribute != null) { return((!node.IsIgnored) ? node.InheritableAttribute : LocalizabilityIgnore); } // To test wether the current node needs to inherit values from parents. // It inherits values if: // o This node is set to Ignore, in which case it propagates parent values. // o Some of its attributes set to Inherit. if (localizabilityFromSource.Category != LocalizationCategory.Ignore && localizabilityFromSource.Category != LocalizationCategory.Inherit && localizabilityFromSource.Readability != Readability.Inherit && localizabilityFromSource.Modifiability != Modifiability.Inherit) { // just return the same one because no value is inherited node.InheritableAttribute = localizabilityFromSource; return(node.InheritableAttribute); } // find the ancestor to inherit values now. ILocalizabilityInheritable ancestor = node.LocalizabilityAncestor; // find out the attribute that is inheritable from above LocalizabilityAttribute inheritableAttribute = ancestor.InheritableAttribute; if (inheritableAttribute == null) { // if ancestor's inheritable value isn't resolved yet, we recursively // resolve it here. BamlStartElementNode elementNode = ancestor as BamlStartElementNode; if (elementNode != null) { string formattingTag; GetLocalizabilityForElementNode(elementNode, out inheritableAttribute, out formattingTag); } else { BamlStartComplexPropertyNode propertyNode = ancestor as BamlStartComplexPropertyNode; GetLocalizabilityForPropertyNode(propertyNode, out inheritableAttribute); } CombineAndPropagateInheritanceValues(ancestor, inheritableAttribute); inheritableAttribute = ancestor.InheritableAttribute; Debug.Assert(inheritableAttribute != null); } // if this item is set to ignore if (localizabilityFromSource.Category == LocalizationCategory.Ignore) { // It propagates ancestor's inheritable localizability, but it will use // its own value declared in source. // We also mark this node as being "Ignored" in the inheritance tree to signal that // this node is not using the inheritance value. node.InheritableAttribute = inheritableAttribute; node.IsIgnored = true; return(LocalizabilityIgnore); } // the item is not set to ignore, so we process the inheritable values BamlTreeNode treeNode = (BamlTreeNode)node; switch (treeNode.NodeType) { case BamlNodeType.StartElement: case BamlNodeType.LiteralContent: { // if everything set to inherit, we just return the inheritable localizability if (localizabilityFromSource.Category == LocalizationCategory.Inherit && localizabilityFromSource.Readability == Readability.Inherit && localizabilityFromSource.Modifiability == Modifiability.Inherit) { // just propagate the ancestor's localizability. node.InheritableAttribute = inheritableAttribute; } else { // set new inherited values node.InheritableAttribute = CreateInheritedLocalizability( localizabilityFromSource, inheritableAttribute ); } break; } case BamlNodeType.Property: case BamlNodeType.StartComplexProperty: { ILocalizabilityInheritable parent = (ILocalizabilityInheritable)treeNode.Parent; // Find the mininum localizability of the containing class and // parent property. Parent property means the proeprty from parent node that // has the same name. LocalizabilityAttribute inheritedAttribute = CombineMinimumLocalizability( inheritableAttribute, parent.InheritableAttribute ); node.InheritableAttribute = CreateInheritedLocalizability( localizabilityFromSource, inheritedAttribute ); if (parent.IsIgnored && localizabilityFromSource.Category == LocalizationCategory.Inherit) { // If the parent node is Ignore and this property is set to inherit, then // this property node is to be ignore as well. We set the the "Ignore" flag so that // the node will always be ignored without looking at the source localizability again. node.IsIgnored = true; return(LocalizabilityIgnore); } break; } default: { Debug.Assert(false, "Can't process localizability attribute on nodes other than Element, Property and LiteralContent."); break; } } return(node.InheritableAttribute); }
/// <summary> /// build a localizable resource from a baml tree node /// </summary> internal BamlLocalizableResource BuildFromNode(BamlLocalizableResourceKey key, BamlTreeNode node) { if (node.Formatted) { // the content of the node has been formatted to be part of // parents' content, so no need to create a seperate entry for the // element return(null); } BamlLocalizableResource resource = null; LocalizabilityAttribute localizability = null; string formattingTag; // // variable controling what comments gets applied // BamlStartElementNode commentNode = null; // node containing comment string commentTargetName = null; // the target of the comment, e.g. $Content, FontSize, etc. // // step 1: Get the localizability attribute from the source files // switch (node.NodeType) { case BamlNodeType.StartElement: { // For element commentNode = (BamlStartElementNode)node; GetLocalizabilityForElementNode(commentNode, out localizability, out formattingTag); commentTargetName = BamlConst.ContentSuffix; break; } case BamlNodeType.LiteralContent: { // For literal content, get the attribute from parent element GetLocalizabilityForElementNode((BamlStartElementNode)node.Parent, out localizability, out formattingTag); commentNode = (BamlStartElementNode)node.Parent; commentTargetName = BamlConst.ContentSuffix; break; } case BamlNodeType.Property: { BamlStartComplexPropertyNode propertyNode = (BamlStartComplexPropertyNode)node; if (LocComments.IsLocCommentsProperty(propertyNode.OwnerTypeFullName, propertyNode.PropertyName) || LocComments.IsLocLocalizabilityProperty(propertyNode.OwnerTypeFullName, propertyNode.PropertyName) ) { // skip Localization.Comments and Localization.Attributes properties. They aren't localizable return(null); } // For property GetLocalizabilityForPropertyNode(propertyNode, out localizability); commentTargetName = propertyNode.PropertyName; commentNode = (BamlStartElementNode)node.Parent; break; } default: { Invariant.Assert(false); // no localizable resource for such node break; } } // // Step 2: Find out the inheritance value // // The node participates in localizability inheritance // let's fill things in localizability = CombineAndPropagateInheritanceValues( node as ILocalizabilityInheritable, localizability ); // // Step 3: We finalized the localizability values. We now apply. // string content = null; if (localizability.Category != LocalizationCategory.NeverLocalize && localizability.Category != LocalizationCategory.Ignore && TryGetContent(key, node, out content)) { // we only create one if it is localizable resource = new BamlLocalizableResource(); resource.Readable = (localizability.Readability == Readability.Readable); resource.Modifiable = (localizability.Modifiability == Modifiability.Modifiable); resource.Category = localizability.Category; // continue to fill in content. resource.Content = content; resource.Comments = _resolver.GetStringComment(commentNode, commentTargetName); } // return the resource return(resource); }
// Token: 0x06006E10 RID: 28176 RVA: 0x001FA87C File Offset: 0x001F8A7C private BamlTree LoadBamlImp(Stream bamlSteam) { this._reader = new BamlReader(bamlSteam); this._reader.Read(); if (this._reader.NodeType != BamlNodeType.StartDocument) { throw new XamlParseException(SR.Get("InvalidStartOfBaml")); } this._root = new BamlStartDocumentNode(); this.PushNodeToStack(this._root); Hashtable hashtable = new Hashtable(8); IL_5C8: while (this._bamlTreeStack.Count > 0 && this._reader.Read()) { switch (this._reader.NodeType) { case BamlNodeType.EndDocument: { BamlTreeNode node = new BamlEndDocumentNode(); this.AddChildToCurrentParent(node); this.PopStack(); break; } case BamlNodeType.ConnectionId: case BamlNodeType.Property: case BamlNodeType.ContentProperty: case BamlNodeType.XmlnsProperty: case BamlNodeType.IncludeReference: case BamlNodeType.DefAttribute: case BamlNodeType.PresentationOptionsAttribute: goto IL_2DF; case BamlNodeType.StartElement: { BamlTreeNode node2 = new BamlStartElementNode(this._reader.AssemblyName, this._reader.Name, this._reader.IsInjected, this._reader.CreateUsingTypeConverter); this.PushNodeToStack(node2); break; } case BamlNodeType.EndElement: { BamlTreeNode node3 = new BamlEndElementNode(); this.AddChildToCurrentParent(node3); this.PopStack(); break; } case BamlNodeType.StartComplexProperty: { BamlStartComplexPropertyNode bamlStartComplexPropertyNode = new BamlStartComplexPropertyNode(this._reader.AssemblyName, this._reader.Name.Substring(0, this._reader.Name.LastIndexOf('.')), this._reader.LocalName); bamlStartComplexPropertyNode.LocalizabilityAncestor = this.PeekPropertyStack(bamlStartComplexPropertyNode.PropertyName); this.PushPropertyToStack(bamlStartComplexPropertyNode.PropertyName, bamlStartComplexPropertyNode); this.PushNodeToStack(bamlStartComplexPropertyNode); break; } case BamlNodeType.EndComplexProperty: { BamlTreeNode node4 = new BamlEndComplexPropertyNode(); this.AddChildToCurrentParent(node4); this.PopStack(); break; } case BamlNodeType.LiteralContent: { BamlTreeNode node5 = new BamlLiteralContentNode(this._reader.Value); this.AddChildToCurrentParent(node5); break; } case BamlNodeType.Text: { BamlTreeNode node6 = new BamlTextNode(this._reader.Value, this._reader.TypeConverterAssemblyName, this._reader.TypeConverterName); this.AddChildToCurrentParent(node6); break; } case BamlNodeType.RoutedEvent: { BamlTreeNode node7 = new BamlRoutedEventNode(this._reader.AssemblyName, this._reader.Name.Substring(0, this._reader.Name.LastIndexOf('.')), this._reader.LocalName, this._reader.Value); this.AddChildToCurrentParent(node7); break; } case BamlNodeType.Event: { BamlTreeNode node8 = new BamlEventNode(this._reader.Name, this._reader.Value); this.AddChildToCurrentParent(node8); break; } case BamlNodeType.PIMapping: { BamlTreeNode node9 = new BamlPIMappingNode(this._reader.XmlNamespace, this._reader.ClrNamespace, this._reader.AssemblyName); this.AddChildToCurrentParent(node9); break; } case BamlNodeType.StartConstructor: { BamlTreeNode node10 = new BamlStartConstructorNode(); this.AddChildToCurrentParent(node10); break; } case BamlNodeType.EndConstructor: { BamlTreeNode node11 = new BamlEndConstructorNode(); this.AddChildToCurrentParent(node11); break; } default: goto IL_2DF; } if (this._reader.HasProperties) { hashtable.Clear(); this._reader.MoveToFirstProperty(); for (;;) { BamlNodeType nodeType = this._reader.NodeType; switch (nodeType) { case BamlNodeType.ConnectionId: { BamlTreeNode node12 = new BamlConnectionIdNode(this._reader.ConnectionId); this.AddChildToCurrentParent(node12); break; } case BamlNodeType.StartElement: case BamlNodeType.EndElement: goto IL_58F; case BamlNodeType.Property: { BamlPropertyNode bamlPropertyNode = new BamlPropertyNode(this._reader.AssemblyName, this._reader.Name.Substring(0, this._reader.Name.LastIndexOf('.')), this._reader.LocalName, this._reader.Value, this._reader.AttributeUsage); bamlPropertyNode.LocalizabilityAncestor = this.PeekPropertyStack(bamlPropertyNode.PropertyName); this.PushPropertyToStack(bamlPropertyNode.PropertyName, bamlPropertyNode); this.AddChildToCurrentParent(bamlPropertyNode); if (hashtable.Contains(this._reader.Name)) { object obj = hashtable[this._reader.Name]; int num = 2; if (obj is BamlPropertyNode) { ((BamlPropertyNode)obj).Index = 1; } else { num = (int)obj; } bamlPropertyNode.Index = num; hashtable[this._reader.Name] = num + 1; } else { hashtable[this._reader.Name] = bamlPropertyNode; } break; } case BamlNodeType.ContentProperty: { BamlTreeNode node13 = new BamlContentPropertyNode(this._reader.AssemblyName, this._reader.Name.Substring(0, this._reader.Name.LastIndexOf('.')), this._reader.LocalName); this.AddChildToCurrentParent(node13); break; } case BamlNodeType.XmlnsProperty: { BamlTreeNode node14 = new BamlXmlnsPropertyNode(this._reader.LocalName, this._reader.Value); this.AddChildToCurrentParent(node14); break; } default: if (nodeType != BamlNodeType.DefAttribute) { if (nodeType != BamlNodeType.PresentationOptionsAttribute) { goto Block_6; } BamlTreeNode node15 = new BamlPresentationOptionsAttributeNode(this._reader.Name, this._reader.Value); this.AddChildToCurrentParent(node15); } else { if (this._reader.Name == "Uid") { ((BamlStartElementNode)this._currentParent).Uid = this._reader.Value; } BamlTreeNode node16 = new BamlDefAttributeNode(this._reader.Name, this._reader.Value); this.AddChildToCurrentParent(node16); } break; } if (!this._reader.MoveToNextProperty()) { goto IL_5C8; } } Block_6: IL_58F: throw new XamlParseException(SR.Get("UnRecognizedBamlNodeType", new object[] { this._reader.NodeType })); } continue; IL_2DF: throw new XamlParseException(SR.Get("UnRecognizedBamlNodeType", new object[] { this._reader.NodeType })); } if (this._reader.Read() || this._bamlTreeStack.Count > 0) { throw new XamlParseException(SR.Get("InvalidEndOfBaml")); } return(new BamlTree(this._root, this._nodeCount)); }
private void SetLocalizationComments( BamlStartElementNode node, ElementComments comments, string stringComment ) { if (!string.IsNullOrEmpty(stringComment)) { try { comments.LocalizationComments = LocComments.ParsePropertyComments(stringComment); } catch (FormatException) { RaiseErrorNotifyEvent( new BamlLocalizerErrorNotifyEventArgs( BamlTreeMap.GetKey(node), BamlLocalizerError.InvalidLocalizationComments ) ); } } }
private static void CreateMissingBamlTreeNode( BamlLocalizationDictionary dictionary, BamlTreeUpdateMap treeMap ) { BamlLocalizationDictionaryEnumerator enumerator = dictionary.GetEnumerator(); while (enumerator.MoveNext()) { BamlLocalizableResourceKey key = enumerator.Key; BamlLocalizableResource resource = enumerator.Value; // get the baml tree node from the tree BamlTreeNode node = treeMap.MapKeyToBamlTreeNode(key); if (node == null) { if (key.PropertyName == BamlConst.ContentSuffix) { // see if there is already a Baml node with the Uid. If so // ignore this entry node = treeMap.MapUidToBamlTreeElementNode(key.Uid); if (node == null) { // create new Baml element node BamlStartElementNode newNode = new BamlStartElementNode( treeMap.Resolver.ResolveAssemblyFromClass(key.ClassName), key.ClassName, false, /*isInjected*/ false /*CreateUsingTypeConverter*/ ); // create new x:Uid node for this element node newNode.AddChild( new BamlDefAttributeNode( XamlReaderHelper.DefinitionUid, key.Uid ) ); TryAddContentPropertyToNewElement(treeMap, newNode); // terminate the node with EndElementNode newNode.AddChild(new BamlEndElementNode()); // store this new node into the map so that it can be found // when other translations reference it as a childplace holder, or property owner treeMap.AddBamlTreeNode(key.Uid, key, newNode); } } else { BamlTreeNode newNode; if (key.PropertyName == BamlConst.LiteralContentSuffix) { // create a LiterContent node newNode = new BamlLiteralContentNode(resource.Content); } else { newNode = new BamlPropertyNode( treeMap.Resolver.ResolveAssemblyFromClass(key.ClassName), key.ClassName, key.PropertyName, resource.Content, BamlAttributeUsage.Default ); } // add to the map treeMap.AddBamlTreeNode(null, key, newNode); } } } }
// Token: 0x06006EAC RID: 28332 RVA: 0x001FC674 File Offset: 0x001FA874 private static bool ApplyChangeToBamlTree(BamlLocalizableResourceKey key, BamlLocalizableResource resource, BamlTreeUpdater.BamlTreeUpdateMap treeMap) { if (resource == null || resource.Content == null || !resource.Modifiable) { return(true); } if (!treeMap.LocalizationDictionary.Contains(key) && !treeMap.IsNewBamlTreeNode(key)) { return(true); } BamlTreeNode bamlTreeNode = treeMap.MapKeyToBamlTreeNode(key); Invariant.Assert(bamlTreeNode != null); BamlNodeType nodeType = bamlTreeNode.NodeType; if (nodeType != BamlNodeType.StartElement) { if (nodeType != BamlNodeType.Property) { if (nodeType == BamlNodeType.LiteralContent) { BamlLiteralContentNode bamlLiteralContentNode = (BamlLiteralContentNode)bamlTreeNode; bamlLiteralContentNode.Content = BamlResourceContentUtil.UnescapeString(resource.Content); if (bamlLiteralContentNode.Parent == null) { BamlTreeNode bamlTreeNode2 = treeMap.MapUidToBamlTreeElementNode(key.Uid); if (bamlTreeNode2 == null) { return(false); } bamlTreeNode2.AddChild(bamlLiteralContentNode); } } } else { BamlPropertyNode bamlPropertyNode = (BamlPropertyNode)bamlTreeNode; bamlPropertyNode.Value = BamlResourceContentUtil.UnescapeString(resource.Content); if (bamlPropertyNode.Parent == null) { BamlStartElementNode bamlStartElementNode = treeMap.MapUidToBamlTreeElementNode(key.Uid); if (bamlStartElementNode == null) { return(false); } bamlStartElementNode.InsertProperty(bamlTreeNode); } } } else { string b = null; if (treeMap.LocalizationDictionary.Contains(key)) { b = treeMap.LocalizationDictionary[key].Content; } if (resource.Content != b) { BamlTreeUpdater.ReArrangeChildren(key, bamlTreeNode, resource.Content, treeMap); } } return(true); }
internal override BamlTreeNode Copy() { BamlStartElementNode node = new BamlStartElementNode(_assemblyName, _typeFullName, _isInjected, _useTypeConverter); node._content = _content; node._uid = _uid; node._inheritableAttribute = _inheritableAttribute; return node; }
/// <summary> /// This builds the localizable string from the baml tree node /// </summary> /// <return> /// return true when the node has valid localizable content, false otherwise. /// </return> internal bool TryGetContent(BamlLocalizableResourceKey key, BamlTreeNode currentNode, out string content) { content = string.Empty; switch (currentNode.NodeType) { case BamlNodeType.Property: { bool isValidContent = true; BamlPropertyNode propertyNode = (BamlPropertyNode)currentNode; content = BamlResourceContentUtil.EscapeString(propertyNode.Value); // // Markup extensions are not localizable values, e.g. {x:Type SolidColorBrush}. // So if the string can be parsed as Markup extensions, we will exclude it unless // the user sets localization comments explicitly to localize this value. // string typeName, args; string tempContent = content; if (MarkupExtensionParser.GetMarkupExtensionTypeAndArgs(ref tempContent, out typeName, out args)) { // See if this value has been marked as localizable explicitly in comments LocalizabilityGroup localizability = _resolver.GetLocalizabilityComment( propertyNode.Parent as BamlStartElementNode, propertyNode.PropertyName ); isValidContent = (localizability != null && localizability.Readability == Readability.Readable); } return(isValidContent); } case BamlNodeType.LiteralContent: { content = BamlResourceContentUtil.EscapeString( ((BamlLiteralContentNode)currentNode).Content ); return(true); // succeed } case BamlNodeType.StartElement: { BamlStartElementNode elementNode = (BamlStartElementNode)currentNode; if (elementNode.Content == null) { StringBuilder contentBuilder = new StringBuilder(); foreach (BamlTreeNode child in elementNode.Children) { // we only format element and text inline // other nodes like property node we don't put them into the content of the element switch (child.NodeType) { case BamlNodeType.StartElement: { string childContent; if (TryFormatElementContent(key, (BamlStartElementNode)child, out childContent)) { contentBuilder.Append(childContent); } else { return(false); // failed to get content for children element } break; } case BamlNodeType.Text: { contentBuilder.Append(BamlResourceContentUtil.EscapeString( ((BamlTextNode)child).Content) ); break; } } } elementNode.Content = contentBuilder.ToString(); } content = elementNode.Content; return(true); } default: return(true); } }
//----------------------------- // private methods //----------------------------- /// <summary> /// build the baml element tree as well as the localizability inheritance tree /// </summary> /// <param name="bamlSteam">input baml stream.</param> /// <returns>the tree constructed.</returns> private BamlTree LoadBamlImp(Stream bamlSteam) { _reader = new BamlReader(bamlSteam); _reader.Read(); if (_reader.NodeType != BamlNodeType.StartDocument) { throw new XamlParseException(SR.Get(SRID.InvalidStartOfBaml)); } // create root element. _root = new BamlStartDocumentNode(); PushNodeToStack(_root); // A hash table used to handle duplicate properties within an element Hashtable propertyOccurrences = new Hashtable(8); // create the tree by depth first traversal. while (_bamlTreeStack.Count > 0 && _reader.Read()) { switch (_reader.NodeType) { case BamlNodeType.StartElement : { BamlTreeNode bamlNode = new BamlStartElementNode( _reader.AssemblyName, _reader.Name, _reader.IsInjected, _reader.CreateUsingTypeConverter ); PushNodeToStack(bamlNode); break; } case BamlNodeType.EndElement : { BamlTreeNode bamlNode = new BamlEndElementNode(); AddChildToCurrentParent(bamlNode); PopStack(); break; } case BamlNodeType.StartComplexProperty : { BamlStartComplexPropertyNode bamlNode = new BamlStartComplexPropertyNode( _reader.AssemblyName, _reader.Name.Substring(0, _reader.Name.LastIndexOf('.')), _reader.LocalName ); bamlNode.LocalizabilityAncestor = PeekPropertyStack(bamlNode.PropertyName); PushPropertyToStack(bamlNode.PropertyName, (ILocalizabilityInheritable) bamlNode); PushNodeToStack(bamlNode); break; } case BamlNodeType.EndComplexProperty : { BamlTreeNode bamlNode = new BamlEndComplexPropertyNode(); AddChildToCurrentParent(bamlNode); PopStack(); break; } case BamlNodeType.Event : { BamlTreeNode bamlNode = new BamlEventNode(_reader.Name, _reader.Value); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.RoutedEvent : { BamlTreeNode bamlNode = new BamlRoutedEventNode( _reader.AssemblyName, _reader.Name.Substring(0, _reader.Name.LastIndexOf('.')), _reader.LocalName, _reader.Value ); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.PIMapping : { BamlTreeNode bamlNode = new BamlPIMappingNode( _reader.XmlNamespace, _reader.ClrNamespace, _reader.AssemblyName ); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.LiteralContent : { BamlTreeNode bamlNode = new BamlLiteralContentNode(_reader.Value); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.Text : { BamlTreeNode bamlNode = new BamlTextNode( _reader.Value, _reader.TypeConverterAssemblyName, _reader.TypeConverterName ); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.StartConstructor : { BamlTreeNode bamlNode = new BamlStartConstructorNode(); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.EndConstructor : { BamlTreeNode bamlNode = new BamlEndConstructorNode(); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.EndDocument : { BamlTreeNode bamlNode = new BamlEndDocumentNode(); AddChildToCurrentParent(bamlNode); PopStack(); break; } default : { throw new XamlParseException(SR.Get(SRID.UnRecognizedBamlNodeType, _reader.NodeType)); } } // read properties if it has any. if (_reader.HasProperties) { // The Hashtable is used to auto-number repeated properties. The usage is as the following: // When encountering the 1st occurrence of the property, it stores a reference to the property's node (BamlTreeNode). // When encountering the property the 2nd time, we start auto-numbering the property including the 1st occurrence // and store the index count (int) in the slot from that point onwards. propertyOccurrences.Clear(); _reader.MoveToFirstProperty(); do { switch (_reader.NodeType) { case BamlNodeType.ConnectionId: { BamlTreeNode bamlNode = new BamlConnectionIdNode(_reader.ConnectionId); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.Property : { BamlPropertyNode bamlNode = new BamlPropertyNode( _reader.AssemblyName, _reader.Name.Substring(0, _reader.Name.LastIndexOf('.')), _reader.LocalName, _reader.Value, _reader.AttributeUsage ); bamlNode.LocalizabilityAncestor = PeekPropertyStack(bamlNode.PropertyName); PushPropertyToStack(bamlNode.PropertyName, (ILocalizabilityInheritable) bamlNode); AddChildToCurrentParent(bamlNode); if (propertyOccurrences.Contains(_reader.Name)) { // we autonumber properties that have occurrences larger than 1 object occurrence = propertyOccurrences[_reader.Name]; int index = 2; if (occurrence is BamlPropertyNode) { // start numbering this property as the 2nd occurrence is encountered // the value stores the 1st occurrence of the property at this point ((BamlPropertyNode) occurrence).Index = 1; }else { // For the 3rd or more occurrences, the value stores the next index // to assign to the property index = (int) occurrence; } // auto-number the current property node ((BamlPropertyNode)bamlNode).Index = index; propertyOccurrences[_reader.Name] = ++index; } else { // store the first occurrence of the property propertyOccurrences[_reader.Name] = bamlNode; } break; } case BamlNodeType.DefAttribute : { if (_reader.Name == XamlReaderHelper.DefinitionUid) { // set the Uid proeprty when we see it. ((BamlStartElementNode)_currentParent).Uid = _reader.Value; } BamlTreeNode bamlNode = new BamlDefAttributeNode( _reader.Name, _reader.Value ); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.XmlnsProperty : { BamlTreeNode bamlNode = new BamlXmlnsPropertyNode( _reader.LocalName, _reader.Value ); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.ContentProperty : { BamlTreeNode bamlNode = new BamlContentPropertyNode( _reader.AssemblyName, _reader.Name.Substring(0, _reader.Name.LastIndexOf('.')), _reader.LocalName ); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.PresentationOptionsAttribute: { BamlTreeNode bamlNode = new BamlPresentationOptionsAttributeNode( _reader.Name, _reader.Value ); AddChildToCurrentParent(bamlNode); break; } default : { throw new XamlParseException(SR.Get(SRID.UnRecognizedBamlNodeType, _reader.NodeType)); } } } while (_reader.MoveToNextProperty()); } } // At this point, the baml tree stack should be completely unwinded and also nothing more to read. if (_reader.Read() || _bamlTreeStack.Count > 0) { throw new XamlParseException(SR.Get(SRID.InvalidEndOfBaml)); } return new BamlTree(_root, _nodeCount); //notice that we don't close the input stream because we don't own it. }
private bool TryFormatElementContent( BamlLocalizableResourceKey key, BamlStartElementNode node, out string content ) { content = string.Empty; string formattingTag; LocalizabilityAttribute attribute; GetLocalizabilityForElementNode(node, out attribute, out formattingTag); attribute = CombineAndPropagateInheritanceValues(node, attribute); if (formattingTag != null && attribute.Category != LocalizationCategory.NeverLocalize && attribute.Category != LocalizationCategory.Ignore && attribute.Modifiability == Modifiability.Modifiable && attribute.Readability == Readability.Readable ) { // this node should be formatted inline StringBuilder contentBuilder = new StringBuilder(); // write opening tag if (node.Uid != null) { contentBuilder.AppendFormat( TypeConverterHelper.InvariantEnglishUS, "<{0} {1}=\"{2}\">", formattingTag, XamlReaderHelper.DefinitionUid, BamlResourceContentUtil.EscapeString(node.Uid) ); } else { contentBuilder.AppendFormat(TypeConverterHelper.InvariantEnglishUS, "<{0}>", formattingTag); } // recurisively call down to format the content string childContent; bool succeed = TryGetContent(key, node, out childContent); if (succeed) { contentBuilder.Append(childContent); // write closing tag contentBuilder.AppendFormat(TypeConverterHelper.InvariantEnglishUS, "</{0}>", formattingTag); // remeber that we format this element so that we don't format the value again. // e.g. <Text x:Uid="t"> <Bold x:Uid="b"> ... </Bold> </Text> // if <Bold> is already inlined in Text element's contennt, we don't need to // have a seperate entry for <Bold> anymore node.Formatted = true; content = contentBuilder.ToString(); } return(succeed); } else { // this node should be represented by place holder. bool succeed = true; if (node.Uid != null) { content = string.Format( TypeConverterHelper.InvariantEnglishUS, "{0}{1}{2}", BamlConst.ChildStart, BamlResourceContentUtil.EscapeString(node.Uid), BamlConst.ChildEnd ); } else { // we want to enforce the rule that all children element // must have UID defined. _resolver.RaiseErrorNotifyEvent( new BamlLocalizerErrorNotifyEventArgs( key, BamlLocalizerError.UidMissingOnChildElement ) ); succeed = false; // failed } return(succeed); } }
//----------------------------- // private methods //----------------------------- /// <summary> /// build the baml element tree as well as the localizability inheritance tree /// </summary> /// <param name="bamlSteam">input baml stream.</param> /// <returns>the tree constructed.</returns> private BamlTree LoadBamlImp(Stream bamlSteam) { _reader = new BamlReader(bamlSteam); _reader.Read(); if (_reader.NodeType != BamlNodeType.StartDocument) { throw new XamlParseException(SR.Get(SRID.InvalidStartOfBaml)); } // create root element. _root = new BamlStartDocumentNode(); PushNodeToStack(_root); // A hash table used to handle duplicate properties within an element Hashtable propertyOccurrences = new Hashtable(8); // create the tree by depth first traversal. while (_bamlTreeStack.Count > 0 && _reader.Read()) { switch (_reader.NodeType) { case BamlNodeType.StartElement: { BamlTreeNode bamlNode = new BamlStartElementNode( _reader.AssemblyName, _reader.Name, _reader.IsInjected, _reader.CreateUsingTypeConverter ); PushNodeToStack(bamlNode); break; } case BamlNodeType.EndElement: { BamlTreeNode bamlNode = new BamlEndElementNode(); AddChildToCurrentParent(bamlNode); PopStack(); break; } case BamlNodeType.StartComplexProperty: { BamlStartComplexPropertyNode bamlNode = new BamlStartComplexPropertyNode( _reader.AssemblyName, _reader.Name.Substring(0, _reader.Name.LastIndexOf('.')), _reader.LocalName ); bamlNode.LocalizabilityAncestor = PeekPropertyStack(bamlNode.PropertyName); PushPropertyToStack(bamlNode.PropertyName, (ILocalizabilityInheritable)bamlNode); PushNodeToStack(bamlNode); break; } case BamlNodeType.EndComplexProperty: { BamlTreeNode bamlNode = new BamlEndComplexPropertyNode(); AddChildToCurrentParent(bamlNode); PopStack(); break; } case BamlNodeType.Event: { BamlTreeNode bamlNode = new BamlEventNode(_reader.Name, _reader.Value); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.RoutedEvent: { BamlTreeNode bamlNode = new BamlRoutedEventNode( _reader.AssemblyName, _reader.Name.Substring(0, _reader.Name.LastIndexOf('.')), _reader.LocalName, _reader.Value ); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.PIMapping: { BamlTreeNode bamlNode = new BamlPIMappingNode( _reader.XmlNamespace, _reader.ClrNamespace, _reader.AssemblyName ); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.LiteralContent: { BamlTreeNode bamlNode = new BamlLiteralContentNode(_reader.Value); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.Text: { BamlTreeNode bamlNode = new BamlTextNode( _reader.Value, _reader.TypeConverterAssemblyName, _reader.TypeConverterName ); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.StartConstructor: { BamlTreeNode bamlNode = new BamlStartConstructorNode(); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.EndConstructor: { BamlTreeNode bamlNode = new BamlEndConstructorNode(); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.EndDocument: { BamlTreeNode bamlNode = new BamlEndDocumentNode(); AddChildToCurrentParent(bamlNode); PopStack(); break; } default: { throw new XamlParseException(SR.Get(SRID.UnRecognizedBamlNodeType, _reader.NodeType)); } } // read properties if it has any. if (_reader.HasProperties) { // The Hashtable is used to auto-number repeated properties. The usage is as the following: // When encountering the 1st occurrence of the property, it stores a reference to the property's node (BamlTreeNode). // When encountering the property the 2nd time, we start auto-numbering the property including the 1st occurrence // and store the index count (int) in the slot from that point onwards. propertyOccurrences.Clear(); _reader.MoveToFirstProperty(); do { switch (_reader.NodeType) { case BamlNodeType.ConnectionId: { BamlTreeNode bamlNode = new BamlConnectionIdNode(_reader.ConnectionId); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.Property: { BamlPropertyNode bamlNode = new BamlPropertyNode( _reader.AssemblyName, _reader.Name.Substring(0, _reader.Name.LastIndexOf('.')), _reader.LocalName, _reader.Value, _reader.AttributeUsage ); bamlNode.LocalizabilityAncestor = PeekPropertyStack(bamlNode.PropertyName); PushPropertyToStack(bamlNode.PropertyName, (ILocalizabilityInheritable)bamlNode); AddChildToCurrentParent(bamlNode); if (propertyOccurrences.Contains(_reader.Name)) { // we autonumber properties that have occurrences larger than 1 object occurrence = propertyOccurrences[_reader.Name]; int index = 2; if (occurrence is BamlPropertyNode) { // start numbering this property as the 2nd occurrence is encountered // the value stores the 1st occurrence of the property at this point ((BamlPropertyNode)occurrence).Index = 1; } else { // For the 3rd or more occurrences, the value stores the next index // to assign to the property index = (int)occurrence; } // auto-number the current property node ((BamlPropertyNode)bamlNode).Index = index; propertyOccurrences[_reader.Name] = ++index; } else { // store the first occurrence of the property propertyOccurrences[_reader.Name] = bamlNode; } break; } case BamlNodeType.DefAttribute: { if (_reader.Name == XamlReaderHelper.DefinitionUid) { // set the Uid proeprty when we see it. ((BamlStartElementNode)_currentParent).Uid = _reader.Value; } BamlTreeNode bamlNode = new BamlDefAttributeNode( _reader.Name, _reader.Value ); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.XmlnsProperty: { BamlTreeNode bamlNode = new BamlXmlnsPropertyNode( _reader.LocalName, _reader.Value ); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.ContentProperty: { BamlTreeNode bamlNode = new BamlContentPropertyNode( _reader.AssemblyName, _reader.Name.Substring(0, _reader.Name.LastIndexOf('.')), _reader.LocalName ); AddChildToCurrentParent(bamlNode); break; } case BamlNodeType.PresentationOptionsAttribute: { BamlTreeNode bamlNode = new BamlPresentationOptionsAttributeNode( _reader.Name, _reader.Value ); AddChildToCurrentParent(bamlNode); break; } default: { throw new XamlParseException(SR.Get(SRID.UnRecognizedBamlNodeType, _reader.NodeType)); } } } while (_reader.MoveToNextProperty()); } } // At this point, the baml tree stack should be completely unwinded and also nothing more to read. if (_reader.Read() || _bamlTreeStack.Count > 0) { throw new XamlParseException(SR.Get(SRID.InvalidEndOfBaml)); } return(new BamlTree(_root, _nodeCount)); //notice that we don't close the input stream because we don't own it. }
// Grab the comments on a BamlTreeNode for the value. internal LocalizabilityGroup GetLocalizabilityComment( BamlStartElementNode node, string localName ) { // get all the comments declares on this node ElementComments comment = LookupCommentForElement(node); for (int i = 0; i < comment.LocalizationAttributes.Length; i++) { if (comment.LocalizationAttributes[i].PropertyName == localName) { return (LocalizabilityGroup) comment.LocalizationAttributes[i].Value; } } return null; }
//-------------------------------------- // Private methods //-------------------------------------- // construct the maps for enumeration internal void EnsureMap() { if (_localizableResources != null) { return; // map is already created. } // create the table based on the treesize passed in // the hashtable is for look-up during update _resolver.InitLocalizabilityCache(); _keyToBamlNodeIndexMap = new Hashtable(_tree.Size); _uidToBamlNodeIndexMap = new Hashtable(_tree.Size / 2); _localizableResources = new BamlLocalizationDictionary(); for (int i = 0; i < _tree.Size; i++) { BamlTreeNode currentNode = _tree[i]; // a node may be marked as unidentifiable if it or its parent has a duplicate uid. if (currentNode.Unidentifiable) { continue; // skip unidentifiable nodes } if (currentNode.NodeType == BamlNodeType.StartElement) { // remember classes encountered in this baml BamlStartElementNode elementNode = (BamlStartElementNode)currentNode; _resolver.AddClassAndAssembly(elementNode.TypeFullName, elementNode.AssemblyName); } // find the Uid of the current node BamlLocalizableResourceKey key = GetKey(currentNode); if (key != null) { if (currentNode.NodeType == BamlNodeType.StartElement) { // store uid mapping to the corresponding element node if (_uidToBamlNodeIndexMap.ContainsKey(key.Uid)) { _resolver.RaiseErrorNotifyEvent( new BamlLocalizerErrorNotifyEventArgs( key, BamlLocalizerError.DuplicateUid ) ); // Mark this element and its properties unidentifiable. currentNode.Unidentifiable = true; if (currentNode.Children != null) { foreach (BamlTreeNode child in currentNode.Children) { if (child.NodeType != BamlNodeType.StartElement) { child.Unidentifiable = true; } } } continue; // skip the duplicate node } else { _uidToBamlNodeIndexMap.Add(key.Uid, i); } } _keyToBamlNodeIndexMap.Add(key, i); if (_localizableResources.RootElementKey == null && currentNode.NodeType == BamlNodeType.StartElement && currentNode.Parent != null && currentNode.Parent.NodeType == BamlNodeType.StartDocument) { // remember the key to the root element so that // users can further add modifications to the root that would have a global impact. // such as FlowDirection or CultureInfo _localizableResources.SetRootElementKey(key); } // create the resource and add to the dictionary BamlLocalizableResource resource = _localizableResourceBuilder.BuildFromNode(key, currentNode); if (resource != null) { _localizableResources.Add(key, resource); } } } _resolver.ReleaseLocalizabilityCache(); }
private bool TryFormatElementContent( BamlLocalizableResourceKey key, BamlStartElementNode node, out string content ) { content = string.Empty; string formattingTag; LocalizabilityAttribute attribute; GetLocalizabilityForElementNode(node, out attribute, out formattingTag); attribute = CombineAndPropagateInheritanceValues(node, attribute); if ( formattingTag != null && attribute.Category != LocalizationCategory.NeverLocalize && attribute.Category != LocalizationCategory.Ignore && attribute.Modifiability == Modifiability.Modifiable && attribute.Readability == Readability.Readable ) { // this node should be formatted inline StringBuilder contentBuilder = new StringBuilder(); // write opening tag if (node.Uid != null) { contentBuilder.AppendFormat( TypeConverterHelper.InvariantEnglishUS, "<{0} {1}=\"{2}\">", formattingTag, XamlReaderHelper.DefinitionUid, BamlResourceContentUtil.EscapeString(node.Uid) ); } else { contentBuilder.AppendFormat(TypeConverterHelper.InvariantEnglishUS, "<{0}>", formattingTag); } // recurisively call down to format the content string childContent; bool succeed = TryGetContent(key, node, out childContent); if (succeed) { contentBuilder.Append(childContent); // write closing tag contentBuilder.AppendFormat(TypeConverterHelper.InvariantEnglishUS, "</{0}>", formattingTag); // remeber that we format this element so that we don't format the value again. // e.g. <Text x:Uid="t"> <Bold x:Uid="b"> ... </Bold> </Text> // if <Bold> is already inlined in Text element's contennt, we don't need to // have a seperate entry for <Bold> anymore node.Formatted = true; content = contentBuilder.ToString(); } return succeed; } else { // this node should be represented by place holder. bool succeed = true; if (node.Uid != null) { content = string.Format( TypeConverterHelper.InvariantEnglishUS, "{0}{1}{2}", BamlConst.ChildStart, BamlResourceContentUtil.EscapeString(node.Uid), BamlConst.ChildEnd ); } else { // we want to enforce the rule that all children element // must have UID defined. _resolver.RaiseErrorNotifyEvent( new BamlLocalizerErrorNotifyEventArgs( key, BamlLocalizerError.UidMissingOnChildElement ) ); succeed = false; // failed } return succeed; } }
//------------------------------------------------- // Internal static //------------------------------------------------- /// <summary> /// Return the localizable resource key for this baml tree node. /// If this node shouldn't be localized, the key returned will be null. /// </summary> internal static BamlLocalizableResourceKey GetKey(BamlTreeNode node) { BamlLocalizableResourceKey key = null; switch (node.NodeType) { case BamlNodeType.StartElement: { BamlStartElementNode elementNode = (BamlStartElementNode)node; if (elementNode.Uid != null) { key = new BamlLocalizableResourceKey( elementNode.Uid, elementNode.TypeFullName, BamlConst.ContentSuffix, elementNode.AssemblyName ); } break; } case BamlNodeType.Property: { BamlPropertyNode propertyNode = (BamlPropertyNode)node; BamlStartElementNode parent = (BamlStartElementNode)propertyNode.Parent; if (parent.Uid != null) { string uid; if (propertyNode.Index <= 0) { uid = parent.Uid; } else { // This node is auto-numbered. This has to do with the fact that // the compiler may compile duplicated properties into Baml under the same element. uid = string.Format( TypeConverterHelper.InvariantEnglishUS, "{0}.{1}_{2}", parent.Uid, propertyNode.PropertyName, propertyNode.Index ); } key = new BamlLocalizableResourceKey( uid, propertyNode.OwnerTypeFullName, propertyNode.PropertyName, propertyNode.AssemblyName ); } break; } case BamlNodeType.LiteralContent: { BamlLiteralContentNode literalNode = (BamlLiteralContentNode)node; BamlStartElementNode parent = (BamlStartElementNode)node.Parent; if (parent.Uid != null) { key = new BamlLocalizableResourceKey( parent.Uid, parent.TypeFullName, BamlConst.LiteralContentSuffix, parent.AssemblyName ); } break; } } return(key); }
private static bool GetBamlTreeNodeFromXmlNode( BamlLocalizableResourceKey key, XmlNode node, // xml node to construct BamlTreeNode from BamlTreeUpdateMap bamlTreeMap, // Baml tree update map IList<BamlTreeNode> newChildrenList // list of new children ) { if (node.NodeType == XmlNodeType.Text) { // construct a Text tree node from the xml content return GetBamlTreeNodeFromText( key, node.Value, bamlTreeMap, newChildrenList ); } else if (node.NodeType == XmlNodeType.Element) { XmlElement child = node as XmlElement; string className = bamlTreeMap.Resolver.ResolveFormattingTagToClass(child.Name); bool invalidResult = string.IsNullOrEmpty(className); string assemblyName = null; if (!invalidResult) { assemblyName = bamlTreeMap.Resolver.ResolveAssemblyFromClass(className); invalidResult = string.IsNullOrEmpty(assemblyName); } if (invalidResult) { bamlTreeMap.Resolver.RaiseErrorNotifyEvent( new BamlLocalizerErrorNotifyEventArgs( key, BamlLocalizerError.UnknownFormattingTag ) ); return false; } // get the uid for this formatting tag string tagUid = null; if (child.HasAttributes) { tagUid = child.GetAttribute(XamlReaderHelper.DefinitionUid); if (!string.IsNullOrEmpty(tagUid)) tagUid = BamlResourceContentUtil.UnescapeString(tagUid); } BamlStartElementNode bamlNode = null; if (tagUid != null) { bamlNode = bamlTreeMap.MapUidToBamlTreeElementNode(tagUid); } if (bamlNode == null) { bamlNode = new BamlStartElementNode( assemblyName, className, false, /*isInjected*/ false /*CreateUsingTypeConverter*/ ); if (tagUid != null) { // store the new node created bamlTreeMap.AddBamlTreeNode( tagUid, new BamlLocalizableResourceKey(tagUid, className, BamlConst.ContentSuffix, assemblyName), bamlNode ); // Add the x:Uid node to the element bamlNode.AddChild( new BamlDefAttributeNode( XamlReaderHelper.DefinitionUid, tagUid ) ); } TryAddContentPropertyToNewElement(bamlTreeMap, bamlNode); // terminate the child by a end element node bamlNode.AddChild(new BamlEndElementNode()); } else { if (bamlNode.TypeFullName != className) { // This can happen if the localizer adds a new element with an id // that is also been added to the newer version of source baml bamlTreeMap.Resolver.RaiseErrorNotifyEvent( new BamlLocalizerErrorNotifyEventArgs( key, BamlLocalizerError.DuplicateUid ) ); return false; } } newChildrenList.Add(bamlNode); bool succeed = true; if (child.HasChildNodes) { // recursively go down IList<BamlTreeNode> list = new List<BamlTreeNode>(); for (int i = 0; i < child.ChildNodes.Count && succeed; i++) { succeed = GetBamlTreeNodeFromXmlNode( key, child.ChildNodes[i], bamlTreeMap, list ); } if (succeed) { // merging the formatting translation with exisiting nodes. // formatting translation doesn't contain properties. MergeChildrenList(key, bamlTreeMap, bamlNode, list); } } return succeed; } return true; // other than text and element nodes }
private ElementComments LookupCommentForElement(BamlStartElementNode node) { Debug.Assert(node.NodeType == BamlNodeType.StartElement); if (node.Uid == null) { return new ElementComments(); // return empty comments for null Uid } for (int i = 0; i < _comments.Length; i++) { if (_comments[i] != null && _comments[i].ElementId == node.Uid) { return _comments[i]; } } ElementComments comment = new ElementComments(); comment.ElementId = node.Uid; if (_commentsDocument != null) { // select the xmlNode containing the comments XmlElement element = FindElementByID(_commentsDocument, node.Uid); if (element != null) { // parse the comments string locAttribute = element.GetAttribute(LocComments.LocLocalizabilityAttribute); SetLocalizationAttributes(node, comment, locAttribute); locAttribute = element.GetAttribute(LocComments.LocCommentsAttribute); SetLocalizationComments(node, comment, locAttribute); } } if (node.Children != null) { // // The baml itself might contain comments too // Grab the missing comments from Baml if there is any. // for (int i = 0; i < node.Children.Count && (comment.LocalizationComments.Length == 0 || comment.LocalizationAttributes.Length == 0); i++) { BamlTreeNode child = (BamlTreeNode) node.Children[i]; if (child.NodeType == BamlNodeType.Property) { BamlPropertyNode propertyNode = (BamlPropertyNode) child; if (LocComments.IsLocCommentsProperty(propertyNode.OwnerTypeFullName, propertyNode.PropertyName) && comment.LocalizationComments.Length == 0) { // grab comments from Baml SetLocalizationComments(node, comment, propertyNode.Value); } else if (LocComments.IsLocLocalizabilityProperty(propertyNode.OwnerTypeFullName, propertyNode.PropertyName) && comment.LocalizationAttributes.Length == 0) { // grab comments from Baml SetLocalizationAttributes(node, comment, propertyNode.Value); } } } } // cached it _comments[_commentsIndex] = comment; _commentsIndex = (_commentsIndex + 1) % _comments.Length; return comment; }
// Token: 0x06006EAE RID: 28334 RVA: 0x001FC7C0 File Offset: 0x001FA9C0 private static void MergeChildrenList(BamlLocalizableResourceKey key, BamlTreeUpdater.BamlTreeUpdateMap treeMap, BamlTreeNode parent, IList <BamlTreeNode> newChildren) { if (newChildren == null) { return; } List <BamlTreeNode> children = parent.Children; int i = 0; StringBuilder stringBuilder = new StringBuilder(); if (children != null) { Hashtable hashtable = new Hashtable(newChildren.Count); foreach (BamlTreeNode bamlTreeNode in newChildren) { if (bamlTreeNode.NodeType == BamlNodeType.StartElement) { BamlStartElementNode bamlStartElementNode = (BamlStartElementNode)bamlTreeNode; if (bamlStartElementNode.Uid != null) { if (hashtable.ContainsKey(bamlStartElementNode.Uid)) { treeMap.Resolver.RaiseErrorNotifyEvent(new BamlLocalizerErrorNotifyEventArgs(key, BamlLocalizerError.DuplicateElement)); return; } hashtable[bamlStartElementNode.Uid] = null; } } } parent.Children = null; for (int j = 0; j < children.Count - 1; j++) { BamlTreeNode bamlTreeNode2 = children[j]; BamlNodeType nodeType = bamlTreeNode2.NodeType; if (nodeType != BamlNodeType.StartElement) { if (nodeType != BamlNodeType.Text) { parent.AddChild(bamlTreeNode2); } } else { BamlStartElementNode bamlStartElementNode2 = (BamlStartElementNode)bamlTreeNode2; if (bamlStartElementNode2.Uid != null) { if (!hashtable.ContainsKey(bamlStartElementNode2.Uid)) { parent.Children = children; treeMap.Resolver.RaiseErrorNotifyEvent(new BamlLocalizerErrorNotifyEventArgs(key, BamlLocalizerError.MismatchedElements)); return; } hashtable.Remove(bamlStartElementNode2.Uid); } while (i < newChildren.Count) { BamlTreeNode bamlTreeNode3 = newChildren[i++]; Invariant.Assert(bamlTreeNode3 != null); if (bamlTreeNode3.NodeType == BamlNodeType.Text) { stringBuilder.Append(((BamlTextNode)bamlTreeNode3).Content); } else { BamlTreeUpdater.TryFlushTextToBamlNode(parent, stringBuilder); parent.AddChild(bamlTreeNode3); if (bamlTreeNode3.NodeType == BamlNodeType.StartElement) { break; } } } } } } while (i < newChildren.Count) { BamlTreeNode bamlTreeNode4 = newChildren[i]; Invariant.Assert(bamlTreeNode4 != null); if (bamlTreeNode4.NodeType == BamlNodeType.Text) { stringBuilder.Append(((BamlTextNode)bamlTreeNode4).Content); } else { BamlTreeUpdater.TryFlushTextToBamlNode(parent, stringBuilder); parent.AddChild(bamlTreeNode4); } i++; } BamlTreeUpdater.TryFlushTextToBamlNode(parent, stringBuilder); parent.AddChild(new BamlEndElementNode()); }