Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3973 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
10 changed files with 387 additions and 62 deletions
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
|
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.XmlEditor; |
||||
|
||||
namespace ICSharpCode.XamlBinding |
||||
{ |
||||
public class MarkupExtensionInfo |
||||
{ |
||||
public string Type { get; set; } |
||||
public IList<AttributeValue> PositionalArguments { get; set; } |
||||
public IDictionary<string, AttributeValue> NamedArguments { get; set; } |
||||
|
||||
public MarkupExtensionInfo() |
||||
: this(string.Empty, new List<AttributeValue>(), new Dictionary<string, AttributeValue>()) |
||||
{ |
||||
} |
||||
|
||||
public MarkupExtensionInfo(string type, IList<AttributeValue> posArgs, IDictionary<string, AttributeValue> namedArgs) |
||||
{ |
||||
this.Type = type; |
||||
this.PositionalArguments = posArgs; |
||||
this.NamedArguments = namedArgs; |
||||
} |
||||
} |
||||
|
||||
public class AttributeValue |
||||
{ |
||||
string stringValue; |
||||
MarkupExtensionInfo extensionValue; |
||||
|
||||
public bool IsString { |
||||
get { return stringValue != null; } |
||||
} |
||||
|
||||
public string StringValue { |
||||
get { return stringValue; } |
||||
} |
||||
|
||||
public MarkupExtensionInfo ExtensionValue { |
||||
get { return extensionValue; } |
||||
} |
||||
|
||||
public AttributeValue(string value) |
||||
{ |
||||
if (value == null) |
||||
throw new ArgumentNullException("value"); |
||||
|
||||
this.stringValue = value; |
||||
this.extensionValue = null; |
||||
} |
||||
|
||||
public AttributeValue(MarkupExtensionInfo value) |
||||
{ |
||||
if (value == null) |
||||
throw new ArgumentNullException("value"); |
||||
|
||||
this.stringValue = null; |
||||
this.extensionValue = value; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3494 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Runtime.Serialization; |
||||
|
||||
namespace ICSharpCode.XamlBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Exception thrown when XAML loading fails because there is a syntax error in a markup extension.
|
||||
/// </summary>
|
||||
[Serializable] |
||||
public class MarkupExtensionParseException : Exception |
||||
{ |
||||
/// <summary>
|
||||
/// Create a new XamlMarkupExtensionParseException instance.
|
||||
/// </summary>
|
||||
public MarkupExtensionParseException() |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Create a new XamlMarkupExtensionParseException instance.
|
||||
/// </summary>
|
||||
public MarkupExtensionParseException(string message) : base(message) |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Create a new XamlMarkupExtensionParseException instance.
|
||||
/// </summary>
|
||||
public MarkupExtensionParseException(string message, Exception innerException) : base(message, innerException) |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Create a new XamlMarkupExtensionParseException instance.
|
||||
/// </summary>
|
||||
protected MarkupExtensionParseException(SerializationInfo info, StreamingContext context) |
||||
: base(info, context) |
||||
{ |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.XamlBinding |
||||
{ |
||||
static class MarkupExtensionParser |
||||
{ |
||||
public static MarkupExtensionInfo Parse(string text) |
||||
{ |
||||
var info = new MarkupExtensionInfo(); |
||||
|
||||
var tokens = MarkupExtensionTokenizer.Tokenize(text); |
||||
|
||||
string argumentName = null; |
||||
|
||||
foreach (var token in tokens) { |
||||
switch (token.Kind) { |
||||
case MarkupExtensionTokenKind.TypeName: |
||||
info.Type = token.Value; |
||||
break; |
||||
case MarkupExtensionTokenKind.Membername: |
||||
argumentName = token.Value; |
||||
break; |
||||
case MarkupExtensionTokenKind.String: |
||||
if (argumentName != null) { |
||||
info.NamedArguments.Add(argumentName, ParseValue(token.Value)); |
||||
argumentName = null; |
||||
} else { |
||||
info.PositionalArguments.Add(ParseValue(token.Value)); |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
|
||||
return info; |
||||
} |
||||
|
||||
static AttributeValue ParseValue(string text) |
||||
{ |
||||
if (text.StartsWith("{", StringComparison.OrdinalIgnoreCase)) |
||||
return new AttributeValue(Parse(text)); |
||||
else |
||||
return new AttributeValue(text); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3494 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.XamlBinding |
||||
{ |
||||
public sealed class MarkupExtensionToken |
||||
{ |
||||
public readonly MarkupExtensionTokenKind Kind; |
||||
public readonly string Value; |
||||
|
||||
public MarkupExtensionToken(MarkupExtensionTokenKind kind, string value) |
||||
{ |
||||
this.Kind = kind; |
||||
this.Value = value; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "[" + Kind + " " + Value + "]"; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3494 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.XamlBinding |
||||
{ |
||||
public enum MarkupExtensionTokenKind |
||||
{ |
||||
OpenBrace, |
||||
CloseBrace, |
||||
Equals, |
||||
Comma, |
||||
TypeName, |
||||
Membername, |
||||
String |
||||
} |
||||
} |
@ -0,0 +1,148 @@
@@ -0,0 +1,148 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision: 3494 $</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
|
||||
namespace ICSharpCode.XamlBinding |
||||
{ |
||||
/// <summary>
|
||||
/// Tokenizer for markup extension attributes.
|
||||
/// [MS-XAML 6.6.7.1]
|
||||
/// </summary>
|
||||
public sealed class MarkupExtensionTokenizer |
||||
{ |
||||
private MarkupExtensionTokenizer() {} |
||||
|
||||
string text; |
||||
int pos; |
||||
List<MarkupExtensionToken> tokens = new List<MarkupExtensionToken>(); |
||||
|
||||
public static List<MarkupExtensionToken> Tokenize(string text) |
||||
{ |
||||
MarkupExtensionTokenizer t = new MarkupExtensionTokenizer(); |
||||
t.text = text; |
||||
t.Parse(); |
||||
return t.tokens; |
||||
} |
||||
|
||||
void AddToken(MarkupExtensionTokenKind kind, string val) |
||||
{ |
||||
tokens.Add(new MarkupExtensionToken(kind, val)); |
||||
} |
||||
|
||||
void Parse() |
||||
{ |
||||
AddToken(MarkupExtensionTokenKind.OpenBrace, "{"); |
||||
Expect('{'); |
||||
ConsumeWhitespace(); |
||||
CheckNotEOF(); |
||||
|
||||
StringBuilder b = new StringBuilder(); |
||||
while (pos < text.Length && !char.IsWhiteSpace(text, pos) && text[pos] != '}') |
||||
b.Append(text[pos++]); |
||||
AddToken(MarkupExtensionTokenKind.TypeName, b.ToString()); |
||||
|
||||
ConsumeWhitespace(); |
||||
while (pos < text.Length) { |
||||
switch (text[pos]) { |
||||
case '}': |
||||
AddToken(MarkupExtensionTokenKind.CloseBrace, "}"); |
||||
pos++; |
||||
break; |
||||
case '=': |
||||
AddToken(MarkupExtensionTokenKind.Equals, "="); |
||||
pos++; |
||||
break; |
||||
case ',': |
||||
AddToken(MarkupExtensionTokenKind.Comma, ","); |
||||
pos++; |
||||
break; |
||||
default: |
||||
MembernameOrString(); |
||||
break; |
||||
} |
||||
ConsumeWhitespace(); |
||||
} |
||||
} |
||||
|
||||
void MembernameOrString() |
||||
{ |
||||
StringBuilder b = new StringBuilder(); |
||||
if (text[pos] == '"' || text[pos] == '\'') { |
||||
char quote = text[pos++]; |
||||
CheckNotEOF(); |
||||
while (!(text[pos] == quote && text[pos-1] != '\\')) { |
||||
char c = text[pos++]; |
||||
if (c != '\\') |
||||
b.Append(c); |
||||
CheckNotEOF(); |
||||
} |
||||
pos++; // consume closing quote
|
||||
ConsumeWhitespace(); |
||||
} else { |
||||
int braceTotal = 0; |
||||
while (true) { |
||||
CheckNotEOF(); |
||||
switch (text[pos]) { |
||||
case '\\': |
||||
pos++; |
||||
CheckNotEOF(); |
||||
b.Append(text[pos++]); |
||||
break; |
||||
case '{': |
||||
b.Append(text[pos++]); |
||||
braceTotal++; |
||||
break; |
||||
case '}': |
||||
if (braceTotal == 0) goto stop; |
||||
b.Append(text[pos++]); |
||||
braceTotal--; |
||||
break; |
||||
case ',': |
||||
case '=': |
||||
if (braceTotal == 0) goto stop; |
||||
b.Append(text[pos++]); |
||||
break; |
||||
default: |
||||
b.Append(text[pos++]); |
||||
break; |
||||
} |
||||
} |
||||
stop:; |
||||
} |
||||
CheckNotEOF(); |
||||
string valueText = b.ToString(); |
||||
if (text[pos] == '=') { |
||||
AddToken(MarkupExtensionTokenKind.Membername, valueText.Trim()); |
||||
} else { |
||||
AddToken(MarkupExtensionTokenKind.String, valueText); |
||||
} |
||||
} |
||||
|
||||
void Expect(char c) |
||||
{ |
||||
CheckNotEOF(); |
||||
if (text[pos] != c) |
||||
throw new MarkupExtensionParseException("Expected '" + c + "'"); |
||||
pos++; |
||||
} |
||||
|
||||
void ConsumeWhitespace() |
||||
{ |
||||
while (pos < text.Length && char.IsWhiteSpace(text, pos)) |
||||
pos++; |
||||
} |
||||
|
||||
void CheckNotEOF() |
||||
{ |
||||
if (pos >= text.Length) |
||||
throw new MarkupExtensionParseException("Unexpected end of markup extension"); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue