3
// This file was derived from a file from #Develop.
5
// Copyright (C) 2001-2007 Mike Krüger <mkrueger@novell.com>
7
// This program is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation; either version 2 of the License, or
10
// (at your option) any later version.
12
// This program is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
17
// You should have received a copy of the GNU General Public License
18
// along with this program; if not, write to the Free Software
19
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
using System.Collections;
25
using MonoDevelop.Projects.Parser;
26
using MonoDevelop.Core;
27
using MonoDevelop.Projects.Ambience;
29
namespace CSharpBinding
31
public class CSharpAmbience : Ambience
33
static string[,] typeConversionList = new string[,] {
34
{"System.Void", "void"},
35
{"System.Object", "object"},
36
{"System.Boolean", "bool"},
37
{"System.Byte", "byte"},
38
{"System.SByte", "sbyte"},
39
{"System.Char", "char"},
40
{"System.Enum", "enum"},
41
{"System.Int16", "short"},
42
{"System.Int32", "int"},
43
{"System.Int64", "long"},
44
{"System.UInt16", "ushort"},
45
{"System.UInt32", "uint"},
46
{"System.UInt64", "ulong"},
47
{"System.Single", "float"},
48
{"System.Double", "double"},
49
{"System.Decimal", "decimal"},
50
{"System.String", "string"}
53
static Hashtable typeConversionTable = new Hashtable();
55
public static Hashtable TypeConversionTable {
57
return typeConversionTable;
61
static CSharpAmbience()
63
for (int i = 0; i < typeConversionList.GetLength(0); ++i) {
64
typeConversionTable[typeConversionList[i, 0]] = typeConversionList[i, 1];
68
bool ModifierIsSet(ModifierEnum modifier, ModifierEnum query)
70
return (modifier & query) == query;
73
public override string Convert (ModifierEnum modifier, ConversionFlags conversionFlags)
75
if (ShowAccessibility(conversionFlags)) {
76
if (ModifierIsSet(modifier, ModifierEnum.Public)) {
78
} else if (ModifierIsSet(modifier, ModifierEnum.Private)) {
80
} else if (ModifierIsSet(modifier, ModifierEnum.ProtectedAndInternal)) {
81
return "protected internal ";
82
} else if (ModifierIsSet(modifier, ModifierEnum.ProtectedOrInternal)) {
83
return "internal protected ";
84
} else if (ModifierIsSet(modifier, ModifierEnum.Internal)) {
86
} else if (ModifierIsSet(modifier, ModifierEnum.Protected)) {
94
string GetModifier(IDecoration decoration, ConversionFlags conversionFlags)
98
if (decoration.IsStatic) mod = "static ";
99
else if (decoration.IsFinal) mod = "final ";
100
else if (decoration.IsVirtual) mod = "virtual ";
101
else if (decoration.IsOverride) mod = "override ";
102
else if (decoration.IsNew) mod = "new ";
105
if (IncludeHTMLMarkup(conversionFlags) | IncludePangoMarkup(conversionFlags))
106
return "<i>" + mod + "</i>";
111
string ConvertTypeName (string typeName, ConversionFlags conversionFlags, ITypeNameResolver resolver)
113
int p = typeName.IndexOf ('`');
115
return GetResolvedTypeName (typeName, conversionFlags, resolver);
117
StringBuilder res = new StringBuilder (GetResolvedTypeName (typeName.Substring (0, p), conversionFlags, resolver));
118
int i = typeName.IndexOf ('[', p);
120
return typeName.Substring (0, p);
122
if (!ParseGenericParamList (res, typeName, ref i, conversionFlags, resolver))
125
res.Append (typeName.Substring (i));
126
return res.ToString ();
129
bool ParseTypeName (StringBuilder res, string str, ref int i, ConversionFlags conversionFlags, ITypeNameResolver resolver)
131
int p = str.IndexOfAny (new char [] { '`', ',', '*', '[', ']'}, i);
135
res.Append (GetResolvedTypeName (str.Substring (i, p - i), conversionFlags, resolver));
139
// It's a generic type
140
i = str.IndexOf ('[', p);
141
if (i == -1) return false;
142
return ParseGenericParamList (res, str, ref i, conversionFlags, resolver);
144
else if (c == ',' || c == ']') {
150
// It's an array, skip it and continue searching
151
i = str.IndexOf (']', p + 1);
152
if (i == -1) return false;
153
res.Append (str, p, i - p + 1);
157
// It's an array, skip it and continue searching
166
bool ParseGenericParamList (StringBuilder res, string str, ref int i, ConversionFlags conversionFlags, ITypeNameResolver resolver)
168
// Parses a list of generic parameters (including the brackets)
170
bool includeMarkup = IncludeHTMLMarkup (conversionFlags) || IncludePangoMarkup (conversionFlags);
171
res.Append ((includeMarkup) ? "<" : "<");
174
while (p < str.Length && str [p] != ']') {
175
if (!ParseTypeName (res, str, ref p, conversionFlags, resolver))
177
if (str [p] == ',') {
182
res.Append ((includeMarkup) ? ">" : ">");
187
public override string Convert (IClass c, ConversionFlags conversionFlags, ITypeNameResolver resolver)
189
StringBuilder builder = new StringBuilder();
191
builder.Append (Convert (c.Modifiers, conversionFlags));
193
if (ShowClassModifiers(conversionFlags)) {
195
switch (c.ClassType) {
196
case ClassType.Delegate:
197
case ClassType.Struct:
202
AppendPangoHtmlTag (builder, "sealed ", "i", conversionFlags);
205
} else if (c.IsAbstract && c.ClassType != ClassType.Interface) {
206
AppendPangoHtmlTag (builder, "abstract ", "i", conversionFlags);
210
if (ShowClassModifiers(conversionFlags)) {
211
switch (c.ClassType) {
212
case ClassType.Delegate:
213
builder.Append("delegate");
214
// Only display the return type when modifiers are to be
215
// shown - this fixes the vay delegates are shown in the
217
if (c.Methods.Count > 0) {
218
foreach(IMethod m in c.Methods) {
219
if (m.Name != "Invoke") continue;
220
builder.Append (' ');
221
builder.Append (Convert (m.ReturnType, ConversionFlags.None, resolver));
225
case ClassType.Class:
226
builder.Append("class");
228
case ClassType.Struct:
229
builder.Append("struct");
231
case ClassType.Interface:
232
builder.Append("interface");
235
builder.Append("enum");
242
if (UseFullyQualifiedMemberNames (conversionFlags) || (UseIntrinsicTypeNames (conversionFlags) && typeConversionTable.Contains (c.FullyQualifiedName)))
243
name = c.FullyQualifiedName;
246
AppendPangoHtmlTag (builder, ConvertTypeName (name, conversionFlags, resolver), "b", conversionFlags);
248
// Display generic parameters only if told so
249
if (ShowGenericParameters(conversionFlags) && c.GenericParameters != null && c.GenericParameters.Count > 0) {
250
bool includeMarkup = IncludeHTMLMarkup(conversionFlags) || IncludePangoMarkup(conversionFlags);
251
builder.Append ((includeMarkup) ? "<" : "<");
252
// Since we know that there is at least one generic parameter in
253
// the list, we can add it outside the loop - so, we don't have
254
// to check whether we may append a comma or not
255
builder.Append (c.GenericParameters[0].Name);
256
// Now continue with the others, if there are any
257
for (int i = 1; i < c.GenericParameters.Count; i++) {
258
builder.Append (", ");
259
builder.Append (c.GenericParameters[i].Name);
261
builder.Append ((includeMarkup) ? ">" : ">");
264
if (c.ClassType == ClassType.Delegate && ShowClassModifiers (conversionFlags)) {
265
builder.Append(" (");
266
if (IncludeHTMLMarkup(conversionFlags)) builder.Append("<br>");
268
foreach(IMethod m in c.Methods) {
269
if (m.Name != "Invoke") continue;
271
for (int i = 0; i < m.Parameters.Count; ++i) {
272
if (IncludeHTMLMarkup(conversionFlags)) builder.Append(" ");
274
builder.Append (Convert (m.Parameters[i], conversionFlags, resolver));
275
if (i + 1 < m.Parameters.Count) builder.Append(", ");
277
if (IncludeHTMLMarkup(conversionFlags)) builder.Append("<br>");
282
} else if (ShowInheritanceList(conversionFlags) && c.ClassType != ClassType.Enum) {
283
if (c.BaseTypes.Count > 0) {
284
builder.Append (" : ");
285
builder.Append (Convert (c.BaseTypes[0], ConversionFlags.None, resolver));
286
for (int i = 1; i < c.BaseTypes.Count; ++i) {
287
builder.Append (", ");
288
builder.Append (Convert (c.BaseTypes[i], ConversionFlags.None, resolver));
293
if (IncludeBodies(conversionFlags)) {
294
builder.Append("\n{");
297
return builder.ToString();
300
public override string ConvertEnd(IClass c, ConversionFlags conversionFlags)
305
public override string Convert (IField field, ConversionFlags conversionFlags, ITypeNameResolver resolver)
307
StringBuilder builder = new StringBuilder();
309
builder.Append (Convert (field.Modifiers, conversionFlags));
311
if (ShowMemberModifiers(conversionFlags)) {
312
if (field.IsStatic && field.IsLiteral)
313
AppendPangoHtmlTag (builder, "const ", "i", conversionFlags);
314
else if (field.IsStatic)
315
AppendPangoHtmlTag (builder, "static ", "i", conversionFlags);
317
if (field.IsReadonly) {
318
AppendPangoHtmlTag (builder, "readonly ", "i", conversionFlags);
322
if (field.ReturnType != null && ShowReturnType (conversionFlags)) {
323
builder.Append (Convert (field.ReturnType, conversionFlags, resolver));
324
builder.Append (' ');
327
if (UseFullyQualifiedMemberNames(conversionFlags))
328
AppendPangoHtmlTag (builder, ConvertTypeName (field.FullyQualifiedName, conversionFlags, null), "b", conversionFlags);
330
AppendPangoHtmlTag (builder, field.Name, "b", conversionFlags);
332
if (IncludeBodies(conversionFlags))
335
return builder.ToString();
338
public override string Convert (IProperty property, ConversionFlags conversionFlags, ITypeNameResolver resolver)
340
StringBuilder builder = new StringBuilder();
342
builder.Append (Convert (property.Modifiers, conversionFlags));
344
if (ShowMemberModifiers(conversionFlags)) {
345
builder.Append(GetModifier(property, conversionFlags));
348
if (property.ReturnType != null && ShowReturnType (conversionFlags)) {
349
builder.Append (Convert (property.ReturnType, conversionFlags, resolver));
353
if (UseFullyQualifiedMemberNames(conversionFlags))
354
AppendPangoHtmlTag (builder, ConvertTypeName (property.FullyQualifiedName, conversionFlags, null), "b", conversionFlags);
356
AppendPangoHtmlTag (builder, property.Name, "b", conversionFlags);
358
if (property.Parameters.Count > 0 && ShowParameters (conversionFlags)) {
359
builder.Append(" (");
361
if (IncludeHTMLMarkup(conversionFlags)) builder.Append("<br> ");
362
builder.Append (Convert (property.Parameters[0], conversionFlags, resolver));
364
for (int i = 0; i < property.Parameters.Count; ++i) {
365
if (IncludeHTMLMarkup(conversionFlags)) builder.Append("<br> ");
366
builder.Append(", ");
367
builder.Append (Convert (property.Parameters[i], conversionFlags, resolver));
369
if (IncludeHTMLMarkup(conversionFlags)) builder.Append("<br>");
374
if (IncludeBodies(conversionFlags)) {
375
builder.Append(" { ");
377
if (property.CanGet) {
378
builder.Append("get; ");
380
if (property.CanSet) {
381
builder.Append("set; ");
384
builder.Append(" } ");
386
return builder.ToString();
389
public override string Convert (IEvent e, ConversionFlags conversionFlags, ITypeNameResolver resolver)
391
StringBuilder builder = new StringBuilder();
393
builder.Append (Convert (e.Modifiers, conversionFlags));
395
if (ShowMemberModifiers(conversionFlags)) {
396
builder.Append(GetModifier(e, conversionFlags));
399
if (e.ReturnType != null && ShowReturnType (conversionFlags)) {
400
builder.Append (Convert (e.ReturnType, conversionFlags, resolver));
401
builder.Append (' ');
404
if (UseFullyQualifiedMemberNames(conversionFlags))
405
AppendPangoHtmlTag (builder, ConvertTypeName (e.FullyQualifiedName, conversionFlags, null), "b", conversionFlags);
407
AppendPangoHtmlTag (builder, e.Name, "b", conversionFlags);
409
if (IncludeBodies(conversionFlags)) builder.Append(";");
411
return builder.ToString();
414
public override string Convert (IIndexer m, ConversionFlags conversionFlags, ITypeNameResolver resolver)
416
StringBuilder builder = new StringBuilder();
417
builder.Append (Convert (m.Modifiers, conversionFlags));
419
if (ShowMemberModifiers(conversionFlags) && m.IsStatic)
420
AppendPangoHtmlTag (builder, "static", "i", conversionFlags);
422
if (m.ReturnType != null && ShowReturnType (conversionFlags)) {
423
builder.Append (Convert (m.ReturnType, conversionFlags, resolver));
427
if (UseFullyQualifiedMemberNames (conversionFlags))
428
AppendPangoHtmlTag (builder, ConvertTypeName (m.FullyQualifiedName, conversionFlags, null), "b", conversionFlags);
430
AppendPangoHtmlTag (builder, ConvertTypeName (m.Name, conversionFlags, null), "b", conversionFlags);
432
builder.Append(" [");
434
Convert (m.Parameters, builder, conversionFlags, resolver);
438
if (IncludeBodies(conversionFlags)) builder.Append(";");
440
return builder.ToString();
443
public void Convert (ParameterCollection parameters, StringBuilder builder, ConversionFlags conversionFlags)
445
Convert (parameters, builder, conversionFlags, null);
448
public void Convert (ParameterCollection parameters, StringBuilder builder, ConversionFlags conversionFlags, ITypeNameResolver resolver)
450
if (parameters.Count > 0) {
451
for (int i = 0; i < parameters.Count; ++i) {
453
builder.Append (", ");
454
if (IncludeHTMLMarkup(conversionFlags))
455
builder.Append("<br> ");
456
builder.Append (Convert (parameters[i], conversionFlags, resolver));
458
if (IncludeHTMLMarkup(conversionFlags))
459
builder.Append("<br>");
463
public override string Convert (IMethod m, ConversionFlags conversionFlags, ITypeNameResolver resolver)
465
bool includeMarkup = IncludeHTMLMarkup(conversionFlags) || IncludePangoMarkup(conversionFlags);
467
StringBuilder builder = new StringBuilder();
468
builder.Append (Convert (m.Modifiers, conversionFlags));
469
if (ShowMemberModifiers(conversionFlags)) {
470
builder.Append(GetModifier(m, conversionFlags));
473
string name = m.Name;
475
if (m.IsSpecialName && (name == "op_Implicit" || name == "op_Explicit")) {
476
// Conversion operators have a special signature
477
if (name == "op_Implicit")
478
builder.Append("implicit operator ");
480
builder.Append("explicit operator ");
481
AppendPangoHtmlTag (builder, Convert (m.ReturnType, conversionFlags, resolver), "b", conversionFlags);
485
if (m.ReturnType != null && ShowReturnType(conversionFlags)) {
486
builder.Append (Convert (m.ReturnType, conversionFlags, resolver));
490
if (m.IsSpecialName) {
491
name = GetSpecialMethodName (name);
493
name = name.Replace ("<", "<");
494
name = name.Replace (">", ">");
498
if (m.IsConstructor) {
499
if (m.DeclaringType != null)
500
AppendPangoHtmlTag (builder, ConvertTypeName (m.DeclaringType.Name, conversionFlags, null), "b", conversionFlags);
502
AppendPangoHtmlTag (builder, name, "b", conversionFlags);
504
if (UseFullyQualifiedMemberNames(conversionFlags)) {
505
string fq = m.DeclaringType.FullyQualifiedName + "." + name;
506
AppendPangoHtmlTag (builder, ConvertTypeName (fq, conversionFlags, resolver), "b", conversionFlags);
509
AppendPangoHtmlTag (builder, name, "b", conversionFlags);
513
// Display generic parameters only if told so
514
if (ShowGenericParameters(conversionFlags) && m.GenericParameters != null && m.GenericParameters.Count > 0) {
515
builder.Append ((includeMarkup) ? "<" : "<");
516
// Since we know that there is at least one generic parameter in
517
// the list, we can add it outside the loop - so, we don't have
518
// to check whether we may append a comma or not
519
builder.Append (m.GenericParameters[0].Name);
520
// Now continue with the others, if there are any
521
for (int i = 1; i < m.GenericParameters.Count; i++) {
522
builder.Append (", ");
523
builder.Append (m.GenericParameters[i].Name);
525
builder.Append ((includeMarkup) ? ">" : ">");
528
if (ShowParameters (conversionFlags)) {
529
builder.Append(" (");
530
Convert (m.Parameters, builder, conversionFlags, resolver);
534
if (IncludeBodies(conversionFlags)) {
535
if (m.DeclaringType != null) {
536
if (m.DeclaringType.ClassType == ClassType.Interface) {
539
builder.Append(" {");
542
builder.Append(" {");
545
return builder.ToString();
548
string GetSpecialMethodName (string name)
552
case "op_Addition": return "operator +";
553
case "op_Subtraction":
554
case "op_UnaryNegation": return "operator -";
555
case "op_Multiply": return "operator *";
556
case "op_Division": return "operator /";
557
case "op_Modulus": return "operator %";
558
case "op_LogicalNot": return "operator !";
559
case "op_BitwiseAnd": return "operator &";
560
case "op_BitwiseOr": return "operator |";
561
case "op_ExclusiveOr": return "operator ^";
562
case "op_LeftShift": return "operator <<";
563
case "op_RightShift": return "operator >>";
564
case "op_GreaterThan": return "operator >";
565
case "op_GreaterThanOrEqual": return "operator >=";
566
case "op_Equality": return "operator ==";
567
case "op_Inequality": return "operator !=";
568
case "op_LessThan": return "operator <";
569
case "op_LessThanOrEqual": return "operator <=";
570
case "op_Increment": return "operator ++";
571
case "op_Decrement": return "operator --";
572
case "op_True": return "operator true";
573
case "op_False": return "operator false";
578
public override string ConvertEnd(IMethod m, ConversionFlags conversionFlags)
583
public override string Convert (IReturnType returnType, ConversionFlags conversionFlags, ITypeNameResolver resolver)
585
if (returnType == null) {
588
StringBuilder builder = new StringBuilder();
590
//bool linkSet = false;
592
//if (UseLinkArrayList(conversionFlags)) {
593
//SharpAssemblyReturnType ret = returnType as SharpAssemblyReturnType;
595
// if (ret.UnderlyingClass != null) {
596
// builder.Append("<a href='as://" + linkArrayList.Add(ret.UnderlyingClass) + "'>");
602
if (UseIntrinsicTypeNames (conversionFlags) && typeConversionTable.Contains (returnType.FullyQualifiedName)) {
603
builder.Append (typeConversionTable[returnType.FullyQualifiedName].ToString());
605
if (UseFullyQualifiedMemberNames(conversionFlags)) {
606
builder.Append (ConvertTypeName (returnType.FullyQualifiedName, conversionFlags, resolver));
608
builder.Append (ConvertTypeName (returnType.Name, conversionFlags, resolver));
612
// Display generic parameters only if told so
613
if (ShowGenericParameters(conversionFlags) && returnType.GenericArguments != null && returnType.GenericArguments.Count > 0) {
614
bool includeMarkup = IncludeHTMLMarkup(conversionFlags) || IncludePangoMarkup(conversionFlags);
615
builder.Append ((includeMarkup) ? "<" : "<");
616
// Since we know that there is at least one generic argument in
617
// the list, we can add it outside the loop - so, we don't have
618
// to check whether we may append a comma or not
619
builder.Append (Convert (returnType.GenericArguments[0], conversionFlags, resolver));
620
// Now continue with the others, if there are any
621
for (int i = 1; i < returnType.GenericArguments.Count; i++) {
622
builder.Append (", ");
623
builder.Append (Convert (returnType.GenericArguments[i], conversionFlags, resolver));
625
builder.Append ((includeMarkup) ? ">" : ">");
629
// builder.Append("</a>");
632
for (int i = 0; i < returnType.PointerNestingLevel; ++i) {
636
for (int i = 0; i < returnType.ArrayCount; ++i) {
638
for (int j = 1; j < returnType.ArrayDimensions[i]; ++j) {
644
return builder.ToString();
647
public override string Convert (IParameter param, ConversionFlags conversionFlags, ITypeNameResolver resolver)
649
StringBuilder builder = new StringBuilder();
652
AppendPangoHtmlTag (builder, "ref ", "i", conversionFlags);
653
else if (param.IsOut)
654
AppendPangoHtmlTag (builder, "out ", "i", conversionFlags);
655
else if (param.IsParams)
656
AppendPangoHtmlTag (builder, "params ", "i", conversionFlags);
658
builder.Append (Convert (param.ReturnType, conversionFlags, resolver));
660
if (ShowParameterNames(conversionFlags)) {
662
AppendPangoHtmlTag (builder, param.Name, "b", conversionFlags);
664
return builder.ToString();
667
public override string Convert (LocalVariable localVariable, ConversionFlags conversionFlags, ITypeNameResolver resolver)
669
StringBuilder builder = new StringBuilder();
670
if (ShowReturnType (conversionFlags)) {
671
builder.Append (Convert (localVariable.ReturnType, conversionFlags, resolver));
674
AppendPangoHtmlTag (builder, localVariable.Name, "b", conversionFlags);
676
return builder.ToString();
679
// pango has some problems with
680
// <i>static </i>bool <b>Equals</b> (<i></i>object a, <i></i>object b)
681
// it will make "object a" italics. so rather tan appending a markup
682
// tag if there might be a modifier, we only do it if there is.
683
void AppendPangoHtmlTag (StringBuilder sb, string str, string tag, ConversionFlags conversionFlags)
685
if (IncludeHTMLMarkup(conversionFlags) | IncludePangoMarkup(conversionFlags)) sb.Append ('<').Append (tag).Append ('>');
689
if (IncludeHTMLMarkup(conversionFlags) | IncludePangoMarkup(conversionFlags)) sb.Append ("</").Append (tag).Append ('>');
692
public override string WrapAttribute(string attribute)
694
return "[" + attribute + "]";
697
public override string WrapComment(string comment)
699
return "// " + comment;
702
public override string GetIntrinsicTypeName (string dotNetTypeName)
704
string tn = typeConversionTable [dotNetTypeName] as string;
708
return dotNetTypeName;