2 // Microsoft.VisualBasic.VBCodeGenerator.cs
\r
5 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
\r
6 // (partially based on CSharpCodeGenerator)
\r
7 // Jochen Wezel (jwezel@compumaster.de)
\r
9 // (C) 2003 Andreas Nahr
\r
10 // (C) 2003 Jochen Wezel (http://www.compumaster.de)
\r
13 // 2003-11-06 JW: some corrections regarding missing spaces in generated code (e. g. "Property ")
\r
14 // 2003-11-06 JW: QuoteSnippetString implemented
\r
15 // 2003-11-08 JW: automatically add Microsoft.VisualBasic
\r
16 // 2003-11-12 JW: some corrections to allow correct compilation
\r
17 // 2003-11-28 JW: implementing code differences into current build of this file
\r
18 // 2003-12-10 JW: added "String." for the ChrW method because mbas doesn't support it without the String currently / TODO: remove it ASAP!
\r
21 // Permission is hereby granted, free of charge, to any person obtaining
\r
22 // a copy of this software and associated documentation files (the
\r
23 // "Software"), to deal in the Software without restriction, including
\r
24 // without limitation the rights to use, copy, modify, merge, publish,
\r
25 // distribute, sublicense, and/or sell copies of the Software, and to
\r
26 // permit persons to whom the Software is furnished to do so, subject to
\r
27 // the following conditions:
\r
29 // The above copyright notice and this permission notice shall be
\r
30 // included in all copies or substantial portions of the Software.
\r
32 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
33 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
34 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
35 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
36 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
37 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
38 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
43 using System.Globalization;
\r
45 using System.Text.RegularExpressions;
\r
46 using System.CodeDom;
\r
47 using System.CodeDom.Compiler;
\r
49 using System.Reflection;
\r
50 using System.Collections;
\r
52 namespace Microsoft.VisualBasic
\r
54 internal class VBCodeGenerator : CodeGenerator
\r
56 private string[] Keywords = new string[] {
\r
57 "AddHandler", "AddressOf", "Alias", "And",
\r
58 "AndAlso", "Ansi", "As", "Assembly",
\r
59 "Auto", "Boolean", "ByRef", "Byte",
\r
60 "ByVal", "Call", "Case", "Catch",
\r
61 "CBool", "CByte", "CChar", "CDate",
\r
62 "CDec", "CDbl", "Char", "CInt",
\r
63 "Class", "CLng", "CObj", "Const",
\r
64 "CShort", "CSng", "CStr", "CType",
\r
65 "Date", "Decimal", "Declare", "Default",
\r
66 "Delegate", "Dim", "DirectCast", "Do",
\r
67 "Double", "Each", "Else", "ElseIf",
\r
68 "End", "Enum", "Erase", "Error",
\r
69 "Event", "Exit", "False", "Finally",
\r
70 "For", "Friend", "Function", "Get",
\r
71 "GetType", "GoSub", "GoTo", "Handles",
\r
72 "If", "Implements", "Imports", "In",
\r
73 "Inherits", "Integer", "Interface", "Is",
\r
74 "Let", "Lib", "Like", "Long",
\r
75 "Loop", "Me", "Mod", "Module",
\r
76 "MustInherit", "MustOverride", "MyBase", "MyClass",
\r
77 "Namespace", "New", "Next", "Not",
\r
78 "Nothing", "NotInheritable", "NotOverridable", "Object",
\r
79 "On", "Option", "Optional", "Or",
\r
80 "OrElse", "Overloads", "Overridable", "Overrides",
\r
81 "ParamArray", "Preserve", "Private", "Property",
\r
82 "Protected", "Public", "RaiseEvent", "ReadOnly",
\r
83 "ReDim", "REM", "RemoveHandler", "Resume",
\r
84 "Return", "Select", "Set", "Shadows",
\r
85 "Shared", "Short", "Single", "Static",
\r
86 "Step", "Stop", "String", "Structure",
\r
87 "Sub", "SyncLock", "Then", "Throw",
\r
88 "To", "True", "Try", "TypeOf",
\r
89 "Unicode", "Until", "Variant", "When",
\r
90 "While", "With", "WithEvents", "WriteOnly",
\r
94 public VBCodeGenerator()
\r
98 protected override string NullToken {
\r
104 protected override void ContinueOnNewLine (string st)
\r
107 Output.WriteLine (" _");
\r
110 protected override void GenerateArrayCreateExpression (CodeArrayCreateExpression expression)
\r
112 TextWriter output = Output;
\r
114 output.Write ("New ");
\r
116 CodeExpressionCollection initializers = expression.Initializers;
\r
117 CodeTypeReference createType = expression.CreateType;
\r
119 if (initializers.Count > 0) {
\r
121 OutputType (createType);
\r
123 output.WriteLine (" {");
\r
125 OutputExpressionList (initializers, true);
\r
127 output.Write ("}");
\r
131 CodeTypeReference arrayType = createType.ArrayElementType;
\r
132 while (arrayType != null)
\r
134 createType = arrayType;
\r
135 arrayType = arrayType.ArrayElementType;
\r
138 OutputType (createType);
\r
140 output.Write ('(');
\r
142 CodeExpression size = expression.SizeExpression;
\r
144 GenerateExpression (size);
\r
146 output.Write (expression.Size);
\r
148 output.Write (')');
\r
152 protected override void GenerateBaseReferenceExpression (CodeBaseReferenceExpression expression)
\r
154 Output.Write ("MyBase");
\r
157 protected override void GenerateCastExpression (CodeCastExpression expression)
\r
159 TextWriter output = Output;
\r
160 // ENHANCE: Use a DirectCast if it is known that expression.Expression is no Value-Type
\r
161 output.Write ("CType(");
\r
162 GenerateExpression (expression.Expression);
\r
163 output.Write (", ");
\r
164 OutputType (expression.TargetType);
\r
165 output.Write (")");
\r
168 private bool AsBool(object datavalue)
\r
170 return datavalue != null && datavalue is bool && (bool)datavalue;
\r
173 private string OnOff(bool datavalue)
\r
175 return datavalue?"On":"Off";
\r
178 protected override void GenerateCompileUnitStart (CodeCompileUnit compileUnit)
\r
180 GenerateComment (new CodeComment ("------------------------------------------------------------------------------"));
\r
181 GenerateComment (new CodeComment (" <autogenerated>"));
\r
182 GenerateComment (new CodeComment (" This code was generated by a tool."));
\r
183 GenerateComment (new CodeComment (" Mono Runtime Version: " + System.Environment.Version));
\r
184 GenerateComment (new CodeComment (""));
\r
185 GenerateComment (new CodeComment (" Changes to this file may cause incorrect behavior and will be lost if "));
\r
186 GenerateComment (new CodeComment (" the code is regenerated."));
\r
187 GenerateComment (new CodeComment (" </autogenerated>"));
\r
188 GenerateComment (new CodeComment ("------------------------------------------------------------------------------"));
\r
189 Output.WriteLine ();
\r
190 if (AsBool(compileUnit.UserData["AllowLateBound"])) {
\r
191 Output.WriteLine("Option Explicit {0}",OnOff(AsBool(compileUnit.UserData["RequireVariableDeclaration"])));
\r
192 Output.WriteLine("Option Strict Off");
\r
194 Output.WriteLine("Option Explicit On"); // Strict On implies Explicit On
\r
195 Output.WriteLine("Option Strict On");
\r
197 Output.WriteLine ();
\r
200 protected override void GenerateCompileUnit (CodeCompileUnit compileUnit)
\r
202 GenerateCompileUnitStart (compileUnit);
\r
204 OutputAttributes (compileUnit.AssemblyCustomAttributes,
\r
205 "Assembly: ", LineHandling.NewLine);
\r
207 GenerateNamespaces (compileUnit);
\r
209 GenerateCompileUnitEnd (compileUnit);
\r
212 protected override void GenerateDelegateCreateExpression (CodeDelegateCreateExpression expression)
\r
214 TextWriter output = Output;
\r
216 output.Write ("AddressOf ");
\r
218 CodeExpression targetObject = expression.TargetObject;
\r
219 if (targetObject != null) {
\r
220 GenerateExpression (targetObject);
\r
221 Output.Write ('.');
\r
223 output.Write (expression.MethodName);
\r
226 protected override void GenerateFieldReferenceExpression (CodeFieldReferenceExpression expression)
\r
228 CodeExpression targetObject = expression.TargetObject;
\r
229 if (targetObject != null) {
\r
230 GenerateExpression (targetObject);
\r
231 Output.Write ('.');
\r
233 Output.Write (expression.FieldName);
\r
236 protected override void GenerateArgumentReferenceExpression (CodeArgumentReferenceExpression expression)
\r
238 Output.Write (expression.ParameterName);
\r
241 protected override void GenerateVariableReferenceExpression (CodeVariableReferenceExpression expression)
\r
243 Output.Write (expression.VariableName);
\r
246 protected override void GenerateIndexerExpression (CodeIndexerExpression expression)
\r
248 TextWriter output = Output;
\r
250 GenerateExpression (expression.TargetObject);
\r
251 output.Write ('(');
\r
252 OutputExpressionList (expression.Indices);
\r
253 output.Write (')');
\r
256 protected override void GenerateArrayIndexerExpression (CodeArrayIndexerExpression expression)
\r
258 TextWriter output = Output;
\r
260 GenerateExpression (expression.TargetObject);
\r
261 output.Write (".Item(");
\r
262 OutputExpressionList (expression.Indices);
\r
263 output.Write (')');
\r
266 protected override void GenerateSnippetExpression (CodeSnippetExpression expression)
\r
268 Output.Write (expression.Value);
\r
271 protected override void GenerateMethodInvokeExpression (CodeMethodInvokeExpression expression)
\r
273 TextWriter output = Output;
\r
275 GenerateMethodReferenceExpression (expression.Method);
\r
277 output.Write ('(');
\r
278 OutputExpressionList (expression.Parameters);
\r
279 output.Write (')');
\r
282 protected override void GenerateMethodReferenceExpression (CodeMethodReferenceExpression expression)
\r
284 GenerateExpression (expression.TargetObject);
\r
285 Output.Write ('.');
\r
286 Output.Write (expression.MethodName);
\r
289 protected override void GenerateEventReferenceExpression (CodeEventReferenceExpression expression)
\r
291 GenerateExpression (expression.TargetObject);
\r
292 Output.Write ('.');
\r
293 Output.Write (expression.EventName);
\r
296 protected override void GenerateDelegateInvokeExpression (CodeDelegateInvokeExpression expression)
\r
298 Output.Write ("RaiseEvent ");
\r
299 GenerateExpression (expression.TargetObject);
\r
300 Output.Write ('(');
\r
301 OutputExpressionList (expression.Parameters);
\r
302 Output.WriteLine (')');
\r
305 protected override void GenerateObjectCreateExpression (CodeObjectCreateExpression expression)
\r
307 Output.Write( "New " );
\r
308 OutputType (expression.CreateType);
\r
309 Output.Write ('(');
\r
310 OutputExpressionList (expression.Parameters);
\r
311 Output.Write (')');
\r
314 protected override void GenerateParameterDeclarationExpression (CodeParameterDeclarationExpression e)
\r
316 OutputAttributes (e.CustomAttributes, null, LineHandling.InLine);
\r
317 OutputDirection (e.Direction);
\r
318 OutputTypeNamePair (e.Type, e.Name);
\r
321 protected override void GeneratePrimitiveExpression (CodePrimitiveExpression e)
\r
323 TextWriter output = Output;
\r
325 if (e.Value == null) {
\r
326 output.Write (NullToken);
\r
330 Type type = e.Value.GetType ();
\r
331 if (type == typeof (bool)) {
\r
332 output.Write (e.Value.ToString ().ToLower (CultureInfo.InvariantCulture));
\r
334 else if (type == typeof (char)) {
\r
335 output.Write ("\"" + e.Value.ToString () + "\"c");
\r
337 else if (type == typeof (string)) {
\r
338 output.Write (QuoteSnippetString ((string) e.Value));
\r
340 else if (type == typeof (byte) || type == typeof (sbyte) || type == typeof (short) ||
\r
341 type == typeof (int) || type == typeof (long) || type == typeof (float) ||
\r
342 type == typeof (double) || type == typeof (decimal)) {
\r
343 output.Write (e.Value.ToString ());
\r
346 throw new ArgumentException ("Value type (" + type + ") is not a primitive type");
\r
350 protected override void GeneratePropertyReferenceExpression (CodePropertyReferenceExpression expression)
\r
352 GenerateMemberReferenceExpression (expression.TargetObject, expression.PropertyName);
\r
355 protected override void GeneratePropertySetValueReferenceExpression (CodePropertySetValueReferenceExpression expression)
\r
357 Output.Write ("Value");
\r
360 protected override void GenerateThisReferenceExpression (CodeThisReferenceExpression expression)
\r
362 Output.Write ("Me");
\r
365 protected override void GenerateExpressionStatement (CodeExpressionStatement statement)
\r
367 GenerateExpression (statement.Expression);
\r
368 Output.WriteLine (); //start new line
\r
371 protected override void GenerateIterationStatement (CodeIterationStatement statement)
\r
373 TextWriter output = Output;
\r
375 GenerateStatement (statement.InitStatement);
\r
376 output.Write ("Do While ");
\r
377 GenerateExpression (statement.TestExpression);
\r
378 output.WriteLine ();
\r
379 GenerateStatements (statement.Statements);
\r
380 GenerateStatement (statement.IncrementStatement);
\r
381 output.WriteLine ("Loop");
\r
384 protected override void GenerateThrowExceptionStatement (CodeThrowExceptionStatement statement)
\r
386 Output.Write ("Throw ");
\r
387 GenerateExpression (statement.ToThrow);
\r
390 protected override void GenerateComment (CodeComment comment)
\r
392 TextWriter output = Output;
\r
394 if (comment.DocComment)
\r
395 output.Write ("''' ");
\r
397 output.Write ("' ");
\r
399 output.WriteLine (comment.Text);
\r
402 protected override void GenerateMethodReturnStatement (CodeMethodReturnStatement statement)
\r
404 TextWriter output = Output;
\r
406 output.Write ("Return ");
\r
407 GenerateExpression (statement.Expression);
\r
408 output.WriteLine ();
\r
411 protected override void GenerateConditionStatement (CodeConditionStatement statement)
\r
413 TextWriter output = Output;
\r
414 output.Write ("If (");
\r
416 GenerateExpression (statement.Condition);
\r
418 output.WriteLine (") Then");
\r
420 GenerateStatements (statement.TrueStatements);
\r
423 CodeStatementCollection falses = statement.FalseStatements;
\r
424 if (falses.Count > 0) {
\r
425 output.WriteLine ("Else");
\r
427 GenerateStatements (falses);
\r
431 if (Options.ElseOnClosing)
\r
432 output.WriteLine ("Else");
\r
434 output.WriteLine ("End If");
\r
437 protected override void GenerateTryCatchFinallyStatement (CodeTryCatchFinallyStatement statement)
\r
439 TextWriter output = Output;
\r
441 output.WriteLine ("Try");
\r
443 GenerateStatements (statement.TryStatements);
\r
445 output.WriteLine ();
\r
447 foreach (CodeCatchClause clause in statement.CatchClauses) {
\r
448 output.Write ("Catch ");
\r
449 OutputTypeNamePair (clause.CatchExceptionType, clause.LocalName);
\r
450 output.WriteLine ();
\r
452 GenerateStatements (clause.Statements);
\r
454 output.WriteLine ();
\r
457 CodeStatementCollection finallies = statement.FinallyStatements;
\r
458 if (finallies.Count > 0) {
\r
460 output.WriteLine ("Finally");
\r
462 GenerateStatements (finallies);
\r
464 output.WriteLine ();
\r
467 if (Options.ElseOnClosing) {
\r
468 if (statement.CatchClauses.Count == 0)
\r
469 output.WriteLine ("Catch");
\r
470 if (statement.FinallyStatements.Count == 0)
\r
471 output.WriteLine ("Finally");
\r
474 output.WriteLine("End Try");
\r
477 protected override void GenerateAssignStatement (CodeAssignStatement statement)
\r
479 TextWriter output = Output;
\r
480 GenerateExpression (statement.Left);
\r
481 output.Write (" = ");
\r
482 GenerateExpression (statement.Right);
\r
483 output.WriteLine ();
\r
486 protected override void GenerateAttachEventStatement (CodeAttachEventStatement statement)
\r
488 TextWriter output = Output;
\r
490 Output.Write ("AddHandler ");
\r
491 GenerateEventReferenceExpression (statement.Event);
\r
492 Output.Write ( ", ");
\r
493 GenerateExpression (statement.Listener);
\r
494 output.WriteLine ();
\r
497 protected override void GenerateRemoveEventStatement (CodeRemoveEventStatement statement)
\r
499 TextWriter output = Output;
\r
501 Output.Write ("RemoveHandler ");
\r
502 GenerateEventReferenceExpression (statement.Event);
\r
503 Output.Write ( ", ");
\r
504 GenerateExpression (statement.Listener);
\r
505 output.WriteLine ();
\r
508 protected override void GenerateGotoStatement (CodeGotoStatement statement)
\r
510 TextWriter output = Output;
\r
512 output.Write ("Goto ");
\r
513 output.Write (statement.Label);
\r
514 output.WriteLine ();
\r
517 protected override void GenerateLabeledStatement (CodeLabeledStatement statement)
\r
519 TextWriter output = Output;
\r
521 output.Write (statement.Label + ":");
\r
522 GenerateStatement (statement.Statement);
\r
525 protected override void GenerateTypeOfExpression (CodeTypeOfExpression e)
\r
527 TextWriter output = Output;
\r
529 output.Write ("GetType(");
\r
530 OutputType (e.Type);
\r
531 output.Write (")");
\r
534 protected override void GenerateVariableDeclarationStatement( CodeVariableDeclarationStatement statement )
\r
536 TextWriter output = Output;
\r
538 output.Write ("Dim ");
\r
539 OutputTypeNamePair (statement.Type, statement.Name);
\r
541 CodeExpression initExpression = statement.InitExpression;
\r
542 if (initExpression != null)
\r
544 output.Write (" = ");
\r
545 GenerateExpression (initExpression);
\r
548 output.WriteLine();
\r
551 protected override void GenerateLinePragmaStart (CodeLinePragma linePragma)
\r
553 Output.WriteLine ();
\r
554 Output.Write ("#ExternalSource(");
\r
555 Output.Write (linePragma.FileName);
\r
556 Output.Write (", ");
\r
557 Output.Write (linePragma.LineNumber);
\r
558 Output.WriteLine (")");
\r
561 protected override void GenerateLinePragmaEnd (CodeLinePragma linePragma)
\r
563 Output.WriteLine ("#End ExternalSource");
\r
566 protected override void GenerateEvent (CodeMemberEvent eventRef, CodeTypeDeclaration declaration)
\r
568 if (IsCurrentDelegate || IsCurrentEnum) {
\r
572 TextWriter output = Output;
\r
574 OutputAttributes (eventRef.CustomAttributes, null,
\r
575 LineHandling.ContinueLine);
\r
577 OutputMemberAccessModifier (eventRef.Attributes);
\r
579 output.Write ("Event ");
\r
580 OutputTypeNamePair (eventRef.Type, GetEventName(eventRef));
\r
583 if (eventRef.ImplementationTypes.Count > 0) {
\r
584 OutputImplementationTypes (eventRef.ImplementationTypes, eventRef.Name);
\r
585 } else if (eventRef.PrivateImplementationType != null) {
\r
586 output.Write (" Implements ");
\r
587 OutputType (eventRef.PrivateImplementationType);
\r
588 output.Write ('.');
\r
589 output.Write (eventRef.Name);
\r
593 output.WriteLine ();
\r
596 protected override void GenerateField (CodeMemberField field)
\r
598 if (IsCurrentDelegate || IsCurrentInterface) {
\r
602 TextWriter output = Output;
\r
604 OutputAttributes (field.CustomAttributes, null,
\r
605 LineHandling.ContinueLine);
\r
607 if (IsCurrentEnum) {
\r
608 output.Write (field.Name);
\r
610 MemberAttributes attributes = field.Attributes;
\r
611 OutputMemberAccessModifier (attributes);
\r
612 OutputVTableModifier (attributes);
\r
613 OutputFieldScopeModifier (attributes);
\r
614 OutputTypeNamePair (field.Type, field.Name);
\r
617 CodeExpression initExpression = field.InitExpression;
\r
618 if (initExpression != null) {
\r
619 output.Write (" = ");
\r
620 GenerateExpression (initExpression);
\r
623 output.WriteLine();
\r
626 protected override void GenerateSnippetMember (CodeSnippetTypeMember member)
\r
628 Output.Write (member.Text);
\r
631 protected override void GenerateEntryPointMethod (CodeEntryPointMethod method, CodeTypeDeclaration declaration)
\r
634 OutputAttributes (method.CustomAttributes, null,
\r
635 LineHandling.ContinueLine);
\r
638 Output.WriteLine ("Public Shared Sub Main()");
\r
640 GenerateStatements (method.Statements);
\r
642 Output.WriteLine ("End Sub");
\r
645 [MonoTODO ("partially implemented")]
\r
646 protected override void GenerateMethod (CodeMemberMethod method, CodeTypeDeclaration declaration)
\r
648 if (IsCurrentDelegate || IsCurrentEnum) {
\r
652 bool isSub = method.ReturnType.BaseType == typeof(void).FullName;
\r
654 TextWriter output = Output;
\r
656 OutputAttributes (method.CustomAttributes, null,
\r
657 LineHandling.ContinueLine);
\r
659 MemberAttributes attributes = method.Attributes;
\r
661 if (!IsCurrentInterface) {
\r
662 if (method.PrivateImplementationType == null) {
\r
663 OutputMemberAccessModifier (attributes);
\r
664 if (IsOverloaded (method, declaration)) {
\r
665 output.Write ("Overloads ");
\r
668 OutputVTableModifier (attributes);
\r
669 OutputMemberScopeModifier (attributes);
\r
671 OutputVTableModifier (attributes);
\r
675 output.Write ("Sub ");
\r
677 output.Write ("Function ");
\r
679 output.Write (GetMethodName(method));
\r
680 output.Write ('(');
\r
681 OutputParameters (method.Parameters);
\r
682 output.Write (')');
\r
685 output.Write (" As ");
\r
686 OutputAttributes (method.ReturnTypeCustomAttributes, null,
\r
687 LineHandling.InLine);
\r
688 OutputType (method.ReturnType);
\r
691 if (method.ImplementationTypes.Count > 0) {
\r
692 OutputImplementationTypes (method.ImplementationTypes, method.Name);
\r
693 } else if (method.PrivateImplementationType != null) {
\r
694 output.Write (" Implements ");
\r
695 OutputType (method.PrivateImplementationType);
\r
696 output.Write ('.');
\r
697 output.Write (method.Name);
\r
700 output.WriteLine ();
\r
701 if (!IsCurrentInterface) {
\r
702 if ((attributes & MemberAttributes.ScopeMask) != MemberAttributes.Abstract) {
\r
704 GenerateStatements (method.Statements);
\r
707 output.WriteLine ("End Sub");
\r
709 output.WriteLine ("End Function");
\r
714 protected override void GenerateProperty (CodeMemberProperty property, CodeTypeDeclaration declaration)
\r
716 if (IsCurrentDelegate || IsCurrentEnum) {
\r
720 TextWriter output = Output;
\r
722 OutputAttributes (property.CustomAttributes, null,
\r
723 LineHandling.ContinueLine);
\r
725 MemberAttributes attributes = property.Attributes;
\r
727 if (!IsCurrentInterface) {
\r
728 if (property.PrivateImplementationType == null) {
\r
729 OutputMemberAccessModifier (attributes);
\r
730 if (IsOverloaded (property, declaration)) {
\r
731 output.Write ("Overloads ");
\r
734 OutputVTableModifier (attributes);
\r
735 OutputMemberScopeModifier (attributes);
\r
737 OutputVTableModifier (attributes);
\r
740 // mark property as default property if we're dealing with an indexer
\r
741 if (string.Compare (GetPropertyName(property), "Item", true, CultureInfo.InvariantCulture) == 0 && property.Parameters.Count > 0) {
\r
742 output.Write ("Default ");
\r
745 if (property.HasGet && (!property.HasSet))
\r
746 output.Write ("ReadOnly " );
\r
748 if (property.HasSet && (!property.HasGet))
\r
749 output.Write ("WriteOnly " );
\r
751 output.Write ("Property ");
\r
752 Output.Write (GetPropertyName (property));
\r
754 // in .NET 2.0, always output parantheses (whether or not there
\r
755 // are any parameters to output
\r
756 Output.Write ('(');
\r
757 OutputParameters (property.Parameters);
\r
758 Output.Write (')');
\r
760 if (property.Parameters.Count > 0) {
\r
761 Output.Write ('(');
\r
762 OutputParameters (property.Parameters);
\r
763 Output.Write (')');
\r
766 Output.Write (" As ");
\r
767 Output.Write (GetTypeOutput(property.Type));
\r
769 if (property.ImplementationTypes.Count > 0) {
\r
770 OutputImplementationTypes (property.ImplementationTypes, property.Name);
\r
771 } else if (property.PrivateImplementationType != null) {
\r
772 output.Write (" Implements ");
\r
773 OutputType (property.PrivateImplementationType);
\r
774 output.Write ('.');
\r
775 output.Write (property.Name);
\r
778 output.WriteLine ();
\r
780 if (!IsCurrentInterface) {
\r
782 if (property.HasGet) {
\r
783 output.WriteLine ("Get");
\r
785 GenerateStatements (property.GetStatements);
\r
787 output.WriteLine ("End Get");
\r
790 if (property.HasSet) {
\r
791 output.WriteLine ("Set");
\r
793 GenerateStatements (property.SetStatements);
\r
795 output.WriteLine ("End Set");
\r
799 output.WriteLine ("End Property");
\r
803 protected override void GenerateConstructor (CodeConstructor constructor, CodeTypeDeclaration declaration)
\r
805 if (IsCurrentDelegate || IsCurrentEnum || IsCurrentInterface) {
\r
809 OutputAttributes (constructor.CustomAttributes, null,
\r
810 LineHandling.ContinueLine);
\r
811 OutputMemberAccessModifier (constructor.Attributes);
\r
812 Output.Write ("Sub New(");
\r
813 OutputParameters (constructor.Parameters);
\r
814 Output.WriteLine (")");
\r
816 // check if ctor passes args on to other ctor in class
\r
817 CodeExpressionCollection ctorArgs = constructor.ChainedConstructorArgs;
\r
818 if (ctorArgs.Count > 0) {
\r
819 Output.Write ("Me.New(");
\r
820 OutputExpressionList (ctorArgs);
\r
821 Output.WriteLine (")");
\r
823 // check if ctor passes args on to ctor in base class
\r
824 ctorArgs = constructor.BaseConstructorArgs;
\r
825 if (ctorArgs.Count > 0) {
\r
826 Output.Write ("MyBase.New(");
\r
827 OutputExpressionList (ctorArgs);
\r
828 Output.WriteLine (")");
\r
830 } else if (IsCurrentClass) {
\r
834 // call default base ctor
\r
835 Output.WriteLine ("MyBase.New()");
\r
838 GenerateStatements (constructor.Statements);
\r
840 Output.WriteLine ("End Sub");
\r
843 protected override void GenerateTypeConstructor (CodeTypeConstructor constructor)
\r
845 if (IsCurrentDelegate || IsCurrentEnum || IsCurrentInterface) {
\r
850 OutputAttributes (constructor.CustomAttributes, null,
\r
851 LineHandling.ContinueLine);
\r
854 Output.WriteLine ("Shared Sub New()");
\r
856 GenerateStatements (constructor.Statements);
\r
858 Output.WriteLine ("End Sub");
\r
861 [MonoTODO ("not implemented")]
\r
862 protected override void GenerateTypeStart (CodeTypeDeclaration declaration)
\r
864 TextWriter output = Output;
\r
866 OutputAttributes (declaration.CustomAttributes, null,
\r
867 LineHandling.ContinueLine);
\r
869 TypeAttributes attributes = declaration.TypeAttributes;
\r
871 if (IsCurrentDelegate) {
\r
872 CodeTypeDelegate delegateDecl = (CodeTypeDelegate) declaration;
\r
874 if ((attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public) {
\r
875 output.Write ("Public ");
\r
878 bool isSub = delegateDecl.ReturnType.BaseType == typeof (void).FullName;
\r
880 output.Write ("Delegate Sub ");
\r
882 output.Write ("Delegate Function ");
\r
885 output.Write (delegateDecl.Name);
\r
886 output.Write ("(");
\r
887 Output.Write (")");
\r
889 Output.Write (" As ");
\r
890 OutputType (delegateDecl.ReturnType);
\r
892 Output.WriteLine ("");
\r
894 OutputTypeAttributes (declaration);
\r
896 output.Write (declaration.Name);
\r
898 if (IsCurrentEnum) {
\r
899 if (declaration.BaseTypes.Count > 0) {
\r
900 output.Write (" As ");
\r
901 OutputType (declaration.BaseTypes[0]);
\r
903 output.WriteLine ();
\r
908 bool firstInherits = true;
\r
909 bool firstImplements = true;
\r
911 for (int i = 0; i < declaration.BaseTypes.Count; i++) {
\r
912 // a struct can only implement interfaces
\r
913 // an interface can only inherit from other interface
\r
915 CodeTypeReference typeRef = declaration.BaseTypes[i];
\r
917 if (firstInherits && !declaration.IsStruct && !typeRef.IsInterface) {
\r
918 output.WriteLine ();
\r
919 output.Write ("Inherits ");
\r
920 firstInherits = false;
\r
921 } else if (!declaration.IsInterface && firstImplements) {
\r
922 output.WriteLine ();
\r
923 output.Write ("Implements ");
\r
924 firstImplements = false;
\r
926 output.Write (", ");
\r
928 OutputType (typeRef);
\r
930 output.WriteLine ();
\r
935 protected override void GenerateTypeEnd (CodeTypeDeclaration declaration)
\r
937 if (IsCurrentDelegate) {
\r
940 string output = string.Empty;
\r
943 if (declaration.IsStruct)
\r
944 output = "End Structure";
\r
945 if (declaration.IsInterface)
\r
946 output = "End Interface";
\r
947 if (declaration.IsEnum)
\r
948 output = "End Enum";
\r
949 if (declaration.IsClass)
\r
950 output = "End Class";
\r
952 Output.WriteLine (output);
\r
955 protected override void GenerateNamespace(CodeNamespace ns)
\r
957 GenerateCommentStatements (ns.Comments);
\r
959 // add regular imports
\r
960 GenerateNamespaceImports (ns);
\r
962 Output.WriteLine ();
\r
963 GenerateNamespaceStart (ns);
\r
964 GenerateTypes (ns);
\r
965 GenerateNamespaceEnd (ns);
\r
969 protected override void GenerateNamespaceStart (CodeNamespace ns)
\r
971 TextWriter output = Output;
\r
973 string name = ns.Name;
\r
974 if (name != null && name != string.Empty) {
\r
975 output.Write ("Namespace ");
\r
976 output.WriteLine (name);
\r
981 protected override void GenerateNamespaceEnd (CodeNamespace ns)
\r
983 string name = ns.Name;
\r
984 if (name != null && name != string.Empty) {
\r
986 Output.WriteLine ("End Namespace");
\r
990 protected override void GenerateNamespaceImport (CodeNamespaceImport import)
\r
992 TextWriter output = Output;
\r
994 output.Write ("Imports ");
\r
995 output.Write (import.Namespace);
\r
996 output.WriteLine ();
\r
999 protected override void GenerateAttributeDeclarationsStart (CodeAttributeDeclarationCollection attributes)
\r
1001 Output.Write ('<');
\r
1004 protected override void GenerateAttributeDeclarationsEnd (CodeAttributeDeclarationCollection attributes)
\r
1006 Output.Write (">");
\r
1009 private void OutputAttributes (CodeAttributeDeclarationCollection attributes, string prefix, LineHandling lineHandling) {
\r
1010 if (attributes.Count == 0) {
\r
1014 GenerateAttributeDeclarationsStart (attributes);
\r
1016 IEnumerator enumerator = attributes.GetEnumerator ();
\r
1017 if (enumerator.MoveNext ()) {
\r
1018 CodeAttributeDeclaration att = (CodeAttributeDeclaration) enumerator.Current;
\r
1019 if (prefix != null) {
\r
1020 Output.Write (prefix);
\r
1022 OutputAttributeDeclaration (att);
\r
1024 while (enumerator.MoveNext ()) {
\r
1025 Output.Write (", ");
\r
1026 if (lineHandling != LineHandling.InLine) {
\r
1027 ContinueOnNewLine ("");
\r
1028 Output.Write (" ");
\r
1030 att = (CodeAttributeDeclaration) enumerator.Current;
\r
1031 if (prefix != null) {
\r
1032 Output.Write (prefix);
\r
1034 OutputAttributeDeclaration (att);
\r
1037 GenerateAttributeDeclarationsEnd (attributes);
\r
1038 Output.Write (" ");
\r
1040 switch (lineHandling) {
\r
1041 case LineHandling.ContinueLine:
\r
1042 ContinueOnNewLine ("");
\r
1044 case LineHandling.NewLine:
\r
1045 Output.WriteLine ();
\r
1050 protected override void OutputAttributeArgument (CodeAttributeArgument argument)
\r
1052 string name = argument.Name;
\r
1053 if (name != null && name.Length > 0) {
\r
1054 Output.Write (name);
\r
1055 Output.Write (":=");
\r
1057 GenerateExpression (argument.Value);
\r
1060 private void OutputAttributeDeclaration (CodeAttributeDeclaration attribute)
\r
1062 Output.Write (attribute.Name.Replace ('+', '.'));
\r
1063 Output.Write ('(');
\r
1064 IEnumerator enumerator = attribute.Arguments.GetEnumerator ();
\r
1065 if (enumerator.MoveNext ()) {
\r
1066 CodeAttributeArgument argument = (CodeAttributeArgument) enumerator.Current;
\r
1067 OutputAttributeArgument (argument);
\r
1069 while (enumerator.MoveNext ()) {
\r
1070 Output.Write (", ");
\r
1071 argument = (CodeAttributeArgument) enumerator.Current;
\r
1072 OutputAttributeArgument (argument);
\r
1075 Output.Write (')');
\r
1078 protected override void OutputDirection (FieldDirection direction)
\r
1080 switch (direction) {
\r
1081 case FieldDirection.In:
\r
1082 Output.Write ("ByVal ");
\r
1084 case FieldDirection.Out:
\r
1085 case FieldDirection.Ref:
\r
1086 Output.Write ("ByRef ");
\r
1091 protected override void OutputFieldScopeModifier (MemberAttributes attributes)
\r
1093 switch (attributes & MemberAttributes.ScopeMask) {
\r
1094 case MemberAttributes.Static:
\r
1095 Output.Write ("Shared ");
\r
1097 case MemberAttributes.Const:
\r
1098 Output.Write ("Const ");
\r
1103 private void OutputImplementationTypes (CodeTypeReferenceCollection implementationTypes, string member)
\r
1105 IEnumerator enumerator = implementationTypes.GetEnumerator ();
\r
1106 if (enumerator.MoveNext ()) {
\r
1107 Output.Write (" Implements ");
\r
1109 CodeTypeReference typeReference = (CodeTypeReference) enumerator.Current;
\r
1110 OutputType (typeReference);
\r
1111 Output.Write ('.');
\r
1112 OutputIdentifier (member);
\r
1114 while (enumerator.MoveNext ()) {
\r
1115 Output.Write (" , ");
\r
1116 typeReference = (CodeTypeReference) enumerator.Current;
\r
1117 OutputType (typeReference);
\r
1118 Output.Write ('.');
\r
1119 OutputIdentifier (member);
\r
1124 protected override void OutputMemberAccessModifier (MemberAttributes attributes)
\r
1126 switch (attributes & MemberAttributes.AccessMask) {
\r
1127 case MemberAttributes.Assembly:
\r
1128 case MemberAttributes.FamilyAndAssembly:
\r
1129 Output.Write ("Friend ");
\r
1131 case MemberAttributes.Family:
\r
1132 Output.Write ("Protected ");
\r
1134 case MemberAttributes.FamilyOrAssembly:
\r
1135 Output.Write ("Protected Friend ");
\r
1137 case MemberAttributes.Private:
\r
1138 Output.Write ("Private ");
\r
1140 case MemberAttributes.Public:
\r
1141 Output.Write ("Public ");
\r
1146 private void OutputVTableModifier (MemberAttributes attributes)
\r
1148 if ((attributes & MemberAttributes.VTableMask) == MemberAttributes.New) {
\r
1149 Output.Write ("Shadows ");
\r
1153 protected override void OutputMemberScopeModifier (MemberAttributes attributes)
\r
1155 switch (attributes & MemberAttributes.ScopeMask) {
\r
1156 case MemberAttributes.Abstract:
\r
1157 Output.Write ("MustOverride ");
\r
1159 case MemberAttributes.Final:
\r
1162 case MemberAttributes.Static:
\r
1163 Output.Write ("Shared ");
\r
1165 case MemberAttributes.Override:
\r
1166 Output.Write ("Overrides ");
\r
1168 case MemberAttributes.Overloaded:
\r
1169 // based on http://gendotnet.com/Code%20Gen%20Articles/codedom.htm
\r
1170 Output.Write ("Overloads ");
\r
1172 MemberAttributes access_ovl = attributes & MemberAttributes.AccessMask;
\r
1173 if (access_ovl == MemberAttributes.Public || access_ovl == MemberAttributes.Family) {
\r
1174 Output.Write ("Overridable ");
\r
1179 // FUNNY! if the scope value is
\r
1180 // rubbish (0 or >Const), and access
\r
1181 // is public, protected make it
\r
1184 // i'm not sure whether this is 100%
\r
1185 // correct, but it seems to be MS
\r
1188 // On MS.NET 2.0, internal properties
\r
1189 // are also marked "virtual".
\r
1191 MemberAttributes access = attributes & MemberAttributes.AccessMask;
\r
1192 if (access == MemberAttributes.Public ||
\r
1194 access == MemberAttributes.Family || access == MemberAttributes.Assembly)
\r
1196 access == MemberAttributes.Family)
\r
1198 Output.Write ("Overridable ");
\r
1203 protected override void OutputOperator (CodeBinaryOperatorType op)
\r
1206 case CodeBinaryOperatorType.Add:
\r
1207 Output.Write ("+");
\r
1209 case CodeBinaryOperatorType.Subtract:
\r
1210 Output.Write ("-");
\r
1212 case CodeBinaryOperatorType.Multiply:
\r
1213 Output.Write ("*");
\r
1215 case CodeBinaryOperatorType.Divide:
\r
1216 Output.Write ("/");
\r
1218 case CodeBinaryOperatorType.Modulus:
\r
1219 Output.Write ("Mod");
\r
1221 case CodeBinaryOperatorType.Assign:
\r
1222 Output.Write ("=");
\r
1224 case CodeBinaryOperatorType.IdentityInequality:
\r
1225 Output.Write ("<>");
\r
1227 case CodeBinaryOperatorType.IdentityEquality:
\r
1228 Output.Write ("Is");
\r
1230 case CodeBinaryOperatorType.ValueEquality:
\r
1231 Output.Write ("=");
\r
1233 case CodeBinaryOperatorType.BitwiseOr:
\r
1234 Output.Write ("Or");
\r
1236 case CodeBinaryOperatorType.BitwiseAnd:
\r
1237 Output.Write ("And");
\r
1239 case CodeBinaryOperatorType.BooleanOr:
\r
1240 Output.Write ("OrElse");
\r
1242 case CodeBinaryOperatorType.BooleanAnd:
\r
1243 Output.Write ("AndAlso");
\r
1245 case CodeBinaryOperatorType.LessThan:
\r
1246 Output.Write ("<");
\r
1248 case CodeBinaryOperatorType.LessThanOrEqual:
\r
1249 Output.Write ("<=");
\r
1251 case CodeBinaryOperatorType.GreaterThan:
\r
1252 Output.Write (">");
\r
1254 case CodeBinaryOperatorType.GreaterThanOrEqual:
\r
1255 Output.Write (">=");
\r
1260 private void OutputTypeAttributes (CodeTypeDeclaration declaration)
\r
1262 TextWriter output = Output;
\r
1263 TypeAttributes attributes = declaration.TypeAttributes;
\r
1265 switch (attributes & TypeAttributes.VisibilityMask) {
\r
1266 case TypeAttributes.Public:
\r
1267 case TypeAttributes.NestedPublic:
\r
1268 output.Write ("Public ");
\r
1270 case TypeAttributes.NestedPrivate:
\r
1271 output.Write ("Private ");
\r
1274 case TypeAttributes.NotPublic:
\r
1275 case TypeAttributes.NestedFamANDAssem:
\r
1276 case TypeAttributes.NestedAssembly:
\r
1277 output.Write ("Friend ");
\r
1279 case TypeAttributes.NestedFamily:
\r
1280 output.Write ("Protected ");
\r
1282 case TypeAttributes.NestedFamORAssem:
\r
1283 output.Write ("Protected Friend ");
\r
1288 if (declaration.IsStruct) {
\r
1289 output.Write ("Structure ");
\r
1290 } else if (declaration.IsEnum) {
\r
1291 output.Write ("Enum ");
\r
1293 if ((attributes & TypeAttributes.Interface) != 0) {
\r
1294 output.Write ("Interface ");
\r
1296 if ((attributes & TypeAttributes.Sealed) != 0)
\r
1297 output.Write ("NotInheritable ");
\r
1299 if ((attributes & TypeAttributes.Abstract) != 0)
\r
1300 output.Write ("MustInherit ");
\r
1302 output.Write ("Class ");
\r
1307 protected override void OutputTypeNamePair (CodeTypeReference typeRef, String name)
\r
1309 Output.Write (name + " As " + GetTypeOutput (typeRef));
\r
1312 protected override void OutputType (CodeTypeReference type)
\r
1314 Output.Write (GetTypeOutput (type));
\r
1317 protected override string QuoteSnippetString (string value)
\r
1319 StringBuilder mySBuilder = new StringBuilder(value.Length);
\r
1320 mySBuilder.Append ("\"");
\r
1321 bool inQuotes = true;
\r
1322 for (int MyCounter = 0; MyCounter < value.Length; MyCounter++)
\r
1324 if (value[MyCounter] == 34) //quotation mark
\r
1328 mySBuilder.Append ("&\"");
\r
1331 mySBuilder.Append (value[MyCounter]);
\r
1332 mySBuilder.Append (value[MyCounter]);
\r
1334 else if (value[MyCounter] >= 32) //standard ansi/unicode characters
\r
1338 mySBuilder.Append ("&\"");
\r
1341 mySBuilder.Append (value[MyCounter]);
\r
1343 else //special chars, e.g. line break
\r
1347 mySBuilder.Append ("\"");
\r
1350 mySBuilder.Append ("&Microsoft.VisualBasic.ChrW(");
\r
1351 mySBuilder.Append ((int)value[MyCounter]);
\r
1352 mySBuilder.Append (")");
\r
1356 mySBuilder.Append ("\"");
\r
1357 return mySBuilder.ToString();
\r
1360 private void GenerateMemberReferenceExpression (CodeExpression targetObject, string memberName)
\r
1362 GenerateExpression (targetObject);
\r
1363 Output.Write ('.');
\r
1364 Output.Write (memberName);
\r
1371 protected override string CreateEscapedIdentifier (string value)
\r
1373 for (int x = 0; x < Keywords.Length; x++)
\r
1374 if (value.ToLower().Equals (Keywords[x].ToLower()))
\r
1375 return "[" + value + "]";
\r
1379 protected override string CreateValidIdentifier (string value)
\r
1381 for (int x = 0; x < Keywords.Length; x++)
\r
1382 if (value.ToLower().Equals (Keywords[x].ToLower()))
\r
1383 return "_" + value;
\r
1387 protected override string GetTypeOutput (CodeTypeReference type)
\r
1390 CodeTypeReference arrayType;
\r
1392 arrayType = type.ArrayElementType;
\r
1393 if (arrayType != null)
\r
1394 output = GetTypeOutput (arrayType);
\r
1396 switch (type.BaseType) {
\r
1397 case "System.DateTime":
\r
1400 case "System.Decimal":
\r
1401 output = "Decimal";
\r
1403 case "System.Double":
\r
1404 output = "Double";
\r
1406 case "System.Single":
\r
1407 output = "Single";
\r
1409 case "System.Byte":
\r
1412 case "System.Int32":
\r
1413 output = "Integer";
\r
1415 case "System.Int64":
\r
1418 case "System.Int16":
\r
1421 case "System.Boolean":
\r
1422 output = "Boolean";
\r
1424 case "System.Char":
\r
1427 case "System.String":
\r
1428 output = "String";
\r
1430 case "System.Object":
\r
1431 output = "Object";
\r
1434 case "System.SByte":
\r
1437 case "System.UInt16":
\r
1438 output = "UShort";
\r
1440 case "System.UInt32":
\r
1441 output = "UInteger";
\r
1443 case "System.UInt64":
\r
1448 output = type.BaseType.Replace('+', '.');
\r
1453 int rank = type.ArrayRank;
\r
1456 for (--rank; rank > 0; --rank)
\r
1464 protected override bool IsValidIdentifier (string identifier)
\r
1466 for (int x = 0; x < Keywords.Length; x++)
\r
1467 if (identifier.ToLower().Equals (Keywords[x].ToLower()))
\r
1472 protected override bool Supports (GeneratorSupport supports)
\r
1477 private bool IsOverloaded (CodeMemberProperty property, CodeTypeDeclaration type)
\r
1479 if ((property.Attributes & MemberAttributes.Overloaded) == MemberAttributes.Overloaded) {
\r
1483 foreach (CodeTypeMember member in type.Members) {
\r
1484 CodeMemberProperty p = member as CodeMemberProperty;
\r
1486 // member is not a property
\r
1490 if (p != property && p.Name == property.Name && p.PrivateImplementationType == null) {
\r
1497 private bool IsOverloaded (CodeMemberMethod method, CodeTypeDeclaration type)
\r
1499 if ((method.Attributes & MemberAttributes.Overloaded) == MemberAttributes.Overloaded) {
\r
1503 foreach (CodeTypeMember member in type.Members) {
\r
1504 CodeMemberMethod m = member as CodeMemberMethod;
\r
1506 // member is not a method
\r
1510 if (!(m is CodeTypeConstructor) && !(m is CodeConstructor) && m != method && m.Name == method.Name && m.PrivateImplementationType == null) {
\r
1517 private string GetEventName (CodeMemberEvent evt)
\r
1520 if (evt.PrivateImplementationType == null) {
\r
1524 string baseType = evt.PrivateImplementationType.BaseType.Replace ('.', '_');
\r
1525 return baseType + "_" + evt.Name;
\r
1531 private string GetMethodName (CodeMemberMethod method)
\r
1533 if (method.PrivateImplementationType == null) {
\r
1534 return method.Name;
\r
1537 string baseType = method.PrivateImplementationType.BaseType.Replace ('.', '_');
\r
1538 return baseType + "_" + method.Name;
\r
1541 private string GetPropertyName (CodeMemberProperty property)
\r
1543 if (property.PrivateImplementationType == null) {
\r
1544 return property.Name;
\r
1547 string baseType = property.PrivateImplementationType.BaseType.Replace ('.', '_');
\r
1548 return baseType + "_" + property.Name;
\r
1551 private enum LineHandling
\r