Example #1
0
        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);
        }
Example #4
0
        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);
        }
Example #6
0
        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);
        }
Example #8
0
        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;
		}
Example #11
0
        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);
        }
Example #12
0
        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);
        }
Example #13
0
        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);
        }
Example #14
0
        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));
        }
Example #15
0
        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);
        }
Example #18
0
        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);
		}
Example #22
0
        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);
        }
Example #26
0
        /// <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());
        }
Example #27
0
		/// <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&lt;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);
        }
Example #44
0
		/// <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;
		}
Example #47
0
		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;
		}