2 // System.CodeDom.Compiler.CodeGenerator.cs
5 // Miguel de Icaza (miguel@ximian.com)
6 // Daniel Stodden (stodden@in.tum.de)
7 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
9 // Marek Safar (marek.safar@seznam.cz)
11 // (C) 2001-2003 Ximian, Inc.
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System.Globalization;
37 using System.Reflection;
39 using System.Collections;
41 namespace System.CodeDom.Compiler {
43 public abstract class CodeGenerator : ICodeGenerator
45 private IndentedTextWriter output;
46 private CodeGeneratorOptions options;
47 private CodeTypeMember currentMember;
48 private CodeTypeDeclaration currentType;
49 private Visitor visitor;
54 protected CodeGenerator()
56 visitor = new Visitor (this);
63 CodeTypeDeclaration CurrentClass {
69 protected CodeTypeMember CurrentMember {
75 protected string CurrentMemberName {
77 if (currentMember == null)
78 return "<% unknown %>";
79 return currentMember.Name;
83 protected string CurrentTypeName {
85 if (currentType == null)
86 return "<% unknown %>";
87 return currentType.Name;
91 protected int Indent {
96 output.Indent = value;
100 protected bool IsCurrentClass {
102 if (currentType == null)
104 return currentType.IsClass && !(currentType is CodeTypeDelegate);
108 protected bool IsCurrentDelegate {
110 return currentType is CodeTypeDelegate;
114 protected bool IsCurrentEnum {
116 if (currentType == null)
118 return currentType.IsEnum;
122 protected bool IsCurrentInterface {
124 if (currentType == null)
126 return currentType.IsInterface;
130 protected bool IsCurrentStruct {
132 if (currentType == null)
134 return currentType.IsStruct;
138 protected abstract string NullToken {
143 protected CodeGeneratorOptions Options {
149 protected TextWriter Output {
158 protected virtual void ContinueOnNewLine (string st)
160 output.WriteLine (st);
164 * Code Generation methods
166 protected abstract void GenerateArgumentReferenceExpression (CodeArgumentReferenceExpression e);
167 protected abstract void GenerateArrayCreateExpression (CodeArrayCreateExpression e);
168 protected abstract void GenerateArrayIndexerExpression (CodeArrayIndexerExpression e);
169 protected abstract void GenerateAssignStatement (CodeAssignStatement s);
170 protected abstract void GenerateAttachEventStatement (CodeAttachEventStatement s);
171 protected abstract void GenerateAttributeDeclarationsStart (CodeAttributeDeclarationCollection attributes);
172 protected abstract void GenerateAttributeDeclarationsEnd (CodeAttributeDeclarationCollection attributes);
173 protected abstract void GenerateBaseReferenceExpression (CodeBaseReferenceExpression e);
175 protected virtual void GenerateBinaryOperatorExpression (CodeBinaryOperatorExpression e)
178 GenerateExpression (e.Left);
180 OutputOperator (e.Operator);
182 GenerateExpression (e.Right);
186 protected abstract void GenerateCastExpression (CodeCastExpression e);
189 public virtual void GenerateCodeFromMember (CodeTypeMember member, TextWriter writer, CodeGeneratorOptions options)
191 throw new NotImplementedException ();
193 protected abstract void GenerateComment (CodeComment comment);
195 protected virtual void GenerateCommentStatement (CodeCommentStatement statement)
197 GenerateComment (statement.Comment);
200 protected virtual void GenerateCommentStatements (CodeCommentStatementCollection statements)
202 foreach (CodeCommentStatement comment in statements)
203 GenerateCommentStatement (comment);
206 protected virtual void GenerateCompileUnit (CodeCompileUnit compileUnit)
208 GenerateCompileUnitStart (compileUnit);
210 CodeAttributeDeclarationCollection attributes = compileUnit.AssemblyCustomAttributes;
211 if (attributes.Count != 0) {
212 foreach (CodeAttributeDeclaration att in attributes) {
213 GenerateAttributeDeclarationsStart (attributes);
214 output.Write ("assembly: ");
215 OutputAttributeDeclaration (att);
216 GenerateAttributeDeclarationsEnd (attributes);
221 foreach (CodeNamespace ns in compileUnit.Namespaces)
222 GenerateNamespace (ns);
224 GenerateCompileUnitEnd (compileUnit);
227 protected virtual void GenerateCompileUnitEnd (CodeCompileUnit compileUnit)
229 if (compileUnit.EndDirectives.Count > 0)
230 GenerateDirectives (compileUnit.EndDirectives);
233 protected virtual void GenerateCompileUnitStart (CodeCompileUnit compileUnit)
235 if (compileUnit.StartDirectives.Count > 0) {
236 GenerateDirectives (compileUnit.StartDirectives);
241 protected abstract void GenerateConditionStatement (CodeConditionStatement s);
242 protected abstract void GenerateConstructor (CodeConstructor x, CodeTypeDeclaration d);
244 protected virtual void GenerateDecimalValue (Decimal d)
246 Output.Write (d.ToString (CultureInfo.InvariantCulture));
250 protected virtual void GenerateDefaultValueExpression (CodeDefaultValueExpression e)
252 throw new NotImplementedException ();
255 protected abstract void GenerateDelegateCreateExpression (CodeDelegateCreateExpression e);
256 protected abstract void GenerateDelegateInvokeExpression (CodeDelegateInvokeExpression e);
258 protected virtual void GenerateDirectionExpression (CodeDirectionExpression e)
260 OutputDirection (e.Direction);
262 GenerateExpression (e.Expression);
265 protected virtual void GenerateDoubleValue (Double d)
267 Output.Write (d.ToString (CultureInfo.InvariantCulture));
270 protected abstract void GenerateEntryPointMethod (CodeEntryPointMethod m, CodeTypeDeclaration d);
271 protected abstract void GenerateEvent (CodeMemberEvent ev, CodeTypeDeclaration d);
272 protected abstract void GenerateEventReferenceExpression (CodeEventReferenceExpression e);
274 protected void GenerateExpression (CodeExpression e)
277 throw new ArgumentNullException ("e");
281 } catch (NotImplementedException) {
282 throw new ArgumentException ("Element type " + e.GetType () + " is not supported.", "e");
286 protected abstract void GenerateExpressionStatement (CodeExpressionStatement statement);
287 protected abstract void GenerateField (CodeMemberField f);
288 protected abstract void GenerateFieldReferenceExpression (CodeFieldReferenceExpression e);
289 protected abstract void GenerateGotoStatement (CodeGotoStatement statement);
290 protected abstract void GenerateIndexerExpression (CodeIndexerExpression e);
291 protected abstract void GenerateIterationStatement (CodeIterationStatement s);
292 protected abstract void GenerateLabeledStatement (CodeLabeledStatement statement);
293 protected abstract void GenerateLinePragmaStart (CodeLinePragma p);
294 protected abstract void GenerateLinePragmaEnd (CodeLinePragma p);
295 protected abstract void GenerateMethod (CodeMemberMethod m, CodeTypeDeclaration d);
296 protected abstract void GenerateMethodInvokeExpression (CodeMethodInvokeExpression e);
297 protected abstract void GenerateMethodReferenceExpression (CodeMethodReferenceExpression e);
298 protected abstract void GenerateMethodReturnStatement (CodeMethodReturnStatement e);
300 protected virtual void GenerateNamespace (CodeNamespace ns)
302 foreach (CodeCommentStatement statement in ns.Comments)
303 GenerateCommentStatement (statement);
305 GenerateNamespaceStart (ns);
307 foreach (CodeNamespaceImport import in ns.Imports) {
308 if (import.LinePragma != null)
309 GenerateLinePragmaStart (import.LinePragma);
311 GenerateNamespaceImport (import);
313 if (import.LinePragma != null)
314 GenerateLinePragmaEnd (import.LinePragma);
321 GenerateNamespaceEnd (ns);
324 protected abstract void GenerateNamespaceStart (CodeNamespace ns);
325 protected abstract void GenerateNamespaceEnd (CodeNamespace ns);
326 protected abstract void GenerateNamespaceImport (CodeNamespaceImport i);
327 protected void GenerateNamespaceImports (CodeNamespace e)
329 foreach (CodeNamespaceImport import in e.Imports) {
330 if (import.LinePragma != null)
331 GenerateLinePragmaStart (import.LinePragma);
333 GenerateNamespaceImport (import);
335 if (import.LinePragma != null)
336 GenerateLinePragmaEnd (import.LinePragma);
340 protected void GenerateNamespaces (CodeCompileUnit e)
342 foreach (CodeNamespace ns in e.Namespaces)
343 GenerateNamespace (ns);
346 protected abstract void GenerateObjectCreateExpression (CodeObjectCreateExpression e);
348 protected virtual void GenerateParameterDeclarationExpression (CodeParameterDeclarationExpression e)
350 if (e.CustomAttributes != null && e.CustomAttributes.Count > 0)
351 OutputAttributeDeclarations (e.CustomAttributes);
352 OutputDirection (e.Direction);
355 output.Write (e.Name);
358 protected virtual void GeneratePrimitiveExpression (CodePrimitiveExpression e)
360 object value = e.Value;
362 output.Write (NullToken);
366 Type type = value.GetType ();
367 TypeCode typeCode = Type.GetTypeCode (type);
369 case TypeCode.Boolean:
370 output.Write (value.ToString ().ToLower (CultureInfo.InvariantCulture));
373 output.Write ("'" + value.ToString () + "'");
375 case TypeCode.String:
376 output.Write (QuoteSnippetString ((string) value));
378 case TypeCode.Single:
379 GenerateSingleFloatValue ((float) value);
381 case TypeCode.Double:
382 GenerateDoubleValue ((double) value);
384 case TypeCode.Decimal:
385 GenerateDecimalValue ((decimal) value);
391 output.Write (((IFormattable)value).ToString (null, CultureInfo.InvariantCulture));
394 throw new ArgumentException (string.Format(CultureInfo.InvariantCulture,
395 "Invalid Primitive Type: {0}. Only CLS compliant primitive " +
396 "types can be used. Consider using CodeObjectCreateExpression.",
401 protected abstract void GenerateProperty (CodeMemberProperty p, CodeTypeDeclaration d);
402 protected abstract void GeneratePropertyReferenceExpression (CodePropertyReferenceExpression e);
403 protected abstract void GeneratePropertySetValueReferenceExpression (CodePropertySetValueReferenceExpression e);
404 protected abstract void GenerateRemoveEventStatement (CodeRemoveEventStatement statement);
406 protected virtual void GenerateSingleFloatValue (Single s)
408 output.Write (s.ToString(CultureInfo.InvariantCulture));
411 protected virtual void GenerateSnippetCompileUnit (CodeSnippetCompileUnit e)
413 if (e.LinePragma != null)
414 GenerateLinePragmaStart (e.LinePragma);
416 output.WriteLine (e.Value);
418 if (e.LinePragma != null)
419 GenerateLinePragmaEnd (e.LinePragma);
423 protected abstract void GenerateSnippetExpression (CodeSnippetExpression e);
424 protected abstract void GenerateSnippetMember (CodeSnippetTypeMember m);
425 protected virtual void GenerateSnippetStatement (CodeSnippetStatement s)
427 output.WriteLine (s.Value);
430 protected void GenerateStatement (CodeStatement s)
432 if (s.StartDirectives.Count > 0)
433 GenerateDirectives (s.StartDirectives);
434 if (s.LinePragma != null)
435 GenerateLinePragmaStart (s.LinePragma);
437 CodeSnippetStatement snippet = s as CodeSnippetStatement;
438 if (snippet != null) {
442 GenerateSnippetStatement (snippet);
449 } catch (NotImplementedException) {
450 throw new ArgumentException ("Element type " + s.GetType () + " is not supported.", "s");
454 if (s.LinePragma != null)
455 GenerateLinePragmaEnd (s.LinePragma);
457 if (s.EndDirectives.Count > 0)
458 GenerateDirectives (s.EndDirectives);
461 protected void GenerateStatements (CodeStatementCollection c)
463 foreach (CodeStatement statement in c)
464 GenerateStatement (statement);
467 protected abstract void GenerateThisReferenceExpression (CodeThisReferenceExpression e);
468 protected abstract void GenerateThrowExceptionStatement (CodeThrowExceptionStatement s);
469 protected abstract void GenerateTryCatchFinallyStatement (CodeTryCatchFinallyStatement s);
470 protected abstract void GenerateTypeEnd (CodeTypeDeclaration declaration);
471 protected abstract void GenerateTypeConstructor (CodeTypeConstructor constructor);
473 protected virtual void GenerateTypeOfExpression (CodeTypeOfExpression e)
475 output.Write ("typeof(");
480 protected virtual void GenerateTypeReferenceExpression (CodeTypeReferenceExpression e)
485 protected void GenerateTypes (CodeNamespace e)
487 foreach (CodeTypeDeclaration type in e.Types) {
488 if (options.BlankLinesBetweenMembers)
495 protected abstract void GenerateTypeStart (CodeTypeDeclaration declaration);
496 protected abstract void GenerateVariableDeclarationStatement (CodeVariableDeclarationStatement e);
497 protected abstract void GenerateVariableReferenceExpression (CodeVariableReferenceExpression e);
506 protected virtual void OutputAttributeArgument (CodeAttributeArgument argument)
508 string name = argument.Name;
509 if ((name != null) && (name.Length > 0)) {
513 GenerateExpression (argument.Value);
516 private void OutputAttributeDeclaration (CodeAttributeDeclaration attribute)
518 output.Write (attribute.Name.Replace ('+', '.'));
520 IEnumerator enumerator = attribute.Arguments.GetEnumerator();
521 if (enumerator.MoveNext()) {
522 CodeAttributeArgument argument = (CodeAttributeArgument)enumerator.Current;
523 OutputAttributeArgument (argument);
525 while (enumerator.MoveNext()) {
527 argument = (CodeAttributeArgument)enumerator.Current;
528 OutputAttributeArgument (argument);
534 protected virtual void OutputAttributeDeclarations (CodeAttributeDeclarationCollection attributes)
536 GenerateAttributeDeclarationsStart (attributes);
538 IEnumerator enumerator = attributes.GetEnumerator();
539 if (enumerator.MoveNext()) {
540 CodeAttributeDeclaration attribute = (CodeAttributeDeclaration)enumerator.Current;
542 OutputAttributeDeclaration (attribute);
544 while (enumerator.MoveNext()) {
545 attribute = (CodeAttributeDeclaration)enumerator.Current;
547 output.WriteLine (',');
548 OutputAttributeDeclaration (attribute);
552 GenerateAttributeDeclarationsEnd (attributes);
555 protected virtual void OutputDirection (FieldDirection direction)
558 case FieldDirection.In:
559 //output.Write ("in ");
561 case FieldDirection.Out:
562 output.Write ("out ");
564 case FieldDirection.Ref:
565 output.Write ("ref ");
570 protected virtual void OutputExpressionList (CodeExpressionCollection expressions)
572 OutputExpressionList (expressions, false);
575 protected virtual void OutputExpressionList (CodeExpressionCollection expressions,
576 bool newLineBetweenItems)
579 IEnumerator enumerator = expressions.GetEnumerator();
580 if (enumerator.MoveNext()) {
581 CodeExpression expression = (CodeExpression)enumerator.Current;
583 GenerateExpression (expression);
585 while (enumerator.MoveNext()) {
586 expression = (CodeExpression)enumerator.Current;
589 if (newLineBetweenItems)
594 GenerateExpression (expression);
600 protected virtual void OutputFieldScopeModifier (MemberAttributes attributes)
602 if ((attributes & MemberAttributes.VTableMask) == MemberAttributes.New)
603 output.Write ("new ");
605 switch (attributes & MemberAttributes.ScopeMask) {
606 case MemberAttributes.Static:
607 output.Write ("static ");
609 case MemberAttributes.Const:
610 output.Write ("const ");
615 protected virtual void OutputIdentifier (string ident)
617 output.Write (ident);
620 protected virtual void OutputMemberAccessModifier (MemberAttributes attributes)
622 switch (attributes & MemberAttributes.AccessMask) {
623 case MemberAttributes.Assembly:
624 output.Write ("internal ");
626 case MemberAttributes.FamilyAndAssembly:
627 output.Write ("internal ");
629 case MemberAttributes.Family:
630 output.Write ("protected ");
632 case MemberAttributes.FamilyOrAssembly:
633 output.Write ("protected internal ");
635 case MemberAttributes.Private:
636 output.Write ("private ");
638 case MemberAttributes.Public:
639 output.Write ("public ");
644 protected virtual void OutputMemberScopeModifier (MemberAttributes attributes)
646 if ((attributes & MemberAttributes.VTableMask) == MemberAttributes.New)
647 output.Write( "new " );
649 switch (attributes & MemberAttributes.ScopeMask) {
650 case MemberAttributes.Abstract:
651 output.Write ("abstract ");
653 case MemberAttributes.Final:
656 case MemberAttributes.Static:
657 output.Write ("static ");
659 case MemberAttributes.Override:
660 output.Write ("override ");
664 // FUNNY! if the scope value is
665 // rubbish (0 or >Const), and access
666 // is public or protected, make it
669 // i'm not sure whether this is 100%
670 // correct, but it seems to be MS
673 // On .NET 2.0, internal members
674 // are also marked "virtual".
676 MemberAttributes access = attributes & MemberAttributes.AccessMask;
677 if (access == MemberAttributes.Public || access == MemberAttributes.Family)
678 output.Write ("virtual ");
683 protected virtual void OutputOperator (CodeBinaryOperatorType op)
686 case CodeBinaryOperatorType.Add:
689 case CodeBinaryOperatorType.Subtract:
692 case CodeBinaryOperatorType.Multiply:
695 case CodeBinaryOperatorType.Divide:
698 case CodeBinaryOperatorType.Modulus:
701 case CodeBinaryOperatorType.Assign:
704 case CodeBinaryOperatorType.IdentityInequality:
707 case CodeBinaryOperatorType.IdentityEquality:
710 case CodeBinaryOperatorType.ValueEquality:
713 case CodeBinaryOperatorType.BitwiseOr:
716 case CodeBinaryOperatorType.BitwiseAnd:
719 case CodeBinaryOperatorType.BooleanOr:
722 case CodeBinaryOperatorType.BooleanAnd:
725 case CodeBinaryOperatorType.LessThan:
728 case CodeBinaryOperatorType.LessThanOrEqual:
731 case CodeBinaryOperatorType.GreaterThan:
734 case CodeBinaryOperatorType.GreaterThanOrEqual:
740 protected virtual void OutputParameters (CodeParameterDeclarationExpressionCollection parameters)
743 foreach (CodeParameterDeclarationExpression expr in parameters) {
748 GenerateExpression (expr);
752 protected abstract void OutputType (CodeTypeReference t);
754 protected virtual void OutputTypeAttributes (TypeAttributes attributes,
758 switch (attributes & TypeAttributes.VisibilityMask) {
759 case TypeAttributes.NotPublic:
760 // private by default
763 case TypeAttributes.Public:
764 case TypeAttributes.NestedPublic:
765 output.Write ("public ");
768 case TypeAttributes.NestedPrivate:
769 output.Write ("private ");
774 output.Write ("struct ");
777 output.Write ("enum ");
779 if ((attributes & TypeAttributes.Interface) != 0)
780 output.Write ("interface ");
781 else if (currentType is CodeTypeDelegate)
782 output.Write ("delegate ");
784 if ((attributes & TypeAttributes.Sealed) != 0)
785 output.Write ("sealed ");
786 if ((attributes & TypeAttributes.Abstract) != 0)
787 output.Write ("abstract ");
789 output.Write ("class ");
794 protected virtual void OutputTypeNamePair (CodeTypeReference type,
802 protected abstract string QuoteSnippetString (string value);
807 protected abstract string CreateEscapedIdentifier (string value);
808 string ICodeGenerator.CreateEscapedIdentifier (string value)
810 return CreateEscapedIdentifier (value);
813 protected abstract string CreateValidIdentifier (string value);
814 string ICodeGenerator.CreateValidIdentifier (string value)
816 return CreateValidIdentifier (value);
819 private void InitOutput (TextWriter output, CodeGeneratorOptions options)
822 options = new CodeGeneratorOptions ();
824 this.output = new IndentedTextWriter (output, options.IndentString);
825 this.options = options;
828 void ICodeGenerator.GenerateCodeFromCompileUnit (CodeCompileUnit compileUnit,
830 CodeGeneratorOptions options)
832 InitOutput (output, options);
834 if (compileUnit is CodeSnippetCompileUnit) {
835 GenerateSnippetCompileUnit ((CodeSnippetCompileUnit) compileUnit);
837 GenerateCompileUnit (compileUnit);
841 void ICodeGenerator.GenerateCodeFromExpression (CodeExpression expression,
843 CodeGeneratorOptions options)
845 InitOutput (output, options);
846 GenerateExpression (expression);
849 void ICodeGenerator.GenerateCodeFromNamespace (CodeNamespace ns,
851 CodeGeneratorOptions options)
853 InitOutput (output, options);
854 GenerateNamespace (ns);
857 void ICodeGenerator.GenerateCodeFromStatement (CodeStatement statement,
859 CodeGeneratorOptions options)
861 InitOutput (output, options);
862 GenerateStatement (statement);
865 void ICodeGenerator.GenerateCodeFromType (CodeTypeDeclaration type,
867 CodeGeneratorOptions options)
869 InitOutput (output, options);
873 private void GenerateType (CodeTypeDeclaration type)
875 this.currentType = type;
876 this.currentMember = null;
878 if (type.StartDirectives.Count > 0)
879 GenerateDirectives (type.StartDirectives);
880 foreach (CodeCommentStatement statement in type.Comments)
881 GenerateCommentStatement (statement);
883 if (type.LinePragma != null)
884 GenerateLinePragmaStart (type.LinePragma);
886 GenerateTypeStart (type);
888 CodeTypeMember[] members = new CodeTypeMember[type.Members.Count];
889 type.Members.CopyTo (members, 0);
891 if (!Options.VerbatimOrder)
893 int[] order = new int[members.Length];
894 for (int n = 0; n < members.Length; n++)
895 order[n] = Array.IndexOf (memberTypes, members[n].GetType ()) * members.Length + n;
897 Array.Sort (order, members);
900 // WARNING: if anything is missing in the foreach loop and you add it, add the type in
901 // its corresponding place in CodeTypeMemberComparer class (below)
903 CodeTypeDeclaration subtype = null;
904 foreach (CodeTypeMember member in members) {
905 CodeTypeMember prevMember = this.currentMember;
906 this.currentMember = member;
908 if (prevMember != null && subtype == null) {
909 if (prevMember.LinePragma != null)
910 GenerateLinePragmaEnd (prevMember.LinePragma);
911 if (prevMember.EndDirectives.Count > 0)
912 GenerateDirectives (prevMember.EndDirectives);
915 if (options.BlankLinesBetweenMembers)
918 subtype = member as CodeTypeDeclaration;
919 if (subtype != null) {
920 GenerateType (subtype);
921 this.currentType = type;
925 if (currentMember.StartDirectives.Count > 0)
926 GenerateDirectives (currentMember.StartDirectives);
927 foreach (CodeCommentStatement statement in member.Comments)
928 GenerateCommentStatement (statement);
930 if (member.LinePragma != null)
931 GenerateLinePragmaStart (member.LinePragma);
934 member.Accept (visitor);
935 } catch (NotImplementedException) {
936 throw new ArgumentException ("Element type " + member.GetType () + " is not supported.");
940 // Hack because of previous continue usage
941 if (currentMember != null && !(currentMember is CodeTypeDeclaration)) {
942 if (currentMember.LinePragma != null)
943 GenerateLinePragmaEnd (currentMember.LinePragma);
944 if (currentMember.EndDirectives.Count > 0)
945 GenerateDirectives (currentMember.EndDirectives);
948 this.currentType = type;
949 GenerateTypeEnd (type);
951 if (type.LinePragma != null)
952 GenerateLinePragmaEnd (type.LinePragma);
954 if (type.EndDirectives.Count > 0)
955 GenerateDirectives (type.EndDirectives);
958 protected abstract string GetTypeOutput (CodeTypeReference type);
960 string ICodeGenerator.GetTypeOutput (CodeTypeReference type)
962 return GetTypeOutput (type);
965 protected abstract bool IsValidIdentifier (string value);
967 bool ICodeGenerator.IsValidIdentifier (string value)
969 return IsValidIdentifier (value);
972 public static bool IsValidLanguageIndependentIdentifier (string value)
976 if (value.Equals (string.Empty))
979 switch (char.GetUnicodeCategory (value[0])) {
980 case UnicodeCategory.LetterNumber:
981 case UnicodeCategory.LowercaseLetter:
982 case UnicodeCategory.TitlecaseLetter:
983 case UnicodeCategory.UppercaseLetter:
984 case UnicodeCategory.OtherLetter:
985 case UnicodeCategory.ModifierLetter:
986 case UnicodeCategory.ConnectorPunctuation:
992 for (int x = 1; x < value.Length; ++x) {
993 switch (char.GetUnicodeCategory (value[x])) {
994 case UnicodeCategory.LetterNumber:
995 case UnicodeCategory.LowercaseLetter:
996 case UnicodeCategory.TitlecaseLetter:
997 case UnicodeCategory.UppercaseLetter:
998 case UnicodeCategory.OtherLetter:
999 case UnicodeCategory.ModifierLetter:
1000 case UnicodeCategory.ConnectorPunctuation:
1001 case UnicodeCategory.DecimalDigitNumber:
1002 case UnicodeCategory.NonSpacingMark:
1003 case UnicodeCategory.SpacingCombiningMark:
1004 case UnicodeCategory.Format:
1014 protected abstract bool Supports (GeneratorSupport supports);
1016 bool ICodeGenerator.Supports (GeneratorSupport value)
1018 return Supports (value);
1021 protected virtual void ValidateIdentifier (string value)
1023 if (!(IsValidIdentifier (value)))
1024 throw new ArgumentException ("Identifier is invalid", "value");
1028 public static void ValidateIdentifiers (CodeObject e)
1030 throw new NotImplementedException();
1033 void ICodeGenerator.ValidateIdentifier (string value)
1035 ValidateIdentifier (value);
1038 // The position in the array determines the order in which those
1039 // kind of CodeTypeMembers are generated. Less is more ;-)
1040 static Type [] memberTypes = { typeof (CodeMemberField),
1041 typeof (CodeSnippetTypeMember),
1042 typeof (CodeTypeConstructor),
1043 typeof (CodeConstructor),
1044 typeof (CodeMemberProperty),
1045 typeof (CodeMemberEvent),
1046 typeof (CodeMemberMethod),
1047 typeof (CodeTypeDeclaration),
1048 typeof (CodeEntryPointMethod)
1051 protected virtual void GenerateDirectives (CodeDirectiveCollection directives)
1055 internal class Visitor : ICodeDomVisitor {
1058 public Visitor (CodeGenerator generator)
1065 public void Visit (CodeArgumentReferenceExpression o)
1067 g.GenerateArgumentReferenceExpression (o);
1070 public void Visit (CodeArrayCreateExpression o)
1072 g.GenerateArrayCreateExpression (o);
1075 public void Visit (CodeArrayIndexerExpression o)
1077 g.GenerateArrayIndexerExpression (o);
1080 public void Visit (CodeBaseReferenceExpression o)
1082 g.GenerateBaseReferenceExpression (o);
1085 public void Visit (CodeBinaryOperatorExpression o)
1087 g.GenerateBinaryOperatorExpression (o);
1090 public void Visit (CodeCastExpression o)
1092 g.GenerateCastExpression (o);
1095 public void Visit (CodeDefaultValueExpression o)
1097 g.GenerateDefaultValueExpression (o);
1100 public void Visit (CodeDelegateCreateExpression o)
1102 g.GenerateDelegateCreateExpression (o);
1105 public void Visit (CodeDelegateInvokeExpression o)
1107 g.GenerateDelegateInvokeExpression (o);
1110 public void Visit (CodeDirectionExpression o)
1112 g.GenerateDirectionExpression (o);
1115 public void Visit (CodeEventReferenceExpression o)
1117 g.GenerateEventReferenceExpression (o);
1120 public void Visit (CodeFieldReferenceExpression o)
1122 g.GenerateFieldReferenceExpression (o);
1125 public void Visit (CodeIndexerExpression o)
1127 g.GenerateIndexerExpression (o);
1130 public void Visit (CodeMethodInvokeExpression o)
1132 g.GenerateMethodInvokeExpression (o);
1135 public void Visit (CodeMethodReferenceExpression o)
1137 g.GenerateMethodReferenceExpression (o);
1140 public void Visit (CodeObjectCreateExpression o)
1142 g.GenerateObjectCreateExpression (o);
1145 public void Visit (CodeParameterDeclarationExpression o)
1147 g.GenerateParameterDeclarationExpression (o);
1150 public void Visit (CodePrimitiveExpression o)
1152 g.GeneratePrimitiveExpression (o);
1155 public void Visit (CodePropertyReferenceExpression o)
1157 g.GeneratePropertyReferenceExpression (o);
1160 public void Visit (CodePropertySetValueReferenceExpression o)
1162 g.GeneratePropertySetValueReferenceExpression (o);
1165 public void Visit (CodeSnippetExpression o)
1167 g.GenerateSnippetExpression (o);
1170 public void Visit (CodeThisReferenceExpression o)
1172 g.GenerateThisReferenceExpression (o);
1175 public void Visit (CodeTypeOfExpression o)
1177 g.GenerateTypeOfExpression (o);
1180 public void Visit (CodeTypeReferenceExpression o)
1182 g.GenerateTypeReferenceExpression (o);
1185 public void Visit (CodeVariableReferenceExpression o)
1187 g.GenerateVariableReferenceExpression (o);
1192 public void Visit (CodeAssignStatement o)
1194 g.GenerateAssignStatement (o);
1197 public void Visit (CodeAttachEventStatement o)
1199 g.GenerateAttachEventStatement (o);
1202 public void Visit (CodeCommentStatement o)
1204 g.GenerateCommentStatement (o);
1207 public void Visit (CodeConditionStatement o)
1209 g.GenerateConditionStatement (o);
1212 public void Visit (CodeExpressionStatement o)
1214 g.GenerateExpressionStatement (o);
1217 public void Visit (CodeGotoStatement o)
1219 g.GenerateGotoStatement (o);
1222 public void Visit (CodeIterationStatement o)
1224 g.GenerateIterationStatement (o);
1227 public void Visit (CodeLabeledStatement o)
1229 g.GenerateLabeledStatement (o);
1232 public void Visit (CodeMethodReturnStatement o)
1234 g.GenerateMethodReturnStatement (o);
1237 public void Visit (CodeRemoveEventStatement o)
1239 g.GenerateRemoveEventStatement (o);
1242 public void Visit (CodeThrowExceptionStatement o)
1244 g.GenerateThrowExceptionStatement (o);
1247 public void Visit (CodeTryCatchFinallyStatement o)
1249 g.GenerateTryCatchFinallyStatement (o);
1252 public void Visit (CodeVariableDeclarationStatement o)
1254 g.GenerateVariableDeclarationStatement (o);
1259 public void Visit (CodeConstructor o)
1261 g.GenerateConstructor (o, g.CurrentClass);
1264 public void Visit (CodeEntryPointMethod o)
1266 g.GenerateEntryPointMethod (o, g.CurrentClass);
1269 public void Visit (CodeMemberEvent o)
1271 g.GenerateEvent (o, g.CurrentClass);
1274 public void Visit (CodeMemberField o)
1276 g.GenerateField (o);
1279 public void Visit (CodeMemberMethod o)
1281 g.GenerateMethod (o, g.CurrentClass);
1284 public void Visit (CodeMemberProperty o)
1286 g.GenerateProperty (o, g.CurrentClass);
1289 public void Visit (CodeSnippetTypeMember o)
1291 g.GenerateSnippetMember (o);
1294 public void Visit (CodeTypeConstructor o)
1296 g.GenerateTypeConstructor (o);