public void GetHashCode_ToIdenticalWithArguments_Equal() { // Arrange var arguments1 = new[] { MarkupExtensionInfoTests.CreateArgument(null, "S1"), MarkupExtensionInfoTests.CreateArgument(null, "S2"), MarkupExtensionInfoTests.CreateArgument("M1", "S3"), MarkupExtensionInfoTests.CreateArgument("M2", "S4") }; var arguments2 = new[] { MarkupExtensionInfoTests.CreateArgument(null, "S1"), MarkupExtensionInfoTests.CreateArgument(null, "S2"), MarkupExtensionInfoTests.CreateArgument("M1", "S3"), MarkupExtensionInfoTests.CreateArgument("M2", "S4") }; var @this = new MarkupExtensionInfo("TypeName", arguments1); var other = new MarkupExtensionInfo("TypeName", arguments2); // Act var hash1 = @this.GetHashCode(); var hash2 = other.GetHashCode(); // Assert Assert.AreEqual(hash1, hash2); }
public void MissingColonTest2() { string markup = "{x:Type xy Type=Button a=b}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "x:Type", StartOffset = 0, EndOffset = 27 }; info.PositionalArguments.Add(new AttributeValue("xy") { StartOffset = 8 }); info.NamedArguments.Add("Type", new AttributeValue("Button") { StartOffset = 16 }); info.NamedArguments.Add("a", new AttributeValue("b") { StartOffset = 25 }); RunParseTest(markup, info); }
public void NestedTest2() { string markup = "{bla a, {bla2}}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "bla", StartOffset = 0, EndOffset = 15 }; info.PositionalArguments.Add(new AttributeValue("a") { StartOffset = 5 }); info.PositionalArguments.Add( new AttributeValue( new MarkupExtensionInfo() { ExtensionType = "bla2", StartOffset = 8, EndOffset = 14 } ) { StartOffset = 8 } ); RunParseTest(markup, info); }
public void GetHashCode_NestedUnequalMarkupExtension_Unequal() { // Arrange var arguments1 = new[] { MarkupExtensionInfoTests.CreateArgument(null, "S1"), MarkupExtensionInfoTests.CreateArgument(null, new MarkupExtensionInfo("TypeName", new[] { MarkupExtensionInfoTests.CreateArgument("M", "S") })), MarkupExtensionInfoTests.CreateArgument("M1", "S3"), MarkupExtensionInfoTests.CreateArgument("M2", "S4") }; var arguments2 = new[] { MarkupExtensionInfoTests.CreateArgument(null, "S1"), MarkupExtensionInfoTests.CreateArgument(null, new MarkupExtensionInfo("TypeName", new[] { MarkupExtensionInfoTests.CreateArgument("N", "S") })), MarkupExtensionInfoTests.CreateArgument("M1", "S3"), MarkupExtensionInfoTests.CreateArgument("M2", "S4") }; var @this = new MarkupExtensionInfo("TypeName", arguments1); var other = new MarkupExtensionInfo("TypeName", arguments2); // Act var hash1 = @this.GetHashCode(); var hash2 = other.GetHashCode(); // Assert Assert.AreNotEqual(hash1, hash2); }
public void PosAndNamedArgTest() { string markup = "{x:Type xy, Type=Button, a=b}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "x:Type", StartOffset = 0, EndOffset = 29 }; info.PositionalArguments.Add(new AttributeValue("xy") { StartOffset = 8 }); info.NamedArguments.Add("Type", new AttributeValue("Button") { StartOffset = 17 }); info.NamedArguments.Add("a", new AttributeValue("b") { StartOffset = 27 }); RunParseTest(markup, info); RunDetectionTest(markup, 29, info); }
public void Equals_NestedUnequalMarkupExtension_Unequal() { // Arrange var arguments1 = new[] { MarkupExtensionInfoTests.CreateArgument(null, "S1"), MarkupExtensionInfoTests.CreateArgument(null, new MarkupExtensionInfo("TypeName", new[] { MarkupExtensionInfoTests.CreateArgument("M", "S") })), MarkupExtensionInfoTests.CreateArgument("M1", "S3"), MarkupExtensionInfoTests.CreateArgument("M2", "S4") }; var arguments2 = new[] { MarkupExtensionInfoTests.CreateArgument(null, "S1"), MarkupExtensionInfoTests.CreateArgument(null, new MarkupExtensionInfo("TypeName", new[] { MarkupExtensionInfoTests.CreateArgument("N", "S") })), MarkupExtensionInfoTests.CreateArgument("M1", "S3"), MarkupExtensionInfoTests.CreateArgument("M2", "S4") }; var @this = new MarkupExtensionInfo("TypeName", arguments1); var other = new MarkupExtensionInfo("TypeName", arguments2); // Act var equal = @this.Equals(other); // Assert Assert.IsFalse(equal); }
static void RunDetectionTest(string markup, int offset, MarkupExtensionInfo expectedResult) { MarkupExtensionInfo data = MarkupExtensionParser.Parse(markup); MarkupExtensionInfo result = Utils.GetMarkupExtensionAtPosition(data, offset); Assert.AreEqual(expectedResult, result); }
public void Equals_ToIdenticalWithArguments_Equal() { // Arrange var arguments1 = new[] { MarkupExtensionInfoTests.CreateArgument(null, "S1"), MarkupExtensionInfoTests.CreateArgument(null, "S2"), MarkupExtensionInfoTests.CreateArgument("M1", "S3"), MarkupExtensionInfoTests.CreateArgument("M2", "S4") }; var arguments2 = new[] { MarkupExtensionInfoTests.CreateArgument(null, "S1"), MarkupExtensionInfoTests.CreateArgument(null, "S2"), MarkupExtensionInfoTests.CreateArgument("M1", "S3"), MarkupExtensionInfoTests.CreateArgument("M2", "S4") }; var @this = new MarkupExtensionInfo("TypeName", arguments1); var other = new MarkupExtensionInfo("TypeName", arguments2); // Act var equal = @this.Equals(other); // Assert Assert.IsTrue(equal); }
public static MarkupExtensionInfo Parse(string input) { #region Parameter Checks if (!MarkupExtensionPattern.IsMatch(input)) { string msg = String.Format("{0} is not a MarkupExtension.", input); throw new InvalidOperationException(msg); } #endregion Parameter Checks var resultInfo = new MarkupExtensionInfo(); using (var reader = new StringReader(input)) { var parsingMode = MarkupExtensionParsingModeEnum.START; try { //Debug.Print("Parsing '{0}'", input); //Debug.Indent(); while (MarkupExtensionParsingModeEnum.END != parsingMode && MarkupExtensionParsingModeEnum.UNEXPECTED != parsingMode) { //Debug.Print(context.ToString()); //Debug.Indent(); switch (parsingMode) { case MarkupExtensionParsingModeEnum.START: parsingMode = reader.ReadMarkupExtensionStart(); break; case MarkupExtensionParsingModeEnum.MARKUP_NAME: parsingMode = reader.ReadMarkupName(resultInfo); break; case MarkupExtensionParsingModeEnum.NAME_VALUE_PAIR: parsingMode = reader.ReadNameValuePair(resultInfo); break; } //Debug.Unindent(); } } catch (Exception exp) { throw new InvalidDataException( String.Format("Cannot parse markup extension string:\r\n \"{0}\"", input), exp); } } return(resultInfo); }
static MarkupExtensionInfo Parse(string text, int offset) { var info = new MarkupExtensionInfo(); string argumentName = null; MarkupExtensionTokenizer tokenizer = new MarkupExtensionTokenizer(text); MarkupExtensionToken token = null; try { token = tokenizer.NextToken(); while (token.Kind != MarkupExtensionTokenKind.EndOfFile) { switch (token.Kind) { case MarkupExtensionTokenKind.OpenBrace: info.StartOffset = token.StartOffset + offset; break; case MarkupExtensionTokenKind.CloseBrace: info.EndOffset = token.EndOffset + offset; info.IsClosed = true; break; case MarkupExtensionTokenKind.TypeName: info.ExtensionType = token.Value; break; case MarkupExtensionTokenKind.MemberName: // if there is an open member without a value add the member name if (argumentName != null) info.TryAddNamedArgument(argumentName, ParseValue("", token.EndOffset + offset)); argumentName = token.Value; break; case MarkupExtensionTokenKind.String: if (argumentName != null) { info.TryAddNamedArgument(argumentName, ParseValue(token.Value, token.StartOffset + offset)); argumentName = null; } else { info.PositionalArguments.Add(ParseValue(token.Value, token.StartOffset + offset)); } break; } token = tokenizer.NextToken(); } } catch (MarkupExtensionParseException) { // ignore parser errors } finally { if (token != null && argumentName != null) info.TryAddNamedArgument(argumentName, ParseValue(token.Value, token.StartOffset + offset)); } if (info.EndOffset == 0 && token != null) { info.EndOffset = token.EndOffset + offset; } return info; }
public void Equals_DifferentTypeName_Unequal() { // Arrange var @this = new MarkupExtensionInfo("TypeName1", new IMarkupExtensionArgumentInfo[0]); var other = new MarkupExtensionInfo("TypeName2", new IMarkupExtensionArgumentInfo[0]); // Act var equal = @this.Equals(other); // Assert Assert.IsFalse(equal); }
public void Equals_ToIdentical_Equal() { // Arrange var @this = new MarkupExtensionInfo("TypeName", new IMarkupExtensionArgumentInfo[0]); var other = new MarkupExtensionInfo("TypeName", new IMarkupExtensionArgumentInfo[0]); // Act var equal = @this.Equals(other); // Assert Assert.IsTrue(equal); }
public void GetHashCode_ToSelf_Equal() { // Arrange var @this = new MarkupExtensionInfo("TypeName", new IMarkupExtensionArgumentInfo[0]); // Act var hash1 = @this.GetHashCode(); var hash2 = @this.GetHashCode(); // Assert Assert.AreEqual(hash1, hash2); }
public void CreateInstance_Parameters_AssignedToProperties() { // Arrange var typeName = "TypeName"; var arguments = new IMarkupExtensionArgumentInfo[0]; // Act var target = new MarkupExtensionInfo(typeName, arguments); // Assert Assert.AreEqual(typeName, target.TypeName); Assert.IsTrue(arguments.SequenceEqual(target.Arguments)); }
public void GetHashCode_DifferentTypeName_Unequal() { // Arrange var @this = new MarkupExtensionInfo("TypeName1", new IMarkupExtensionArgumentInfo[0]); var other = new MarkupExtensionInfo("TypeName2", new IMarkupExtensionArgumentInfo[0]); // Act var hash1 = @this.GetHashCode(); var hash2 = other.GetHashCode(); // Assert Assert.AreNotEqual(hash1, hash2); }
public void EmptyTest() { string markup = "{x:Type}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "x:Type", StartOffset = 0, EndOffset = 8 }; RunParseTest(markup, info); RunDetectionTest(markup, 5, info); }
public void EmptyTest() { string markup = "{x:Type}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "x:Type", StartOffset = 0, EndOffset = 8 }; RunParseTest(markup, info); RunDetectionTest(markup, 5, info); }
public void Equals_ToSelf_Equal() { // Arrange var @this = new MarkupExtensionInfo("TypeName", new IMarkupExtensionArgumentInfo[0]); // Act // ReSharper disable EqualExpressionComparison var equal = @this.Equals(@this); // ReSharper restore EqualExpressionComparison // Assert Assert.IsTrue(equal); }
public static MarkupExtensionInfo Parse(string input) { if (!MarkupExtensionPattern.IsMatch(input)) { throw new InvalidOperationException($"{input} is not a MarkupExtension."); } var resultInfo = new MarkupExtensionInfo(); using (var reader = new StringReader(input)) { var parsingMode = MarkupExtensionParsingModeEnum.Start; try { //Debug.Print("Parsing '{0}'", input); //Debug.Indent(); while ((MarkupExtensionParsingModeEnum.End != parsingMode) && (MarkupExtensionParsingModeEnum.Unexpected != parsingMode)) { //Debug.Print(context.ToString()); //Debug.Indent(); switch (parsingMode) { case MarkupExtensionParsingModeEnum.Start: parsingMode = reader.ReadMarkupExtensionStart(); break; case MarkupExtensionParsingModeEnum.MarkupName: parsingMode = reader.ReadMarkupName(resultInfo); break; case MarkupExtensionParsingModeEnum.NameValuePair: parsingMode = reader.ReadNameValuePair(resultInfo); break; } //Debug.Unindent(); } } catch (Exception e) { throw new InvalidDataException($"Cannot parse markup extension string:\r\n \"{input}\"", e); } } return(resultInfo); }
public void SimpleNamedArgTest() { string markup = "{x:Type Type=Button}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "x:Type", StartOffset = 0, EndOffset = 20 }; info.NamedArguments.Add("Type", new AttributeValue("Button") { StartOffset = 13 }); RunParseTest(markup, info); RunDetectionTest(markup, 0, info); }
public void SimpleTest() { string markup = "{x:Type Button}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "x:Type", StartOffset = 0, EndOffset = 15 }; info.PositionalArguments.Add(new AttributeValue("Button") { StartOffset = 8 }); RunParseTest(markup, info); RunDetectionTest(markup, 10, info); }
public void CreateInstance_ArgumentsParameter_CopiesArguments() { // Arrange var arguments = new[] { MarkupExtensionInfoTests.CreateArgument(null, "S1"), MarkupExtensionInfoTests.CreateArgument(null, "S2"), MarkupExtensionInfoTests.CreateArgument("M1", "S3"), MarkupExtensionInfoTests.CreateArgument("M2", "S4") }.ToList(); // Act var target = new MarkupExtensionInfo("TypeName", arguments); // Assert Assert.AreNotEqual(arguments, target.Arguments); Assert.IsTrue(arguments.SequenceEqual(target.Arguments)); }
/// <summary> /// Single line attribute line in style as: /// attribute_name="attribute_value" /// </summary> /// <param name="attrInfo"></param> /// <returns></returns> public static string ToSingleLineString(this AttributeInfo attrInfo) { string valuePart; if (attrInfo.IsMarkupExtension) { MarkupExtensionInfo info = MarkupExtensionParser.Parse(attrInfo.Value); valuePart = info.ToSingleLineString(); } else { valuePart = attrInfo.Value.ToXmlEncodedString(); } return(String.Format("{0}=\"{1}\"", attrInfo.Name, valuePart)); }
public void SimpleTest() { string markup = "{x:Type Button}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "x:Type", StartOffset = 0, EndOffset = 15 }; info.PositionalArguments.Add(new AttributeValue("Button") { StartOffset = 8 }); RunParseTest(markup, info); RunDetectionTest(markup, 10, info); }
public void SimpleNamedArgTest() { string markup = "{x:Type Type=Button}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "x:Type", StartOffset = 0, EndOffset = 20 }; info.NamedArguments.Add("Type", new AttributeValue("Button") { StartOffset = 13 }); RunParseTest(markup, info); RunDetectionTest(markup, 0, info); }
/// <summary> /// Handles markup extension value in style as: /// XyzAttribute="{XyzMarkup value1, /// value2, /// key1=value1, /// key2=value2}" /// </summary> /// <param name="attributeInfo"></param> /// <param name="baseIndentationString"></param> /// <returns></returns> public static string ToMultiLineString(this AttributeInfo attributeInfo, string baseIndentationString) { if (!attributeInfo.IsMarkupExtension) { throw new ArgumentException( "AttributeInfo must have a markup extension value.", MethodBase.GetCurrentMethod().GetParameters()[0].Name); } MarkupExtensionInfo info = MarkupExtensionParser.Parse(attributeInfo.Value); string currentIndentationString = baseIndentationString + String.Empty.PadLeft((attributeInfo.Name.Length + 2), ' '); string value = info.ToMultiLineString(currentIndentationString); var buffer = new StringBuilder(); buffer.AppendFormat("{0}=\"{1}\"", attributeInfo.Name, value); return(buffer.ToString()); }
/// <summary> /// Gets the of a markup extension at the given position. /// </summary> /// <param name="info">The markup extension data to parse.</param> /// <param name="offset">The offset to look at.</param> /// <returns> /// A string, if the at offset is the extension type. <br /> /// An AttributeValue, if at the offset is a positional argument. <br /> /// A KeyValuePair<string, AttributeValue>, if at the offset is a named argument. /// </returns> /// <remarks>offset != Caret.Offset, but offset == ValueStartOffset</remarks> public static object GetMarkupDataAtPosition(MarkupExtensionInfo info, int offset) { object previous = info.ExtensionType; int endOffset = info.StartOffset + info.ExtensionType.Length; foreach (var item in info.PositionalArguments) { if (item.StartOffset <= offset && offset <= item.EndOffset) previous = item.IsString ? item : GetMarkupDataAtPosition(item.ExtensionValue, offset); endOffset = item.EndOffset; } foreach (var pair in info.NamedArguments) { if (pair.Value.StartOffset <= offset && offset <= pair.Value.EndOffset) previous = pair.Value.IsString ? pair : GetMarkupDataAtPosition(pair.Value.ExtensionValue, offset); else if (endOffset <= offset && offset <= pair.Value.StartOffset) previous = pair; endOffset = pair.Value.EndOffset; } return previous; }
public void NestedTest4() { string markup = "{bla a, x={bla3 {a}, b={c}, d=e}, y=z}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "bla", StartOffset = 0, EndOffset = 38 }; info.PositionalArguments.Add(new AttributeValue("a") { StartOffset = 5 }); //x={bla3 {a}, b={c}, d=e} MarkupExtensionInfo inner = new MarkupExtensionInfo() { ExtensionType = "bla3", StartOffset = 10, EndOffset = 32 }; MarkupExtensionInfo smallInner = new MarkupExtensionInfo() { ExtensionType = "a", StartOffset = 16, EndOffset = 19 }; inner.PositionalArguments.Add(new AttributeValue(smallInner) { StartOffset = 16 }); MarkupExtensionInfo smallInner2 = new MarkupExtensionInfo() { ExtensionType = "c", StartOffset = 23, EndOffset = 26 }; inner.NamedArguments.Add("b", new AttributeValue(smallInner2) { StartOffset = 23 }); inner.NamedArguments.Add("d", new AttributeValue("e") { StartOffset = 30 }); info.NamedArguments.Add("x", new AttributeValue(inner) { StartOffset = 10 }); info.NamedArguments.Add("y", new AttributeValue("z") { StartOffset = 36 }); RunParseTest(markup, info); RunDetectionTest(markup, 9, info); RunDetectionTest(markup, 11, inner); RunDetectionTest(markup, 17, smallInner); RunDetectionTest(markup, 19, inner); RunDetectionTest(markup, 32, info); }
public void NestedTest3() { string markup = "{bla a, {bla2}, b, {bla3 {a}, b}}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "bla", StartOffset = 0, EndOffset = 33 }; info.PositionalArguments.Add(new AttributeValue("a") { StartOffset = 5 }); info.PositionalArguments.Add( new AttributeValue( new MarkupExtensionInfo() { ExtensionType = "bla2", StartOffset = 8, EndOffset = 14 } ) { StartOffset = 8 } ); info.PositionalArguments.Add(new AttributeValue("b") { StartOffset = 16 }); var nested2 = new MarkupExtensionInfo() { ExtensionType = "bla3", StartOffset = 19, EndOffset = 32 }; nested2.PositionalArguments.Add( new AttributeValue( new MarkupExtensionInfo() { ExtensionType = "a", StartOffset = 25, EndOffset = 28 } ) { StartOffset = 25 } ); nested2.PositionalArguments.Add(new AttributeValue("b") { StartOffset = 30 }); info.PositionalArguments.Add( new AttributeValue(nested2) { StartOffset = 19 } ); RunParseTest(markup, info); }
public void NestedTest2() { string markup = "{bla a, {bla2}}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "bla", StartOffset = 0, EndOffset = 15 }; info.PositionalArguments.Add(new AttributeValue("a") { StartOffset = 5 }); info.PositionalArguments.Add( new AttributeValue( new MarkupExtensionInfo() { ExtensionType = "bla2", StartOffset = 8, EndOffset = 14 } ) { StartOffset = 8 } ); RunParseTest(markup, info); }
public void MissingColonTest2() { string markup = "{x:Type xy Type=Button a=b}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "x:Type", StartOffset = 0, EndOffset = 27 }; info.PositionalArguments.Add(new AttributeValue("xy") { StartOffset = 8 }); info.NamedArguments.Add("Type", new AttributeValue("Button") { StartOffset = 16 }); info.NamedArguments.Add("a", new AttributeValue("b") { StartOffset = 25 }); RunParseTest(markup, info); }
public void PosAndNamedArgTest() { string markup = "{x:Type xy, Type=Button, a=b}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "x:Type", StartOffset = 0, EndOffset = 29 }; info.PositionalArguments.Add(new AttributeValue("xy") { StartOffset = 8 }); info.NamedArguments.Add("Type", new AttributeValue("Button") { StartOffset = 17 }); info.NamedArguments.Add("a", new AttributeValue("b") { StartOffset = 27 }); RunParseTest(markup, info); RunDetectionTest(markup, 29, info); }
public void NestedTest3() { string markup = "{bla a, {bla2}, b, {bla3 {a}, b}}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "bla", StartOffset = 0, EndOffset = 33 }; info.PositionalArguments.Add(new AttributeValue("a") { StartOffset = 5 }); info.PositionalArguments.Add( new AttributeValue( new MarkupExtensionInfo() { ExtensionType = "bla2", StartOffset = 8, EndOffset = 14 } ) { StartOffset = 8 } ); info.PositionalArguments.Add(new AttributeValue("b") { StartOffset = 16 }); var nested2 = new MarkupExtensionInfo() { ExtensionType = "bla3", StartOffset = 19, EndOffset = 32 }; nested2.PositionalArguments.Add( new AttributeValue( new MarkupExtensionInfo() { ExtensionType = "a", StartOffset = 25, EndOffset = 28 } ) { StartOffset = 25 } ); nested2.PositionalArguments.Add(new AttributeValue("b") { StartOffset = 30 }); info.PositionalArguments.Add( new AttributeValue(nested2) { StartOffset = 19 } ); RunParseTest(markup, info); }
static void RunParseTest(string markup, MarkupExtensionInfo expectedResult) { MarkupExtensionInfo data = MarkupExtensionParser.Parse(markup); Assert.AreEqual(expectedResult, data); }
public static string ToSingleLineString(this MarkupExtensionInfo info) { var buffer = new StringBuilder(); buffer.Append('{'); buffer.Append(info.Name); if (info.ValueOnlyProperties.Count > 0) { for (int i = 0; i < info.ValueOnlyProperties.Count; i++) { object valueObject = info.ValueOnlyProperties[i]; buffer.Append(' '); if (valueObject is MarkupExtensionInfo) { var nestedInfo = valueObject as MarkupExtensionInfo; string value = nestedInfo.ToSingleLineString(); buffer.Append(value); } else { var value = valueObject as String; value = value.ToXmlEncodedString(); buffer.Append(value); } if (i == info.ValueOnlyProperties.Count - 1) { if (info.KeyValueProperties.Count > 0) { buffer.Append(','); } } else { buffer.Append(','); } } } if (info.KeyValueProperties.Count > 0) { for (int i = 0; i < info.KeyValueProperties.Count; i++) { buffer.Append(' '); KeyValuePair <string, object> keyValue = info.KeyValueProperties[i]; if (keyValue.Value is MarkupExtensionInfo) { var nestedInfo = keyValue.Value as MarkupExtensionInfo; string value = nestedInfo.ToSingleLineString(); buffer.AppendFormat("{0}={1}", keyValue.Key, value); } else { var value = keyValue.Value as String; value = value.ToXmlEncodedString(); buffer.AppendFormat("{0}={1}", keyValue.Key, value); } if (i != info.KeyValueProperties.Count - 1) { buffer.Append(','); } } } buffer.Append('}'); return(buffer.ToString()); }
private static MarkupExtensionParsingModeEnum ReadMarkupName(this StringReader reader, MarkupExtensionInfo info) { string methodName = MethodBase.GetCurrentMethod().Name; char[] stopChars = { ' ', '}' }; var resultParsingMode = MarkupExtensionParsingModeEnum.UNEXPECTED; var buffer = new StringBuilder(); while (!reader.IsEnd()) { char c = reader.ReadChar(); if (stopChars.Contains(c)) { switch (c) { case ' ': resultParsingMode = MarkupExtensionParsingModeEnum.NAME_VALUE_PAIR; break; case '}': resultParsingMode = MarkupExtensionParsingModeEnum.END; break; default: throw new InvalidDataException( String.Format("[{0}] Should not encounter '{1}'.", methodName, c)); } info.Name = buffer.ToString().Trim(); buffer.Clear(); // break out the while break; } buffer.Append(c); } if (MarkupExtensionParsingModeEnum.UNEXPECTED == resultParsingMode) { throw new InvalidDataException( String.Format("[{0}] Invalid result context: {1}", methodName, resultParsingMode)); } return(resultParsingMode); }
static void RunParseTest(string markup, MarkupExtensionInfo expectedResult) { MarkupExtensionInfo data = MarkupExtensionParser.Parse(markup); Assert.AreEqual(expectedResult, data); }
public void NestedTest4() { string markup = "{bla a, x={bla3 {a}, b={c}, d=e}, y=z}"; MarkupExtensionInfo info = new MarkupExtensionInfo() { ExtensionType = "bla", StartOffset = 0, EndOffset = 38 }; info.PositionalArguments.Add(new AttributeValue("a") { StartOffset = 5 }); //x={bla3 {a}, b={c}, d=e} MarkupExtensionInfo inner = new MarkupExtensionInfo() { ExtensionType = "bla3", StartOffset = 10, EndOffset = 32 }; MarkupExtensionInfo smallInner = new MarkupExtensionInfo() { ExtensionType = "a", StartOffset = 16, EndOffset = 19 }; inner.PositionalArguments.Add(new AttributeValue(smallInner) { StartOffset = 16 }); MarkupExtensionInfo smallInner2 = new MarkupExtensionInfo() { ExtensionType = "c", StartOffset = 23, EndOffset = 26 }; inner.NamedArguments.Add("b", new AttributeValue(smallInner2) { StartOffset = 23 }); inner.NamedArguments.Add("d", new AttributeValue("e") { StartOffset = 30 }); info.NamedArguments.Add("x", new AttributeValue(inner) { StartOffset = 10 }); info.NamedArguments.Add("y", new AttributeValue("z") { StartOffset = 36 }); RunParseTest(markup, info); RunDetectionTest(markup, 9, info); RunDetectionTest(markup, 11, inner); RunDetectionTest(markup, 17, smallInner); RunDetectionTest(markup, 19, inner); RunDetectionTest(markup, 32, info); }
void DoNamedArgsCompletion(XamlCompletionItemList list, XamlCompletionContext context, IType type, MarkupExtensionInfo markup) { if (markup.NamedArguments.Count > 0 && !context.Editor.GetWordBeforeCaret().StartsWith(",", StringComparison.OrdinalIgnoreCase)) { int lastStart = markup.NamedArguments.Max(i => i.Value.StartOffset); var item = markup.NamedArguments.First(p => p.Value.StartOffset == lastStart); if (context.RawAttributeValue.EndsWith("=", StringComparison.OrdinalIgnoreCase) || (item.Value.IsString && item.Value.StringValue.EndsWith(context.Editor.GetWordBeforeCaretExtended(), StringComparison.Ordinal))) { var resolver = new XamlResolver(compilation); MemberResolveResult mrr = resolver.ResolveAttributeValue(item.Key, context) as MemberResolveResult; if (mrr != null && mrr.Member != null && mrr.Member.ReturnType != null) { IType memberType = mrr.Member.ReturnType; list.Items.AddRange(MemberCompletion(context, memberType, string.Empty)); } return; } } list.Items.AddRange(type.GetProperties().Where(p => p.CanSet && p.IsPublic).Select(p => new XamlCompletionItem(p.Name + "=", p))); }
static void RunDetectionTest(string markup, int offset, MarkupExtensionInfo expectedResult) { MarkupExtensionInfo data = MarkupExtensionParser.Parse(markup); MarkupExtensionInfo result = Utils.GetMarkupExtensionAtPosition(data, offset); Assert.AreEqual(expectedResult, result); }
public static string ToMultiLineString(this MarkupExtensionInfo info, string baseIndentationString) { string currentIndentationString = baseIndentationString + String.Empty.PadLeft(info.Name.Length + 2, ' '); var buffer = new StringBuilder(); buffer.Append('{'); buffer.Append(info.Name); if (info.ValueOnlyProperties.Count > 0) { buffer.Append(' '); for (int i = 0; i < info.ValueOnlyProperties.Count; i++) { object valueObject = info.ValueOnlyProperties[i]; if (valueObject is MarkupExtensionInfo) { var nestedInfo = valueObject as MarkupExtensionInfo; string value = nestedInfo.ToMultiLineString(currentIndentationString); buffer.Append(value); } else { var value = valueObject as String; value = value.ToXmlEncodedString(); buffer.Append(value); } if (i == info.ValueOnlyProperties.Count - 1) { if (info.KeyValueProperties.Count > 0) { buffer.Append(','); buffer.Append(Environment.NewLine); buffer.Append(currentIndentationString); } } else { buffer.Append(','); buffer.Append(Environment.NewLine); buffer.Append(currentIndentationString); } } } if (info.KeyValueProperties.Count > 0) { // Append a space after Markup Extension Name if (0 == info.ValueOnlyProperties.Count) { buffer.Append(' '); } for (int i = 0; i < info.KeyValueProperties.Count; i++) { KeyValuePair <string, object> keyValue = info.KeyValueProperties[i]; if (keyValue.Value is MarkupExtensionInfo) { var nestedInfo = keyValue.Value as MarkupExtensionInfo; string nextLevelIndentationString = currentIndentationString + String.Empty.PadLeft(keyValue.Key.Length + 1, ' '); string value = nestedInfo.ToMultiLineString(nextLevelIndentationString); buffer.AppendFormat("{0}={1}", keyValue.Key, value); } else { var value = keyValue.Value as String; value = value.ToXmlEncodedString(); buffer.AppendFormat("{0}={1}", keyValue.Key, value); } if (i != info.KeyValueProperties.Count - 1) { buffer.Append(','); buffer.Append(Environment.NewLine); buffer.Append(currentIndentationString); } } } buffer.Append('}'); return(buffer.ToString()); }
private static MarkupExtensionParsingModeEnum ReadNameValuePair(this StringReader reader, MarkupExtensionInfo info) { string methodName = MethodBase.GetCurrentMethod().Name; char[] stopChars = { ',', '=', '}' }; MarkupExtensionParsingModeEnum resultParsingMode; string key = null; object value = null; reader.SeekTill(x => !Char.IsWhiteSpace(x)); // When '{' is the starting char, the following must be a value instead of a key. // // E.g., // <Setter x:Uid="Setter_75" // Property="Foreground" // Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" /> // // In other words, "key" shall not start with '{', as it won't be a valid property name. if ('{' != reader.PeekChar()) { string temp = reader.ReadTill(stopChars.Contains).Trim(); char keyValueIndicatorChar = reader.PeekChar(); switch (keyValueIndicatorChar) { case ',': case '}': value = temp; break; case '=': key = temp; // Consume the '=' reader.Read(); break; default: throw new InvalidDataException( String.Format("[{0}] Should not encounter '{1}'.", methodName, keyValueIndicatorChar)); } } if (null == value) { reader.SeekTill(x => !(Char.IsWhiteSpace(x))); string input = reader.ReadValueString().Trim(); if (MarkupExtensionPattern.IsMatch(input)) { value = Parse(input); } else { value = input; } } if (String.IsNullOrEmpty(key)) { info.ValueOnlyProperties.Add(value); } else { info.KeyValueProperties.Add(new KeyValuePair <string, object>(key, value)); } reader.SeekTill(x => !Char.IsWhiteSpace(x)); char stopChar = reader.ReadChar(); switch (stopChar) { case ',': resultParsingMode = MarkupExtensionParsingModeEnum.NAME_VALUE_PAIR; break; case '}': resultParsingMode = MarkupExtensionParsingModeEnum.END; break; default: throw new InvalidDataException( String.Format("[{0}] Should not encounter '{1}'.", methodName, stopChar)); } if (MarkupExtensionParsingModeEnum.UNEXPECTED == resultParsingMode) { throw new InvalidDataException( String.Format("[{0}] Invalid result context: {1}", methodName, resultParsingMode)); } return(resultParsingMode); }
private static MarkupExtensionParsingModeEnum ReadMarkupName(this StringReader reader, MarkupExtensionInfo info) { char[] stopChars = { ' ', '}' }; var resultParsingMode = MarkupExtensionParsingModeEnum.Unexpected; var buffer = new StringBuilder(); while (!reader.IsEnd()) { char c = reader.ReadChar(); if (stopChars.Contains(c)) { switch (c) { case ' ': resultParsingMode = MarkupExtensionParsingModeEnum.NameValuePair; break; case '}': resultParsingMode = MarkupExtensionParsingModeEnum.End; break; default: throw new InvalidDataException($"[{nameof(ReadMarkupName)}] Should not encounter '{c}'."); } info.Name = buffer.ToString().Trim(); buffer.Clear(); break; } buffer.Append(c); } if (MarkupExtensionParsingModeEnum.Unexpected == resultParsingMode) { throw new InvalidDataException($"[{nameof(ReadMarkupName)}] Invalid result context: {resultParsingMode}"); } return(resultParsingMode); }
/// <remarks>offset != Caret.Offset, but offset == ValueStartOffset</remarks> public static MarkupExtensionInfo GetMarkupExtensionAtPosition(MarkupExtensionInfo info, int offset) { MarkupExtensionInfo tmp = info; foreach (var item in info.PositionalArguments) { int endOffset = item.EndOffset; if (!item.IsClosed) endOffset++; if (item.StartOffset < offset && offset < endOffset) tmp = item.IsString ? tmp : GetMarkupExtensionAtPosition(item.ExtensionValue, offset); } foreach (var pair in info.NamedArguments) { int endOffset = pair.Value.EndOffset; if (!pair.Value.IsClosed) endOffset++; if (pair.Value.StartOffset < offset && offset < endOffset) tmp = pair.Value.IsString ? tmp : GetMarkupExtensionAtPosition(pair.Value.ExtensionValue, offset); } return tmp; }
public static string GetTypeNameFromTypeExtension(MarkupExtensionInfo info, XamlCompletionContext context) { IReturnType type = CompletionDataHelper.ResolveType(info.ExtensionType, context) ?? CompletionDataHelper.ResolveType(info.ExtensionType + "Extension", context); if (type == null || type.FullyQualifiedName != "System.Windows.Markup.TypeExtension") return string.Empty; var item = info.PositionalArguments.FirstOrDefault(); if (item != null && item.IsString) { return item.StringValue; } else { if (info.NamedArguments.TryGetValue("typename", out item)) { if (item.IsString) return item.StringValue; } } return string.Empty; }
/// <remarks>returns true if elements from named args completion should be added afterwards.</remarks> bool DoPositionalArgsCompletion(XamlCompletionItemList list, XamlCompletionContext context, MarkupExtensionInfo markup, IType type) { switch (type.FullName) { case "System.Windows.Markup.ArrayExtension": case "System.Windows.Markup.NullExtension": // x:Null/x:Array does not need completion, ignore it break; case "System.Windows.Markup.StaticExtension": if (context.AttributeValue.ExtensionValue.PositionalArguments.Count <= 1) return DoStaticExtensionCompletion(list, context); break; case "System.Windows.Markup.TypeExtension": if (context.AttributeValue.ExtensionValue.PositionalArguments.Count <= 1) { list.Items.AddRange(GetClassesFromContext(context).FlattenToList()); AttributeValue selItem = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset) .PositionalArguments.LastOrDefault(); string word = context.Editor.GetWordBeforeCaret().TrimEnd(); if (selItem != null && selItem.IsString && word == selItem.StringValue) { list.PreselectionLength = selItem.StringValue.Length; } } break; default: var ctors = type.GetMethods(m => m.IsPublic && m.IsConstructor && m.Parameters.Count >= markup.PositionalArguments.Count + 1); if (context.Forced) return true; if (ctors.Any() || markup.PositionalArguments.Count == 0) return false; break; } return true; }
string GetTypeNameFromTypeExtension(MarkupExtensionInfo info, XamlContext context) { IType type = ResolveExpression(info.ExtensionType, context).Type; if (type.Kind == TypeKind.Unknown) type = ResolveExpression(info.ExtensionType + "Extension", context).Type; if (type.FullName != "System.Windows.Markup.TypeExtension") return string.Empty; var item = info.PositionalArguments.FirstOrDefault(); if (item != null && item.IsString) return item.StringValue; if (info.NamedArguments.TryGetValue("typename", out item)) { if (item.IsString) return item.StringValue; } return string.Empty; }