Merge pull request #1691 from esdrubal/exitevent
[mono.git] / mcs / class / System / Test / System.CodeDom.Compiler / CodeGeneratorGenerateFromCompileUnitTest.cs
1 //
2 // CodeGenerator.GenerateFromCompileUnit Tests
3 //
4 // Authors:
5 // Ilker Cetinkaya (mail@ilker.de)
6 //
7 // This is a specific test for an issue on GenerateFromCompileUnit.
8 // Up until 2012 (version 2.10.n) the method emits attribute first
9 // and imports afterwards on global namespace scope. Example:
10 //
11 // ~~~~
12 // [assembly: AssemblyVersion("1.0")]
13 // using System.Reflection;
14 // ~~~~
15 //
16 // This in particular causes compiler to bail with CS1529.
17 // Albeit well aware that this is a _language specific_ issue
18 // (or requirement), the actual fix is aimed on CodeGenerator since
19 // the wrong emit order is as well in GenerateFromCompileUnit of abstract
20 // base. The probability to harm any other language generators
21 // is very low. It's near common sense to have imports on top
22 // on global namespace / file level.
23 //
24 // The test is being repeated for the internal `CSharpCodeGenerator`.
25 // See `Microsoft.CSharp` (Mono.CSharp namespace) for details.
26 //
27 // This test verifies the issue as well as describes correct expectation.
28
29 using System;
30 using System.CodeDom;
31 using System.CodeDom.Compiler;
32 using Microsoft.CSharp;
33 using System.IO;
34
35 using NUnit.Framework;
36
37 namespace MonoTests.System.CodeDom.Compiler
38 {
39         [TestFixture]
40         public class CodeGeneratorGenerateFromCompileUnitTest {
41                 [Test]
42                 [Ignore ("This test is wrong; on .NET, ATTRIBUTE is not written and this attributePosition is always < 0.")]
43                 public void When_Having_AssemblyAttribute_And_Using_Namespace_It_Should_Generate_Namespace_First_And_Attribute_Afterwards () {
44                         ICodeGenerator generator = new SampleCodeGenerator ();
45                         var compileUnit = ACompileUnitWithAttributeAndNamespace ();
46                         var writer = new StringWriter ();
47                         var options = new CodeGeneratorOptions ();
48
49                         generator.GenerateCodeFromCompileUnit (compileUnit, writer, options);
50
51                         string result = writer.ToString ();
52                         
53                         int importPosition = result.IndexOf (IMPORT);
54                         int attributePosition = result.IndexOf (ATTRIBUTE);
55
56                         Assert.Greater (attributePosition, importPosition, "Actual order: " + result);
57                 }
58
59                 [Test]
60                 public void CodeSnippetBlankLines ()
61                 {
62                         var opt = new CodeGeneratorOptions () {
63                                 BlankLinesBetweenMembers = false,
64                                 VerbatimOrder = false
65                         };
66
67                         var ccu = new CodeCompileUnit ();
68                         var ns = new CodeNamespace ("Foo");
69                         ccu.Namespaces.Add (ns);
70                         var t = new CodeTypeDeclaration ("Bar");
71                         ns.Types.Add (t);
72
73                         t.Members.Add (new CodeSnippetTypeMember ("#line hidden"));
74                         t.Members.Add (new CodeSnippetTypeMember ("#line hidden2"));
75         
76                         t.Members.Add (new CodeMemberMethod () { Name = "Foo" });
77
78                         using (var sw = new StringWriter ()) {
79                                 new CSharpCodeProvider ().GenerateCodeFromCompileUnit (ccu, sw, opt);
80                                 var str = sw.ToString ();
81
82                                 Assert.IsFalse (str.Contains ("hidden2private"), "#0");
83                                 Assert.IsTrue (str.Contains( "#line hidden#line hidden2"), "#1");
84                         }
85                 }
86
87                 [Test]
88                 public void CodeSnippetBlankLinesVerbatimOrder ()
89                 {
90                         var opt = new CodeGeneratorOptions () {
91                                 BlankLinesBetweenMembers = false,
92                                 VerbatimOrder = true
93                         };
94
95                         var ccu = new CodeCompileUnit ();
96                         var ns = new CodeNamespace ("Foo");
97                         ccu.Namespaces.Add (ns);
98                         var t = new CodeTypeDeclaration ("Bar");
99                         ns.Types.Add (t);
100
101                         t.Members.Add (new CodeSnippetTypeMember ("#line hidden"));
102                         t.Members.Add (new CodeSnippetTypeMember ("#line hidden2"));
103         
104                         t.Members.Add (new CodeMemberMethod () { Name = "Foo" });
105
106                         using (var sw = new StringWriter ()) {
107                                 new CSharpCodeProvider ().GenerateCodeFromCompileUnit (ccu, sw, opt);
108                                 var str = sw.ToString ();
109
110                                 Assert.IsFalse (str.Contains ("hidden2private"), "#0");
111                                 Assert.IsFalse (str.Contains( "#line hidden#line hidden2"), "#1");
112                                 Assert.IsTrue (str.Contains( "#line hidden" + Environment.NewLine), "#2");
113                                 Assert.IsTrue (str.Contains( "#line hidden2" + Environment.NewLine), "#3");
114                         }
115                 }
116
117                 private const string ATTRIBUTE = "ATTRIBUTE";
118                 private const string IMPORT = "IMPORT";
119
120                 private CodeCompileUnit ACompileUnitWithAttributeAndNamespace () {
121                         var compileUnit = new CodeCompileUnit ();
122                         var importNs = new CodeNamespace ();
123
124                         importNs.Imports.Add (new CodeNamespaceImport (IMPORT));
125
126                         compileUnit.AssemblyCustomAttributes.Add (new CodeAttributeDeclaration (ATTRIBUTE));
127                         compileUnit.Namespaces.Add (importNs);
128
129                         return compileUnit;
130                 }
131
132                 private class SampleCodeGenerator : CodeGenerator {
133                         /* test overrides */
134                         protected override void GenerateAttributeDeclarationsStart (CodeAttributeDeclarationCollection attributes) { Output.Write ("ATTRIBUTE"); }
135                         protected override void GenerateAttributeDeclarationsEnd (CodeAttributeDeclarationCollection attributes) {}
136                         protected override void GenerateNamespaceImport (CodeNamespaceImport i) { Output.Write ("IMPORT"); }
137                         /* must overrides */
138                         protected override string NullToken { get { return string.Empty; } }
139                         protected override void GenerateArgumentReferenceExpression (CodeArgumentReferenceExpression e) {}
140                         protected override void GenerateArrayCreateExpression (CodeArrayCreateExpression e) {}
141                         protected override void GenerateArrayIndexerExpression (CodeArrayIndexerExpression e) {}
142                         protected override void GenerateAssignStatement (CodeAssignStatement s) {}
143                         protected override void GenerateAttachEventStatement (CodeAttachEventStatement s) {}
144                         protected override void GenerateBaseReferenceExpression (CodeBaseReferenceExpression e) {}
145                         protected override void GenerateCastExpression (CodeCastExpression e) {}
146                         protected override void GenerateComment (CodeComment comment) {}
147                         protected override void GenerateConditionStatement (CodeConditionStatement s) {}
148                         protected override void GenerateConstructor (CodeConstructor x, CodeTypeDeclaration d) {}
149                         protected override void GenerateDelegateCreateExpression (CodeDelegateCreateExpression e) {}
150                         protected override void GenerateDelegateInvokeExpression (CodeDelegateInvokeExpression e) {}
151                         protected override void GenerateEntryPointMethod (CodeEntryPointMethod m, CodeTypeDeclaration d) {}
152                         protected override void GenerateEvent (CodeMemberEvent ev, CodeTypeDeclaration d) {}
153                         protected override void GenerateEventReferenceExpression (CodeEventReferenceExpression e) {}
154                         protected override void GenerateExpressionStatement (CodeExpressionStatement statement) {}
155                         protected override void GenerateField (CodeMemberField f) {}
156                         protected override void GenerateFieldReferenceExpression (CodeFieldReferenceExpression e) {}
157                         protected override void GenerateGotoStatement (CodeGotoStatement statement) {}
158                         protected override void GenerateIndexerExpression (CodeIndexerExpression e) {}
159                         protected override void GenerateIterationStatement (CodeIterationStatement s) {}
160                         protected override void GenerateLabeledStatement (CodeLabeledStatement statement) {}
161                         protected override void GenerateLinePragmaStart (CodeLinePragma p) {}
162                         protected override void GenerateLinePragmaEnd (CodeLinePragma p) {}
163                         protected override void GenerateMethod (CodeMemberMethod m, CodeTypeDeclaration d) {}
164                         protected override void GenerateMethodInvokeExpression (CodeMethodInvokeExpression e) {}
165                         protected override void GenerateMethodReferenceExpression (CodeMethodReferenceExpression e) {}
166                         protected override void GenerateMethodReturnStatement (CodeMethodReturnStatement e) {}
167                         protected override void GenerateNamespaceStart (CodeNamespace ns) {}
168                         protected override void GenerateNamespaceEnd (CodeNamespace ns) {}
169                         protected override void GenerateObjectCreateExpression (CodeObjectCreateExpression e) {}
170                         protected override void GenerateProperty (CodeMemberProperty p, CodeTypeDeclaration d) {}
171                         protected override void GeneratePropertyReferenceExpression (CodePropertyReferenceExpression e) {}
172                         protected override void GeneratePropertySetValueReferenceExpression (CodePropertySetValueReferenceExpression e) {}
173                         protected override void GenerateRemoveEventStatement (CodeRemoveEventStatement statement) {}
174                         protected override void GenerateSnippetExpression (CodeSnippetExpression e) {}
175                         protected override void GenerateSnippetMember (CodeSnippetTypeMember m) {}
176                         protected override void GenerateThisReferenceExpression (CodeThisReferenceExpression e) {}
177                         protected override void GenerateThrowExceptionStatement (CodeThrowExceptionStatement s) {}
178                         protected override void GenerateTryCatchFinallyStatement (CodeTryCatchFinallyStatement s) {}
179                         protected override void GenerateTypeEnd (CodeTypeDeclaration declaration) {}
180                         protected override void GenerateTypeConstructor (CodeTypeConstructor constructor) {}
181                         protected override void GenerateTypeStart (CodeTypeDeclaration declaration) {}
182                         protected override void GenerateVariableDeclarationStatement (CodeVariableDeclarationStatement e) {}
183                         protected override void GenerateVariableReferenceExpression (CodeVariableReferenceExpression e) {}
184                         protected override void OutputType (CodeTypeReference t) {}
185                         protected override string QuoteSnippetString (string value) { return string.Empty; }
186                         protected override string CreateEscapedIdentifier (string value) { return string.Empty; }
187                         protected override string CreateValidIdentifier (string value) { return string.Empty; }
188                         protected override string GetTypeOutput (CodeTypeReference type) { return string.Empty; }
189                         protected override bool IsValidIdentifier (string value) { return false; }
190                         protected override bool Supports (GeneratorSupport supports) { return false; }
191                 }
192         }
193 }