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