using System.Collections;
using System.Text;
+#if NET_2_0
+ using System.Collections.Generic;
+#endif
+
internal class CSharpCodeGenerator
: CodeGenerator
{
+#if NET_2_0
+ IDictionary <string, string> providerOptions;
+#endif
+
// It is used for beautiful "for" syntax
bool dont_write_semicolon;
dont_write_semicolon = false;
}
+#if NET_2_0
+ public CSharpCodeGenerator (IDictionary <string, string> providerOptions)
+ {
+ this.providerOptions = providerOptions;
+ }
+
+ protected IDictionary <string, string> ProviderOptions {
+ get { return providerOptions; }
+ }
+#endif
+
//
// Properties
//
protected override void GenerateEventReferenceExpression (CodeEventReferenceExpression expression)
{
- GenerateExpression (expression.TargetObject);
- Output.Write ('.');
+ if (expression.TargetObject != null) {
+ GenerateExpression (expression.TargetObject);
+ Output.Write ('.');
+ }
Output.Write (GetSafeName (expression.EventName));
}
protected override void GenerateDelegateInvokeExpression (CodeDelegateInvokeExpression expression)
{
- GenerateExpression (expression.TargetObject);
+ if (expression.TargetObject != null)
+ GenerateExpression (expression.TargetObject);
Output.Write ('(');
OutputExpressionList (expression.Parameters);
Output.Write (')');
GenerateExpression (statement.TestExpression);
output.Write ("; ");
GenerateStatement (statement.IncrementStatement);
- output.Write (") ");
+ output.Write (")");
dont_write_semicolon = false;
OutputStartBrace ();
++Indent;
protected override void GenerateComment (CodeComment comment)
{
TextWriter output = Output;
- string[] lines = comment.Text.Split ('\n');
- bool first = true;
- foreach (string line in lines){
- if (comment.DocComment)
- output.Write ("///");
- else
- output.Write ("//");
- if (first) {
- output.Write (' ');
- first = false;
+
+ string commentChars = null;
+
+ if (comment.DocComment) {
+ commentChars = "///";
+ } else {
+ commentChars = "//";
+ }
+
+ output.Write (commentChars);
+ output.Write (' ');
+ string text = comment.Text;
+
+ for (int i = 0; i < text.Length; i++) {
+ output.Write (text[i]);
+ if (text[i] == '\r') {
+ if (i < (text.Length - 1) && text[i + 1] == '\n') {
+ continue;
+ }
+ output.Write (commentChars);
+ } else if (text[i] == '\n') {
+ output.Write (commentChars);
}
- output.WriteLine (line);
}
+
+ output.WriteLine ();
}
protected override void GenerateMethodReturnStatement (CodeMethodReturnStatement statement)
output.Write (' ');
else
output.WriteLine ();
- output.WriteLine ("else");
+ output.Write ("else");
OutputStartBrace ();
++Indent;
GenerateStatements (falses);
TextWriter output = Output;
CodeGeneratorOptions options = Options;
- output.WriteLine ("try");
+ output.Write ("try");
OutputStartBrace ();
++Indent;
GenerateStatements (statement.TryStatements);
--Indent;
- output.Write ('}');
foreach (CodeCatchClause clause in statement.CatchClauses) {
+ output.Write ('}');
if (options.ElseOnClosing)
output.Write (' ');
else
output.WriteLine ();
output.Write ("catch (");
OutputTypeNamePair (clause.CatchExceptionType, GetSafeName(clause.LocalName));
- output.WriteLine (")");
+ output.Write (")");
OutputStartBrace ();
++Indent;
GenerateStatements (clause.Statements);
--Indent;
- output.Write ('}');
}
CodeStatementCollection finallies = statement.FinallyStatements;
if (finallies.Count > 0) {
+ output.Write ('}');
if (options.ElseOnClosing)
output.Write (' ');
else
output.WriteLine ();
- output.WriteLine ("finally");
+ output.Write ("finally");
OutputStartBrace ();
++Indent;
GenerateStatements (finallies);
--Indent;
- output.WriteLine ('}');
}
- output.WriteLine();
+ output.WriteLine('}');
}
protected override void GenerateAssignStatement (CodeAssignStatement statement)
{
TextWriter output = Output;
GenerateEventReferenceExpression (statement.Event);
- Output.Write (" -= ");
+ output.Write (" -= ");
GenerateExpression (statement.Listener);
output.WriteLine (';');
}
output.Write ("goto ");
output.Write (GetSafeName (statement.Label));
- output.Write (";");
+ output.WriteLine (";");
}
protected override void GenerateLabeledStatement (CodeLabeledStatement statement)
{
- Output.Write (String.Concat (GetSafeName (statement.Label), ": "));
+ Indent--;
+ Output.Write (statement.Label);
+ Output.WriteLine (":");
+ Indent++;
- if (statement.Statement != null)
+ if (statement.Statement != null) {
GenerateStatement (statement.Statement);
+ }
}
protected override void GenerateVariableDeclarationStatement (CodeVariableDeclarationStatement statement)
GenerateExpression (initExpression);
}
- output.WriteLine (';');
+ if (!dont_write_semicolon) {
+ output.WriteLine (';');
+ }
}
protected override void GenerateLinePragmaStart (CodeLinePragma linePragma)
{
Output.WriteLine ();
Output.WriteLine ("#line default");
+#if NET_2_0
+ Output.WriteLine ("#line hidden");
+#endif
}
protected override void GenerateEvent (CodeMemberEvent eventRef, CodeTypeDeclaration declaration)
protected override void GenerateEntryPointMethod (CodeEntryPointMethod method,
CodeTypeDeclaration declaration)
{
- method.Name = "Main";
- GenerateMethod (method, 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++;
+ GenerateStatements (method.Statements);
+ Indent--;
+ Output.WriteLine ("}");
}
protected override void GenerateMethod (CodeMemberMethod method,
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;");
Indent--;
Output.WriteLine ('}');
}
-
+
protected override void GenerateTypeConstructor (CodeTypeConstructor constructor)
{
if (IsCurrentDelegate || IsCurrentEnum || IsCurrentInterface) {
private void OutputAttributes (CodeAttributeDeclarationCollection attributes, string prefix, bool inline)
{
+#if NET_2_0
+ bool params_set = false;
+#endif
+
foreach (CodeAttributeDeclaration att in attributes) {
+#if NET_2_0
+ if (att.Name == "System.ParamArrayAttribute") {
+ params_set = true;
+ continue;
+ }
+#endif
+
GenerateAttributeDeclarationsStart (attributes);
if (prefix != null) {
Output.Write (prefix);
Output.WriteLine ();
}
}
+
+#if NET_2_0
+ if (params_set) {
+ if (prefix != null)
+ Output.Write (prefix);
+ Output.Write ("params");
+ if (inline)
+ Output.Write (" ");
+ else
+ Output.WriteLine ();
+ }
+#endif
}
private void OutputAttributeDeclaration (CodeAttributeDeclaration attribute)
return "\"" + output + "\"";
}
+ protected override void GeneratePrimitiveExpression(CodePrimitiveExpression e)
+ {
+ 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 uint) {
+ uint ui = (uint) e.Value;
+ Output.Write (ui.ToString(CultureInfo.InvariantCulture));
+ Output.Write ("u");
+ } else if (e.Value is ulong) {
+ ulong ul = (ulong) e.Value;
+ Output.Write (ul.ToString(CultureInfo.InvariantCulture));
+ Output.Write ("ul");
+ } else if (e.Value is sbyte) {
+ sbyte sb = (sbyte) e.Value;
+ Output.Write (sb.ToString(CultureInfo.InvariantCulture));
+#endif
+ } else {
+ base.GeneratePrimitiveExpression (e);
+ }
+ }
+
+ private void GenerateCharValue (char c)
+ {
+ Output.Write ('\'');
+
+ switch (c) {
+ case '\0':
+ Output.Write ("\\0");
+ break;
+ case '\t':
+ Output.Write ("\\t");
+ break;
+ case '\n':
+ Output.Write ("\\n");
+ break;
+ case '\r':
+ Output.Write ("\\r");
+ break;
+ case '"':
+ Output.Write ("\\\"");
+ break;
+ case '\'':
+ Output.Write ("\\'");
+ break;
+ case '\\':
+ Output.Write ("\\\\");
+ 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);
+ break;
+ }
+
+ Output.Write ('\'');
+ }
+
+ protected override void GenerateSingleFloatValue (float f)
+ {
+ base.GenerateSingleFloatValue (f);
+ base.Output.Write ('F');
+ }
+
+ protected override void GenerateDecimalValue (decimal d)
+ {
+ base.GenerateDecimalValue (d);
+ base.Output.Write ('m');
+ }
+
protected override void GenerateParameterDeclarationExpression (CodeParameterDeclarationExpression e)
{
OutputAttributes (e.CustomAttributes, null, true);
else
return value;
}
-
+
protected override string GetTypeOutput (CodeTypeReference type)
{
+#if NET_2_0
+ if ((type.Options & CodeTypeReferenceOptions.GenericTypeParameter) != 0)
+ return type.BaseType;
+#endif
+
string typeOutput = null;
if (type.ArrayElementType != null) {
}
typeOutput += ']';
}
+
return typeOutput;
}
// 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)
Output.Write ("\" \"");
Output.Write (pragma.ChecksumAlgorithmId.ToString ("B"));
Output.Write ("\" \"");
- foreach (byte b in pragma.ChecksumData) {
- Output.Write (b.ToString ("X2"));
+ if (pragma.ChecksumData != null) {
+ foreach (byte b in pragma.ChecksumData) {
+ Output.Write (b.ToString ("X2"));
+ }
}
Output.WriteLine ("\"");
}
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 ('<');