PageRenderTime 28ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs

https://gitlab.com/N3X15/ILSpy
C# | 337 lines | 298 code | 22 blank | 17 comment | 0 complexity | 4a0447c1188684bae632389844ddb9d7 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  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 ICSharpCode.NRefactory.Semantics;
  20. using ICSharpCode.NRefactory.TypeSystem;
  21. using NUnit.Framework;
  22. namespace ICSharpCode.NRefactory.CSharp.Resolver
  23. {
  24. [TestFixture]
  25. public class LinqTests : ResolverTestBase
  26. {
  27. [Test]
  28. public void SimpleLinq()
  29. {
  30. string program = @"using System; using System.Linq;
  31. class TestClass {
  32. void Test(string[] input) {
  33. var r = from e in input
  34. where e.StartsWith(""/"")
  35. select e.Trim();
  36. r.ToString();
  37. }
  38. }
  39. ";
  40. LocalResolveResult lrr = Resolve<LocalResolveResult>(program.Replace("where e", "where $e$"));
  41. Assert.AreEqual("System.String", lrr.Type.ReflectionName);
  42. lrr = Resolve<LocalResolveResult>(program.Replace("select e", "select $e$"));
  43. Assert.AreEqual("System.String", lrr.Type.ReflectionName);
  44. lrr = Resolve<LocalResolveResult>(program.Replace("from e", "from $e$"));
  45. Assert.AreEqual("System.String", lrr.Type.ReflectionName);
  46. lrr = Resolve<LocalResolveResult>(program.Replace("r.ToString", "$r$.ToString"));
  47. Assert.AreEqual("System.Collections.Generic.IEnumerable", lrr.Type.FullName);
  48. Assert.AreEqual("System.String", ((ParameterizedType)lrr.Type).TypeArguments[0].FullName);
  49. }
  50. [Test]
  51. public void Group()
  52. {
  53. string program = @"using System; using System.Linq;
  54. class TestClass {
  55. void Test(string[] input) {
  56. var r = from e in input
  57. group e.ToUpper() by e.Length;
  58. $r$.ToString();
  59. }
  60. }
  61. ";
  62. LocalResolveResult lrr = Resolve<LocalResolveResult>(program);
  63. Assert.AreEqual("System.Collections.Generic.IEnumerable", lrr.Type.FullName);
  64. ParameterizedType rt = (ParameterizedType)((ParameterizedType)lrr.Type).TypeArguments[0];
  65. Assert.AreEqual("System.Linq.IGrouping", rt.FullName);
  66. Assert.AreEqual("System.Int32", rt.TypeArguments[0].FullName);
  67. Assert.AreEqual("System.String", rt.TypeArguments[1].FullName);
  68. }
  69. [Test]
  70. public void QueryableGroup()
  71. {
  72. string program = @"using System; using System.Linq;
  73. class TestClass {
  74. void Test(IQueryable<string> input) {
  75. var r = from e in input
  76. group e.ToUpper() by e.Length;
  77. $r$.ToString();
  78. }
  79. }
  80. ";
  81. LocalResolveResult lrr = Resolve<LocalResolveResult>(program);
  82. Assert.AreEqual("System.Linq.IQueryable", lrr.Type.FullName);
  83. ParameterizedType rt = (ParameterizedType)((ParameterizedType)lrr.Type).TypeArguments[0];
  84. Assert.AreEqual("System.Linq.IGrouping", rt.FullName);
  85. Assert.AreEqual("System.Int32", rt.TypeArguments[0].FullName);
  86. Assert.AreEqual("System.String", rt.TypeArguments[1].FullName);
  87. }
  88. [Test]
  89. public void Parenthesized()
  90. {
  91. string program = @"using System; using System.Linq;
  92. class TestClass {
  93. void Test(string[] input) {
  94. $(from e in input select e.Length)$.ToArray();
  95. }
  96. }
  97. ";
  98. var rr = Resolve<CSharpInvocationResolveResult>(program);
  99. Assert.AreEqual("System.Linq.Enumerable.Select", rr.Member.FullName);
  100. Assert.AreEqual("System.Collections.Generic.IEnumerable", rr.Type.FullName);
  101. Assert.AreEqual("System.Int32", ((ParameterizedType)rr.Type).TypeArguments[0].FullName);
  102. }
  103. [Test]
  104. public void SelectReturnType()
  105. {
  106. string program = @"using System;
  107. class TestClass { static void M() {
  108. $(from a in new XYZ() select a.ToUpper())$.ToString();
  109. }}
  110. class XYZ {
  111. public int Select<U>(Func<string, U> f) { return 42; }
  112. }";
  113. var rr = Resolve<CSharpInvocationResolveResult>(program);
  114. Assert.AreEqual("XYZ.Select", rr.Member.FullName);
  115. Assert.AreEqual("System.Int32", rr.Type.FullName);
  116. }
  117. [Test]
  118. public void Continuation()
  119. {
  120. string program = @"using System; using System.Linq;
  121. class TestClass {
  122. void Test(string[] input) {
  123. var r = from x in input
  124. select x.GetHashCode() into x
  125. where x == 42
  126. select x * x;
  127. r.ToString();
  128. }
  129. }
  130. ";
  131. LocalResolveResult lrr = Resolve<LocalResolveResult>(program.Replace("from x", "from $x$"));
  132. Assert.AreEqual("System.String", lrr.Type.ReflectionName);
  133. lrr = Resolve<LocalResolveResult>(program.Replace("select x.G", "select $x$.G"));
  134. Assert.AreEqual("System.String", lrr.Type.ReflectionName);
  135. lrr = Resolve<LocalResolveResult>(program.Replace("into x", "into $x$"));
  136. Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
  137. lrr = Resolve<LocalResolveResult>(program.Replace("where x", "where $x$"));
  138. Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
  139. lrr = Resolve<LocalResolveResult>(program.Replace("select x * x", "select x * $x$"));
  140. Assert.AreEqual("System.Int32", lrr.Type.ReflectionName);
  141. lrr = Resolve<LocalResolveResult>(program.Replace("r.ToString", "$r$.ToString"));
  142. Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.Int32]]", lrr.Type.ReflectionName);
  143. }
  144. [Test]
  145. public void OrderingWithSelectCall()
  146. {
  147. string program = @"using System; using System.Linq;
  148. class TestClass {
  149. void Test(string[] input) {
  150. $var$ r = from x in input
  151. orderby x.Length
  152. select x + x;
  153. }
  154. }
  155. ";
  156. TypeResolveResult rr = Resolve<TypeResolveResult>(program);
  157. Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", rr.Type.ReflectionName);
  158. }
  159. [Test]
  160. public void OrderingWithoutSelectCall()
  161. {
  162. string program = @"using System; using System.Linq;
  163. class TestClass {
  164. void Test(string[] input) {
  165. $var$ r = from x in input
  166. orderby x.Length
  167. select x;
  168. }
  169. }
  170. ";
  171. TypeResolveResult rr = Resolve<TypeResolveResult>(program);
  172. Assert.AreEqual("System.Linq.IOrderedEnumerable`1[[System.String]]", rr.Type.ReflectionName);
  173. }
  174. [Test]
  175. public void OrderingWithSelectCallDueToSecondRangeVariable1()
  176. {
  177. string program = @"using System; using System.Linq;
  178. class TestClass {
  179. void Test(string[] input) {
  180. $var$ r = from x in input
  181. from y in input
  182. orderby x.Length
  183. select x;
  184. }
  185. }
  186. ";
  187. TypeResolveResult rr = Resolve<TypeResolveResult>(program);
  188. Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", rr.Type.ReflectionName);
  189. }
  190. [Test]
  191. public void OrderingWithSelectCallDueToSecondRangeVariable2()
  192. {
  193. string program = @"using System; using System.Linq;
  194. class TestClass {
  195. void Test(string[] input) {
  196. $var$ r = from x in input
  197. join y in input on x equals y
  198. orderby x.Length
  199. select x;
  200. }
  201. }
  202. ";
  203. TypeResolveResult rr = Resolve<TypeResolveResult>(program);
  204. Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", rr.Type.ReflectionName);
  205. }
  206. [Test]
  207. public void OrderingWithSelectCallDueToSecondRangeVariable3()
  208. {
  209. string program = @"using System; using System.Linq;
  210. class TestClass {
  211. void Test(string[] input) {
  212. $var$ r = from x in input
  213. join y in input on x equals y into g
  214. orderby x.Length
  215. select x;
  216. }
  217. }
  218. ";
  219. TypeResolveResult rr = Resolve<TypeResolveResult>(program);
  220. Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", rr.Type.ReflectionName);
  221. }
  222. [Test]
  223. public void OrderingWithSelectCallDueToSecondRangeVariable4()
  224. {
  225. string program = @"using System; using System.Linq;
  226. class TestClass {
  227. void Test(string[] input) {
  228. $var$ r = from x in input
  229. let y = x
  230. orderby x.Length
  231. select x;
  232. }
  233. }
  234. ";
  235. TypeResolveResult rr = Resolve<TypeResolveResult>(program);
  236. Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", rr.Type.ReflectionName);
  237. }
  238. [Test]
  239. public void DegenerateQuery()
  240. {
  241. string program = @"using System; using System.Linq;
  242. class TestClass {
  243. void Test(string[] input) {
  244. $var$ r = from x in input select x;
  245. }
  246. }
  247. ";
  248. TypeResolveResult rr = Resolve<TypeResolveResult>(program);
  249. Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", rr.Type.ReflectionName);
  250. }
  251. [Test, Ignore("Parser bug (incorrect position), but also resolver bug (handles Select as a separate call when it's combined into the GroupJoin)")]
  252. public void GroupJoinWithCustomMethod()
  253. {
  254. string program = @"using System;
  255. using System.Collections.Generic;
  256. class TestClass { static void M(long [] args) {
  257. var q = (from a in new XYZ() join b in args on a equals b into g select g);
  258. }}
  259. class XYZ {
  260. public XYZ GroupJoin<T, R>(IEnumerable<T> f, Func<string, object> key1, Func<T, object> key2, Func<string, decimal, R> s) { return this; }
  261. public int Select<U>(Func<string, U> f) { return 42; }
  262. }";
  263. var local = Resolve<LocalResolveResult>(program.Replace("into g", "into $g$"));
  264. Assert.AreEqual("System.Decimal", local.Type.FullName);
  265. local = Resolve<LocalResolveResult>(program.Replace("select g", "select $g$"));
  266. Assert.AreEqual("System.Decimal", local.Type.FullName);
  267. var trr = Resolve<TypeResolveResult>(program.Replace("var", "$var$"));
  268. Assert.AreEqual("XYZ", trr.Type.FullName); // because 'Select' is done as part of GroupJoin()
  269. }
  270. [Test]
  271. public void GroupJoinWithOverloadedCustomMethod()
  272. {
  273. string program = @"using System;
  274. using System.Collections.Generic;
  275. class TestClass
  276. {
  277. static void M(string[] args)
  278. {
  279. var q = $(from a in new XYZ() join b in args on a equals b into g select g.ToUpper())$;
  280. }
  281. }
  282. class XYZ
  283. {
  284. public int GroupJoin(IEnumerable<string> f, Func<string, object> key1, Func<string, object> key2, Func<string, int, int> s) { return 0; }
  285. public decimal GroupJoin(IEnumerable<string> f, Func<string, object> key1, Func<string, object> key2, Func<string, string, string> s) { return 0; }
  286. }";
  287. var rr = Resolve<CSharpInvocationResolveResult>(program);
  288. Assert.IsFalse(rr.IsError);
  289. Assert.AreEqual("GroupJoin", rr.Member.Name);
  290. Assert.AreEqual("System.Decimal", rr.Type.FullName);
  291. rr = Resolve<CSharpInvocationResolveResult>(program.Replace("g.ToUpper()", "g.CompareTo(42)"));
  292. Assert.IsFalse(rr.IsError);
  293. Assert.AreEqual("GroupJoin", rr.Member.Name);
  294. Assert.AreEqual("System.Int32", rr.Type.FullName);
  295. }
  296. [Test]
  297. public void GroupWithQueryContinuation()
  298. {
  299. string program = @"using System; using System.Linq;
  300. class TestClass
  301. {
  302. static void M(string[] args)
  303. {
  304. var query =
  305. from w in ""one to three"".Split()
  306. group w by w.Length into g
  307. orderby g.Key descending
  308. select new { g.Key, Count = g.Count(), Avg = g.Average ($w$ => w.Length) };
  309. }
  310. }";
  311. var rr = Resolve<LocalResolveResult>(program);
  312. Assert.AreEqual("System.String", rr.Type.FullName);
  313. }
  314. }
  315. }