// Author:
// Daniel Stodden (stodden@in.tum.de)
// Marek Safar (marek.safar@seznam.cz)
+// Ilker Cetinkaya (mail@ilker.de)
//
// (C) 2002 Ximian, Inc.
//
using System.Reflection;
using System.Collections;
using System.Text;
-
+ using System.Collections.Generic;
+
internal class CSharpCodeGenerator
: CodeGenerator
{
+ IDictionary <string, string> providerOptions;
+
// It is used for beautiful "for" syntax
bool dont_write_semicolon;
dont_write_semicolon = false;
}
+ public CSharpCodeGenerator (IDictionary <string, string> providerOptions)
+ {
+ this.providerOptions = providerOptions;
+ }
+
+ protected IDictionary <string, string> ProviderOptions {
+ get { return providerOptions; }
+ }
+
//
// Properties
//
{
GenerateCompileUnitStart (compileUnit);
+ GenerateGlobalNamespace (compileUnit);
+
if (compileUnit.AssemblyCustomAttributes.Count > 0) {
OutputAttributes (compileUnit.AssemblyCustomAttributes,
"assembly: ", false);
Output.WriteLine ("");
}
- foreach (CodeNamespace ns in compileUnit.Namespaces)
- GenerateNamespace (ns);
+ GenerateLocalNamespaces (compileUnit);
GenerateCompileUnitEnd (compileUnit);
}
+ private void GenerateGlobalNamespace (CodeCompileUnit compileUnit) {
+ CodeNamespace globalNamespace = null;
+
+ foreach (CodeNamespace codeNamespace in compileUnit.Namespaces)
+ if (string.IsNullOrEmpty (codeNamespace.Name))
+ globalNamespace = codeNamespace;
+
+ if (globalNamespace != null)
+ GenerateNamespace (globalNamespace);
+ }
+
+ private void GenerateLocalNamespaces (CodeCompileUnit compileUnit) {
+ foreach (CodeNamespace codeNamespace in compileUnit.Namespaces)
+ if (!string.IsNullOrEmpty (codeNamespace.Name))
+ GenerateNamespace (codeNamespace);
+ }
+
+ protected override void GenerateDefaultValueExpression (CodeDefaultValueExpression e)
+ {
+ Output.Write ("default(");
+ OutputType (e.Type);
+ Output.Write (')');
+ }
+
protected override void GenerateDelegateCreateExpression (CodeDelegateCreateExpression expression)
{
TextWriter output = Output;
Output.Write ('.');
};
Output.Write (GetSafeName (expression.MethodName));
-#if NET_2_0
if (expression.TypeArguments.Count > 0)
Output.Write (GetTypeArguments (expression.TypeArguments));
-#endif
}
protected override void GenerateEventReferenceExpression (CodeEventReferenceExpression expression)
protected override void GenerateDelegateInvokeExpression (CodeDelegateInvokeExpression expression)
{
- GenerateExpression (expression.TargetObject);
+ if (expression.TargetObject != null)
+ GenerateExpression (expression.TargetObject);
Output.Write ('(');
OutputExpressionList (expression.Parameters);
Output.Write (')');
{
Output.WriteLine ();
Output.WriteLine ("#line default");
+ Output.WriteLine ("#line hidden");
}
protected override void GenerateEvent (CodeMemberEvent eventRef, CodeTypeDeclaration declaration)
protected override void GenerateEntryPointMethod (CodeEntryPointMethod method,
CodeTypeDeclaration declaration)
{
-#if NET_2_0
OutputAttributes (method.CustomAttributes, null, false);
-#endif
Output.Write ("public static ");
-#if NET_2_0
OutputType (method.ReturnType);
-#else
- Output.Write ("void");
-#endif
Output.Write (" Main()");
OutputStartBrace ();
Indent++;
}
output.Write (GetSafeName (method.Name));
-#if NET_2_0
GenerateGenericsParameters (method.TypeParameters);
-#endif
output.Write ('(');
OutputParameters (method.Parameters);
output.Write (')');
-#if NET_2_0
GenerateGenericsConstraints (method.TypeParameters);
-#endif
- if ((attributes & MemberAttributes.ScopeMask) == MemberAttributes.Abstract || declaration.IsInterface)
+ if (IsAbstract (attributes) || declaration.IsInterface)
output.WriteLine (';');
else {
OutputStartBrace ();
}
}
+ static bool IsAbstract (MemberAttributes attributes)
+ {
+ return (attributes & MemberAttributes.ScopeMask) == MemberAttributes.Abstract;
+ }
+
protected override void GenerateProperty (CodeMemberProperty property,
CodeTypeDeclaration declaration)
{
OutputParameters(property.Parameters);
output.Write(']');
} else {
- output.Write (property.Name);
+ output.Write (GetSafeName (property.Name));
}
OutputStartBrace ();
++Indent;
- if (declaration.IsInterface)
+ if (declaration.IsInterface || IsAbstract (property.Attributes))
{
if (property.HasGet) output.WriteLine("get;");
if (property.HasSet) output.WriteLine("set;");
return;
}
-#if NET_2_0
OutputAttributes (constructor.CustomAttributes, null, false);
-#endif
Output.Write ("static " + GetSafeName (CurrentTypeName) + "()");
OutputStartBrace ();
output.Write (GetSafeName (declaration.Name));
-#if NET_2_0
GenerateGenericsParameters (declaration.TypeParameters);
-#endif
IEnumerator enumerator = declaration.BaseTypes.GetEnumerator ();
if (enumerator.MoveNext ()) {
}
}
-#if NET_2_0
GenerateGenericsConstraints (declaration.TypeParameters);
-#endif
OutputStartBrace ();
++Indent;
} else {
private void OutputAttributes (CodeAttributeDeclarationCollection attributes, string prefix, bool inline)
{
+ bool params_set = false;
+
foreach (CodeAttributeDeclaration att in attributes) {
+ if (att.Name == "System.ParamArrayAttribute") {
+ params_set = true;
+ continue;
+ }
+
GenerateAttributeDeclarationsStart (attributes);
if (prefix != null) {
Output.Write (prefix);
Output.WriteLine ();
}
}
+
+ if (params_set) {
+ if (prefix != null)
+ Output.Write (prefix);
+ Output.Write ("params");
+ if (inline)
+ Output.Write (" ");
+ else
+ Output.WriteLine ();
+ }
}
private void OutputAttributeDeclaration (CodeAttributeDeclaration attribute)
}
}
-#if NET_2_0
// Note: this method should in fact be private as in .NET 2.0, the
// CSharpCodeGenerator no longer derives from CodeGenerator but we
break;
}
}
-#endif
private void OutputTypeAttributes (CodeTypeDeclaration declaration)
{
case TypeAttributes.NestedPrivate:
output.Write ("private ");
break;
-#if NET_2_0
case TypeAttributes.NotPublic:
case TypeAttributes.NestedFamANDAssem:
case TypeAttributes.NestedAssembly:
case TypeAttributes.NestedFamORAssem:
output.Write ("protected internal ");
break;
-#endif
}
+ if ((declaration.Attributes & MemberAttributes.New) != 0)
+ output.Write ("new ");
+
if (declaration.IsStruct) {
-#if NET_2_0
if (declaration.IsPartial) {
output.Write ("partial ");
}
-#endif
output.Write ("struct ");
} else if (declaration.IsEnum) {
output.Write ("enum ");
} else {
if ((attributes & TypeAttributes.Interface) != 0) {
-#if NET_2_0
if (declaration.IsPartial) {
output.Write ("partial ");
}
-#endif
output.Write ("interface ");
} else {
if ((attributes & TypeAttributes.Sealed) != 0)
output.Write ("sealed ");
if ((attributes & TypeAttributes.Abstract) != 0)
output.Write ("abstract ");
-#if NET_2_0
if (declaration.IsPartial) {
output.Write ("partial ");
}
-#endif
output.Write ("class ");
}
}
{
if (e.Value is char) {
this.GenerateCharValue ((char) e.Value);
-#if NET_2_0
} else if (e.Value is ushort) {
ushort uc = (ushort) e.Value;
Output.Write (uc.ToString(CultureInfo.InvariantCulture));
} else if (e.Value is sbyte) {
sbyte sb = (sbyte) e.Value;
Output.Write (sb.ToString(CultureInfo.InvariantCulture));
-#endif
} else {
base.GeneratePrimitiveExpression (e);
}
break;
case '\u2028':
Output.Write ("\\u");
-#if NET_2_0
Output.Write (((int) c).ToString ("X4", CultureInfo.InvariantCulture));
-#else
- Output.Write (((int) c).ToString (CultureInfo.InvariantCulture));
-#endif
break;
case '\u2029':
Output.Write ("\\u");
-#if NET_2_0
Output.Write (((int) c).ToString ("X4", CultureInfo.InvariantCulture));
-#else
- Output.Write (((int) c).ToString (CultureInfo.InvariantCulture));
-#endif
break;
default:
Output.Write (c);
protected override string GetTypeOutput (CodeTypeReference type)
{
+ if ((type.Options & CodeTypeReferenceOptions.GenericTypeParameter) != 0)
+ return type.BaseType;
+
string typeOutput = null;
if (type.ArrayElementType != null) {
}
typeOutput += ']';
}
+
return typeOutput;
}
case "system.void":
typeOutput = "void";
break;
-#if NET_2_0
case "system.byte":
typeOutput = "byte";
break;
case "system.uint64":
typeOutput = "ulong";
break;
-#endif
default:
-#if NET_2_0
StringBuilder sb = new StringBuilder (baseType.Length);
- if (type.Options == CodeTypeReferenceOptions.GlobalReference) {
+ if ((type.Options & CodeTypeReferenceOptions.GlobalReference) != 0) {
sb.Append ("global::");
}
// skip ` character
i++;
// determine number of type arguments to output
- int typeArgCount = baseType[i] - '0';
+ int end = i;
+ while (end < baseType.Length && Char.IsDigit (baseType [end]))
+ end++;
+ int typeArgCount = Int32.Parse (baseType.Substring (i, end - i));
// output type arguments
OutputTypeArguments (type.TypeArguments, sb, typeArgCount);
// skip type argument indicator
- i++;
+ i = end;
// if next character is . or +, then append .
if ((i < baseType.Length) && ((baseType[i] == '+') || (baseType[i] == '.'))) {
sb.Append ('.');
}
typeOutput = sb.ToString ();
-#else
- typeOutput = GetSafeName (baseType);
- typeOutput = typeOutput.Replace ('+', '.');
-#endif
break;
}
return typeOutput;
}
+ static bool is_identifier_start_character (char c)
+ {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '@' || Char.IsLetter (c);
+ }
+
+ static bool is_identifier_part_character (char c)
+ {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9') || Char.IsLetter (c);
+ }
+
protected override bool IsValidIdentifier (string identifier)
{
+ if (identifier == null || identifier.Length == 0)
+ return false;
+
if (keywordsTable == null)
FillKeywordTable ();
- return !keywordsTable.Contains (identifier);
+ if (keywordsTable.Contains (identifier))
+ return false;
+
+ if (!is_identifier_start_character (identifier [0]))
+ return false;
+
+ for (int i = 1; i < identifier.Length; i ++)
+ if (! is_identifier_part_character (identifier [i]))
+ return false;
+
+ return true;
}
protected override bool Supports (GeneratorSupport supports)
return true;
}
-#if NET_2_0
protected override void GenerateDirectives (CodeDirectiveCollection directives)
{
foreach (CodeDirective d in directives) {
void GenerateCodeChecksumPragma (CodeChecksumPragma pragma)
{
- Output.Write ("#pragma checksum \"");
- Output.Write (pragma.FileName);
- Output.Write ("\" \"");
+ Output.Write ("#pragma checksum ");
+ Output.Write (QuoteSnippetString (pragma.FileName));
+ Output.Write (" \"");
Output.Write (pragma.ChecksumAlgorithmId.ToString ("B"));
Output.Write ("\" \"");
if (pragma.ChecksumData != null) {
if (count == 0)
return;
- ++Indent;
- foreach (CodeTypeParameter p in parameters) {
- if (p.Constraints.Count == 0)
- continue;
+ bool indented = false;
+
+ for (int i = 0; i < count; i++) {
+ CodeTypeParameter p = parameters [i];
+ bool hasConstraints = (p.Constraints.Count != 0);
Output.WriteLine ();
+ if (!hasConstraints && !p.HasConstructorConstraint)
+ continue;
+
+ if (!indented) {
+ ++Indent;
+ indented = true;
+ }
+
Output.Write ("where ");
Output.Write (p.Name);
Output.Write (" : ");
- bool is_first = true;
- foreach (CodeTypeReference r in p.Constraints) {
- if (is_first)
- is_first = false;
- else
+ for (int j = 0; j < p.Constraints.Count; j++) {
+ if (j > 0)
Output.Write (", ");
- OutputType (r);
+ OutputType (p.Constraints [j]);
}
+
if (p.HasConstructorConstraint) {
- if (!is_first)
+ if (hasConstraints)
Output.Write (", ");
- Output.Write ("new ()");
+ Output.Write ("new");
+ if (hasConstraints)
+ Output.Write (" ");
+ Output.Write ("()");
}
-
}
- --Indent;
+
+ if (indented)
+ --Indent;
}
string GetTypeArguments (CodeTypeReferenceCollection collection)
{
if (count == 0) {
return;
+ } else if (typeArguments.Count == 0) {
+ // generic type definition
+ sb.Append ("<>");
+ return;
}
sb.Append ('<');
sb.Append ('>');
}
-#endif
#if false
//[MonoTODO]
"namespace",
"object","bool","byte","float","uint","char","ulong","ushort",
"decimal","int","sbyte","short","double","long","string","void",
-#if NET_2_0
"partial", "yield", "where"
-#endif
};
}
}