40deccd6061c1241bfafe47f28ed7d6b0392cb50
[mono.git] / mcs / class / System / Microsoft.VisualBasic / VBCodeGenerator.cs
1 //\r
2 // Microsoft.VisualBasic.VBCodeGenerator.cs\r
3 //\r
4 // Author:\r
5 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)\r
6 //   (partially based on CSharpCodeGenerator)\r
7 //   Jochen Wezel (jwezel@compumaster.de)\r
8 //\r
9 // (C) 2003 Andreas Nahr\r
10 // (C) 2003 Jochen Wezel (http://www.compumaster.de)\r
11 //\r
12 // Modifications:\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!
19
20 //
21 // Permission is hereby granted, free of charge, to any person obtaining
22 // a copy of this software and associated documentation files (the
23 // "Software"), to deal in the Software without restriction, including
24 // without limitation the rights to use, copy, modify, merge, publish,
25 // distribute, sublicense, and/or sell copies of the Software, and to
26 // permit persons to whom the Software is furnished to do so, subject to
27 // the following conditions:
28 // 
29 // The above copyright notice and this permission notice shall be
30 // included in all copies or substantial portions of the Software.
31 // 
32 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
33 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
34 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
35 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
36 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
37 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
38 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 //
40
41 \r
42 using System;\r
43 using System.Text;\r
44 using System.Text.RegularExpressions;\r
45 using System.CodeDom;\r
46 using System.CodeDom.Compiler;\r
47 using System.IO;\r
48 using System.Reflection;\r
49 using System.Collections;\r
50 \r
51 namespace Microsoft.VisualBasic\r
52 {\r
53         internal class VBCodeGenerator : CodeGenerator\r
54         {\r
55                 private string[] Keywords = new string[] {\r
56                         "AddHandler", "AddressOf", "Alias", "And",\r
57                         "AndAlso", "Ansi", "As", "Assembly",\r
58                         "Auto", "Boolean", "ByRef", "Byte", \r
59                         "ByVal", "Call", "Case", "Catch", \r
60                         "CBool", "CByte", "CChar", "CDate", \r
61                         "CDec", "CDbl", "Char", "CInt", \r
62                         "Class", "CLng", "CObj", "Const", \r
63                         "CShort", "CSng", "CStr", "CType", \r
64                         "Date", "Decimal", "Declare", "Default", \r
65                         "Delegate", "Dim", "DirectCast", "Do", \r
66                         "Double", "Each", "Else", "ElseIf", \r
67                         "End", "Enum", "Erase", "Error", \r
68                         "Event", "Exit", "False", "Finally", \r
69                         "For", "Friend", "Function", "Get", \r
70                         "GetType", "GoSub", "GoTo", "Handles", \r
71                         "If", "Implements", "Imports", "In", \r
72                         "Inherits", "Integer", "Interface", "Is", \r
73                         "Let", "Lib", "Like", "Long", \r
74                         "Loop", "Me", "Mod", "Module", \r
75                         "MustInherit", "MustOverride", "MyBase", "MyClass", \r
76                         "Namespace", "New", "Next", "Not", \r
77                         "Nothing", "NotInheritable", "NotOverridable", "Object", \r
78                         "On", "Option", "Optional", "Or", \r
79                         "OrElse", "Overloads", "Overridable", "Overrides", \r
80                         "ParamArray", "Preserve", "Private", "Property", \r
81                         "Protected", "Public", "RaiseEvent", "ReadOnly", \r
82                         "ReDim", "REM", "RemoveHandler", "Resume", \r
83                         "Return", "Select", "Set", "Shadows", \r
84                         "Shared", "Short", "Single", "Static", \r
85                         "Step", "Stop", "String", "Structure", \r
86                         "Sub", "SyncLock", "Then", "Throw", \r
87                         "To", "True", "Try", "TypeOf", \r
88                         "Unicode", "Until", "Variant", "When", \r
89                         "While", "With", "WithEvents", "WriteOnly", \r
90                         "Xor" \r
91                 };\r
92 \r
93                 public VBCodeGenerator()\r
94                 {\r
95                 }\r
96 \r
97                 protected override string NullToken {\r
98                         get {\r
99                                 return "Nothing";\r
100                         }\r
101                 }\r
102 \r
103                 protected override void GenerateArrayCreateExpression (CodeArrayCreateExpression expression)\r
104                 {\r
105                         TextWriter output = Output;\r
106 \r
107                         output.Write ("New ");\r
108 \r
109                         CodeExpressionCollection initializers = expression.Initializers;\r
110                         CodeTypeReference createType = expression.CreateType;\r
111 \r
112                         if (initializers.Count > 0) {\r
113 \r
114                                 OutputType (createType);\r
115                                 \r
116                                 output.WriteLine (" {");\r
117                                 ++Indent;\r
118                                 OutputExpressionList (initializers, true);\r
119                                 --Indent;\r
120                                 output.Write ("}");\r
121 \r
122                         } \r
123                         else {\r
124                                 CodeTypeReference arrayType = createType.ArrayElementType;\r
125                                 while (arrayType != null) \r
126                                 {\r
127                                         createType = arrayType;\r
128                                         arrayType = arrayType.ArrayElementType;\r
129                                 }\r
130 \r
131                                 OutputType (createType);\r
132 \r
133                                 output.Write ('(');\r
134 \r
135                                 CodeExpression size = expression.SizeExpression;\r
136                                 if (size != null)\r
137                                         GenerateExpression (size);\r
138                                 else\r
139                                         output.Write (expression.Size);\r
140 \r
141                                 output.Write (')');\r
142                         }\r
143                 }\r
144 \r
145                 protected override void GenerateBaseReferenceExpression (CodeBaseReferenceExpression expression)\r
146                 {\r
147                         Output.Write ("MyBase");\r
148                 }\r
149 \r
150                 protected override void GenerateCastExpression (CodeCastExpression expression)\r
151                 {\r
152                         TextWriter output = Output;\r
153                         // ENHANCE: Use a DirectCast if it is known that expression.Expression is no Value-Type\r
154                         output.Write ("CType(");\r
155                         GenerateExpression (expression.Expression);\r
156                         output.Write (", ");\r
157                         OutputType (expression.TargetType);\r
158                         output.Write (")");\r
159                 }\r
160 \r
161                 private bool AsBool(object datavalue)\r
162                 {\r
163                         return datavalue != null && datavalue is bool && (bool)datavalue;\r
164                 }\r
165                 \r
166                 private string OnOff(bool datavalue)\r
167                 {\r
168                         return datavalue?"On":"Off";\r
169                 }\r
170 \r
171                 protected override void GenerateCompileUnitStart (CodeCompileUnit compileUnit)\r
172                 {\r
173                         GenerateComment (new CodeComment ("------------------------------------------------------------------------------"));\r
174                         GenerateComment (new CodeComment (" <autogenerated>"));\r
175                         GenerateComment (new CodeComment ("     This code was generated by a tool."));\r
176                         GenerateComment (new CodeComment ("     Mono Runtime Version: " + System.Environment.Version));\r
177                         GenerateComment (new CodeComment (""));\r
178                         GenerateComment (new CodeComment ("     Changes to this file may cause incorrect behavior and will be lost if "));\r
179                         GenerateComment (new CodeComment ("     the code is regenerated."));\r
180                         GenerateComment (new CodeComment (" </autogenerated>"));\r
181                         GenerateComment (new CodeComment ("------------------------------------------------------------------------------"));\r
182                         Output.WriteLine ();
183                         if (AsBool(compileUnit.UserData["AllowLateBound"])) {
184                                 Output.WriteLine("Option Explicit {0}",OnOff(AsBool(compileUnit.UserData["RequireVariableDeclaration"])));\r
185                                 Output.WriteLine("Option Strict Off");
186                         } else {
187                                 Output.WriteLine("Option Explicit On"); // Strict On implies Explicit On\r
188                                 Output.WriteLine("Option Strict On");
189                         }\r
190                         Output.WriteLine ();                            \r
191                 }\r
192 \r
193                 protected override void GenerateDelegateCreateExpression (CodeDelegateCreateExpression expression)\r
194                 {\r
195                         TextWriter output = Output;\r
196 \r
197                         output.Write ("AddressOf ");\r
198 \r
199                         CodeExpression targetObject = expression.TargetObject;\r
200                         if (targetObject != null) {\r
201                                 GenerateExpression (targetObject);\r
202                                 Output.Write ('.');\r
203                         }\r
204                         output.Write (expression.MethodName);\r
205                 }\r
206 \r
207                 protected override void GenerateFieldReferenceExpression (CodeFieldReferenceExpression expression)\r
208                 {\r
209                         CodeExpression targetObject = expression.TargetObject;\r
210                         if (targetObject != null) {\r
211                                 GenerateExpression (targetObject);\r
212                                 Output.Write ('.');\r
213                         }\r
214                         Output.Write (expression.FieldName);\r
215                 }\r
216                 \r
217                 protected override void GenerateArgumentReferenceExpression (CodeArgumentReferenceExpression expression)\r
218                 {\r
219                         Output.Write (expression.ParameterName);\r
220                 }\r
221 \r
222                 protected override void GenerateVariableReferenceExpression (CodeVariableReferenceExpression expression)\r
223                 {\r
224                         Output.Write (expression.VariableName);\r
225                 }\r
226                 \r
227                 protected override void GenerateIndexerExpression (CodeIndexerExpression expression)\r
228                 {\r
229                         TextWriter output = Output;\r
230 \r
231                         GenerateExpression (expression.TargetObject);\r
232                         output.Write ('(');\r
233                         OutputExpressionList (expression.Indices);\r
234                         output.Write (')');\r
235                 }\r
236                 \r
237                 protected override void GenerateArrayIndexerExpression (CodeArrayIndexerExpression expression)\r
238                 {\r
239                         TextWriter output = Output;\r
240 \r
241                         GenerateExpression (expression.TargetObject);\r
242                         output.Write (".Item(");\r
243                         OutputExpressionList (expression.Indices);\r
244                         output.Write (')');\r
245                 }\r
246                 \r
247                 protected override void GenerateSnippetExpression (CodeSnippetExpression expression)\r
248                 {\r
249                         Output.Write (expression.Value);\r
250                 }\r
251                 \r
252                 protected override void GenerateMethodInvokeExpression (CodeMethodInvokeExpression expression)\r
253                 {\r
254                         TextWriter output = Output;\r
255 \r
256                         GenerateMethodReferenceExpression (expression.Method);\r
257 \r
258                         output.Write ('(');\r
259                         OutputExpressionList (expression.Parameters);\r
260                         output.Write (')');\r
261                 }\r
262 \r
263                 protected override void GenerateMethodReferenceExpression (CodeMethodReferenceExpression expression)\r
264                 {\r
265                         GenerateExpression (expression.TargetObject);\r
266                         Output.Write ('.');\r
267                         Output.Write (expression.MethodName);\r
268                 }\r
269 \r
270                 protected override void GenerateEventReferenceExpression (CodeEventReferenceExpression expression)\r
271                 {\r
272                         GenerateExpression (expression.TargetObject);\r
273                         Output.Write ('.');\r
274                         Output.Write (expression.EventName);\r
275                 }\r
276 \r
277                 protected override void GenerateDelegateInvokeExpression (CodeDelegateInvokeExpression expression)\r
278                 {\r
279                         Output.Write ("RaiseEvent ");\r
280                         GenerateExpression (expression.TargetObject);\r
281                         Output.Write ('(');\r
282                         OutputExpressionList (expression.Parameters);\r
283                         Output.WriteLine (')');\r
284                 }\r
285                 \r
286                 protected override void GenerateObjectCreateExpression (CodeObjectCreateExpression expression)\r
287                 {\r
288                         Output.Write( "New " );\r
289                         OutputType (expression.CreateType);\r
290                         Output.Write ('(');\r
291                         OutputExpressionList (expression.Parameters);\r
292                         Output.Write (')');\r
293                 }\r
294 \r
295                 protected override void GenerateParameterDeclarationExpression (CodeParameterDeclarationExpression e)\r
296                 {\r
297                         if (e.CustomAttributes != null && e.CustomAttributes.Count > 0)\r
298                                 OutputAttributeDeclarations (e.CustomAttributes);\r
299                         OutputDirection (e.Direction);\r
300                         OutputTypeNamePair (e.Type, e.Name);\r
301                 }\r
302 \r
303                 protected override void GeneratePrimitiveExpression (CodePrimitiveExpression e)\r
304                 {\r
305                         TextWriter output = Output;\r
306 \r
307                         if (e.Value == null) {\r
308                                 output.Write (NullToken);\r
309                                 return;\r
310                         }\r
311 \r
312                         Type type = e.Value.GetType ();\r
313                         if (type == typeof (bool)) {\r
314                                 if ((bool)e.Value)\r
315                                         output.Write ("True");\r
316                                 else\r
317                                         output.Write ("False");\r
318                         } \r
319                         else if (type == typeof (char)) {\r
320                                 output.Write ("\"" + e.Value.ToString () + "\"c");\r
321                         } \r
322                         else if (type == typeof (string)) {\r
323                                 output.Write (QuoteSnippetString ((string) e.Value));\r
324                         } \r
325                         else if (type == typeof (byte) || type == typeof (sbyte) || type == typeof (short) ||\r
326                                 type == typeof (int) || type == typeof (long) || type == typeof (float) ||\r
327                                 type == typeof (double) || type == typeof (decimal)) {\r
328                                 output.Write (e.Value.ToString ());\r
329                         } \r
330                         else {\r
331                                 throw new ArgumentException ("Value type (" + type + ") is not a primitive type");\r
332                         }\r
333                 }\r
334 \r
335                 protected override void GeneratePropertyReferenceExpression (CodePropertyReferenceExpression expression)\r
336                 {\r
337                         GenerateMemberReferenceExpression (expression.TargetObject, expression.PropertyName);\r
338                 }\r
339 \r
340                 protected override void GeneratePropertySetValueReferenceExpression (CodePropertySetValueReferenceExpression expression)\r
341                 {\r
342                         Output.Write ("Value"); \r
343                 }\r
344 \r
345                 protected override void GenerateThisReferenceExpression (CodeThisReferenceExpression expression)\r
346                 {\r
347                         Output.Write ("Me");\r
348                 }\r
349 \r
350                 protected override void GenerateExpressionStatement (CodeExpressionStatement statement)\r
351                 {\r
352                         GenerateExpression (statement.Expression);\r
353                         Output.WriteLine (); //start new line\r
354                 }\r
355 \r
356                 protected override void GenerateIterationStatement (CodeIterationStatement statement)\r
357                 {\r
358                         TextWriter output = Output;\r
359 \r
360                         GenerateStatement (statement.InitStatement);\r
361                         output.Write ("Do While ");\r
362                         GenerateExpression (statement.TestExpression);\r
363                         output.WriteLine ();\r
364                         GenerateStatements (statement.Statements);\r
365                         GenerateStatement (statement.IncrementStatement);\r
366                         output.WriteLine ("Loop");\r
367                 }\r
368 \r
369                 protected override void GenerateThrowExceptionStatement (CodeThrowExceptionStatement statement)\r
370                 {\r
371                         Output.Write ("Throw ");\r
372                         GenerateExpression (statement.ToThrow);\r
373                 }\r
374 \r
375                 protected override void GenerateComment (CodeComment comment)\r
376                 {\r
377                         TextWriter output = Output;\r
378 \r
379                         if (comment.DocComment)\r
380                                 output.Write ("''' ");\r
381                         else\r
382                                 output.Write ("' ");\r
383 \r
384                         output.WriteLine (comment.Text);\r
385                 }\r
386 \r
387                 protected override void GenerateMethodReturnStatement (CodeMethodReturnStatement statement)\r
388                 {\r
389                         TextWriter output = Output;\r
390 \r
391                         output.Write ("Return ");\r
392                         GenerateExpression (statement.Expression);\r
393                         output.WriteLine ();\r
394                 }\r
395 \r
396                 protected override void GenerateConditionStatement (CodeConditionStatement statement)\r
397                 {\r
398                         TextWriter output = Output;\r
399                         output.Write ("If (");\r
400 \r
401                         GenerateExpression (statement.Condition);\r
402 \r
403                         output.WriteLine (") Then");\r
404                         ++Indent;\r
405                         GenerateStatements (statement.TrueStatements);\r
406                         --Indent;\r
407 \r
408                         CodeStatementCollection falses = statement.FalseStatements;\r
409                         if (falses.Count > 0) {\r
410                                 output.WriteLine ("Else");\r
411                                 ++Indent;\r
412                                 GenerateStatements (falses);\r
413                                 --Indent;\r
414                         }\r
415                         else {\r
416                                 if (Options.ElseOnClosing)\r
417                                         output.WriteLine ("Else");\r
418                         }\r
419                         output.WriteLine ("End If");\r
420                 }\r
421 \r
422                 protected override void GenerateTryCatchFinallyStatement (CodeTryCatchFinallyStatement statement)\r
423                 {\r
424                         TextWriter output = Output;\r
425 \r
426                         output.WriteLine ("Try");\r
427                         ++Indent;\r
428                         GenerateStatements (statement.TryStatements);\r
429                         --Indent;\r
430                         output.WriteLine ();\r
431                         \r
432                         foreach (CodeCatchClause clause in statement.CatchClauses) {\r
433                                 output.Write ("Catch ");\r
434                                 OutputTypeNamePair (clause.CatchExceptionType, clause.LocalName);\r
435                                 output.WriteLine ();\r
436                                 ++Indent;\r
437                                 GenerateStatements (clause.Statements);\r
438                                 --Indent;\r
439                                 output.WriteLine ();\r
440                         }\r
441 \r
442                         CodeStatementCollection finallies = statement.FinallyStatements;\r
443                         if (finallies.Count > 0) {\r
444 \r
445                                 output.WriteLine ("Finally");\r
446                                 ++Indent;\r
447                                 GenerateStatements (finallies);\r
448                                 --Indent;\r
449                                 output.WriteLine ();\r
450                         }\r
451 \r
452                         if (Options.ElseOnClosing) {\r
453                                 if (statement.CatchClauses.Count == 0)\r
454                                         output.WriteLine ("Catch");\r
455                                 if (statement.FinallyStatements.Count == 0)\r
456                                         output.WriteLine ("Finally");\r
457                         }\r
458 \r
459                         output.WriteLine("End Try");\r
460                 }\r
461 \r
462                 protected override void GenerateAssignStatement (CodeAssignStatement statement)\r
463                 {                       \r
464                         TextWriter output = Output;\r
465                         GenerateExpression (statement.Left);\r
466                         output.Write (" = ");\r
467                         GenerateExpression (statement.Right);\r
468                         output.WriteLine ();\r
469                 }\r
470 \r
471                 protected override void GenerateAttachEventStatement (CodeAttachEventStatement statement)\r
472                 {\r
473                         TextWriter output = Output;\r
474 \r
475                         Output.Write ("AddHandler ");\r
476                         GenerateEventReferenceExpression (statement.Event);\r
477                         Output.Write ( ", ");\r
478                         GenerateExpression (statement.Listener);\r
479                         output.WriteLine ();\r
480                 }\r
481 \r
482                 protected override void GenerateRemoveEventStatement (CodeRemoveEventStatement statement)\r
483                 {\r
484                         TextWriter output = Output;\r
485 \r
486                         Output.Write ("RemoveHandler ");\r
487                         GenerateEventReferenceExpression (statement.Event);\r
488                         Output.Write ( ", ");\r
489                         GenerateExpression (statement.Listener);\r
490                         output.WriteLine ();\r
491                 }\r
492 \r
493                 protected override void GenerateGotoStatement (CodeGotoStatement statement)\r
494                 {\r
495                         TextWriter output = Output;\r
496 \r
497                         output.Write ("Goto ");\r
498                         output.Write (statement.Label);\r
499                         output.WriteLine ();\r
500                 }\r
501                 \r
502                 protected override void GenerateLabeledStatement (CodeLabeledStatement statement)\r
503                 {\r
504                         TextWriter output = Output;\r
505 \r
506                         output.Write (statement.Label + ":");\r
507                         GenerateStatement (statement.Statement);\r
508                 }\r
509 \r
510                 protected override void GenerateTypeOfExpression (CodeTypeOfExpression e)\r
511                 {\r
512                         TextWriter output = Output;\r
513 \r
514                         output.Write ("GetType(");\r
515                         OutputType (e.Type);\r
516                         output.Write (")");\r
517                 }\r
518 \r
519                 protected override void GenerateVariableDeclarationStatement( CodeVariableDeclarationStatement statement )\r
520                 {\r
521                         TextWriter output = Output;\r
522 \r
523                         output.Write ("Dim ");\r
524                         OutputTypeNamePair (statement.Type, statement.Name);\r
525 \r
526                         CodeExpression initExpression = statement.InitExpression;\r
527                         if (initExpression != null) \r
528                         {\r
529                                 output.Write (" = ");\r
530                                 GenerateExpression (initExpression);\r
531                         }\r
532 \r
533                         output.WriteLine();\r
534                 }\r
535 \r
536                 protected override void GenerateLinePragmaStart (CodeLinePragma linePragma)\r
537                 {\r
538                         Output.WriteLine ();\r
539                         Output.Write ("#ExternalSource(");\r
540                         Output.Write (linePragma.FileName);\r
541                         Output.Write (", ");\r
542                         Output.Write (linePragma.LineNumber);\r
543                         Output.WriteLine (")");\r
544                 }\r
545 \r
546                 protected override void GenerateLinePragmaEnd (CodeLinePragma linePragma)\r
547                 {\r
548                         Output.WriteLine ("#End ExternalSource");\r
549                 }\r
550 \r
551                 protected override void GenerateEvent (CodeMemberEvent eventRef, CodeTypeDeclaration declaration)\r
552                 {\r
553                         TextWriter output = Output;\r
554 \r
555                         if (eventRef.CustomAttributes.Count > 0)\r
556                                 OutputAttributeDeclarations (eventRef.CustomAttributes);\r
557 \r
558                         MemberAttributes attributes = eventRef.Attributes;\r
559 \r
560                         OutputMemberAccessModifier (attributes);\r
561                         OutputMemberScopeModifier (attributes);\r
562 \r
563                         output.Write ("Event ");\r
564                         OutputTypeNamePair (eventRef.Type, eventRef.Name);\r
565                         output.WriteLine ();\r
566                 }\r
567 \r
568                 protected override void GenerateField (CodeMemberField field)\r
569                 {\r
570                         TextWriter output = Output;\r
571 \r
572                         if (field.CustomAttributes.Count > 0)\r
573                                 OutputAttributeDeclarations (field.CustomAttributes);\r
574 \r
575                         MemberAttributes attributes = field.Attributes;\r
576                         OutputMemberAccessModifier (attributes);\r
577                         OutputFieldScopeModifier (attributes);\r
578 \r
579                         OutputTypeNamePair (field.Type, field.Name);\r
580 \r
581                         CodeExpression initExpression = field.InitExpression;\r
582                         if (initExpression != null) {\r
583                                 output.Write (" = ");\r
584                                 GenerateExpression (initExpression);\r
585                         }\r
586 \r
587                         output.WriteLine();\r
588                 }\r
589                 \r
590                 protected override void GenerateSnippetMember (CodeSnippetTypeMember member)\r
591                 {\r
592                         Output.Write (member.Text);\r
593                 }\r
594                 \r
595                 protected override void GenerateEntryPointMethod( CodeEntryPointMethod method, CodeTypeDeclaration declaration )\r
596                 {\r
597                         method.Name = "Main";\r
598                         GenerateMethod (method, declaration);\r
599                 }\r
600                 \r
601                 [MonoTODO ("partially implemented")]\r
602                 protected override void GenerateMethod (CodeMemberMethod method, CodeTypeDeclaration declaration)\r
603                 {\r
604                         bool isSub = method.ReturnType == null || method.ReturnType.BaseType == "System.Void";\r
605 \r
606                         TextWriter output = Output;\r
607 \r
608                         if (method.CustomAttributes.Count > 0)\r
609                                 OutputAttributeDeclarations (method.CustomAttributes);\r
610 \r
611                         MemberAttributes attributes = method.Attributes;\r
612 \r
613                         OutputMemberAccessModifier (attributes);\r
614                         OutputMemberScopeModifier (attributes);\r
615 \r
616                         if (isSub)\r
617                                 output.Write ("Sub ");\r
618                         else\r
619                                 output.Write ("Function ");\r
620 \r
621                         output.Write (method.Name);\r
622                         output.Write ('(');\r
623                         OutputParameters (method.Parameters);\r
624                         output.Write (')');\r
625 \r
626                         if (!isSub) {\r
627                                 output.Write (" As ");\r
628                                 OutputType (method.ReturnType);\r
629                         }\r
630 \r
631                         if (method.ImplementationTypes.Count > 0) {\r
632                                 output.Write (" Implements ");\r
633                                 foreach (CodeTypeReference type in method.ImplementationTypes)\r
634                                 {\r
635                                         OutputType (type);\r
636                                         output.Write ('.');\r
637                                         // TODO implementation incomplete\r
638 \r
639                                 }\r
640                         }\r
641 \r
642                         // TODO private implementations\r
643 \r
644                         if ((attributes & MemberAttributes.ScopeMask) == MemberAttributes.Abstract)\r
645                                 output.WriteLine ();\r
646                         else {\r
647                                 output.WriteLine ();\r
648                                 ++Indent;\r
649                                 GenerateStatements (method.Statements);\r
650                                 --Indent;\r
651                                 if (isSub)\r
652                                         output.WriteLine ("End Sub");\r
653                                 else\r
654                                         output.WriteLine ("End Function");\r
655                         }\r
656                 }\r
657 \r
658                 protected override void GenerateProperty (CodeMemberProperty property, CodeTypeDeclaration declaration)\r
659                 {\r
660                         TextWriter output = Output;\r
661 \r
662                         if (property.CustomAttributes.Count > 0)\r
663                                 OutputAttributeDeclarations (property.CustomAttributes);\r
664 \r
665                         MemberAttributes attributes = property.Attributes;\r
666                         OutputMemberAccessModifier (attributes);\r
667                         OutputMemberScopeModifier (attributes);\r
668 \r
669                         if (property.HasGet && (!property.HasSet))\r
670                                 output.Write ("ReadOnly " );\r
671 \r
672                         if (property.HasSet && (!property.HasGet))\r
673                                 output.Write ("WriteOnly " );\r
674 \r
675                         output.Write ("Property " );\r
676                         \r
677                         OutputTypeNamePair (property.Type, property.Name);\r
678                         output.WriteLine ();\r
679                         ++Indent;\r
680 \r
681                         if (property.HasGet) {\r
682                                 output.WriteLine ("Get");\r
683                                 ++Indent;\r
684 \r
685                                 GenerateStatements (property.GetStatements);\r
686 \r
687                                 --Indent;\r
688                                 output.WriteLine ("End Get");\r
689                         }\r
690                         \r
691                         if (property.HasSet) {\r
692                                 output.Write ("Set (");\r
693                                 OutputTypeNamePair (property.Type, "Value");
694                                 output.WriteLine (")");
695                                 ++Indent;\r
696 \r
697                                 GenerateStatements (property.SetStatements);\r
698 \r
699                                 --Indent;\r
700                                 output.WriteLine ("End Set");\r
701                         }\r
702 \r
703                         --Indent;\r
704                         output.WriteLine ("End Property");\r
705                 }\r
706 \r
707                 [MonoTODO ("not implemented")]\r
708                 protected override void GenerateConstructor (CodeConstructor constructor, CodeTypeDeclaration declaration)\r
709                 {\r
710                         if (constructor.CustomAttributes.Count > 0)\r
711                                 OutputAttributeDeclarations (constructor.CustomAttributes);\r
712                         OutputMemberAccessModifier (constructor.Attributes);\r
713                         Output.Write ("Sub New(");\r
714                         OutputParameters (constructor.Parameters);\r
715                         Output.WriteLine (")");\r
716                         // Handle BaseConstructorArgs, ChainedConstructorArgs, ImplementationTypes\r
717                         Indent++;\r
718                         GenerateStatements (constructor.Statements);\r
719                         Indent--;\r
720                         Output.WriteLine ("End Sub");\r
721                 }\r
722                 \r
723                 protected override void GenerateTypeConstructor (CodeTypeConstructor constructor)\r
724                 {\r
725                         Output.WriteLine ("Shared Sub New()");\r
726                         Indent++;\r
727                         GenerateStatements (constructor.Statements);\r
728                         Indent--;\r
729                         Output.WriteLine ("End Sub");\r
730                 }\r
731 \r
732                 [MonoTODO ("not implemented")]\r
733                 protected override void GenerateTypeStart (CodeTypeDeclaration declaration)\r
734                 {\r
735                         TextWriter output = Output;\r
736 \r
737                         if (declaration.CustomAttributes.Count > 0)\r
738                                 OutputAttributeDeclarations (declaration.CustomAttributes);\r
739                         TypeAttributes attributes = declaration.TypeAttributes;\r
740                         OutputTypeAttributes (attributes,\r
741                                 declaration.IsStruct,\r
742                                 declaration.IsEnum);\r
743 \r
744                         output.WriteLine (declaration.Name);\r
745 \r
746                         ++Indent;\r
747                         \r
748                         IEnumerator enumerator = declaration.BaseTypes.GetEnumerator();\r
749                         if (enumerator.MoveNext()) \r
750                         {\r
751                                 CodeTypeReference type = (CodeTypeReference)enumerator.Current;\r
752                         \r
753                                 if (type != null)\r
754                                 {\r
755                                         output.Write ("Inherits ");\r
756                                         OutputType (type);\r
757                                         output.WriteLine ();\r
758                                 }\r
759                                 \r
760                                 while (enumerator.MoveNext()) \r
761                                 {\r
762                                         type = (CodeTypeReference)enumerator.Current;\r
763                                 \r
764                                         if (type != null)\r
765                                         {\r
766                                                 output.Write ("Implements ");\r
767                                                 OutputType (type);\r
768                                                 output.WriteLine ();\r
769                                         }\r
770                                 }\r
771                         }                       \r
772                 }\r
773 \r
774                 protected override void GenerateTypeEnd (CodeTypeDeclaration declaration)\r
775                 {\r
776                         string output = string.Empty;\r
777 \r
778                         --Indent;\r
779                         if (declaration.IsStruct)\r
780                                 output = "End Structure";\r
781                         if (declaration.IsInterface)\r
782                                 output = "End Interface";\r
783                         if (declaration.IsEnum)\r
784                                 output = "End Enum";\r
785                         if (declaration.IsClass)\r
786                                 output = "End Class";\r
787 \r
788                         Output.WriteLine (output);\r
789                 }\r
790 \r
791                 protected override void GenerateNamespace(CodeNamespace ns)\r
792                 {\r
793                         GenerateCommentStatements (ns.Comments);\r
794                         \r
795                         bool Imports2MSVBFound;\r
796                         Imports2MSVBFound = false;\r
797                         if (null != ns.Imports) \r
798                         {\r
799                                 foreach (CodeNamespaceImport import in ns.Imports)\r
800                                 {\r
801                                         if (string.Compare (import.Namespace, "Microsoft.VisualBasic", true, System.Globalization.CultureInfo.InvariantCulture) == 0)\r
802                                                 Imports2MSVBFound = true;\r
803                                 }\r
804                         }\r
805                         // add standard import to Microsoft.VisualBasic if missing\r
806                         if (Imports2MSVBFound == false)\r
807                                 Output.WriteLine ("Imports Microsoft.VisualBasic");\r
808                         // add regular imports\r
809                         GenerateNamespaceImports (ns);\r
810 \r
811                         TextWriter output = Output;\r
812                         output.WriteLine(); \r
813                         GenerateNamespaceStart (ns); \r
814                         GenerateTypes (ns);\r
815                         GenerateNamespaceEnd (ns);\r
816                 }\r
817 \r
818 \r
819                 protected override void GenerateNamespaceStart (CodeNamespace ns)\r
820                 {\r
821                         TextWriter output = Output;\r
822                         \r
823                         string name = ns.Name;\r
824                         if (name != null && name != string.Empty) {\r
825                                 output.Write ("Namespace ");\r
826                                 output.WriteLine (name);\r
827                                 ++Indent;\r
828                         }\r
829                 }\r
830 \r
831                 protected override void GenerateNamespaceEnd (CodeNamespace ns)\r
832                 {\r
833                         string name = ns.Name;\r
834                         if (name != null && name != string.Empty) {\r
835                                 --Indent;\r
836                                 Output.WriteLine ("End Namespace");\r
837                         }\r
838                 }\r
839 \r
840                 protected override void GenerateNamespaceImport (CodeNamespaceImport import)\r
841                 {\r
842                         TextWriter output = Output;\r
843 \r
844                         output.Write ("Imports ");\r
845                         output.Write (import.Namespace);\r
846                         output.WriteLine ();\r
847                 }\r
848                 \r
849                 protected override void GenerateAttributeDeclarationsStart (CodeAttributeDeclarationCollection attributes)\r
850                 {\r
851                         Output.Write ('<');\r
852                 }\r
853                 \r
854                 protected override void GenerateAttributeDeclarationsEnd (CodeAttributeDeclarationCollection attributes)\r
855                 {\r
856                         Output.WriteLine ("> _");\r
857                 }\r
858 \r
859                 protected override void OutputDirection (FieldDirection direction)\r
860                 {\r
861                         switch (direction) {\r
862                         case FieldDirection.In:\r
863                                 //there is no "In"\r
864                                 break;\r
865                         case FieldDirection.Out:\r
866                                 Output.Write ("ByVal ");\r
867                                 break;\r
868                         case FieldDirection.Ref:\r
869                                 Output.Write ("ByRef ");\r
870                                 break;\r
871                         }\r
872                 }\r
873 \r
874                 protected override void OutputFieldScopeModifier (MemberAttributes attributes)\r
875                 {\r
876                         if ((attributes & MemberAttributes.VTableMask) == MemberAttributes.New)\r
877                                 Output.Write ("New ");\r
878 \r
879                         switch (attributes & MemberAttributes.ScopeMask) {\r
880                         case MemberAttributes.Static:\r
881                                 Output.Write ("Shared ");\r
882                                 break;\r
883                         case MemberAttributes.Const:\r
884                                 Output.Write ("Const ");\r
885                                 break;\r
886                         }\r
887                 }\r
888 \r
889                 protected override void OutputMemberAccessModifier (MemberAttributes attributes)\r
890                 {\r
891                         switch (attributes & MemberAttributes.AccessMask) {\r
892                         case MemberAttributes.Assembly:\r
893                                 Output.Write ("Friend ");\r
894                                 break;\r
895                         case MemberAttributes.FamilyAndAssembly:\r
896                                 Output.Write ("Friend "); \r
897                                 break;\r
898                         case MemberAttributes.Family:\r
899                                 Output.Write ("Protected ");\r
900                                 break;\r
901                         case MemberAttributes.FamilyOrAssembly:\r
902                                 Output.Write ("Protected Friend ");\r
903                                 break;\r
904                         case MemberAttributes.Private:\r
905                                 Output.Write ("Private ");\r
906                                 break;\r
907                         case MemberAttributes.Public:\r
908                                 Output.Write ("Public ");\r
909                                 break;\r
910                         }\r
911                 }\r
912 \r
913                 protected override void OutputMemberScopeModifier (MemberAttributes attributes)\r
914                 {\r
915                         if ((attributes & MemberAttributes.VTableMask) == MemberAttributes.New)\r
916                                 Output.Write ("New ");\r
917 \r
918                         switch (attributes & MemberAttributes.ScopeMask) {\r
919                         case MemberAttributes.Abstract:\r
920                                 Output.Write ("MustOverride ");\r
921                                 break;\r
922                         case MemberAttributes.Final:\r
923                                 //JW 2004-06-03: seems to be the "sealed" keyword in C# and the "NotOverridable" keyword in VB, but conflicts with ASP.NET generation
924                                 //Output.Write ("NotOverridable ");\r
925                                 break;\r
926                         case MemberAttributes.Static:\r
927                                 Output.Write ("Shared ");\r
928                                 break;\r
929                         case MemberAttributes.Override:\r
930                                 Output.Write ("Overrides ");\r
931                                 break;\r
932                         case MemberAttributes.Overloaded:
933                                 // based on http://gendotnet.com/Code%20Gen%20Articles/codedom.htm
934                                 Output.Write ("Overloads ");
935                                 MemberAttributes access_ovl = attributes & MemberAttributes.AccessMask;
936                                 if ( access_ovl == MemberAttributes.Public || 
937                                         access_ovl == MemberAttributes.Family )
938                                         Output.Write ("Overridable ");
939                                 break;
940                         default:\r
941                                 //\r
942                                 // FUNNY! if the scope value is\r
943                                 // rubbish (0 or >Const), and access\r
944                                 // is public or protected, make it\r
945                                 // "virtual".\r
946                                 //\r
947                                 // i'm not sure whether this is 100%\r
948                                 // correct, but it seems to be MS\r
949                                 // behavior. \r
950                                 //\r
951                                 MemberAttributes access = attributes & MemberAttributes.AccessMask;\r
952                                 if ( access == MemberAttributes.Public || \r
953                                         access == MemberAttributes.Family )\r
954                                         Output.Write ("Overridable ");\r
955                                 break;\r
956                         }\r
957                 }\r
958 \r
959                 protected override void OutputOperator (CodeBinaryOperatorType op)\r
960                 {\r
961                         switch (op) {\r
962                         case CodeBinaryOperatorType.Add:\r
963                                 Output.Write ("+");\r
964                                 break;\r
965                         case CodeBinaryOperatorType.Subtract:\r
966                                 Output.Write ("-");\r
967                                 break;\r
968                         case CodeBinaryOperatorType.Multiply:\r
969                                 Output.Write ("*");\r
970                                 break;\r
971                         case CodeBinaryOperatorType.Divide:\r
972                                 Output.Write ("/");\r
973                                 break;\r
974                         case CodeBinaryOperatorType.Modulus:\r
975                                 Output.Write ("Mod");\r
976                                 break;\r
977                         case CodeBinaryOperatorType.Assign:\r
978                                 Output.Write ("=");\r
979                                 break;\r
980                         case CodeBinaryOperatorType.IdentityInequality:\r
981                                 Output.Write ("<>");\r
982                                 break;\r
983                         case CodeBinaryOperatorType.IdentityEquality:\r
984                                 Output.Write ("Is");\r
985                                 break;\r
986                         case CodeBinaryOperatorType.ValueEquality:\r
987                                 Output.Write ("=");\r
988                                 break;\r
989                         case CodeBinaryOperatorType.BitwiseOr:\r
990                                 Output.Write ("Or");\r
991                                 break;\r
992                         case CodeBinaryOperatorType.BitwiseAnd:\r
993                                 Output.Write ("And");\r
994                                 break;\r
995                         case CodeBinaryOperatorType.BooleanOr:\r
996                                 Output.Write ("OrElse");\r
997                                 break;\r
998                         case CodeBinaryOperatorType.BooleanAnd:\r
999                                 Output.Write ("AndAlso");\r
1000                                 break;\r
1001                         case CodeBinaryOperatorType.LessThan:\r
1002                                 Output.Write ("<");\r
1003                                 break;\r
1004                         case CodeBinaryOperatorType.LessThanOrEqual:\r
1005                                 Output.Write ("<=");\r
1006                                 break;\r
1007                         case CodeBinaryOperatorType.GreaterThan:\r
1008                                 Output.Write (">");\r
1009                                 break;\r
1010                         case CodeBinaryOperatorType.GreaterThanOrEqual:\r
1011                                 Output.Write (">=");\r
1012                                 break;\r
1013                         }\r
1014                 }\r
1015 \r
1016                 protected override void OutputTypeAttributes (TypeAttributes attributes, bool isStruct, bool isEnum)\r
1017                 {\r
1018                         TextWriter output = Output;\r
1019 \r
1020                         switch (attributes & TypeAttributes.VisibilityMask) {\r
1021                         case TypeAttributes.NotPublic:\r
1022                                 // Does this mean friend access?\r
1023                                 output.Write ("Friend ");\r
1024                                 break; \r
1025 \r
1026                         case TypeAttributes.Public:\r
1027                         case TypeAttributes.NestedPublic:\r
1028                                 output.Write ("Public ");\r
1029                                 break;\r
1030 \r
1031                         case TypeAttributes.NestedPrivate:\r
1032                                 output.Write ("Private ");\r
1033                                 break;\r
1034                         case TypeAttributes.NestedAssembly:\r
1035                                 output.Write ("Friend ");\r
1036                                 break;\r
1037                         case TypeAttributes.NestedFamily:\r
1038                                 output.Write ("Protected ");\r
1039                                 break;\r
1040                         case TypeAttributes.NestedFamORAssem:\r
1041                                 output.Write ("Protected Friend ");\r
1042                                 break;\r
1043                         case TypeAttributes.NestedFamANDAssem:\r
1044                                 output.Write ("Friend ");\r
1045                                 break;\r
1046                         }\r
1047 \r
1048                         if (isStruct)\r
1049                                 output.Write ("Structure ");\r
1050 \r
1051                         else if (isEnum)\r
1052                                 output.Write ("Enumeration ");\r
1053 \r
1054                         else {\r
1055                                 if ((attributes & TypeAttributes.Interface) != 0) \r
1056                                         output.Write ("Interface ");\r
1057 \r
1058                                 else {\r
1059                                         if ((attributes & TypeAttributes.Sealed) != 0)\r
1060                                                 output.Write ("NotInheritable ");\r
1061 \r
1062                                         if ((attributes & TypeAttributes.Abstract) != 0)\r
1063                                                 output.Write ("MustInherit ");\r
1064                                         \r
1065                                         output.Write ("Class ");\r
1066                                 }\r
1067                         }\r
1068                 }\r
1069 \r
1070                 protected override void OutputTypeNamePair (CodeTypeReference typeRef, String name)\r
1071                 {\r
1072                         Output.Write (name + " As " + GetTypeOutput (typeRef));\r
1073                 }\r
1074 \r
1075                 protected override void OutputType (CodeTypeReference type)\r
1076                 {\r
1077                         Output.Write (GetTypeOutput (type));\r
1078                 }\r
1079 \r
1080                 protected override string QuoteSnippetString (string value)\r
1081                 {\r
1082                         StringBuilder mySBuilder = new StringBuilder(value.Length);\r
1083                         mySBuilder.Append ("\"");\r
1084                         bool inQuotes = true;\r
1085                         for (int MyCounter = 0; MyCounter < value.Length; MyCounter++)\r
1086                         {\r
1087                                 if (value[MyCounter] == 34) //quotation mark\r
1088                                 {\r
1089                                         if (!inQuotes)\r
1090                                         {\r
1091                                                 mySBuilder.Append ("&\"");\r
1092                                                 inQuotes = true;\r
1093                                         }\r
1094                                         mySBuilder.Append (value[MyCounter]);\r
1095                                         mySBuilder.Append (value[MyCounter]);\r
1096                                 }\r
1097                                 else if (value[MyCounter] >= 32) //standard ansi/unicode characters\r
1098                                 {\r
1099                                         if (!inQuotes)\r
1100                                         {\r
1101                                                 mySBuilder.Append ("&\"");\r
1102                                                 inQuotes = true;\r
1103                                         }\r
1104                                         mySBuilder.Append (value[MyCounter]);\r
1105                                 }\r
1106                                 else //special chars, e.g. line break\r
1107                                 {\r
1108                                         if (inQuotes)\r
1109                                         { \r
1110                                                 mySBuilder.Append ("\"");\r
1111                                                 inQuotes = false;\r
1112                                         }\r
1113                                         mySBuilder.Append ("&Microsoft.VisualBasic.ChrW(");\r
1114                                         mySBuilder.Append ((int)value[MyCounter]); \r
1115                                         mySBuilder.Append (")");\r
1116                                 }                       \r
1117                         }\r
1118                         if (inQuotes)\r
1119                                 mySBuilder.Append ("\"");\r
1120                         return mySBuilder.ToString();\r
1121                 }\r
1122 \r
1123                 private void GenerateMemberReferenceExpression (CodeExpression targetObject, string memberName)\r
1124                 {\r
1125                         GenerateExpression (targetObject);\r
1126                         Output.Write ('.');\r
1127                         Output.Write (memberName);\r
1128                 }\r
1129                         \r
1130                 /* \r
1131                  * ICodeGenerator\r
1132                  */\r
1133 \r
1134                 protected override string CreateEscapedIdentifier (string value)\r
1135                 {\r
1136                         for (int x = 0; x < Keywords.Length; x++)\r
1137                                 if (value.ToLower().Equals (Keywords[x].ToLower()))\r
1138                                         return "[" + value + "]";\r
1139                         return value;\r
1140                 }\r
1141 \r
1142                 protected override string CreateValidIdentifier (string value)\r
1143                 {\r
1144                         for (int x = 0; x < Keywords.Length; x++)\r
1145                                 if (value.ToLower().Equals (Keywords[x].ToLower()))\r
1146                                         return "_" + value;\r
1147                         return value;\r
1148                 }\r
1149 \r
1150                 protected override string GetTypeOutput (CodeTypeReference type)\r
1151                 {\r
1152                         string output;\r
1153                         CodeTypeReference arrayType;\r
1154 \r
1155                         arrayType = type.ArrayElementType;\r
1156                         if (arrayType != null)\r
1157                                 output = GetTypeOutput (arrayType);\r
1158                         else { \r
1159                                 switch (type.BaseType) {\r
1160 \r
1161                                 case "System.Decimal":\r
1162                                         output = "Decimal";\r
1163                                         break;\r
1164                                 case "System.Double":\r
1165                                         output = "Double";\r
1166                                         break;\r
1167                                 case "System.Single":\r
1168                                         output = "Single";\r
1169                                         break;\r
1170                                 \r
1171                                 case "System.Byte":\r
1172                                         output = "Byte";\r
1173                                         break;\r
1174                                 case "System.SByte":\r
1175                                         output = "SByte";\r
1176                                         break;\r
1177                                 case "System.Int32":\r
1178                                         output = "Integer";\r
1179                                         break;\r
1180                                 case "System.UInt32":\r
1181                                         output = "UInt32";\r
1182                                         break;\r
1183                                 case "System.Int64":\r
1184                                         output = "Long";\r
1185                                         break;\r
1186                                 case "System.UInt64":\r
1187                                         output = "UInt64";\r
1188                                         break;\r
1189                                 case "System.Int16":\r
1190                                         output = "Short";\r
1191                                         break;\r
1192                                 case "System.UInt16":\r
1193                                         output = "UInt16";\r
1194                                         break;\r
1195 \r
1196                                 case "System.Boolean":\r
1197                                         output = "Boolean";\r
1198                                         break;\r
1199                                 \r
1200                                 case "System.Char":\r
1201                                         output = "Char";\r
1202                                         break;\r
1203 \r
1204                                 case "System.String":\r
1205                                         output = "String";\r
1206                                         break;\r
1207                                 case "System.Object":\r
1208                                         output = "Object";\r
1209                                         break;\r
1210 \r
1211                                 case "System.Void":\r
1212                                         output = "Nothing";\r
1213                                         break;\r
1214 \r
1215                                 default:\r
1216                                         output = type.BaseType;\r
1217                                         break;\r
1218                                 }\r
1219                         }\r
1220 \r
1221                         int rank = type.ArrayRank;\r
1222                         if (rank > 0) {\r
1223                                 output += "(";\r
1224                                 for (--rank; rank > 0; --rank)\r
1225                                         output += ",";\r
1226                                 output += ")";\r
1227                         }\r
1228 \r
1229                         return output;\r
1230                 }\r
1231 \r
1232                 protected override bool IsValidIdentifier (string identifier)\r
1233                 {\r
1234                         for (int x = 0; x < Keywords.Length; x++)\r
1235                                 if (identifier.ToLower().Equals (Keywords[x].ToLower()))\r
1236                                         return false;\r
1237                         return true;\r
1238                 }\r
1239 \r
1240                 protected override bool Supports (GeneratorSupport supports)\r
1241                 {\r
1242                         return true;\r
1243                 }\r
1244         }\r
1245 }\r