/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/AttributeSectionTests.cs

http://github.com/icsharpcode/ILSpy · C# · 261 lines · 219 code · 24 blank · 18 comment · 0 complexity · 1c13232442e0663deacbe3c515aff04e MD5 · raw file

  1. // Copyright (c) AlphaSierraPapa for the SharpDevelop Team
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4. // software and associated documentation files (the "Software"), to deal in the Software
  5. // without restriction, including without limitation the rights to use, copy, modify, merge,
  6. // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7. // to whom the Software is furnished to do so, subject to the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be included in all copies or
  10. // substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  13. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  14. // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
  15. // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  17. // DEALINGS IN THE SOFTWARE.
  18. using System;
  19. using System.IO;
  20. using System.Linq;
  21. using System.Text.RegularExpressions;
  22. using ICSharpCode.NRefactory.PatternMatching;
  23. using ICSharpCode.NRefactory.TypeSystem;
  24. using NUnit.Framework;
  25. namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
  26. {
  27. [TestFixture]
  28. public class AttributeSectionTests
  29. {
  30. [Test]
  31. public void AttributesUsingNamespaceAlias()
  32. {
  33. string program = @"[global::Microsoft.VisualBasic.CompilerServices.DesignerGenerated()]
  34. [someprefix::DesignerGenerated()]
  35. public class Form1 {
  36. }";
  37. TypeDeclaration decl = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(program);
  38. Assert.AreEqual(2, decl.Attributes.Count);
  39. Assert.AreEqual("global::Microsoft.VisualBasic.CompilerServices.DesignerGenerated",
  40. decl.Attributes.First().Attributes.Single().Type.ToString());
  41. Assert.AreEqual("someprefix::DesignerGenerated", decl.Attributes.Last().Attributes.Single().Type.ToString());
  42. }
  43. [Test]
  44. public void AssemblyAttribute()
  45. {
  46. string program = @"[assembly: System.Attribute()]";
  47. AttributeSection decl = ParseUtilCSharp.ParseGlobal<AttributeSection>(program);
  48. Assert.AreEqual(new TextLocation(1, 1), decl.StartLocation);
  49. Assert.AreEqual("assembly", decl.AttributeTarget);
  50. }
  51. [Test]
  52. public void ModuleAttribute()
  53. {
  54. string program = @"[module: System.Attribute()]";
  55. AttributeSection decl = ParseUtilCSharp.ParseGlobal<AttributeSection>(program);
  56. Assert.AreEqual(new TextLocation(1, 1), decl.StartLocation);
  57. Assert.AreEqual("module", decl.AttributeTarget);
  58. }
  59. [Test]
  60. public void TypeAttribute()
  61. {
  62. string program = @"[type: System.Attribute()] class Test {}";
  63. TypeDeclaration type = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(program);
  64. AttributeSection decl = type.Attributes.Single();
  65. Assert.AreEqual(new TextLocation(1, 1), decl.StartLocation);
  66. Assert.AreEqual("type", decl.AttributeTarget);
  67. }
  68. [Test]
  69. public void AttributeWithoutParenthesis()
  70. {
  71. string program = @"[Attr] class Test {}";
  72. TypeDeclaration type = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(program);
  73. var attr = type.Attributes.Single().Attributes.Single();
  74. Assert.IsTrue(attr.GetChildByRole(Roles.LPar).IsNull);
  75. Assert.IsTrue(attr.GetChildByRole(Roles.RPar).IsNull);
  76. }
  77. [Test, Ignore("Parser bug - parenthesis are missing")]
  78. public void AttributeWithEmptyParenthesis()
  79. {
  80. string program = @"[Attr()] class Test {}";
  81. TypeDeclaration type = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(program);
  82. var attr = type.Attributes.Single().Attributes.Single();
  83. Assert.IsFalse(attr.GetChildByRole(Roles.LPar).IsNull);
  84. Assert.IsFalse(attr.GetChildByRole(Roles.RPar).IsNull);
  85. }
  86. [Test]
  87. public void TwoAttributesInSameSection()
  88. {
  89. ParseUtilCSharp.AssertGlobal(
  90. @"[A, B] class Test {}",
  91. new TypeDeclaration {
  92. ClassType = ClassType.Class,
  93. Name = "Test",
  94. Attributes = {
  95. new AttributeSection {
  96. Attributes = {
  97. new Attribute { Type = new SimpleType("A") },
  98. new Attribute { Type = new SimpleType("B") }
  99. }
  100. }}});
  101. }
  102. [Test]
  103. public void TwoAttributesInSameSectionLocations()
  104. {
  105. string program = @"[A, B] class Test {}";
  106. TypeDeclaration type = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(program);
  107. var attributeSection = type.Attributes.Single();
  108. var firstAttribute = attributeSection.Attributes.First();
  109. Assert.AreEqual(2, firstAttribute.StartLocation.Column);
  110. Assert.AreEqual(3, firstAttribute.EndLocation.Column);
  111. var lastAttribute = attributeSection.Attributes.Last();
  112. Assert.AreEqual(5, lastAttribute.StartLocation.Column);
  113. Assert.AreEqual(6, lastAttribute.EndLocation.Column);
  114. Assert.AreEqual(1, attributeSection.StartLocation.Column);
  115. Assert.AreEqual(7, attributeSection.EndLocation.Column);
  116. }
  117. [Test]
  118. public void TwoAttributesWithOptionalCommaInSameSectionLocations()
  119. {
  120. string program = @"[A, B,] class Test {}";
  121. TypeDeclaration type = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(program);
  122. var attributeSection = type.Attributes.Single();
  123. var firstAttribute = attributeSection.Attributes.First();
  124. Assert.AreEqual(2, firstAttribute.StartLocation.Column);
  125. Assert.AreEqual(3, firstAttribute.EndLocation.Column);
  126. var lastAttribute = attributeSection.Attributes.Last();
  127. Assert.AreEqual(5, lastAttribute.StartLocation.Column);
  128. Assert.AreEqual(6, lastAttribute.EndLocation.Column);
  129. Assert.AreEqual(1, attributeSection.StartLocation.Column);
  130. Assert.AreEqual(8, attributeSection.EndLocation.Column);
  131. }
  132. [Test]
  133. public void AttributesOnTypeParameter()
  134. {
  135. ParseUtilCSharp.AssertGlobal(
  136. "class Test<[A,B]C> {}",
  137. new TypeDeclaration {
  138. ClassType = ClassType.Class,
  139. Name = "Test",
  140. TypeParameters = {
  141. new TypeParameterDeclaration {
  142. Attributes = {
  143. new AttributeSection {
  144. Attributes = {
  145. new Attribute { Type = new SimpleType("A") },
  146. new Attribute { Type = new SimpleType("B") }
  147. }
  148. }
  149. },
  150. Name = "C"
  151. }
  152. }});
  153. }
  154. [Test]
  155. public void AttributeOnMethodParameter()
  156. {
  157. ParseUtilCSharp.AssertTypeMember(
  158. "void M([In] int p);",
  159. new MethodDeclaration {
  160. ReturnType = new PrimitiveType("void"),
  161. Name = "M",
  162. Parameters = {
  163. new ParameterDeclaration {
  164. Attributes = { new AttributeSection(new Attribute { Type = new SimpleType("In") }) },
  165. Type = new PrimitiveType("int"),
  166. Name = "p"
  167. }
  168. }});
  169. }
  170. [Test]
  171. public void AttributeOnSetterValue()
  172. {
  173. ParseUtilCSharp.AssertTypeMember(
  174. "int P { get; [param: In] set; }",
  175. new PropertyDeclaration {
  176. ReturnType = new PrimitiveType("int"),
  177. Name = "P",
  178. Getter = new Accessor(),
  179. Setter = new Accessor {
  180. Attributes = {
  181. new AttributeSection {
  182. AttributeTarget = "param",
  183. Attributes = { new Attribute { Type = new SimpleType("In") } },
  184. } },
  185. }});
  186. }
  187. // TODO: Tests for other contexts where attributes can appear
  188. [Test]
  189. public void AttributeWithNamedArguments ()
  190. {
  191. ParseUtilCSharp.AssertTypeMember (
  192. @"[A(0, a:1, b=2)] class Test {}",
  193. new TypeDeclaration {
  194. ClassType = ClassType.Class,
  195. Name = "Test",
  196. Attributes = {
  197. new AttributeSection {
  198. Attributes = {
  199. new Attribute {
  200. Type = new SimpleType("A"),
  201. Arguments = {
  202. new PrimitiveExpression(0),
  203. new NamedArgumentExpression("a", new PrimitiveExpression(1)),
  204. new NamedExpression("b", new PrimitiveExpression(2))
  205. }
  206. }
  207. }
  208. }
  209. }});
  210. }
  211. [Ignore("Fixme!")]
  212. [Test]
  213. public void AssemblyAttributeBeforeNamespace()
  214. {
  215. var syntaxTree = SyntaxTree.Parse("using System; [assembly: Attr] namespace X {}");
  216. Assert.AreEqual(
  217. new Type[] {
  218. typeof(UsingDeclaration),
  219. typeof(AttributeSection),
  220. typeof(NamespaceDeclaration)
  221. }, syntaxTree.Children.Select(c => c.GetType()).ToArray());
  222. }
  223. [Ignore("Fixme!")]
  224. [Test]
  225. public void AssemblyAttributeBeforeClass()
  226. {
  227. var syntaxTree = SyntaxTree.Parse("using System; [assembly: Attr] class X {}");
  228. Assert.AreEqual(
  229. new Type[] {
  230. typeof(UsingDeclaration),
  231. typeof(AttributeSection),
  232. typeof(TypeDeclaration)
  233. }, syntaxTree.Children.Select(c => c.GetType()).ToArray());
  234. Assert.That(((TypeDeclaration)syntaxTree.LastChild).Attributes, Is.Empty);
  235. }
  236. }
  237. }