Merge pull request #3381 from krytarowski/netbsd-support-20
[mono.git] / mcs / class / System.Xaml / System.Xaml / ParsedMarkupExtensionInfo.cs
1 //
2 // Copyright (C) 2010 Novell Inc. http://novell.com
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 //
23 using System;
24 using System.Collections.Generic;
25 using System.IO;
26 using System.Linq;
27 using System.Xml;
28 using System.Xaml.Schema;
29
30 namespace System.Xaml
31 {
32         internal class ParsedMarkupExtensionInfo
33         {
34                 Dictionary<XamlMember,object> args = new Dictionary<XamlMember,object> ();
35                 public Dictionary<XamlMember,object> Arguments {
36                         get { return args; }
37                 }
38         
39                 public XamlType Type { get; set; }
40
41                 public static ParsedMarkupExtensionInfo Parse (string raw, IXamlNamespaceResolver nsResolver, XamlSchemaContext sctx)
42                 {
43                         if (raw == null)
44                                 throw new ArgumentNullException ("raw");
45                         if (raw.Length == 0 || raw [0] != '{')
46                                 throw Error ("Invalid markup extension attribute. It should begin with '{{', but was {0}", raw);
47                         var ret = new ParsedMarkupExtensionInfo ();
48                         int idx = raw.IndexOf ('}');
49                         if (idx < 0)
50                                 throw Error ("Expected '}}' in the markup extension attribute: '{0}'", raw);
51                         raw = raw.Substring (1, idx - 1);
52                         idx = raw.IndexOf (' ');
53                         string name = idx < 0 ? raw : raw.Substring (0, idx);
54
55                         XamlTypeName xtn;
56                         if (!XamlTypeName.TryParse (name, nsResolver, out xtn))
57                                 throw Error ("Failed to parse type name '{0}'", name);
58                         var xt = sctx.GetXamlType (xtn);
59                         ret.Type = xt;
60
61                         if (idx < 0)
62                                 return ret;
63
64                         string [] vpairs = raw.Substring (idx + 1, raw.Length - idx - 1).Split (',');
65                         List<string> posPrms = null;
66                         foreach (string vpair in vpairs) {
67                                 idx = vpair.IndexOf ('=');
68                                 // FIXME: unescape string (e.g. comma)
69                                 if (idx < 0) {
70                                         if (posPrms == null) {
71                                                 posPrms = new List<string> ();
72                                                 ret.Arguments.Add (XamlLanguage.PositionalParameters, posPrms);
73                                         }
74                                         posPrms.Add (UnescapeValue (vpair.Trim ()));
75                                 } else {
76                                         var key = vpair.Substring (0, idx).Trim ();
77                                         // FIXME: is unknown member always isAttacheable = false?
78                                         var xm = xt.GetMember (key) ?? new XamlMember (key, xt, false);
79                                         ret.Arguments.Add (xm, UnescapeValue (vpair.Substring (idx + 1).Trim ()));
80                                 }
81                         }
82                         return ret;
83                 }
84                 
85                 static string UnescapeValue (string s)
86                 {
87                         // change XamlXmlWriter too if we change here.
88                         if (s == "\"\"") // FIXME: there could be some escape syntax.
89                                 return String.Empty;
90                         else
91                                 return s;
92                 }
93
94                 static Exception Error (string format, params object [] args)
95                 {
96                         return new XamlParseException (String.Format (format, args));
97                 }
98         }
99 }