private void PopStack() { BamlTreeNode node = _bamlTreeStack.Pop(); if (node.Children != null) { // pop properties from property inheritance stack as well foreach (BamlTreeNode child in node.Children) { BamlStartComplexPropertyNode propertyNode = child as BamlStartComplexPropertyNode; if (propertyNode != null) { PopPropertyFromStack(propertyNode.PropertyName); } } } if (_bamlTreeStack.Count > 0) { _currentParent = _bamlTreeStack.Peek(); } else { // stack is empty. Set CurrentParent to null _currentParent = null; } }
// Token: 0x06006E39 RID: 28217 RVA: 0x001FBCC0 File Offset: 0x001F9EC0 private void CreateInternalIndex(ref BamlTreeNode parent, ref List <BamlTreeNode> nodeList, bool toCopy) { List <BamlTreeNode> children = parent.Children; if (toCopy) { parent = parent.Copy(); if (children != null) { parent.Children = new List <BamlTreeNode>(children.Count); } } nodeList.Add(parent); if (children == null) { return; } for (int i = 0; i < children.Count; i++) { BamlTreeNode bamlTreeNode = children[i]; this.CreateInternalIndex(ref bamlTreeNode, ref nodeList, toCopy); if (toCopy) { bamlTreeNode.Parent = parent; parent.Children.Add(bamlTreeNode); } } }
// 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); }
// Token: 0x06006E12 RID: 28178 RVA: 0x001FAEE2 File Offset: 0x001F90E2 private void AddChildToCurrentParent(BamlTreeNode node) { if (this._currentParent == null) { throw new InvalidOperationException(SR.Get("NullParentNode")); } this._currentParent.AddChild(node); this._nodeCount++; }
// Token: 0x06006EAF RID: 28335 RVA: 0x001FC9DC File Offset: 0x001FABDC private static void TryFlushTextToBamlNode(BamlTreeNode parent, StringBuilder textContent) { if (textContent.Length > 0) { BamlTreeNode child = new BamlTextNode(textContent.ToString()); parent.AddChild(child); textContent.Length = 0; } }
// Token: 0x06006E40 RID: 28224 RVA: 0x001FBD4D File Offset: 0x001F9F4D internal void AddChild(BamlTreeNode child) { if (this._children == null) { this._children = new List <BamlTreeNode>(); } this._children.Add(child); child.Parent = this; }
/// <summary> /// Create a baml tree on a root node. /// </summary> internal BamlTree(BamlTreeNode root, int size) { Debug.Assert(root != null, "Baml tree root is null!"); Debug.Assert(size > 0, "Baml tree size is less than 1"); _root = root; _nodeList = new List<BamlTreeNode>(size); CreateInternalIndex(ref _root, ref _nodeList, false); }
/// <summary> /// Create a baml tree on a root node. /// </summary> internal BamlTree(BamlTreeNode root, int size) { Debug.Assert(root != null, "Baml tree root is null!"); Debug.Assert(size > 0, "Baml tree size is less than 1"); _root = root; _nodeList = new List <BamlTreeNode>(size); CreateInternalIndex(ref _root, ref _nodeList, false); }
// Token: 0x06006E11 RID: 28177 RVA: 0x001FAEAB File Offset: 0x001F90AB private void PushNodeToStack(BamlTreeNode node) { if (this._currentParent != null) { this._currentParent.AddChild(node); } this._bamlTreeStack.Push(node); this._currentParent = node; this._nodeCount++; }
// Token: 0x06008D40 RID: 36160 RVA: 0x00258FB8 File Offset: 0x002571B8 internal BamlTreeNode MapKeyToBamlTreeNode(BamlLocalizableResourceKey key) { BamlTreeNode bamlTreeNode = this._originalMap.MapKeyToBamlTreeNode(key, this._tree); if (bamlTreeNode == null && this._keyToNewBamlNodeIndexMap.Contains(key)) { bamlTreeNode = this._tree[(int)this._keyToNewBamlNodeIndexMap[key]]; } return(bamlTreeNode); }
//---------------------------- // internal methods //---------------------------- /// <summary> /// Add a child to this node. /// </summary> /// <param name="child">child node to add</param> internal void AddChild(BamlTreeNode child) { if (_children == null) { _children = new List <BamlTreeNode>(); } _children.Add(child); // Add the children child.Parent = this; // Link to its parent }
private void PushNodeToStack(BamlTreeNode node) { if (_currentParent != null) { _currentParent.AddChild(node); } _bamlTreeStack.Push(node); _currentParent = node; _nodeCount++; }
// Token: 0x06006E37 RID: 28215 RVA: 0x001FBC70 File Offset: 0x001F9E70 internal BamlTree Copy() { BamlTreeNode root = this._root; List <BamlTreeNode> nodeList = new List <BamlTreeNode>(this.Size); this.CreateInternalIndex(ref root, ref nodeList, true); return(new BamlTree { _root = root, _nodeList = nodeList }); }
// 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: 0x06006E2E RID: 28206 RVA: 0x001FB950 File Offset: 0x001F9B50 private InternalBamlLocalizabilityResolver.ElementComments LookupCommentForElement(BamlStartElementNode node) { if (node.Uid == null) { return(new InternalBamlLocalizabilityResolver.ElementComments()); } for (int i = 0; i < this._comments.Length; i++) { if (this._comments[i] != null && this._comments[i].ElementId == node.Uid) { return(this._comments[i]); } } InternalBamlLocalizabilityResolver.ElementComments elementComments = new InternalBamlLocalizabilityResolver.ElementComments(); elementComments.ElementId = node.Uid; if (this._commentsDocument != null) { XmlElement xmlElement = InternalBamlLocalizabilityResolver.FindElementByID(this._commentsDocument, node.Uid); if (xmlElement != null) { string attribute = xmlElement.GetAttribute("Attributes"); this.SetLocalizationAttributes(node, elementComments, attribute); attribute = xmlElement.GetAttribute("Comments"); this.SetLocalizationComments(node, elementComments, attribute); } } if (node.Children != null) { int num = 0; while (num < node.Children.Count && (elementComments.LocalizationComments.Length == 0 || elementComments.LocalizationAttributes.Length == 0)) { BamlTreeNode bamlTreeNode = node.Children[num]; if (bamlTreeNode.NodeType == BamlNodeType.Property) { BamlPropertyNode bamlPropertyNode = (BamlPropertyNode)bamlTreeNode; if (LocComments.IsLocCommentsProperty(bamlPropertyNode.OwnerTypeFullName, bamlPropertyNode.PropertyName) && elementComments.LocalizationComments.Length == 0) { this.SetLocalizationComments(node, elementComments, bamlPropertyNode.Value); } else if (LocComments.IsLocLocalizabilityProperty(bamlPropertyNode.OwnerTypeFullName, bamlPropertyNode.PropertyName) && elementComments.LocalizationAttributes.Length == 0) { this.SetLocalizationAttributes(node, elementComments, bamlPropertyNode.Value); } } num++; } } this._comments[this._commentsIndex] = elementComments; this._commentsIndex = (this._commentsIndex + 1) % this._comments.Length; return(elementComments); }
internal BamlTreeNode MapKeyToBamlTreeNode(BamlLocalizableResourceKey key) { BamlTreeNode node = _originalMap.MapKeyToBamlTreeNode(key, _tree); if (node == null) { // find it in the new nodes if (_keyToNewBamlNodeIndexMap.Contains(key)) { node = _tree[(int)_keyToNewBamlNodeIndexMap[key]]; } } return(node); }
// create a deep copy of the tree internal BamlTree Copy() { // create new root and new list BamlTreeNode newTreeRoot = _root; List <BamlTreeNode> newNodeList = new List <BamlTreeNode>(Size); // create a new copy of the tree. CreateInternalIndex(ref newTreeRoot, ref newNodeList, true); BamlTree newTree = new BamlTree(); newTree._root = newTreeRoot; newTree._nodeList = newNodeList; return(newTree); }
internal void AddBamlTreeNode( string uid, BamlLocalizableResourceKey key, BamlTreeNode node ) { // add to node _tree.AddTreeNode(node); // remember the tree node index if (uid != null) { _uidToNewBamlNodeIndexMap[uid] = _tree.Size - 1; } _keyToNewBamlNodeIndexMap[key] = _tree.Size - 1; }
//---------------------------------- // 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: 0x06006E60 RID: 28256 RVA: 0x001FBF58 File Offset: 0x001FA158 internal void InsertProperty(BamlTreeNode child) { if (this._children == null) { base.AddChild(child); return; } int index = 0; for (int i = 0; i < this._children.Count; i++) { if (this._children[i].NodeType == BamlNodeType.Property) { index = i; } } this._children.Insert(index, child); child.Parent = this; }
private static void ReArrangeChildren( BamlLocalizableResourceKey key, BamlTreeNode node, string translation, BamlTreeUpdateMap treeMap ) { // // Split the translation into a list of BamlNodes. // IList <BamlTreeNode> nodes = SplitXmlContent( key, translation, treeMap ); // merge the nodes from translation with the source nodes MergeChildrenList(key, treeMap, node, nodes); }
// travese the tree and store the node in the arraylist in the same order as travesals. // it can also create a a new tree by give true to "toCopy" private void CreateInternalIndex(ref BamlTreeNode parent, ref List <BamlTreeNode> nodeList, bool toCopy) { // gets the old children List <BamlTreeNode> children = parent.Children; if (toCopy) { // creates a copy of the current node parent = parent.Copy(); if (children != null) { // create an new list if there are children. parent.Children = new List <BamlTreeNode>(children.Count); } } // add the node to the flattened list nodeList.Add(parent); // return if this is the leaf if (children == null) { return; } // for each child for (int i = 0; i < children.Count; i++) { // get to the child BamlTreeNode child = children[i]; // recursively create index CreateInternalIndex(ref child, ref nodeList, toCopy); if (toCopy) { // if toCopy, we link the new child and new parent. child.Parent = parent; parent.Children.Add(child); } } }
/// <summary> /// insert property node /// </summary> /// <remarks> /// Property node needs to be group in front of /// child elements. This method is called when creating a /// new property node. /// </remarks> internal void InsertProperty(BamlTreeNode child) { if (_children == null) { AddChild(child); } else { int lastProperty = 0; for (int i = 0; i < _children.Count; i++) { if (_children[i].NodeType == BamlNodeType.Property) { lastProperty = i; } } _children.Insert(lastProperty, child); child.Parent = this; } }
// Token: 0x06006E13 RID: 28179 RVA: 0x001FAF18 File Offset: 0x001F9118 private void PopStack() { BamlTreeNode bamlTreeNode = this._bamlTreeStack.Pop(); if (bamlTreeNode.Children != null) { foreach (BamlTreeNode bamlTreeNode2 in bamlTreeNode.Children) { BamlStartComplexPropertyNode bamlStartComplexPropertyNode = bamlTreeNode2 as BamlStartComplexPropertyNode; if (bamlStartComplexPropertyNode != null) { this.PopPropertyFromStack(bamlStartComplexPropertyNode.PropertyName); } } } if (this._bamlTreeStack.Count > 0) { this._currentParent = this._bamlTreeStack.Peek(); return; } this._currentParent = null; }
// Token: 0x06006EB2 RID: 28338 RVA: 0x001FCC7C File Offset: 0x001FAE7C private static bool GetBamlTreeNodeFromText(BamlLocalizableResourceKey key, string content, BamlTreeUpdater.BamlTreeUpdateMap bamlTreeMap, IList <BamlTreeNode> newChildrenList) { BamlStringToken[] array = BamlResourceContentUtil.ParseChildPlaceholder(content); if (array == null) { bamlTreeMap.Resolver.RaiseErrorNotifyEvent(new BamlLocalizerErrorNotifyEventArgs(key, BamlLocalizerError.IncompleteElementPlaceholder)); return(false); } bool result = true; for (int i = 0; i < array.Length; i++) { BamlStringToken.TokenType type = array[i].Type; if (type != BamlStringToken.TokenType.Text) { if (type == BamlStringToken.TokenType.ChildPlaceHolder) { BamlTreeNode bamlTreeNode = bamlTreeMap.MapUidToBamlTreeElementNode(array[i].Value); if (bamlTreeNode != null) { newChildrenList.Add(bamlTreeNode); } else { bamlTreeMap.Resolver.RaiseErrorNotifyEvent(new BamlLocalizerErrorNotifyEventArgs(new BamlLocalizableResourceKey(array[i].Value, string.Empty, string.Empty), BamlLocalizerError.InvalidUid)); result = false; } } } else { BamlTreeNode item = new BamlTextNode(array[i].Value); newChildrenList.Add(item); } } return(result); }
// 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 static void MergeChildrenList( BamlLocalizableResourceKey key, BamlTreeUpdateMap treeMap, BamlTreeNode parent, IList<BamlTreeNode> newChildren ) { if (newChildren == null) return; List<BamlTreeNode> oldChildren = parent.Children; int nodeIndex = 0; StringBuilder textBuffer = new StringBuilder(); if (oldChildren != null) { Hashtable uidSubstitutions = new Hashtable(newChildren.Count); foreach (BamlTreeNode node in newChildren) { if (node.NodeType == BamlNodeType.StartElement) { BamlStartElementNode element = (BamlStartElementNode) node; // element's Uid can be null if it is a formatting tag. if (element.Uid != null) { if (uidSubstitutions.ContainsKey(element.Uid)) { treeMap.Resolver.RaiseErrorNotifyEvent( new BamlLocalizerErrorNotifyEventArgs( key, BamlLocalizerError.DuplicateElement ) ); return; // the substitution contains duplicate elements. } uidSubstitutions[element.Uid] = null; // stored in Hashtable } } } parent.Children = null; // start re-adding child element to parent // The last node is EndStartElement node and must remain to be at the end, // so it won't be rearranged. for (int i = 0; i < oldChildren.Count - 1; i++) { BamlTreeNode child = oldChildren[i]; switch (child.NodeType) { case BamlNodeType.StartElement: { BamlStartElementNode element = (BamlStartElementNode) child; if (element.Uid != null) { if (!uidSubstitutions.ContainsKey(element.Uid)) { // cannot apply uid susbstitution because the susbstituition doesn't // contain all the existing uids. parent.Children = oldChildren; // reset to old children and exit treeMap.Resolver.RaiseErrorNotifyEvent( new BamlLocalizerErrorNotifyEventArgs( key, BamlLocalizerError.MismatchedElements ) ); return; } // Each Uid can only appear once. uidSubstitutions.Remove(element.Uid); } // Append all the contents till the matching element. while (nodeIndex < newChildren.Count) { BamlTreeNode newNode = newChildren[nodeIndex++]; Invariant.Assert(newNode != null); if (newNode.NodeType == BamlNodeType.Text) { textBuffer.Append(((BamlTextNode) newNode).Content); // Collect all text into the buffer } else { TryFlushTextToBamlNode(parent, textBuffer); parent.AddChild(newNode); if (newNode.NodeType == BamlNodeType.StartElement) break; } } break; } case BamlNodeType.Text: { // Skip original text node. New text node will be created from // text tokens in translation break; } default: { parent.AddChild(child); break; } } } } // finish the rest of the nodes for (; nodeIndex < newChildren.Count; nodeIndex++) { BamlTreeNode newNode = newChildren[nodeIndex]; Invariant.Assert(newNode != null); if (newNode.NodeType == BamlNodeType.Text) { textBuffer.Append(((BamlTextNode) newNode).Content); // Collect all text into the buffer } else { TryFlushTextToBamlNode(parent, textBuffer); parent.AddChild(newNode); } } TryFlushTextToBamlNode(parent, textBuffer); // Always terminate the list with EndElementNode; parent.AddChild(new BamlEndElementNode()); }
/// <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; }
private static void ReArrangeChildren( BamlLocalizableResourceKey key, BamlTreeNode node, string translation, BamlTreeUpdateMap treeMap ) { // // Split the translation into a list of BamlNodes. // IList<BamlTreeNode> nodes = SplitXmlContent( key, translation, treeMap ); // merge the nodes from translation with the source nodes MergeChildrenList(key, treeMap, node, nodes); }
/// <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> /// 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; } }
/// <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); } }
/// <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); }
// travese the tree and store the node in the arraylist in the same order as travesals. // it can also create a a new tree by give true to "toCopy" private void CreateInternalIndex(ref BamlTreeNode parent, ref List<BamlTreeNode> nodeList, bool toCopy) { // gets the old children List<BamlTreeNode> children = parent.Children; if (toCopy) { // creates a copy of the current node parent = parent.Copy(); if (children != null) { // create an new list if there are children. parent.Children = new List<BamlTreeNode>(children.Count); } } // add the node to the flattened list nodeList.Add(parent); // return if this is the leaf if (children == null) return; // for each child for (int i = 0; i < children.Count; i++) { // get to the child BamlTreeNode child = children[i]; // recursively create index CreateInternalIndex(ref child, ref nodeList, toCopy); if (toCopy) { // if toCopy, we link the new child and new parent. child.Parent = parent; parent.Children.Add(child); } } }
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 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 void TryFlushTextToBamlNode(BamlTreeNode parent, StringBuilder textContent) { if (textContent.Length > 0) { BamlTreeNode textNode = new BamlTextNode(textContent.ToString()); parent.AddChild(textNode); textContent.Length = 0; } }
private void AddChildToCurrentParent(BamlTreeNode node) { if (_currentParent == null) { throw new InvalidOperationException(SR.Get(SRID.NullParentNode)); } _currentParent.AddChild(node); _nodeCount++; }
private void PushNodeToStack(BamlTreeNode node) { if (_currentParent != null) _currentParent.AddChild(node); _bamlTreeStack.Push(node); _currentParent = node; _nodeCount++; }
// adds a node into the flattened tree node list. internal void AddTreeNode(BamlTreeNode node) { _nodeList.Add(node); }
//---------------------------- // internal methods //---------------------------- /// <summary> /// Add a child to this node. /// </summary> /// <param name="child">child node to add</param> internal void AddChild(BamlTreeNode child) { if (_children == null) { _children = new List<BamlTreeNode>(); } _children.Add(child); // Add the children child.Parent = this; // Link to its parent }
//------------------------------------------------- // 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); }