// there are two kind of attribute: // 1) in lined : argument="some value" // 2) <argument> // <Expression ....../> // </argument> // here, for (1) return the source location of "some value". // for (2) return null private static SourceLocation GetInlineAttributeValueLocation(LineColumnPair startPoint, SourceTextScanner sourceTextScanner) { const char SingleQuote = '\''; const char DoubleQuote = '"'; const char StartAngleBracket = '<'; Tuple <LineColumnPair, char> start = sourceTextScanner.SearchCharAfter(startPoint, SingleQuote, DoubleQuote, StartAngleBracket); if (start == null) { return(null); } if (start.Item2 == StartAngleBracket) { return(null); } Tuple <LineColumnPair, char> end = sourceTextScanner.SearchCharAfter(start.Item1, start.Item2); if (end == null) { SharedFx.Assert("end of SourceLocation is not found"); return(null); } return(new SourceLocation(null, start.Item1.LineNumber, start.Item1.ColumnNumber, end.Item1.LineNumber, end.Item1.ColumnNumber)); }
internal Tuple <LineColumnPair, char> SearchCharAfter(LineColumnPair startPoint, params char[] charsToSearch) { SharedFx.Assert(startPoint != null, "startPoint != null"); int line = startPoint.LineNumber - 1; int column = startPoint.ColumnNumber - 1; HashSet <char> charsToSearchSet = new HashSet <char>(charsToSearch); int index = this.GetIndex(line, column); if (index < 0) { return(null); } bool firstLoop = true; foreach (Tuple <char, int> currentPair in this.Scan(index)) { if (firstLoop) { firstLoop = false; } else { if (charsToSearchSet.Contains(currentPair.Item1)) { LineColumnPair location = this.GetLocation(currentPair.Item2); SharedFx.Assert(location != null, "invalid location"); return(Tuple.Create(location, currentPair.Item1)); } } } return(null); }
// For dynamic activity property, we needs to collect the source location of // its default value when the value is inlined. private KeyValuePair <string, SourceLocation> TransformDynamicActivityProperty( XamlReader reader, XamlObjectWriter objectWriter, SourceTextScanner sourceTextScanner) { // (Number of SM -Number of EM) since SM DAP.Name is read. // SO DAP ---nameReadingLevel=0 // SM NAME ---nameReadingLevel=1 // SO String ---nameReadingLevel=1 // SM Initialize ---nameReadingLevel=2 // VA StringValue ---nameReadingLevel=2 // EM ---nameReadingLevel=1 // SO ---nameReadingLevel=1 // EM ---nameReadingLevel=0 // EO ---nameReadingLevel=0 int nameReadingLevel = 0; IXamlLineInfo lineInfo = (IXamlLineInfo)reader; SourceLocation defaultValueLocation = null; string propertyName = null; while (reader.Read()) { switch (reader.NodeType) { case XamlNodeType.StartMember: if (nameReadingLevel > 0 || reader.Member == this.dynamicActivityPropertyNameMember) { ++nameReadingLevel; } else if (reader.Member == this.dynamicActivityPropertyValueMember) { LineColumnPair startPoint = new LineColumnPair(lineInfo.LineNumber, lineInfo.LinePosition); defaultValueLocation = GetInlineAttributeValueLocation(startPoint, sourceTextScanner); } break; case XamlNodeType.EndMember: if (nameReadingLevel > 0) { --nameReadingLevel; } break; case XamlNodeType.Value: if (nameReadingLevel > 0) { propertyName = reader.Value as string; } break; } objectWriter.WriteNode(reader); } if (propertyName != null && defaultValueLocation != null) { return(new KeyValuePair <string, SourceLocation>(propertyName, defaultValueLocation)); } return(new KeyValuePair <string, SourceLocation>()); }