[runtime] Disable some tests in full-aot mode which cannot be AOTed because of type...
[mono.git] / mcs / class / monodoc / Monodoc / generators / html / Ecma2Html.cs
1 using System;
2 using System.IO;
3 using System.Text;
4 using System.Linq;
5 using System.Xml;
6 using System.Xml.Xsl;
7 using System.Xml.XPath;
8 using System.Collections.Generic;
9
10 using Mono.Documentation;
11 using BF = System.Reflection.BindingFlags;
12
13 namespace Monodoc.Generators.Html
14 {
15         public class Ecma2Html : IHtmlExporter
16         {
17                 static string css_ecma;
18                 static string js;
19                 static XslCompiledTransform ecma_transform;
20                 readonly ExtensionObject ExtObject = new ExtensionObject ();
21
22                 public Ecma2Html ()
23                 {
24                 }
25
26                 public string CssCode {
27                         get {
28                                 if (css_ecma != null)
29                                         return css_ecma;
30                                 var assembly = typeof(Ecma2Html).Assembly;
31                                 Stream str_css = assembly.GetManifestResourceStream ("mono-ecma.css");
32                                 css_ecma = (new StreamReader (str_css)).ReadToEnd();
33                                 return css_ecma;
34                         }
35                 }
36
37                 public string JsCode {
38                         get {
39                                 if (js != null)
40                                         return js;
41                                 var assembly = typeof(Ecma2Html).Assembly;
42                                 Stream str_js = assembly.GetManifestResourceStream ("helper.js");
43                                 js = (new StreamReader (str_js)).ReadToEnd();
44                                 return js;
45                         }
46                 }
47                 
48                 public string Htmlize (XmlReader ecma_xml, Dictionary<string, string> extraArgs)
49                 {
50                         var args = new XsltArgumentList ();
51                         args.AddExtensionObject("monodoc:///extensions", ExtObject);
52                         string specialPage;
53                         if (extraArgs.TryGetValue ("specialpage", out specialPage) && specialPage == "root") {
54                                 extraArgs.Remove ("specialpage");
55                                 extraArgs["show"] = "masteroverview";
56                         }
57
58                         foreach (var kvp in extraArgs)
59                                 args.AddParam (kvp.Key, string.Empty, kvp.Value);
60
61                         return Htmlize (ecma_xml, args);
62                 }
63
64                 public string Htmlize (XmlReader ecma_xml, XsltArgumentList args)
65                 {
66                         try{
67                                 EnsureTransform ();
68                         
69                                 var output = new StringBuilder ();
70                                 ecma_transform.Transform (ecma_xml, 
71                                                           args, 
72                                                           XmlWriter.Create (output, ecma_transform.OutputSettings),
73                                                           CreateDocumentResolver ());
74                                 return output.ToString ();
75                         }
76                         catch(Exception x)
77                         {
78                                 var msg = x.ToString ();
79                                 return msg;
80                         }
81                 }
82                 
83                 protected virtual XmlResolver CreateDocumentResolver ()
84                 {
85                         // results in using XmlUrlResolver
86                         return null;
87                 }
88
89                 public string Export (Stream stream, Dictionary<string, string> extraArgs)
90                 {
91                         return Htmlize (XmlReader.Create (new StreamReader(stream)), extraArgs);
92                 }
93
94                 public string Export (string input, Dictionary<string, string> extraArgs)
95                 {
96                         return Htmlize (XmlReader.Create (new StringReader(input)), extraArgs);
97                 }
98
99                 
100                 static void EnsureTransform ()
101                 {
102                         if (ecma_transform == null) {
103                                 ecma_transform = new XslCompiledTransform ();
104                                 var assembly = System.Reflection.Assembly.GetAssembly (typeof (Ecma2Html));
105                         
106                                 Stream stream = assembly.GetManifestResourceStream ("mono-ecma-css.xsl");
107                                 XmlReader xml_reader = new XmlTextReader (stream);
108                                 XmlResolver r = new ManifestResourceResolver (".");
109                                 ecma_transform.Load (xml_reader, XsltSettings.TrustedXslt, r);                  
110                         }
111                 }
112
113                 public class ExtensionObject
114                 {
115                         bool quiet = true;
116                         Dictionary<string, System.Reflection.Assembly> assemblyCache = new Dictionary<string, System.Reflection.Assembly> ();
117
118                         public string Colorize(string code, string lang)
119                         {
120                                 return Mono.Utilities.Colorizer.Colorize(code,lang);
121                         }
122
123                         // Used by stylesheet to nicely reformat the <see cref=> tags. 
124                         public string MakeNiceSignature(string sig, string contexttype)
125                         {
126                                 if (sig.Length < 3)
127                                         return sig;
128                                 if (sig[1] != ':')
129                                         return sig;
130
131                                 char s = sig[0];
132                                 sig = sig.Substring(2);
133                         
134                                 switch (s) {
135                                 case 'N': return sig;
136                                 case 'T': return ShortTypeName (sig, contexttype);
137
138                                 case 'C': case 'M': case 'P': case 'F': case 'E':
139                                         string type, mem, arg;
140                                         
141                                         // Get arguments
142                                         int paren;
143                                         if (s == 'C' || s == 'M')
144                                                 paren = sig.IndexOf("(");
145                                         else if (s == 'P')
146                                                 paren = sig.IndexOf("[");
147                                         else
148                                                 paren = 0;
149                                         
150                                         if (paren > 0 && paren < sig.Length-1) {
151                                                 string[] args = sig.Substring(paren+1, sig.Length-paren-2).Split(',');                                          
152                                                 for (int i = 0; i < args.Length; i++)
153                                                         args[i] = ShortTypeName(args[i], contexttype);
154                                                 arg = "(" + String.Join(", ", args) + ")";
155                                                 sig = sig.Substring(0, paren); 
156                                         } else {
157                                                 arg = string.Empty;
158                                         }
159
160                                         // Get type and member names
161                                         int dot = sig.LastIndexOf(".");
162                                         if (s == 'C' || dot <= 0 || dot == sig.Length-1) {
163                                                 mem = string.Empty;
164                                                 type = sig;
165                                         } else {
166                                                 type = sig.Substring(0, dot);
167                                                 mem = sig.Substring(dot);
168                                         }
169                                                 
170                                         type = ShortTypeName(type, contexttype);
171                                         
172                                         return type + mem + arg;
173
174                                 default:
175                                         return sig;
176                                 }
177                         }
178
179                         static string ShortTypeName(string name, string contexttype)
180                         {
181                                 int dot = contexttype.LastIndexOf(".");
182                                 if (dot < 0) return name;
183                                 string contextns = contexttype.Substring(0, dot+1);
184
185                                 if (name == contexttype)
186                                         return name.Substring(dot+1);
187                         
188                                 if (name.StartsWith(contextns))
189                                         return name.Substring(contextns.Length);
190                         
191                                 return name.Replace("+", ".");
192                         }
193
194                         string MonoImpInfo(string assemblyname, string typename, string membername, string arglist, bool strlong)
195                         {
196                                 if (quiet)
197                                         return string.Empty;
198                                 
199                                 var a = new List<string> ();
200                                 if (!string.IsNullOrEmpty (arglist)) a.Add (arglist);
201                                 return MonoImpInfo(assemblyname, typename, membername, a, strlong);
202                         }
203
204                         string MonoImpInfo(string assemblyname, string typename, string membername, XPathNodeIterator itr, bool strlong)
205                         {
206                                 if (quiet)
207                                         return string.Empty;
208                                 
209                                 var rgs = itr.Cast<XPathNavigator> ().Select (nav => nav.Value).ToList ();
210                         
211                                 return MonoImpInfo (assemblyname, typename, membername, rgs, strlong);
212                         }
213                 
214                         string MonoImpInfo(string assemblyname, string typename, string membername, List<string> arglist, bool strlong)
215                         {
216                                 try {
217                                         System.Reflection.Assembly assembly = null;
218                                 
219                                         try {
220                                                 if (!assemblyCache.TryGetValue (assemblyname, out assembly)) {
221                                                         assembly = System.Reflection.Assembly.LoadWithPartialName(assemblyname);
222                                                         if (assembly != null)
223                                                                 assemblyCache[assemblyname] = assembly;
224                                                 }
225                                         } catch (Exception) {
226                                                 // nothing.
227                                         }
228                                 
229                                         if (assembly == null) {
230                                                 /*if (strlong) return "The assembly " + assemblyname + " is not available to MonoDoc.";
231                                                   else return string.Empty;*/
232                                                 return string.Empty; // silently ignore
233                                         }
234
235                                         Type t = assembly.GetType(typename, false);
236                                         if (t == null) {
237                                                 if (strlong)
238                                                         return typename + " has not been implemented.";
239                                                 else
240                                                         return "Not implemented.";
241                                         }
242
243                                         // The following code is flakey and fails to find existing members
244                                         return string.Empty;
245                                 } catch (Exception) {
246                                         return string.Empty;
247                                 }
248                         }
249                 
250                         string MonoImpInfo(System.Reflection.MemberInfo mi, string itemtype, bool strlong)
251                         {
252                                 if (quiet)
253                                         return string.Empty;
254                                 
255                                 string s = string.Empty;
256
257                                 object[] atts = mi.GetCustomAttributes(true);
258                                 int todoctr = 0;
259                                 foreach (object att in atts) if (att.GetType().Name == "MonoTODOAttribute") todoctr++;
260
261                                 if (todoctr > 0) {
262                                         if (strlong)
263                                                 s = "This " + itemtype + " is marked as being unfinished.<BR/>\n";
264                                         else 
265                                                 s = "Unfinished.";
266                                 }
267
268                                 return s;
269                         }
270
271                         public string MonoImpInfo(string assemblyname, string typename, bool strlong)
272                         {
273                                 if (quiet)
274                                         return string.Empty;
275                                 
276                                 try {
277                                         if (assemblyname == string.Empty)
278                                                 return string.Empty;
279
280                                         System.Reflection.Assembly assembly;
281                                         if (!assemblyCache.TryGetValue (assemblyname, out assembly)) {
282                                                 assembly = System.Reflection.Assembly.LoadWithPartialName(assemblyname);
283                                                 if (assembly != null)
284                                                         assemblyCache[assemblyname] = assembly;
285                                         }
286
287                                         if (assembly == null)
288                                                 return string.Empty;
289
290                                         Type t = assembly.GetType(typename, false);
291                                         if (t == null) {
292                                                 if (strlong)
293                                                         return typename + " has not been implemented.";
294                                                 else
295                                                         return "Not implemented.";
296                                         }
297
298                                         string s = MonoImpInfo(t, "type", strlong);
299
300                                         if (strlong) {
301                                                 var mis = t.GetMembers (BF.Static | BF.Instance | BF.Public | BF.NonPublic);
302
303                                                 // Scan members for MonoTODO attributes
304                                                 int mctr = 0;
305                                                 foreach (var mi in mis) {
306                                                         string mii = MonoImpInfo(mi, null, false);
307                                                         if (mii != string.Empty) mctr++; 
308                                                 }
309                                                 if (mctr > 0) {
310                                                         s += "This type has " + mctr + " members that are marked as unfinished.<BR/>";
311                                                 }
312                                         }
313
314                                         return s;
315
316                                 } catch (Exception) {
317                                         return string.Empty;
318                                 }                       
319                         }
320
321                         public bool MonoEditing ()
322                         {
323                                 return false;
324                         }
325                 
326                         public bool IsToBeAdded(string text)
327                         {
328                                 return text.StartsWith ("To be added");
329                         }
330                 }
331         }
332                 
333 }