PageRenderTime 60ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

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

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