PageRenderTime 55ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/CSharpFactoryVS2010/CSharpTreeBuilderTest/CSharpSemanticGraphBuilder/TypeResolutionTest.cs

#
C# | 2727 lines | 1888 code | 301 blank | 538 comment | 3 complexity | 5a952e316211ba313b425e7aa8124f4f MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. using System.Linq;
  2. using System.Reflection;
  3. using CSharpTreeBuilder.CSharpSemanticGraph;
  4. using CSharpTreeBuilder.CSharpSemanticGraphBuilder;
  5. using CSharpTreeBuilder.ProjectContent;
  6. using Microsoft.VisualStudio.TestTools.UnitTesting;
  7. using SoftwareApproach.TestingExtensions;
  8. namespace CSharpTreeBuilderTest.CSharpSemanticGraphBuilder
  9. {
  10. // ================================================================================================
  11. /// <summary>
  12. /// Tests the type resolution logic.
  13. /// </summary>
  14. // ================================================================================================
  15. [TestClass]
  16. public class TypeResolutionTest : ParserTestBed
  17. {
  18. // ----------------------------------------------------------------------------------------------
  19. /// <summary>
  20. /// No type arguments (§4.4.1) can be present in a namespace-name (only types can have type arguments).
  21. /// </summary>
  22. // ----------------------------------------------------------------------------------------------
  23. [TestMethod]
  24. public void Error_NoTypeArgumentsCanBePresentInANamespaceName()
  25. {
  26. var project = new CSharpProject(WorkingFolder);
  27. project.AddFile(@"TypeResolution\Error_NoTypeArgumentsCanBePresentInANamespaceName.cs");
  28. InvokeParser(project).ShouldBeFalse();
  29. project.Errors.Count.ShouldEqual(1);
  30. project.Errors[0].Code.ShouldEqual("TBD001");
  31. project.Warnings.Count.ShouldEqual(0);
  32. project.SemanticGraph.GlobalNamespace.UsingNamespaces.ToArray()[0].NamespaceReference.ResolutionState.ShouldEqual(ResolutionState.Unresolvable);
  33. }
  34. // ----------------------------------------------------------------------------------------------
  35. /// <summary>
  36. /// Resolving a type to type parameter.
  37. /// </summary>
  38. // ----------------------------------------------------------------------------------------------
  39. [TestMethod]
  40. public void TypeParameter()
  41. {
  42. var project = new CSharpProject(WorkingFolder);
  43. project.AddFile(@"TypeResolution\TypeParameter.cs");
  44. InvokeParser(project).ShouldBeTrue();
  45. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A", 1);
  46. var fieldEntity = classEntity.OwnMembers.ToArray()[0] as FieldEntity;
  47. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  48. fieldEntity.TypeReference.Target.ToString().ShouldEqual("global::A`1.T1");
  49. }
  50. // ----------------------------------------------------------------------------------------------
  51. /// <summary>
  52. /// Resolving types in type parameter constraints.
  53. /// </summary>
  54. // ----------------------------------------------------------------------------------------------
  55. [TestMethod]
  56. public void TypeParameterConstraints()
  57. {
  58. var project = new CSharpProject(WorkingFolder);
  59. project.AddFile(@"TypeResolution\TypeParameterConstraints.cs");
  60. InvokeParser(project).ShouldBeTrue();
  61. var global = project.SemanticGraph.GlobalNamespace;
  62. var classA = global.GetSingleChildType<ClassEntity>("A", 4);
  63. // where T1 : B, T2, I1, I2, T4, new()
  64. {
  65. var typeParameter = classA.GetOwnTypeParameterByName("T1");
  66. typeParameter.ClassTypeConstraint.ToString().ShouldEqual("global::B");
  67. typeParameter.ClassTypeConstraints.Count().ShouldEqual(1);
  68. var interfaceTypes = typeParameter.InterfaceTypeConstraints.ToList();
  69. interfaceTypes.Count().ShouldEqual(2);
  70. interfaceTypes[0].ToString().ShouldEqual("global::I1");
  71. interfaceTypes[1].ToString().ShouldEqual("global::I2`1[global::System.Int32]");
  72. var typeParams = typeParameter.TypeParameterConstraints.ToList();
  73. typeParams.Count().ShouldEqual(2);
  74. typeParams[0].ShouldEqual(classA.GetOwnTypeParameterByName("T2"));
  75. typeParams[1].ShouldEqual(classA.GetOwnTypeParameterByName("T4"));
  76. typeParameter.BaseClass.ToString().ShouldEqual("global::B");
  77. typeParameter.BaseInterfaces.Count.ShouldEqual(2);
  78. var interfaces = typeParameter.BaseInterfaces.OrderBy(x => x.ToString()).ToList();
  79. interfaces[0].ToString().ShouldEqual("global::I1");
  80. interfaces[1].ToString().ShouldEqual("global::I2`1[global::System.Int32]");
  81. }
  82. }
  83. // ----------------------------------------------------------------------------------------------
  84. /// <summary>
  85. /// Test the resolution of single-tag namespace names in using namespace entities.
  86. /// </summary>
  87. // ----------------------------------------------------------------------------------------------
  88. [TestMethod]
  89. public void UsingNamespaceNames_SingleTag()
  90. {
  91. var project = new CSharpProject(WorkingFolder);
  92. project.AddFile(@"TypeResolution\UsingNamespaceNames_SingleTag.cs");
  93. InvokeParser(project).ShouldBeTrue();
  94. var global = project.SemanticGraph.GlobalNamespace;
  95. var namespaceA = global.GetChildNamespace("A");
  96. var namespaceB = namespaceA.GetChildNamespace("B");
  97. // using A;
  98. {
  99. var usingNamespace = global.UsingNamespaces.ToArray()[0];
  100. usingNamespace.NamespaceReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  101. usingNamespace.NamespaceReference.Target.ShouldEqual(namespaceA);
  102. usingNamespace.ImportedNamespace.ShouldEqual(namespaceA);
  103. }
  104. // using B;
  105. {
  106. var usingNamespace = namespaceA.UsingNamespaces.ToArray()[0];
  107. usingNamespace.NamespaceReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  108. usingNamespace.NamespaceReference.Target.ShouldEqual(namespaceB);
  109. usingNamespace.ImportedNamespace.ShouldEqual(namespaceB);
  110. }
  111. }
  112. // ----------------------------------------------------------------------------------------------
  113. /// <summary>
  114. /// Error CS0576: Namespace 'namespace' contains a definition conflicting with alias 'identifier' (using alias)
  115. /// </summary>
  116. // ----------------------------------------------------------------------------------------------
  117. [TestMethod]
  118. public void CS0576_UsingAliasConflictsWithNamespaceDeclaration()
  119. {
  120. var project = new CSharpProject(WorkingFolder);
  121. project.AddFile(@"TypeResolution\CS0576_UsingAliasConflictsWithNamespaceDeclaration.cs");
  122. InvokeParser(project).ShouldBeFalse();
  123. project.Errors.Count.ShouldEqual(1);
  124. project.Errors[0].Code.ShouldEqual("CS0576");
  125. project.Warnings.Count.ShouldEqual(0);
  126. }
  127. // ----------------------------------------------------------------------------------------------
  128. /// <summary>
  129. /// Error CS0576: Namespace 'namespace' contains a definition conflicting with alias 'identifier' (using alias)
  130. /// </summary>
  131. // ----------------------------------------------------------------------------------------------
  132. [TestMethod]
  133. public void CS0576_UsingAliasConflictsWithTypeDeclaration()
  134. {
  135. var project = new CSharpProject(WorkingFolder);
  136. project.AddFile(@"TypeResolution\CS0576_UsingAliasConflictsWithTypeDeclaration.cs");
  137. InvokeParser(project).ShouldBeFalse();
  138. project.Errors.Count.ShouldEqual(1);
  139. project.Errors[0].Code.ShouldEqual("CS0576");
  140. project.Warnings.Count.ShouldEqual(0);
  141. }
  142. // ----------------------------------------------------------------------------------------------
  143. /// <summary>
  144. /// error CS0246: The type or namespace name 'A' could not be found (are you missing a using directive or an assembly reference?)
  145. /// </summary>
  146. // ----------------------------------------------------------------------------------------------
  147. [TestMethod]
  148. public void CS0246_NamespaceNameCouldNotBeFound()
  149. {
  150. var project = new CSharpProject(WorkingFolder);
  151. project.AddFile(@"TypeResolution\CS0246_NamespaceNameCouldNotBeFound.cs");
  152. InvokeParser(project).ShouldBeFalse();
  153. project.Errors.Count.ShouldEqual(1);
  154. project.Errors[0].Code.ShouldEqual("CS0246");
  155. project.Warnings.Count.ShouldEqual(0);
  156. }
  157. // ----------------------------------------------------------------------------------------------
  158. /// <summary>
  159. /// Resolving builtin types.
  160. /// </summary>
  161. // ----------------------------------------------------------------------------------------------
  162. [TestMethod]
  163. public void BuiltInTypes()
  164. {
  165. var project = new CSharpProject(WorkingFolder);
  166. project.AddFile(@"TypeResolution\BuiltInTypes.cs");
  167. InvokeParser(project).ShouldBeTrue();
  168. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A");
  169. int i = 0;
  170. // sbyte a1;
  171. {
  172. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  173. fieldEntity.Name.ShouldEqual("a1");
  174. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  175. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  176. typeEntity.ToString().ShouldEqual("global::System.SByte");
  177. typeEntity.BuiltInTypeValue = BuiltInType.Sbyte;
  178. typeEntity.IsSimpleType.ShouldBeTrue();
  179. typeEntity.IsNumericType.ShouldBeTrue();
  180. typeEntity.IsIntegralType.ShouldBeTrue();
  181. typeEntity.IsFloatingPointType.ShouldBeFalse();
  182. typeEntity.IsNullableType.ShouldBeFalse();
  183. }
  184. // byte a2;
  185. {
  186. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  187. fieldEntity.Name.ShouldEqual("a2");
  188. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  189. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  190. typeEntity.ToString().ShouldEqual("global::System.Byte");
  191. typeEntity.IsSimpleType.ShouldBeTrue();
  192. typeEntity.IsNumericType.ShouldBeTrue();
  193. typeEntity.IsIntegralType.ShouldBeTrue();
  194. typeEntity.IsFloatingPointType.ShouldBeFalse();
  195. typeEntity.IsNullableType.ShouldBeFalse();
  196. }
  197. // short a3;
  198. {
  199. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  200. fieldEntity.Name.ShouldEqual("a3");
  201. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  202. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  203. typeEntity.ToString().ShouldEqual("global::System.Int16");
  204. typeEntity.IsSimpleType.ShouldBeTrue();
  205. typeEntity.IsNumericType.ShouldBeTrue();
  206. typeEntity.IsIntegralType.ShouldBeTrue();
  207. typeEntity.IsFloatingPointType.ShouldBeFalse();
  208. typeEntity.IsNullableType.ShouldBeFalse();
  209. }
  210. // ushort a4;
  211. {
  212. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  213. fieldEntity.Name.ShouldEqual("a4");
  214. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  215. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  216. typeEntity.ToString().ShouldEqual("global::System.UInt16");
  217. typeEntity.IsSimpleType.ShouldBeTrue();
  218. typeEntity.IsNumericType.ShouldBeTrue();
  219. typeEntity.IsIntegralType.ShouldBeTrue();
  220. typeEntity.IsFloatingPointType.ShouldBeFalse();
  221. typeEntity.IsNullableType.ShouldBeFalse();
  222. }
  223. // int a5;
  224. {
  225. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  226. fieldEntity.Name.ShouldEqual("a5");
  227. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  228. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  229. typeEntity.ToString().ShouldEqual("global::System.Int32");
  230. typeEntity.IsSimpleType.ShouldBeTrue();
  231. typeEntity.IsNumericType.ShouldBeTrue();
  232. typeEntity.IsIntegralType.ShouldBeTrue();
  233. typeEntity.IsFloatingPointType.ShouldBeFalse();
  234. typeEntity.IsNullableType.ShouldBeFalse();
  235. }
  236. // uint a6;
  237. {
  238. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  239. fieldEntity.Name.ShouldEqual("a6");
  240. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  241. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  242. typeEntity.ToString().ShouldEqual("global::System.UInt32");
  243. typeEntity.IsSimpleType.ShouldBeTrue();
  244. typeEntity.IsNumericType.ShouldBeTrue();
  245. typeEntity.IsIntegralType.ShouldBeTrue();
  246. typeEntity.IsFloatingPointType.ShouldBeFalse();
  247. typeEntity.IsNullableType.ShouldBeFalse();
  248. }
  249. // long a7;
  250. {
  251. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  252. fieldEntity.Name.ShouldEqual("a7");
  253. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  254. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  255. typeEntity.ToString().ShouldEqual("global::System.Int64");
  256. typeEntity.IsSimpleType.ShouldBeTrue();
  257. typeEntity.IsNumericType.ShouldBeTrue();
  258. typeEntity.IsIntegralType.ShouldBeTrue();
  259. typeEntity.IsFloatingPointType.ShouldBeFalse();
  260. typeEntity.IsNullableType.ShouldBeFalse();
  261. }
  262. // ulong a8;
  263. {
  264. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  265. fieldEntity.Name.ShouldEqual("a8");
  266. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  267. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  268. typeEntity.ToString().ShouldEqual("global::System.UInt64");
  269. typeEntity.IsSimpleType.ShouldBeTrue();
  270. typeEntity.IsNumericType.ShouldBeTrue();
  271. typeEntity.IsIntegralType.ShouldBeTrue();
  272. typeEntity.IsFloatingPointType.ShouldBeFalse();
  273. typeEntity.IsNullableType.ShouldBeFalse();
  274. }
  275. // char a9;
  276. {
  277. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  278. fieldEntity.Name.ShouldEqual("a9");
  279. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  280. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  281. typeEntity.ToString().ShouldEqual("global::System.Char");
  282. typeEntity.IsSimpleType.ShouldBeTrue();
  283. typeEntity.IsNumericType.ShouldBeTrue();
  284. typeEntity.IsIntegralType.ShouldBeTrue();
  285. typeEntity.IsFloatingPointType.ShouldBeFalse();
  286. typeEntity.IsNullableType.ShouldBeFalse();
  287. }
  288. // float a10;
  289. {
  290. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  291. fieldEntity.Name.ShouldEqual("a10");
  292. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  293. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  294. typeEntity.ToString().ShouldEqual("global::System.Single");
  295. typeEntity.IsSimpleType.ShouldBeTrue();
  296. typeEntity.IsNumericType.ShouldBeTrue();
  297. typeEntity.IsIntegralType.ShouldBeFalse();
  298. typeEntity.IsFloatingPointType.ShouldBeTrue();
  299. typeEntity.IsNullableType.ShouldBeFalse();
  300. }
  301. // double a11;
  302. {
  303. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  304. fieldEntity.Name.ShouldEqual("a11");
  305. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  306. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  307. typeEntity.ToString().ShouldEqual("global::System.Double");
  308. typeEntity.IsSimpleType.ShouldBeTrue();
  309. typeEntity.IsNumericType.ShouldBeTrue();
  310. typeEntity.IsIntegralType.ShouldBeFalse();
  311. typeEntity.IsFloatingPointType.ShouldBeTrue();
  312. typeEntity.IsNullableType.ShouldBeFalse();
  313. }
  314. // bool a12;
  315. {
  316. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  317. fieldEntity.Name.ShouldEqual("a12");
  318. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  319. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  320. typeEntity.ToString().ShouldEqual("global::System.Boolean");
  321. typeEntity.IsSimpleType.ShouldBeTrue();
  322. typeEntity.IsNumericType.ShouldBeFalse();
  323. typeEntity.IsIntegralType.ShouldBeFalse();
  324. typeEntity.IsFloatingPointType.ShouldBeFalse();
  325. typeEntity.IsNullableType.ShouldBeFalse();
  326. }
  327. // decimal a13;
  328. {
  329. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  330. fieldEntity.Name.ShouldEqual("a13");
  331. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  332. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  333. typeEntity.ToString().ShouldEqual("global::System.Decimal");
  334. typeEntity.IsSimpleType.ShouldBeTrue();
  335. typeEntity.IsNumericType.ShouldBeTrue();
  336. typeEntity.IsIntegralType.ShouldBeFalse();
  337. typeEntity.IsFloatingPointType.ShouldBeFalse();
  338. typeEntity.IsNullableType.ShouldBeFalse();
  339. }
  340. // object a14;
  341. {
  342. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  343. fieldEntity.Name.ShouldEqual("a14");
  344. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  345. var typeEntity = fieldEntity.TypeReference.Target as ClassEntity;
  346. typeEntity.ToString().ShouldEqual("global::System.Object");
  347. typeEntity.IsSimpleType.ShouldBeFalse();
  348. typeEntity.IsNumericType.ShouldBeFalse();
  349. typeEntity.IsIntegralType.ShouldBeFalse();
  350. typeEntity.IsFloatingPointType.ShouldBeFalse();
  351. typeEntity.IsNullableType.ShouldBeFalse();
  352. }
  353. // string a15;
  354. {
  355. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  356. fieldEntity.Name.ShouldEqual("a15");
  357. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  358. var typeEntity = fieldEntity.TypeReference.Target as ClassEntity;
  359. typeEntity.ToString().ShouldEqual("global::System.String");
  360. typeEntity.IsSimpleType.ShouldBeFalse();
  361. typeEntity.IsNumericType.ShouldBeFalse();
  362. typeEntity.IsIntegralType.ShouldBeFalse();
  363. typeEntity.IsFloatingPointType.ShouldBeFalse();
  364. typeEntity.IsNullableType.ShouldBeFalse();
  365. }
  366. // int? a16;
  367. {
  368. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  369. fieldEntity.Name.ShouldEqual("a16");
  370. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  371. var nullable = fieldEntity.TypeReference.Target as StructEntity;
  372. nullable.ToString().ShouldEqual("global::System.Nullable`1[global::System.Int32]");
  373. nullable.IsSimpleType.ShouldBeFalse();
  374. nullable.IsNumericType.ShouldBeFalse();
  375. nullable.IsIntegralType.ShouldBeFalse();
  376. nullable.IsFloatingPointType.ShouldBeFalse();
  377. nullable.IsNullableType.ShouldBeTrue();
  378. }
  379. // int*[] a17;
  380. {
  381. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  382. fieldEntity.Name.ShouldEqual("a17");
  383. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  384. var array = fieldEntity.TypeReference.Target as ArrayTypeEntity;
  385. var pointer = array.UnderlyingType as PointerTypeEntity;
  386. var typeEntity = pointer.UnderlyingType as StructEntity;
  387. typeEntity.ToString().ShouldEqual("global::System.Int32");
  388. }
  389. // delegate void D();
  390. {
  391. var delegateEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<DelegateEntity>("D");
  392. delegateEntity.Name.ShouldEqual("D");
  393. delegateEntity.ReturnTypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  394. var typeEntity = delegateEntity.ReturnType as StructEntity;
  395. typeEntity.FullyQualifiedName.ShouldEqual("System.Void");
  396. }
  397. }
  398. // ----------------------------------------------------------------------------------------------
  399. /// <summary>
  400. /// Tests the resolution of built-in base types
  401. /// </summary>
  402. // ----------------------------------------------------------------------------------------------
  403. [TestMethod]
  404. public void BuiltInBaseTypes()
  405. {
  406. var project = new CSharpProject(WorkingFolder);
  407. project.AddFile(@"TypeResolution\BuiltInBaseTypes.cs");
  408. InvokeParser(project).ShouldBeTrue();
  409. // class A1 : object
  410. {
  411. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A1");
  412. var baseTypeRef = classEntity.BaseTypeReferences.ToArray()[0];
  413. baseTypeRef.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  414. baseTypeRef.Target.FullyQualifiedName.ShouldEqual("System.Object");
  415. }
  416. }
  417. // ----------------------------------------------------------------------------------------------
  418. /// <summary>
  419. /// Resolving pointer-to-type references.
  420. /// </summary>
  421. // ----------------------------------------------------------------------------------------------
  422. [TestMethod]
  423. public void PointerToType()
  424. {
  425. var project = new CSharpProject(WorkingFolder);
  426. project.AddFile(@"TypeResolution\PointerToType.cs");
  427. InvokeParser(project).ShouldBeTrue();
  428. var underlyingType = project.SemanticGraph.GlobalNamespace.GetSingleChildType<StructEntity>("A2");
  429. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A1");
  430. var fieldEntity = classEntity.OwnMembers.ToArray()[0] as FieldEntity;
  431. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  432. var pointer1 = fieldEntity.TypeReference.Target as PointerTypeEntity;
  433. pointer1.BaseTypeReferences.Count().ShouldEqual(0);
  434. pointer1.OwnMembers.Count().ShouldEqual(0);
  435. pointer1.Name.ShouldEqual("A2");
  436. pointer1.FullyQualifiedName.ShouldEqual("A2");
  437. pointer1.ToString().ShouldEqual("global::A2**");
  438. pointer1.Parent.ShouldEqual(underlyingType.Parent);
  439. pointer1.SyntaxNodes.Count.ShouldEqual(0);
  440. pointer1.IsPointerType.ShouldBeTrue();
  441. pointer1.IsReferenceType.ShouldBeFalse();
  442. pointer1.IsValueType.ShouldBeFalse();
  443. var pointer2 = pointer1.UnderlyingType as PointerTypeEntity;
  444. pointer2.BaseTypeReferences.Count().ShouldEqual(0);
  445. pointer2.OwnMembers.Count().ShouldEqual(0);
  446. pointer2.Name.ShouldEqual("A2");
  447. pointer2.FullyQualifiedName.ShouldEqual("A2");
  448. pointer2.ToString().ShouldEqual("global::A2*");
  449. pointer2.Parent.ShouldEqual(underlyingType.Parent);
  450. pointer2.SyntaxNodes.Count.ShouldEqual(0);
  451. pointer2.UnderlyingType.PointerType.ShouldEqual(pointer2);
  452. underlyingType.PointerType.ShouldEqual(pointer2);
  453. pointer2.PointerType.ShouldEqual(pointer1);
  454. }
  455. // ----------------------------------------------------------------------------------------------
  456. /// <summary>
  457. /// Resolving pointer-to-unknown (void*) references.
  458. /// </summary>
  459. // ----------------------------------------------------------------------------------------------
  460. [TestMethod]
  461. public void PointerToUnknown()
  462. {
  463. var project = new CSharpProject(WorkingFolder);
  464. project.AddFile(@"TypeResolution\PointerToUnknown.cs");
  465. InvokeParser(project).ShouldBeTrue();
  466. {
  467. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A1");
  468. var fieldEntity = classEntity.OwnMembers.ToArray()[0] as FieldEntity;
  469. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  470. var pointer1 = fieldEntity.TypeReference.Target as PointerTypeEntity;
  471. pointer1.BaseTypeReferences.Count().ShouldEqual(0);
  472. pointer1.OwnMembers.Count().ShouldEqual(0);
  473. pointer1.FullyQualifiedName.ShouldEqual("System.Void");
  474. pointer1.ToString().ShouldEqual("global::System.Void*");
  475. pointer1.Name.ShouldEqual("Void");
  476. pointer1.Parent.ToString().ShouldEqual("global::System");
  477. pointer1.SyntaxNodes.Count.ShouldEqual(0);
  478. pointer1.IsPointerType.ShouldBeTrue();
  479. pointer1.IsReferenceType.ShouldBeFalse();
  480. pointer1.IsValueType.ShouldBeFalse();
  481. var underlyingType = pointer1.UnderlyingType as StructEntity;
  482. underlyingType.ToString().ShouldEqual("global::System.Void");
  483. underlyingType.PointerType.ShouldEqual(pointer1);
  484. }
  485. }
  486. // ----------------------------------------------------------------------------------------------
  487. /// <summary>
  488. /// Resolving nullable type references.
  489. /// </summary>
  490. // ----------------------------------------------------------------------------------------------
  491. [TestMethod]
  492. public void NullableType()
  493. {
  494. var project = new CSharpProject(WorkingFolder);
  495. project.AddFile(@"TypeResolution\NullableType.cs");
  496. InvokeParser(project).ShouldBeTrue();
  497. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A1");
  498. var structA2 = project.SemanticGraph.GlobalNamespace.GetSingleChildType<StructEntity>("A2");
  499. // A2? a1;
  500. {
  501. var fieldEntity = classEntity.OwnMembers.ToArray()[0] as FieldEntity;
  502. fieldEntity.Name.ShouldEqual("a1");
  503. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  504. var nullable = fieldEntity.TypeReference.Target;
  505. nullable.Name.ShouldEqual("Nullable");
  506. nullable.FullyQualifiedName.ShouldEqual("System.Nullable");
  507. nullable.ToString().ShouldEqual("global::System.Nullable`1[global::A2]");
  508. nullable.Parent.ToString().ShouldEqual("global::System");
  509. nullable.SyntaxNodes.Count.ShouldEqual(0);
  510. nullable.IsPointerType.ShouldBeFalse();
  511. nullable.IsReferenceType.ShouldBeFalse();
  512. nullable.IsValueType.ShouldBeTrue();
  513. nullable.IsNullableType.ShouldBeTrue();
  514. nullable.UnderlyingOfNullableType.ToString().ShouldEqual("global::A2");
  515. var underlyingType = nullable.DirectGenericTemplate as StructEntity;
  516. underlyingType.FullyQualifiedName.ShouldEqual("System.Nullable");
  517. underlyingType.ToString().ShouldEqual("global::System.Nullable`1");
  518. }
  519. // A2?[] a2;
  520. {
  521. var fieldEntity = classEntity.OwnMembers.ToArray()[1] as FieldEntity;
  522. fieldEntity.Name.ShouldEqual("a2");
  523. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  524. var array = fieldEntity.TypeReference.Target as ArrayTypeEntity;
  525. array.IsNullableType.ShouldBeFalse();
  526. array.UnderlyingOfNullableType.ShouldBeNull();
  527. var nullable = array.UnderlyingType;
  528. nullable.DirectGenericTemplate.ShouldEqual(project.SemanticGraph.NullableGenericTypeDefinition);
  529. nullable.ShouldEqual(classEntity.GetOwnMember<FieldEntity>("a1").Type);
  530. }
  531. }
  532. // ----------------------------------------------------------------------------------------------
  533. /// <summary>
  534. /// Resolving array type references.
  535. /// </summary>
  536. // ----------------------------------------------------------------------------------------------
  537. [TestMethod]
  538. public void ArrayType()
  539. {
  540. var project = new CSharpProject(WorkingFolder);
  541. project.AddFile(@"TypeResolution\ArrayType.cs");
  542. InvokeParser(project).ShouldBeTrue();
  543. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A1");
  544. // A2[][,] a1;
  545. {
  546. var fieldEntity = classEntity.OwnMembers.ToArray()[0] as FieldEntity;
  547. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  548. var array1 = fieldEntity.TypeReference.Target as ArrayTypeEntity;
  549. array1.BaseClass.FullyQualifiedName.ShouldEqual("System.Array");
  550. array1.OwnMembers.Count().ShouldEqual(0);
  551. array1.Name.ShouldEqual("A2");
  552. array1.FullyQualifiedName.ShouldEqual("A2");
  553. array1.ToString().ShouldEqual("global::A2[][,]");
  554. array1.Parent.ShouldEqual(project.SemanticGraph.GlobalNamespace.ChildTypes.ToList()[1].Parent);
  555. array1.Rank.ShouldEqual(2);
  556. array1.SyntaxNodes.Count.ShouldEqual(0);
  557. array1.IsPointerType.ShouldBeFalse();
  558. array1.IsReferenceType.ShouldBeTrue();
  559. array1.IsValueType.ShouldBeFalse();
  560. array1.UnderlyingType.GetArrayTypeByRank(2).ShouldEqual(array1);
  561. var array2 = array1.UnderlyingType as ArrayTypeEntity;
  562. array2.Name.ShouldEqual("A2");
  563. array2.FullyQualifiedName.ShouldEqual("A2");
  564. array2.ToString().ShouldEqual("global::A2[]");
  565. array2.Parent.ShouldEqual(project.SemanticGraph.GlobalNamespace.ChildTypes.ToList()[1].Parent);
  566. array2.Rank.ShouldEqual(1);
  567. array2.SyntaxNodes.Count.ShouldEqual(0);
  568. array2.UnderlyingType.GetArrayTypeByRank(1).ShouldEqual(array2);
  569. }
  570. // A2**[][,] a2;
  571. {
  572. var fieldEntity = classEntity.OwnMembers.ToArray()[1] as FieldEntity;
  573. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  574. var array1 = fieldEntity.TypeReference.Target as ArrayTypeEntity;
  575. array1.ToString().ShouldEqual("global::A2**[][,]");
  576. var array2 = array1.UnderlyingType as ArrayTypeEntity;
  577. array2.ToString().ShouldEqual("global::A2**[]");
  578. var pointer1 = array2.UnderlyingType as PointerTypeEntity;
  579. pointer1.ToString().ShouldEqual("global::A2**");
  580. var pointer2 = pointer1.UnderlyingType as PointerTypeEntity;
  581. pointer2.ToString().ShouldEqual("global::A2*");
  582. var structEntity = pointer2.UnderlyingType as StructEntity;
  583. structEntity.ToString().ShouldEqual("global::A2");
  584. }
  585. }
  586. // ----------------------------------------------------------------------------------------------
  587. /// <summary>
  588. /// Test the resolution of namespace names in using namespace entities.
  589. /// </summary>
  590. // ----------------------------------------------------------------------------------------------
  591. [TestMethod]
  592. public void UsingNamespaceNames_MultiTag()
  593. {
  594. var project = new CSharpProject(WorkingFolder);
  595. project.AddFile(@"TypeResolution\UsingNamespaceNames_MultiTag.cs");
  596. InvokeParser(project).ShouldBeTrue();
  597. project.Errors.Count.ShouldEqual(0);
  598. project.Warnings.Count.ShouldEqual(0);
  599. var global = project.SemanticGraph.GlobalNamespace;
  600. var namespaceA = global.GetChildNamespace("A");
  601. var namespaceB = namespaceA.GetChildNamespace("B");
  602. var namespaceC = namespaceB.GetChildNamespace("C");
  603. // using A.B;
  604. {
  605. var usingNamespace = global.UsingNamespaces.ToArray()[0];
  606. usingNamespace.NamespaceReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  607. usingNamespace.NamespaceReference.Target.ShouldEqual(namespaceB);
  608. usingNamespace.ImportedNamespace.ShouldEqual(namespaceB);
  609. }
  610. // using B.C;
  611. {
  612. var usingNamespace = namespaceA.UsingNamespaces.ToArray()[0];
  613. usingNamespace.NamespaceReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  614. usingNamespace.NamespaceReference.Target.ShouldEqual(namespaceC);
  615. usingNamespace.ImportedNamespace.ShouldEqual(namespaceC);
  616. }
  617. }
  618. // ----------------------------------------------------------------------------------------------
  619. /// <summary>
  620. /// Resolving to type declared in base class.
  621. /// </summary>
  622. // ----------------------------------------------------------------------------------------------
  623. [TestMethod]
  624. public void DeclaredInBaseClass()
  625. {
  626. var project = new CSharpProject(WorkingFolder);
  627. project.AddFile(@"TypeResolution\DeclaredInBaseClass.cs");
  628. InvokeParser(project).ShouldBeTrue();
  629. int i = 0;
  630. var classA = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A");
  631. // E x1;
  632. {
  633. var field = classA.OwnMembers.ToArray()[i++] as FieldEntity;
  634. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  635. field.TypeReference.Target.ToString().ShouldEqual("global::C+E");
  636. }
  637. // E<int> x2;
  638. {
  639. var field = classA.OwnMembers.ToArray()[i++] as FieldEntity;
  640. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  641. field.TypeReference.Target.ToString().ShouldEqual("global::C+E`1[global::System.Int32]");
  642. field.TypeReference.Target.DirectGenericTemplate.ToString().ShouldEqual("global::C+E`1");
  643. }
  644. // F.G x3;
  645. {
  646. var field = classA.OwnMembers.ToArray()[i++] as FieldEntity;
  647. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  648. field.TypeReference.Target.ToString().ShouldEqual("global::D+F+G");
  649. }
  650. // F<int>.G x4;
  651. {
  652. var field = classA.OwnMembers.ToArray()[i++] as FieldEntity;
  653. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  654. field.TypeReference.Target.ToString().ShouldEqual("global::D+F`1[global::System.Int32]+G");
  655. }
  656. // F<int>.G<int> x5;
  657. {
  658. var field = classA.OwnMembers.ToArray()[i++] as FieldEntity;
  659. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  660. field.TypeReference.Target.ToString().ShouldEqual("global::D+F`1[global::System.Int32]+G`1[global::System.Int32]");
  661. field.TypeReference.Target.DirectGenericTemplate.ToString().ShouldEqual("global::D+F`1[global::System.Int32]+G`1[global::D+F`1+G`1.T3]");
  662. field.TypeReference.Target.OriginalGenericTemplate.ToString().ShouldEqual("global::D+F`1+G`1");
  663. }
  664. }
  665. // ----------------------------------------------------------------------------------------------
  666. /// <summary>
  667. /// Error CS0118: 'A' is a 'namespace' but is used like a 'type'
  668. /// </summary>
  669. // ----------------------------------------------------------------------------------------------
  670. [TestMethod]
  671. public void CS0118_NamespaceIsUsedLikeAType()
  672. {
  673. var project = new CSharpProject(WorkingFolder);
  674. project.AddFile(@"TypeResolution\CS0118_NamespaceIsUsedLikeAType.cs");
  675. InvokeParser(project).ShouldBeFalse();
  676. project.Errors.Count.ShouldEqual(1);
  677. project.Errors[0].Code.ShouldEqual("CS0118");
  678. project.Warnings.Count.ShouldEqual(0);
  679. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("B");
  680. var baseTypeRef = classEntity.BaseTypeReferences.ToArray()[0];
  681. baseTypeRef.ResolutionState.ShouldEqual(ResolutionState.Unresolvable);
  682. }
  683. // ----------------------------------------------------------------------------------------------
  684. /// <summary>
  685. /// Resolving a constructed generic class in mscorlib.
  686. /// </summary>
  687. // ----------------------------------------------------------------------------------------------
  688. [TestMethod]
  689. public void ConstructedGenericClassInMscorlib()
  690. {
  691. var project = new CSharpProject(WorkingFolder);
  692. InvokeParser(project).ShouldBeTrue();
  693. var comparer = project.SemanticGraph.GlobalNamespace.GetChildNamespace("System").GetChildNamespace("Collections").
  694. GetChildNamespace("Generic").GetSingleChildType<ClassEntity>("Comparer", 1);
  695. var icomparer = comparer.BaseInterfaces.Where(x => x.Name == "IComparer" && x.AllTypeParameterCount == 1).First();
  696. icomparer.ToString().ShouldEqual("global::System.Collections.Generic.IComparer`1[global::System.Collections.Generic.Comparer`1.T]");
  697. icomparer.IsOpen.ShouldBeTrue();
  698. icomparer.IsGenericClone.ShouldBeTrue();
  699. icomparer.IsUnboundGeneric.ShouldBeFalse();
  700. }
  701. // ----------------------------------------------------------------------------------------------
  702. /// <summary>
  703. /// Resolving a constructed generic class.
  704. /// </summary>
  705. // ----------------------------------------------------------------------------------------------
  706. [TestMethod]
  707. public void ConstructedGenericClass()
  708. {
  709. var project = new CSharpProject(WorkingFolder);
  710. project.AddFile(@"TypeResolution\ConstructedGenericClass.cs");
  711. InvokeParser(project).ShouldBeTrue();
  712. var classA = project.SemanticGraph.GlobalNamespace.GetChildNamespace("N").GetSingleChildType<ClassEntity>("A", 2);
  713. var fields = classA.OwnMembers.ToArray();
  714. var classB1 = classA.GetSingleChildType<ClassEntity>("B1");
  715. var classB2 = classA.GetSingleChildType<ClassEntity>("B2", 1);
  716. var classB3 = classA.GetSingleChildType<ClassEntity>("B3", 1);
  717. // public class B1
  718. {
  719. classB1.ToString().ShouldEqual("global::N.A`2+B1");
  720. classB1.IsGenericClone.ShouldBeFalse();
  721. classB1.DirectGenericTemplate.ShouldBeNull();
  722. classB1.IsGeneric.ShouldBeTrue();
  723. classB1.IsUnboundGeneric.ShouldBeTrue();
  724. classB1.IsOpen.ShouldBeTrue();
  725. var typeParameterMap = classB1.TypeParameterMap;
  726. typeParameterMap.IsEmpty.ShouldBeFalse();
  727. typeParameterMap.Count.ShouldEqual(2);
  728. var typeParameters = typeParameterMap.TypeParameters.ToList();
  729. typeParameters[0].ToString().ShouldEqual("global::N.A`2.T1");
  730. typeParameters[1].ToString().ShouldEqual("global::N.A`2.T2");
  731. var typeArguments = typeParameterMap.TypeArguments.ToList();
  732. typeArguments[0].ShouldBeNull();
  733. typeArguments[1].ShouldBeNull();
  734. }
  735. // public class B2<T1>
  736. {
  737. classB2.ToString().ShouldEqual("global::N.A`2+B2`1");
  738. classB2.IsGenericClone.ShouldBeFalse();
  739. classB2.DirectGenericTemplate.ShouldBeNull();
  740. classB2.IsGeneric.ShouldBeTrue();
  741. classB2.IsUnboundGeneric.ShouldBeTrue();
  742. classB2.IsOpen.ShouldBeTrue();
  743. var typeParameterMap = classB2.TypeParameterMap;
  744. typeParameterMap.IsEmpty.ShouldBeFalse();
  745. typeParameterMap.Count.ShouldEqual(3);
  746. var typeParameters = typeParameterMap.TypeParameters.ToList();
  747. typeParameters[0].ToString().ShouldEqual("global::N.A`2.T1");
  748. typeParameters[1].ToString().ShouldEqual("global::N.A`2.T2");
  749. typeParameters[2].ToString().ShouldEqual("global::N.A`2+B2`1.T1");
  750. var typeArguments = typeParameterMap.TypeArguments.ToList();
  751. typeArguments[0].ShouldBeNull();
  752. typeArguments[1].ShouldBeNull();
  753. typeArguments[2].ShouldBeNull();
  754. }
  755. // public class B3<T3>
  756. {
  757. classB3.ToString().ShouldEqual("global::N.A`2+B3`1");
  758. var typeParameterMap = classB3.TypeParameterMap;
  759. typeParameterMap.IsEmpty.ShouldBeFalse();
  760. typeParameterMap.Count.ShouldEqual(3);
  761. var typeParameters = typeParameterMap.TypeParameters.ToList();
  762. typeParameters[0].ToString().ShouldEqual("global::N.A`2.T1");
  763. typeParameters[1].ToString().ShouldEqual("global::N.A`2.T2");
  764. typeParameters[2].ToString().ShouldEqual("global::N.A`2+B3`1.T3");
  765. var typeArguments = typeParameterMap.TypeArguments.ToList();
  766. typeArguments[0].ShouldBeNull();
  767. typeArguments[1].ShouldBeNull();
  768. typeArguments[2].ShouldBeNull();
  769. }
  770. int i = 0;
  771. // A<A1, A2> a1;
  772. {
  773. var fieldEntity = fields[i++] as FieldEntity;
  774. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  775. var typeEntity = fieldEntity.TypeReference.Target as ClassEntity;
  776. typeEntity.Name.ShouldEqual("A");
  777. typeEntity.FullyQualifiedName.ShouldEqual("N.A");
  778. typeEntity.ToString().ShouldEqual("global::N.A`2[global::N.A1,global::N.A2]");
  779. typeEntity.IsGenericClone.ShouldBeTrue();
  780. typeEntity.DirectGenericTemplate.ShouldEqual(classA);
  781. classA.GetGenericClone(typeEntity.TypeParameterMap).ShouldEqual(typeEntity);
  782. }
  783. // A<T1, T2> a2;
  784. {
  785. var fieldEntity = fields[i++] as FieldEntity;
  786. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  787. var typeEntity = fieldEntity.TypeReference.Target as ClassEntity;
  788. typeEntity.Name.ShouldEqual("A");
  789. typeEntity.FullyQualifiedName.ShouldEqual("N.A");
  790. typeEntity.ToString().ShouldEqual("global::N.A`2[global::N.A`2.T1,global::N.A`2.T2]");
  791. typeEntity.DirectGenericTemplate.ShouldEqual(classA);
  792. classA.GetGenericClone(typeEntity.TypeParameterMap).ShouldEqual(typeEntity);
  793. }
  794. // A<T1, T2> a3;
  795. {
  796. var fieldEntity = fields[i++] as FieldEntity;
  797. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  798. var typeEntity = fieldEntity.TypeReference.Target as ClassEntity;
  799. typeEntity.ToString().ShouldEqual("global::N.A`2[global::N.A`2.T1,global::N.A`2.T2]");
  800. typeEntity.DirectGenericTemplate.ShouldEqual(classA);
  801. // Should not create a new constructed entity because the previous field has the same type.
  802. classA.GenericClones.Count().ShouldEqual(2);
  803. }
  804. // A<A1, A2>.B1 b1;
  805. {
  806. var fieldEntity = fields[i++] as FieldEntity;
  807. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  808. var typeEntity = fieldEntity.TypeReference.Target as ClassEntity;
  809. typeEntity.Name.ShouldEqual("B1");
  810. typeEntity.FullyQualifiedName.ShouldEqual("N.A.B1");
  811. typeEntity.ToString().ShouldEqual("global::N.A`2[global::N.A1,global::N.A2]+B1");
  812. typeEntity.DirectGenericTemplate.ShouldEqual(classB1);
  813. classB1.GetGenericClone(typeEntity.TypeParameterMap).ShouldEqual(typeEntity);
  814. }
  815. // A<A1, A2>.B2<A3> b2;
  816. {
  817. var fieldEntity = fields[i++] as FieldEntity;
  818. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  819. var typeEntity = fieldEntity.TypeReference.Target as ClassEntity;
  820. typeEntity.Name.ShouldEqual("B2");
  821. typeEntity.FullyQualifiedName.ShouldEqual("N.A.B2");
  822. typeEntity.ToString().ShouldEqual("global::N.A`2[global::N.A1,global::N.A2]+B2`1[global::N.A3]");
  823. typeEntity.DirectGenericTemplate.ToString().ShouldEqual("global::N.A`2[global::N.A1,global::N.A2]+B2`1[global::N.A`2+B2`1.T1]");
  824. typeEntity.OriginalGenericTemplate.ToString().ShouldEqual("global::N.A`2+B2`1");
  825. }
  826. // A<A1, A2>.B3<A4> b3;
  827. {
  828. var fieldEntity = fields[i++] as FieldEntity;
  829. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  830. var typeEntity = fieldEntity.TypeReference.Target as ClassEntity;
  831. typeEntity.Name.ShouldEqual("B3");
  832. typeEntity.FullyQualifiedName.ShouldEqual("N.A.B3");
  833. typeEntity.ToString().ShouldEqual("global::N.A`2[global::N.A1,global::N.A2]+B3`1[global::N.A4]");
  834. typeEntity.DirectGenericTemplate.ToString().ShouldEqual("global::N.A`2[global::N.A1,global::N.A2]+B3`1[global::N.A`2+B3`1.T3]");
  835. typeEntity.OriginalGenericTemplate.ToString().ShouldEqual("global::N.A`2+B3`1");
  836. }
  837. // A<A1, A2> a1; --> public class B1
  838. {
  839. var type = (classA.GetOwnMember<FieldEntity>("a1").Type as ClassEntity).GetSingleChildType<ClassEntity>("B1");
  840. type.ToString().ShouldEqual("global::N.A`2[global::N.A1,global::N.A2]+B1");
  841. type.IsOpen.ShouldBeFalse();
  842. type.IsGenericClone.ShouldBeTrue();
  843. type.IsUnboundGeneric.ShouldBeFalse();
  844. }
  845. // A<A1, A2> a1; --> public class B2<T1>
  846. {
  847. var type = (classA.GetOwnMember<FieldEntity>("a1").Type as ClassEntity).GetSingleChildType<ClassEntity>("B2", 1);
  848. type.ToString().ShouldEqual("global::N.A`2[global::N.A1,global::N.A2]+B2`1[global::N.A`2+B2`1.T1]");
  849. type.IsOpen.ShouldBeTrue();
  850. type.IsGenericClone.ShouldBeTrue();
  851. type.IsUnboundGeneric.ShouldBeFalse();
  852. }
  853. // A<A1, A2> a1; --> A<A1, A2>.B2<A3> b2;
  854. {
  855. var type = classA.GetOwnMember<FieldEntity>("a1").Type.GetOwnMember<FieldEntity>("b2").Type;
  856. type.ToString().ShouldEqual("global::N.A`2[global::N.A1,global::N.A2]+B2`1[global::N.A3]");
  857. type.IsOpen.ShouldBeFalse();
  858. type.IsGenericClone.ShouldBeTrue();
  859. type.IsUnboundGeneric.ShouldBeFalse();
  860. }
  861. }
  862. // ----------------------------------------------------------------------------------------------
  863. /// <summary>
  864. /// Resolving a constructed generic struct.
  865. /// </summary>
  866. // ----------------------------------------------------------------------------------------------
  867. [TestMethod]
  868. public void ConstructedGenericStruct()
  869. {
  870. var project = new CSharpProject(WorkingFolder);
  871. project.AddFile(@"TypeResolution\ConstructedGenericStruct.cs");
  872. InvokeParser(project).ShouldBeTrue();
  873. var structEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<StructEntity>("A");
  874. var fields = structEntity.OwnMembers.ToArray();
  875. int i = 0;
  876. // B<int> a;
  877. {
  878. var fieldEntity = fields[i++] as FieldEntity;
  879. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  880. var typeEntity = fieldEntity.TypeReference.Target as StructEntity;
  881. typeEntity.Name.ShouldEqual("B");
  882. typeEntity.FullyQualifiedName.ShouldEqual("B");
  883. typeEntity.ToString().ShouldEqual("global::B`1[global::System.Int32]");
  884. typeEntity.Parent.ShouldEqual(project.SemanticGraph.GlobalNamespace);
  885. typeEntity.IsPointerType.ShouldBeFalse();
  886. typeEntity.IsReferenceType.ShouldBeFalse();
  887. typeEntity.IsValueType.ShouldBeTrue();
  888. typeEntity.TypeParameterMap.TypeArguments.ToList()[0].ToString().ShouldEqual("global::System.Int32");
  889. typeEntity.DirectGenericTemplate.ToString().ShouldEqual("global::B`1");
  890. }
  891. }
  892. // ----------------------------------------------------------------------------------------------
  893. /// <summary>
  894. /// Resolving a generic type, where the type argument is also a generic type.
  895. /// </summary>
  896. // ----------------------------------------------------------------------------------------------
  897. [TestMethod]
  898. public void GenericTypeArgument()
  899. {
  900. var project = new CSharpProject(WorkingFolder);
  901. project.AddFile(@"TypeResolution\GenericTypeArgument.cs");
  902. InvokeParser(project).ShouldBeTrue();
  903. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A1");
  904. var fieldEntity = classEntity.OwnMembers.ToArray()[0] as FieldEntity;
  905. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  906. var typeEntity = fieldEntity.TypeReference.Target as ClassEntity;
  907. typeEntity.ShouldNotBeNull();
  908. typeEntity.Name.ShouldEqual("A3");
  909. typeEntity.FullyQualifiedName.ShouldEqual("A2.A3");
  910. typeEntity.ToString().ShouldEqual("global::A2+A3`1[global::A2+A3`1[global::A4]]");
  911. typeEntity.DirectGenericTemplate.ToString().ShouldEqual("global::A2+A3`1");
  912. var typeArgTypeEntity = typeEntity.TypeParameterMap.TypeArguments.ToList()[0] as ClassEntity;
  913. typeArgTypeEntity.ToString().ShouldEqual("global::A2+A3`1[global::A4]");
  914. typeArgTypeEntity.DirectGenericTemplate.ToString().ShouldEqual("global::A2+A3`1");
  915. var typeArgTypeEntity2 = typeArgTypeEntity.TypeParameterMap.TypeArguments.ToList()[0] as ClassEntity;
  916. typeArgTypeEntity2.ToString().ShouldEqual("global::A4");
  917. }
  918. // ----------------------------------------------------------------------------------------------
  919. /// <summary>
  920. /// Precedence rule 1: name in local declaration space has precedence 1
  921. /// </summary>
  922. // ----------------------------------------------------------------------------------------------
  923. [TestMethod]
  924. public void Precedence1_Local()
  925. {
  926. var project = new CSharpProject(WorkingFolder);
  927. project.AddFile(@"TypeResolution\Precedence1_Local.cs");
  928. InvokeParser(project).ShouldBeTrue();
  929. project.Errors.Count.ShouldEqual(0);
  930. project.Warnings.Count.ShouldEqual(0);
  931. var field = project.SemanticGraph.GlobalNamespace.GetChildNamespace("A").ChildTypes.ToList()[0].OwnMembers.ToList()[0] as FieldEntity;
  932. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  933. field.TypeReference.Target.ToString().ShouldEqual("global::A.B+C");
  934. }
  935. // ----------------------------------------------------------------------------------------------
  936. /// <summary>
  937. /// Precedence rule 2: name in base type's declaration space has precedence 2
  938. /// </summary>
  939. // ----------------------------------------------------------------------------------------------
  940. [TestMethod]
  941. public void Precedence2_BaseType()
  942. {

Large files files are truncated, but you can click here to view the full file