VBCodeGenerator.cs 35 KB

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