CodeGenerator.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959
  1. //
  2. // System.CodeDom.Compiler CodeGenerator class
  3. //
  4. // Author:
  5. // Miguel de Icaza ([email protected])
  6. // Daniel Stodden ([email protected])
  7. //
  8. // (C) 2001 Ximian, Inc.
  9. //
  10. using System.CodeDom;
  11. using System.Reflection;
  12. using System.IO;
  13. using System.Collections;
  14. namespace System.CodeDom.Compiler {
  15. public abstract class CodeGenerator
  16. : ICodeGenerator
  17. {
  18. private IndentedTextWriter output;
  19. private CodeGeneratorOptions options;
  20. private CodeTypeMember currentMember;
  21. private CodeTypeDeclaration currentType;
  22. //
  23. // Constructors
  24. //
  25. protected CodeGenerator()
  26. {
  27. }
  28. //
  29. // Properties
  30. //
  31. protected CodeTypeMember CurrentMember {
  32. get {
  33. return currentMember;
  34. }
  35. }
  36. protected string CurrentMemberName {
  37. get {
  38. if ( currentType == null )
  39. return null;
  40. return currentMember.Name;
  41. }
  42. }
  43. protected string CurrentTypeName {
  44. get {
  45. if ( currentType == null )
  46. return null;
  47. return currentType.Name;
  48. }
  49. }
  50. protected int Indent {
  51. get {
  52. return output.Indent;
  53. }
  54. set {
  55. output.Indent = value;
  56. }
  57. }
  58. protected bool IsCurrentClass {
  59. get {
  60. if ( currentType == null )
  61. return false;
  62. return currentType.IsClass;
  63. }
  64. }
  65. protected bool IsCurrentDelegate {
  66. get {
  67. return currentType is CodeTypeDelegate;
  68. }
  69. }
  70. protected bool IsCurrentEnum {
  71. get {
  72. if ( currentType == null )
  73. return false;
  74. return currentType.IsEnum;
  75. }
  76. }
  77. protected bool IsCurrentInterface {
  78. get {
  79. if ( currentType == null )
  80. return false;
  81. return currentType.IsInterface;
  82. }
  83. }
  84. protected bool IsCurrentStruct {
  85. get {
  86. if ( currentType == null )
  87. return false;
  88. return currentType.IsStruct;
  89. }
  90. }
  91. protected abstract string NullToken {
  92. get;
  93. }
  94. protected CodeGeneratorOptions Options {
  95. get {
  96. return options;
  97. }
  98. }
  99. protected TextWriter Output {
  100. get {
  101. return output;
  102. }
  103. }
  104. //
  105. // Methods
  106. //
  107. protected virtual void ContinueOnNewLine( string st )
  108. {
  109. }
  110. /*
  111. * Code Generation methods
  112. */
  113. protected abstract void GenerateArgumentReferenceExpression (CodeArgumentReferenceExpression e);
  114. protected abstract void GenerateArrayCreateExpression (CodeArrayCreateExpression e);
  115. protected abstract void GenerateArrayIndexerExpression( CodeArrayIndexerExpression e );
  116. protected abstract void GenerateAssignStatement (CodeAssignStatement s);
  117. protected abstract void GenerateAttachEventStatement (CodeAttachEventStatement s);
  118. protected abstract void GenerateAttributeDeclarationsStart( CodeAttributeDeclarationCollection attributes );
  119. protected abstract void GenerateAttributeDeclarationsEnd( CodeAttributeDeclarationCollection attributes );
  120. protected abstract void GenerateBaseReferenceExpression (CodeBaseReferenceExpression e);
  121. protected virtual void GenerateBinaryOperatorExpression (CodeBinaryOperatorExpression e)
  122. {
  123. GenerateExpression( e.Left );
  124. switch ( e.Operator ) {
  125. case CodeBinaryOperatorType.Add:
  126. output.Write( " + " );
  127. break;
  128. case CodeBinaryOperatorType.Assign:
  129. output.Write( " = " );
  130. break;
  131. case CodeBinaryOperatorType.BitwiseAnd:
  132. output.Write( " & " );
  133. break;
  134. case CodeBinaryOperatorType.BitwiseOr:
  135. output.Write( " | " );
  136. break;
  137. case CodeBinaryOperatorType.BooleanAnd:
  138. output.Write( " && " );
  139. break;
  140. case CodeBinaryOperatorType.BooleanOr:
  141. output.Write( " || " );
  142. break;
  143. case CodeBinaryOperatorType.Divide:
  144. output.Write( " / " );
  145. break;
  146. case CodeBinaryOperatorType.GreaterThan:
  147. output.Write( " > " );
  148. break;
  149. case CodeBinaryOperatorType.GreaterThanOrEqual:
  150. output.Write( " >= " );
  151. break;
  152. case CodeBinaryOperatorType.IdentityEquality:
  153. output.Write( " == " );
  154. break;
  155. case CodeBinaryOperatorType.IdentityInequality:
  156. output.Write( " != " );
  157. break;
  158. case CodeBinaryOperatorType.LessThan:
  159. output.Write( " < " );
  160. break;
  161. case CodeBinaryOperatorType.LessThanOrEqual:
  162. output.Write( " <= " );
  163. break;
  164. case CodeBinaryOperatorType.Modulus:
  165. output.Write( " % " );
  166. break;
  167. case CodeBinaryOperatorType.Multiply:
  168. output.Write( " * " );
  169. break;
  170. case CodeBinaryOperatorType.Subtract:
  171. output.Write( " - " );
  172. break;
  173. case CodeBinaryOperatorType.ValueEquality:
  174. output.Write( " == " );
  175. break;
  176. }
  177. GenerateExpression( e.Right );
  178. }
  179. protected abstract void GenerateCastExpression (CodeCastExpression e);
  180. protected abstract void GenerateComment( CodeComment comment );
  181. protected virtual void GenerateCommentStatement( CodeCommentStatement statement )
  182. {
  183. GenerateComment( statement.Comment );
  184. }
  185. protected virtual void GenerateCommentStatements (CodeCommentStatementCollection statements)
  186. {
  187. foreach ( CodeCommentStatement comment in statements )
  188. GenerateCommentStatement( comment );
  189. }
  190. protected virtual void GenerateCompileUnit( CodeCompileUnit compileUnit )
  191. {
  192. GenerateCompileUnitStart( compileUnit );
  193. CodeAttributeDeclarationCollection attributes = compileUnit.AssemblyCustomAttributes;
  194. if ( attributes.Count != 0 ) {
  195. GenerateAttributeDeclarationsStart( attributes );
  196. output.Write( "assembly: " );
  197. OutputAttributeDeclarations( compileUnit.AssemblyCustomAttributes );
  198. GenerateAttributeDeclarationsEnd( attributes );
  199. }
  200. foreach ( CodeNamespace ns in compileUnit.Namespaces )
  201. GenerateNamespace( ns );
  202. GenerateCompileUnitEnd( compileUnit );
  203. }
  204. protected virtual void GenerateCompileUnitEnd( CodeCompileUnit compileUnit )
  205. {
  206. }
  207. protected virtual void GenerateCompileUnitStart( CodeCompileUnit compileUnit )
  208. {
  209. }
  210. protected abstract void GenerateConditionStatement( CodeConditionStatement s );
  211. protected abstract void GenerateConstructor (CodeConstructor x, CodeTypeDeclaration d);
  212. protected abstract void GenerateDelegateCreateExpression( CodeDelegateCreateExpression e );
  213. protected abstract void GenerateDelegateInvokeExpression( CodeDelegateInvokeExpression e );
  214. protected virtual void GenerateDirectionExpression( CodeDirectionExpression e )
  215. {
  216. OutputDirection( e.Direction );
  217. output.Write( ' ' );
  218. GenerateExpression( e.Expression );
  219. }
  220. protected abstract void GenerateEntryPointMethod( CodeEntryPointMethod m, CodeTypeDeclaration d );
  221. protected abstract void GenerateEvent( CodeMemberEvent ev, CodeTypeDeclaration d );
  222. protected abstract void GenerateEventReferenceExpression( CodeEventReferenceExpression e );
  223. protected void GenerateExpression( CodeExpression e )
  224. {
  225. CodeArgumentReferenceExpression argref = e as CodeArgumentReferenceExpression;
  226. if ( argref != null ) {
  227. GenerateArgumentReferenceExpression( argref );
  228. return;
  229. }
  230. CodeArrayCreateExpression mkarray = e as CodeArrayCreateExpression;
  231. if ( mkarray != null ) {
  232. GenerateArrayCreateExpression( mkarray );
  233. return;
  234. }
  235. CodeArrayIndexerExpression arrayidx = e as CodeArrayIndexerExpression;
  236. if ( arrayidx != null ) {
  237. GenerateArrayIndexerExpression( arrayidx );
  238. return;
  239. }
  240. CodeBaseReferenceExpression baseref = e as CodeBaseReferenceExpression;
  241. if ( baseref != null ) {
  242. GenerateBaseReferenceExpression( baseref );
  243. return;
  244. }
  245. CodeBinaryOperatorExpression binary = e as CodeBinaryOperatorExpression;
  246. if ( binary != null ) {
  247. GenerateBinaryOperatorExpression( binary );
  248. return;
  249. }
  250. CodeCastExpression cast = e as CodeCastExpression;
  251. if ( cast != null ) {
  252. GenerateCastExpression( cast );
  253. return;
  254. }
  255. CodeDelegateCreateExpression mkdel = e as CodeDelegateCreateExpression;
  256. if ( mkdel != null ) {
  257. GenerateDelegateCreateExpression( mkdel );
  258. return;
  259. }
  260. CodeDelegateInvokeExpression delinvoke = e as CodeDelegateInvokeExpression;
  261. if ( delinvoke != null ) {
  262. GenerateDelegateInvokeExpression( delinvoke );
  263. return;
  264. }
  265. CodeDirectionExpression direction = e as CodeDirectionExpression;
  266. if ( direction != null ) {
  267. GenerateDirectionExpression( direction );
  268. return;
  269. }
  270. CodeEventReferenceExpression eventref = e as CodeEventReferenceExpression;
  271. if ( eventref != null ) {
  272. GenerateEventReferenceExpression( eventref );
  273. return;
  274. }
  275. CodeFieldReferenceExpression fieldref = e as CodeFieldReferenceExpression;
  276. if ( fieldref != null ) {
  277. GenerateFieldReferenceExpression( fieldref );
  278. return;
  279. }
  280. CodeIndexerExpression idx = e as CodeIndexerExpression;
  281. if ( idx != null ) {
  282. GenerateIndexerExpression( idx );
  283. return;
  284. }
  285. CodeMethodInvokeExpression methodinv = e as CodeMethodInvokeExpression;
  286. if ( methodinv != null ) {
  287. GenerateMethodInvokeExpression( methodinv );
  288. return;
  289. }
  290. CodeMethodReferenceExpression methodref = e as CodeMethodReferenceExpression;
  291. if ( methodref != null ) {
  292. GenerateMethodReferenceExpression( methodref );
  293. return;
  294. }
  295. CodeObjectCreateExpression objref = e as CodeObjectCreateExpression;
  296. if ( objref != null ) {
  297. GenerateObjectCreateExpression( objref );
  298. return;
  299. }
  300. CodeParameterDeclarationExpression param = e as CodeParameterDeclarationExpression;
  301. if ( param != null ) {
  302. GenerateParameterDeclarationExpression( param );
  303. return;
  304. }
  305. CodePrimitiveExpression primitive = e as CodePrimitiveExpression;
  306. if ( primitive != null ) {
  307. GeneratePrimitiveExpression( primitive );
  308. return;
  309. }
  310. CodePropertyReferenceExpression propref = e as CodePropertyReferenceExpression;
  311. if ( propref != null ) {
  312. GeneratePropertyReferenceExpression( propref );
  313. return;
  314. }
  315. CodePropertySetValueReferenceExpression propset = e as CodePropertySetValueReferenceExpression;
  316. if ( propset != null ) {
  317. GeneratePropertySetValueReferenceExpression( propset );
  318. return;
  319. }
  320. CodeSnippetExpression snippet = e as CodeSnippetExpression;
  321. if ( snippet != null ) {
  322. GenerateSnippetExpression( snippet );
  323. return;
  324. }
  325. CodeThisReferenceExpression thisref = e as CodeThisReferenceExpression;
  326. if ( thisref != null ) {
  327. GenerateThisReferenceExpression( thisref );
  328. return;
  329. }
  330. CodeTypeOfExpression typeOf = e as CodeTypeOfExpression;
  331. if ( typeOf != null ) {
  332. GenerateTypeOfExpression( typeOf );
  333. return;
  334. }
  335. CodeTypeReferenceExpression typeref = e as CodeTypeReferenceExpression;
  336. if ( typeref != null ) {
  337. GenerateTypeReferenceExpression( typeref );
  338. return;
  339. }
  340. CodeVariableReferenceExpression varref = e as CodeVariableReferenceExpression;
  341. if ( varref != null ) {
  342. GenerateVariableReferenceExpression( varref );
  343. return;
  344. }
  345. }
  346. protected abstract void GenerateExpressionStatement( CodeExpressionStatement statement );
  347. protected abstract void GenerateField (CodeMemberField f);
  348. protected abstract void GenerateFieldReferenceExpression (CodeFieldReferenceExpression e);
  349. protected abstract void GenerateGotoStatement( CodeGotoStatement statement );
  350. protected abstract void GenerateIndexerExpression (CodeIndexerExpression e);
  351. protected abstract void GenerateIterationStatement( CodeIterationStatement s );
  352. protected abstract void GenerateLabeledStatement( CodeLabeledStatement statement );
  353. protected abstract void GenerateLinePragmaStart (CodeLinePragma p);
  354. protected abstract void GenerateLinePragmaEnd (CodeLinePragma p);
  355. protected abstract void GenerateMethod (CodeMemberMethod m, CodeTypeDeclaration d);
  356. protected abstract void GenerateMethodInvokeExpression (CodeMethodInvokeExpression e);
  357. protected abstract void GenerateMethodReferenceExpression( CodeMethodReferenceExpression e );
  358. protected abstract void GenerateMethodReturnStatement (CodeMethodReturnStatement e);
  359. protected virtual void GenerateNamespace (CodeNamespace ns)
  360. {
  361. foreach ( CodeCommentStatement statement in ns.Comments )
  362. GenerateCommentStatement( statement );
  363. GenerateNamespaceStart( ns );
  364. foreach ( CodeNamespaceImport import in ns.Imports )
  365. GenerateNamespaceImport( import );
  366. output.WriteLine();
  367. foreach ( CodeTypeDeclaration type in ns.Types )
  368. GenerateCodeFromType( type, output, options );
  369. GenerateNamespaceEnd( ns );
  370. }
  371. protected abstract void GenerateNamespaceStart (CodeNamespace ns);
  372. protected abstract void GenerateNamespaceEnd (CodeNamespace ns);
  373. protected abstract void GenerateNamespaceImport (CodeNamespaceImport i);
  374. protected abstract void GenerateObjectCreateExpression (CodeObjectCreateExpression e);
  375. protected virtual void GenerateParameterDeclarationExpression (CodeParameterDeclarationExpression e)
  376. {
  377. OutputAttributeDeclarations( e.CustomAttributes );
  378. OutputDirection( e.Direction );
  379. OutputType( e.Type );
  380. output.Write( ' ' );
  381. output.Write( e.Name );
  382. }
  383. protected virtual void GeneratePrimitiveExpression (CodePrimitiveExpression e)
  384. {
  385. if (e.Value == null) {
  386. output.Write ("null");
  387. return;
  388. }
  389. if (e.Value is bool) {
  390. output.Write (e.Value.ToString ().ToLower ());
  391. return;
  392. }
  393. output.Write (e.Value);
  394. }
  395. protected abstract void GenerateProperty (CodeMemberProperty p, CodeTypeDeclaration d);
  396. protected abstract void GeneratePropertyReferenceExpression (CodePropertyReferenceExpression e);
  397. protected abstract void GeneratePropertySetValueReferenceExpression( CodePropertySetValueReferenceExpression e );
  398. protected abstract void GenerateRemoveEventStatement( CodeRemoveEventStatement statement );
  399. protected abstract void GenerateSnippetExpression( CodeSnippetExpression e );
  400. protected abstract void GenerateSnippetMember( CodeSnippetTypeMember m );
  401. protected virtual void GenerateSnippetStatement( CodeSnippetStatement s )
  402. {
  403. output.Write( s.Value );
  404. }
  405. protected void GenerateStatement( CodeStatement s )
  406. {
  407. CodeAssignStatement assign = s as CodeAssignStatement;
  408. if ( assign != null ) {
  409. GenerateAssignStatement( assign );
  410. return;
  411. }
  412. CodeAttachEventStatement attach = s as CodeAttachEventStatement;
  413. if ( attach != null ) {
  414. GenerateAttachEventStatement( attach );
  415. return;
  416. }
  417. CodeCommentStatement comment = s as CodeCommentStatement;
  418. if ( comment != null ) {
  419. GenerateCommentStatement( comment );
  420. return;
  421. }
  422. CodeConditionStatement condition = s as CodeConditionStatement;
  423. if ( condition != null ) {
  424. GenerateConditionStatement( condition );
  425. return;
  426. }
  427. CodeExpressionStatement expression = s as CodeExpressionStatement;
  428. if ( expression != null ) {
  429. GenerateExpressionStatement( expression );
  430. return;
  431. }
  432. CodeGotoStatement gotostmt = s as CodeGotoStatement;
  433. if ( gotostmt != null ) {
  434. GenerateGotoStatement( gotostmt );
  435. return;
  436. }
  437. CodeIterationStatement iteration = s as CodeIterationStatement;
  438. if ( iteration != null ) {
  439. GenerateIterationStatement( iteration );
  440. return;
  441. }
  442. CodeLabeledStatement label = s as CodeLabeledStatement;
  443. if ( label != null ) {
  444. GenerateLabeledStatement( label );
  445. return;
  446. }
  447. CodeMethodReturnStatement returnstmt = s as CodeMethodReturnStatement;
  448. if ( returnstmt != null ) {
  449. GenerateMethodReturnStatement( returnstmt );
  450. return;
  451. }
  452. CodeRemoveEventStatement remove = s as CodeRemoveEventStatement;
  453. if ( remove != null ) {
  454. GenerateRemoveEventStatement( remove );
  455. return;
  456. }
  457. CodeSnippetStatement snippet = s as CodeSnippetStatement;
  458. if ( snippet != null ) {
  459. GenerateSnippetStatement( snippet );
  460. return;
  461. }
  462. CodeThrowExceptionStatement exception = s as CodeThrowExceptionStatement;
  463. if ( exception != null ) {
  464. GenerateThrowExceptionStatement( exception );
  465. return;
  466. }
  467. CodeTryCatchFinallyStatement trycatch = s as CodeTryCatchFinallyStatement;
  468. if ( trycatch != null ) {
  469. GenerateTryCatchFinallyStatement( trycatch );
  470. return;
  471. }
  472. CodeVariableDeclarationStatement declaration = s as CodeVariableDeclarationStatement;
  473. if ( declaration != null ) {
  474. GenerateVariableDeclarationStatement( declaration );
  475. return;
  476. }
  477. }
  478. protected void GenerateStatements( CodeStatementCollection c )
  479. {
  480. foreach ( CodeStatement statement in c )
  481. GenerateStatement( statement );
  482. }
  483. protected abstract void GenerateThisReferenceExpression (CodeThisReferenceExpression e);
  484. protected abstract void GenerateThrowExceptionStatement (CodeThrowExceptionStatement s);
  485. protected abstract void GenerateTryCatchFinallyStatement (CodeTryCatchFinallyStatement s);
  486. protected abstract void GenerateTypeEnd( CodeTypeDeclaration declaration );
  487. protected abstract void GenerateTypeConstructor( CodeTypeConstructor constructor );
  488. protected virtual void GenerateTypeOfExpression (CodeTypeOfExpression e)
  489. {
  490. output.Write( "typeof(" );
  491. OutputType( e.Type );
  492. output.Write( ")" );
  493. }
  494. protected virtual void GenerateTypeReferenceExpression (CodeTypeReferenceExpression e)
  495. {
  496. OutputType( e.Type );
  497. }
  498. protected abstract void GenerateTypeStart( CodeTypeDeclaration declaration );
  499. protected abstract void GenerateVariableDeclarationStatement (CodeVariableDeclarationStatement e);
  500. protected abstract void GenerateVariableReferenceExpression( CodeVariableReferenceExpression e );
  501. //
  502. // Other members
  503. //
  504. /*
  505. * Output Methods
  506. */
  507. protected virtual void OutputAttributeArgument( CodeAttributeArgument argument )
  508. {
  509. string name = argument.Name;
  510. if ( name != null ) {
  511. output.Write( name );
  512. output.Write( '=' );
  513. }
  514. GenerateExpression( argument.Value );
  515. }
  516. private void OutputAttributeDeclaration( CodeAttributeDeclaration attribute )
  517. {
  518. output.Write( attribute.Name );
  519. output.Write( '(' );
  520. IEnumerator enumerator = attribute.Arguments.GetEnumerator();
  521. if ( enumerator.MoveNext() ) {
  522. CodeAttributeArgument argument = (CodeAttributeArgument)enumerator.Current;
  523. OutputAttributeArgument( argument );
  524. while ( enumerator.MoveNext() ) {
  525. output.Write( ',' );
  526. argument = (CodeAttributeArgument)enumerator.Current;
  527. OutputAttributeArgument( argument );
  528. }
  529. }
  530. output.Write( ')' );
  531. }
  532. protected virtual void OutputAttributeDeclarations( CodeAttributeDeclarationCollection attributes )
  533. {
  534. GenerateAttributeDeclarationsStart( attributes );
  535. IEnumerator enumerator = attributes.GetEnumerator();
  536. if ( enumerator.MoveNext() ) {
  537. CodeAttributeDeclaration attribute = (CodeAttributeDeclaration)enumerator.Current;
  538. OutputAttributeDeclaration( attribute );
  539. while ( enumerator.MoveNext() ) {
  540. attribute = (CodeAttributeDeclaration)enumerator.Current;
  541. output.WriteLine( ',' );
  542. OutputAttributeDeclaration( attribute );
  543. }
  544. }
  545. GenerateAttributeDeclarationsEnd( attributes );
  546. }
  547. protected virtual void OutputDirection( FieldDirection direction )
  548. {
  549. switch ( direction ) {
  550. case FieldDirection.In:
  551. output.Write( "in " );
  552. break;
  553. case FieldDirection.Out:
  554. output.Write( "out " );
  555. break;
  556. case FieldDirection.Ref:
  557. output.Write( "ref " );
  558. break;
  559. }
  560. }
  561. protected virtual void OutputExpressionList( CodeExpressionCollection expressions )
  562. {
  563. OutputExpressionList( expressions, false );
  564. }
  565. protected virtual void OutputExpressionList( CodeExpressionCollection expressions,
  566. bool newLineBetweenItems )
  567. {
  568. IEnumerator enumerator = expressions.GetEnumerator();
  569. if ( enumerator.MoveNext() ) {
  570. CodeExpression expression = (CodeExpression)enumerator.Current;
  571. GenerateExpression( expression );
  572. while ( enumerator.MoveNext() ) {
  573. expression = (CodeExpression)enumerator.Current;
  574. output.Write( ',' );
  575. if ( newLineBetweenItems )
  576. output.WriteLine();
  577. else
  578. output.Write( ' ' );
  579. GenerateExpression( expression );
  580. }
  581. }
  582. }
  583. protected virtual void OutputFieldScopeModifier( MemberAttributes attributes )
  584. {
  585. if ( (attributes & MemberAttributes.VTableMask) == MemberAttributes.New )
  586. output.Write( "new " );
  587. switch ( attributes & MemberAttributes.ScopeMask ) {
  588. case MemberAttributes.Static:
  589. output.Write( "static " );
  590. break;
  591. case MemberAttributes.Const:
  592. output.Write( "const " );
  593. break;
  594. }
  595. }
  596. protected virtual void OutputIdentifier( string ident )
  597. {
  598. }
  599. protected virtual void OutputMemberAccessModifier( MemberAttributes attributes )
  600. {
  601. switch ( attributes & MemberAttributes.AccessMask ) {
  602. case MemberAttributes.Assembly:
  603. output.Write( "internal " );
  604. break;
  605. case MemberAttributes.FamilyAndAssembly:
  606. output.Write( "/* FamAndAssem */ internal " );
  607. break;
  608. case MemberAttributes.Family:
  609. output.Write( "protected " );
  610. break;
  611. case MemberAttributes.FamilyOrAssembly:
  612. output.Write( "protected internal " );
  613. break;
  614. case MemberAttributes.Private:
  615. output.Write( "private " );
  616. break;
  617. case MemberAttributes.Public:
  618. output.Write( "public " );
  619. break;
  620. }
  621. }
  622. protected virtual void OutputMemberScopeModifier( MemberAttributes attributes )
  623. {
  624. if ( (attributes & MemberAttributes.VTableMask) == MemberAttributes.New )
  625. output.Write( "new " );
  626. switch ( attributes & MemberAttributes.ScopeMask ) {
  627. case MemberAttributes.Abstract:
  628. output.Write( "abstract " );
  629. break;
  630. case MemberAttributes.Final:
  631. output.Write( "sealed " );
  632. break;
  633. case MemberAttributes.Static:
  634. output.Write( "static " );
  635. break;
  636. case MemberAttributes.Override:
  637. output.Write( "override " );
  638. break;
  639. default:
  640. //
  641. // FUNNY! if the scope value is
  642. // rubbish (0 or >Const), and access
  643. // is public or protected, make it
  644. // "virtual".
  645. //
  646. // i'm not sure whether this is 100%
  647. // correct, but it seems to be MS
  648. // behavior.
  649. //
  650. MemberAttributes access = attributes & MemberAttributes.AccessMask;
  651. if ( access == MemberAttributes.Public ||
  652. access == MemberAttributes.Family )
  653. output.Write( "virtual " );
  654. break;
  655. }
  656. }
  657. protected virtual void OutputOperator( CodeBinaryOperatorType op )
  658. {
  659. }
  660. protected virtual void OutputParameters( CodeParameterDeclarationExpressionCollection parameters )
  661. {
  662. }
  663. protected abstract void OutputType( CodeTypeReference t );
  664. protected virtual void OutputTypeAttributes( TypeAttributes attributes,
  665. bool isStruct,
  666. bool isEnum )
  667. {
  668. switch ( attributes & TypeAttributes.VisibilityMask ) {
  669. case TypeAttributes.NotPublic:
  670. // private by default
  671. break;
  672. case TypeAttributes.Public:
  673. case TypeAttributes.NestedPublic:
  674. output.Write( "public " );
  675. break;
  676. case TypeAttributes.NestedPrivate:
  677. output.Write( "private " );
  678. break;
  679. }
  680. if ( isStruct )
  681. output.Write( "struct " );
  682. else if ( isEnum )
  683. output.Write( "enum " );
  684. else {
  685. if ( (attributes & TypeAttributes.Interface) != 0 )
  686. output.Write( "interface " );
  687. else {
  688. if ( (attributes & TypeAttributes.Sealed) != 0 )
  689. output.Write( "sealed " );
  690. if ( (attributes & TypeAttributes.Abstract) != 0 )
  691. output.Write( "abstract " );
  692. output.Write( "class " );
  693. }
  694. }
  695. }
  696. protected virtual void OutputTypeNamePair( CodeTypeReference type,
  697. string name )
  698. {
  699. OutputType( type );
  700. output.Write( ' ' );
  701. output.Write( name );
  702. }
  703. protected abstract string QuoteSnippetString( string value );
  704. /*
  705. * ICodeGenerator
  706. */
  707. protected abstract string CreateEscapedIdentifier( string value );
  708. string ICodeGenerator.CreateEscapedIdentifier( string value )
  709. {
  710. return CreateEscapedIdentifier( value );
  711. }
  712. protected abstract string CreateValidIdentifier( string value );
  713. string ICodeGenerator.CreateValidIdentifier( string value )
  714. {
  715. return CreateValidIdentifier( value );
  716. }
  717. private void InitOutput( TextWriter output, CodeGeneratorOptions options )
  718. {
  719. if ( options == null )
  720. options = new CodeGeneratorOptions();
  721. this.output = new IndentedTextWriter( output, options.IndentString );
  722. this.options = options;
  723. }
  724. public virtual void GenerateCodeFromCompileUnit( CodeCompileUnit compileUnit,
  725. TextWriter output,
  726. CodeGeneratorOptions options )
  727. {
  728. InitOutput( output, options );
  729. GenerateCompileUnit( compileUnit );
  730. }
  731. [MonoTODO]
  732. public virtual void GenerateCodeFromExpression( CodeExpression expression,
  733. TextWriter output,
  734. CodeGeneratorOptions options )
  735. {
  736. InitOutput( output, options );
  737. }
  738. public virtual void GenerateCodeFromNamespace( CodeNamespace ns,
  739. TextWriter output,
  740. CodeGeneratorOptions options )
  741. {
  742. InitOutput( output, options );
  743. GenerateNamespace( ns );
  744. }
  745. public virtual void GenerateCodeFromStatement( CodeStatement statement,
  746. TextWriter output,
  747. CodeGeneratorOptions options )
  748. {
  749. InitOutput( output, options );
  750. }
  751. public virtual void GenerateCodeFromType( CodeTypeDeclaration type,
  752. TextWriter output,
  753. CodeGeneratorOptions options )
  754. {
  755. CodeTypeDeclaration prevType = this.currentType;
  756. this.currentType = type;
  757. InitOutput( output, options );
  758. GenerateTypeStart( type );
  759. foreach ( CodeTypeMember member in type.Members ) {
  760. CodeTypeMember prevMember = this.currentMember;
  761. this.currentMember = member;
  762. if ( options.BlankLinesBetweenMembers )
  763. output.WriteLine();
  764. CodeMemberEvent eventm = member as CodeMemberEvent;
  765. if ( eventm != null ) {
  766. GenerateEvent( eventm, type );
  767. continue;
  768. }
  769. CodeMemberField field = member as CodeMemberField;
  770. if ( field != null ) {
  771. GenerateField( field );
  772. continue;
  773. }
  774. CodeEntryPointMethod epmethod = member as CodeEntryPointMethod;
  775. if ( epmethod != null ) {
  776. GenerateEntryPointMethod( epmethod, type );
  777. continue;
  778. }
  779. CodeTypeConstructor typeCtor = member as CodeTypeConstructor;
  780. if (typeCtor != null) {
  781. GenerateTypeConstructor (typeCtor);
  782. continue;
  783. }
  784. CodeConstructor ctor = member as CodeConstructor;
  785. if (ctor != null) {
  786. GenerateConstructor (ctor, type);
  787. continue;
  788. }
  789. CodeMemberMethod method = member as CodeMemberMethod;
  790. if ( method != null ) {
  791. GenerateMethod( method, type );
  792. continue;
  793. }
  794. CodeMemberProperty property = member as CodeMemberProperty;
  795. if ( property != null ) {
  796. GenerateProperty( property, type );
  797. continue;
  798. }
  799. CodeSnippetTypeMember snippet = member as CodeSnippetTypeMember;
  800. if ( snippet != null ) {
  801. GenerateSnippetMember( snippet );
  802. continue;
  803. }
  804. CodeTypeDeclaration subtype = member as CodeTypeDeclaration;
  805. if ( subtype != null ) {
  806. GenerateCodeFromType( subtype, output, options );
  807. continue;
  808. }
  809. this.currentMember = prevMember;
  810. }
  811. GenerateTypeEnd( type );
  812. this.currentType = prevType;
  813. }
  814. protected abstract string GetTypeOutput( CodeTypeReference type );
  815. string ICodeGenerator.GetTypeOutput( CodeTypeReference type )
  816. {
  817. return GetTypeOutput( type );
  818. }
  819. protected abstract bool IsValidIdentifier( string value );
  820. bool ICodeGenerator.IsValidIdentifier( string value )
  821. {
  822. return IsValidIdentifier( value );
  823. }
  824. protected abstract bool Supports( GeneratorSupport supports );
  825. bool ICodeGenerator.Supports( GeneratorSupport value )
  826. {
  827. return Supports( value );
  828. }
  829. [MonoTODO]
  830. protected virtual void ValidateIdentifier( string value )
  831. {
  832. throw new NotImplementedException();
  833. }
  834. void ICodeGenerator.ValidateIdentifier( string value )
  835. {
  836. ValidateIdentifier( value );
  837. }
  838. }
  839. }