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