PageRenderTime 68ms CodeModel.GetById 21ms 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
  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. {
  943. var project = new CSharpProject(WorkingFolder);
  944. project.AddFile(@"TypeResolution\Precedence2_BaseType.cs");
  945. InvokeParser(project).ShouldBeTrue();
  946. project.Errors.Count.ShouldEqual(0);
  947. project.Warnings.Count.ShouldEqual(0);
  948. var field = project.SemanticGraph.GlobalNamespace.GetChildNamespace("A").ChildTypes.ToList()[0].OwnMembers.ToList()[0] as FieldEntity;
  949. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  950. field.TypeReference.Target.ToString().ShouldEqual("global::D+C");
  951. }
  952. // ----------------------------------------------------------------------------------------------
  953. /// <summary>
  954. /// Precedence rule 3a: name in one level higher parent's declaration space has precedence 3.
  955. /// </summary>
  956. // ----------------------------------------------------------------------------------------------
  957. [TestMethod]
  958. public void Precedence3a_Level1_Parent()
  959. {
  960. var project = new CSharpProject(WorkingFolder);
  961. project.AddFile(@"TypeResolution\Precedence3a_Level1_Parent.cs");
  962. InvokeParser(project).ShouldBeTrue();
  963. project.Errors.Count.ShouldEqual(0);
  964. project.Warnings.Count.ShouldEqual(0);
  965. var field = project.SemanticGraph.GlobalNamespace.GetChildNamespace("A").ChildTypes.ToList()[0].OwnMembers.ToList()[0] as FieldEntity;
  966. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  967. field.TypeReference.Target.ToString().ShouldEqual("global::A.C");
  968. }
  969. // ----------------------------------------------------------------------------------------------
  970. /// <summary>
  971. /// Precedence rule 3b: alias defined one level higher has precedence 3.
  972. /// </summary>
  973. // ----------------------------------------------------------------------------------------------
  974. [TestMethod]
  975. public void Precedence3b_Level1_UsingAlias()
  976. {
  977. var project = new CSharpProject(WorkingFolder);
  978. project.AddFile(@"TypeResolution\Precedence3b_Level1_UsingAlias.cs");
  979. InvokeParser(project).ShouldBeTrue();
  980. project.Errors.Count.ShouldEqual(0);
  981. project.Warnings.Count.ShouldEqual(0);
  982. var field = project.SemanticGraph.GlobalNamespace.GetChildNamespace("A").ChildTypes.ToList()[0].OwnMembers.ToList()[0] as FieldEntity;
  983. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  984. field.TypeReference.Target.ToString().ShouldEqual("global::E");
  985. }
  986. // ----------------------------------------------------------------------------------------------
  987. /// <summary>
  988. /// Precedence rule 4: using namespace defined one level higher has precedence 4.
  989. /// </summary>
  990. // ----------------------------------------------------------------------------------------------
  991. [TestMethod]
  992. public void Precedence4_Level1_UsingNamespace()
  993. {
  994. var project = new CSharpProject(WorkingFolder);
  995. project.AddFile(@"TypeResolution\Precedence4_Level1_UsingNamespace.cs");
  996. InvokeParser(project).ShouldBeTrue();
  997. project.Errors.Count.ShouldEqual(0);
  998. project.Warnings.Count.ShouldEqual(0);
  999. var field = project.SemanticGraph.GlobalNamespace.GetChildNamespace("A").ChildTypes.ToList()[0].OwnMembers.ToList()[0] as FieldEntity;
  1000. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1001. field.TypeReference.Target.ToString().ShouldEqual("global::N.C");
  1002. }
  1003. // ----------------------------------------------------------------------------------------------
  1004. /// <summary>
  1005. /// Precedence rule 5a: name in two level higher parent's declaration space has precedence 5.
  1006. /// </summary>
  1007. // ----------------------------------------------------------------------------------------------
  1008. [TestMethod]
  1009. public void Precedence5a_Level2_Parent()
  1010. {
  1011. var project = new CSharpProject(WorkingFolder);
  1012. project.AddFile(@"TypeResolution\Precedence5a_Level2_Parent.cs");
  1013. InvokeParser(project).ShouldBeTrue();
  1014. project.Errors.Count.ShouldEqual(0);
  1015. project.Warnings.Count.ShouldEqual(0);
  1016. var field = project.SemanticGraph.GlobalNamespace.GetChildNamespace("A").ChildTypes.ToList()[0].OwnMembers.ToList()[0] as FieldEntity;
  1017. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1018. field.TypeReference.Target.ToString().ShouldEqual("global::C");
  1019. }
  1020. // ----------------------------------------------------------------------------------------------
  1021. /// <summary>
  1022. /// Precedence rule 5b: alias defined one level higher has precedence 5.
  1023. /// </summary>
  1024. // ----------------------------------------------------------------------------------------------
  1025. [TestMethod]
  1026. public void Precedence5b_Level2_UsingAlias()
  1027. {
  1028. var project = new CSharpProject(WorkingFolder);
  1029. project.AddFile(@"TypeResolution\Precedence5b_Level2_UsingAlias.cs");
  1030. InvokeParser(project).ShouldBeTrue();
  1031. project.Errors.Count.ShouldEqual(0);
  1032. project.Warnings.Count.ShouldEqual(0);
  1033. var field = project.SemanticGraph.GlobalNamespace.GetChildNamespace("A").ChildTypes.ToList()[0].OwnMembers.ToList()[0] as FieldEntity;
  1034. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1035. field.TypeReference.Target.ToString().ShouldEqual("global::E");
  1036. }
  1037. // ----------------------------------------------------------------------------------------------
  1038. /// <summary>
  1039. /// Precedence rule 6: using namespace defined two level higher has precedence 6.
  1040. /// </summary>
  1041. // ----------------------------------------------------------------------------------------------
  1042. [TestMethod]
  1043. public void Precedence6_Level2_UsingNamespace()
  1044. {
  1045. var project = new CSharpProject(WorkingFolder);
  1046. project.AddFile(@"TypeResolution\Precedence6_Level2_UsingNamespace.cs");
  1047. InvokeParser(project).ShouldBeTrue();
  1048. project.Errors.Count.ShouldEqual(0);
  1049. project.Warnings.Count.ShouldEqual(0);
  1050. var field = project.SemanticGraph.GlobalNamespace.GetChildNamespace("A").ChildTypes.ToList()[0].OwnMembers.ToList()[0] as FieldEntity;
  1051. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1052. field.TypeReference.Target.ToString().ShouldEqual("global::N.C");
  1053. }
  1054. // ----------------------------------------------------------------------------------------------
  1055. /// <summary>
  1056. /// Tests that namespaces are not imported with using namespace directives (only types).
  1057. /// </summary>
  1058. // ----------------------------------------------------------------------------------------------
  1059. [TestMethod]
  1060. public void NamespacesAreNotImportedWithUsing()
  1061. {
  1062. var project = new CSharpProject(WorkingFolder);
  1063. project.AddFile(@"TypeResolution\NamespacesAreNotImportedWithUsing.cs");
  1064. InvokeParser(project).ShouldBeFalse();
  1065. project.Errors.Count.ShouldEqual(1);
  1066. project.Errors[0].Code.ShouldEqual("CS0246");
  1067. project.Warnings.Count.ShouldEqual(0);
  1068. }
  1069. // ----------------------------------------------------------------------------------------------
  1070. /// <summary>
  1071. /// Tests that only those usings are considered that has the name to be resolved in scope.
  1072. /// </summary>
  1073. // ----------------------------------------------------------------------------------------------
  1074. [TestMethod]
  1075. public void NotInScopeForUsingNamespace()
  1076. {
  1077. var project = new CSharpProject(WorkingFolder);
  1078. project.AddFile(@"TypeResolution\NotInScopeForUsingNamespace.cs");
  1079. InvokeParser(project).ShouldBeFalse();
  1080. project.Errors.Count.ShouldEqual(1);
  1081. project.Errors[0].Code.ShouldEqual("CS0246");
  1082. project.Warnings.Count.ShouldEqual(0);
  1083. }
  1084. // ----------------------------------------------------------------------------------------------
  1085. /// <summary>
  1086. /// error CS0104: 'C' is an ambiguous reference between 'B1.C' and 'B2.C'
  1087. /// </summary>
  1088. // ----------------------------------------------------------------------------------------------
  1089. [TestMethod]
  1090. public void CS0104_AmbigousReference()
  1091. {
  1092. var project = new CSharpProject(WorkingFolder);
  1093. project.AddFile(@"TypeResolution\CS0104_AmbigousReference.cs");
  1094. InvokeParser(project).ShouldBeFalse();
  1095. project.Errors.Count.ShouldEqual(1);
  1096. project.Errors[0].Code.ShouldEqual("CS0104");
  1097. project.Warnings.Count.ShouldEqual(0);
  1098. }
  1099. // ----------------------------------------------------------------------------------------------
  1100. /// <summary>
  1101. /// Tests that using namespace directive finds embedded types too.
  1102. /// </summary>
  1103. // ----------------------------------------------------------------------------------------------
  1104. [TestMethod]
  1105. public void UsingFindsEmbeddedTypeToo()
  1106. {
  1107. var project = new CSharpProject(WorkingFolder);
  1108. project.AddFile(@"TypeResolution\UsingFindsEmbeddedTypeToo.cs");
  1109. InvokeParser(project).ShouldBeTrue();
  1110. project.Errors.Count.ShouldEqual(0);
  1111. project.Warnings.Count.ShouldEqual(0);
  1112. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A");
  1113. var field = classEntity.OwnMembers.ToList()[0] as FieldEntity;
  1114. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1115. field.TypeReference.Target.ToString().ShouldEqual("global::B.C+D");
  1116. }
  1117. // ----------------------------------------------------------------------------------------------
  1118. /// <summary>
  1119. /// Tests that using namespace directive finds generic types too.
  1120. /// </summary>
  1121. // ----------------------------------------------------------------------------------------------
  1122. [TestMethod]
  1123. public void UsingFindsGenericTypeToo()
  1124. {
  1125. var project = new CSharpProject(WorkingFolder);
  1126. project.AddFile(@"TypeResolution\UsingFindsGenericTypeToo.cs");
  1127. InvokeParser(project).ShouldBeTrue();
  1128. project.Errors.Count.ShouldEqual(0);
  1129. project.Warnings.Count.ShouldEqual(0);
  1130. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A");
  1131. var field = classEntity.OwnMembers.ToList()[0] as FieldEntity;
  1132. field.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1133. field.TypeReference.Target.ToString().ShouldEqual("global::B.C`1[global::System.Int32]+D`1[global::System.Int64]");
  1134. }
  1135. // ----------------------------------------------------------------------------------------------
  1136. /// <summary>
  1137. /// Tests the resolution of non-generic base types
  1138. /// </summary>
  1139. // ----------------------------------------------------------------------------------------------
  1140. [TestMethod]
  1141. public void NonGenericBaseTypes()
  1142. {
  1143. var project = new CSharpProject(WorkingFolder);
  1144. project.AddFile(@"TypeResolution\NonGenericBaseTypes.cs");
  1145. InvokeParser(project).ShouldBeTrue();
  1146. // class A1 : C0
  1147. {
  1148. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A1");
  1149. var baseTypeRef = classEntity.BaseTypeReferences.ToArray()[0];
  1150. baseTypeRef.Target.ToString().ShouldEqual("global::C0");
  1151. }
  1152. // class A2 : C0.C1
  1153. {
  1154. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A2");
  1155. var baseTypeRef = classEntity.BaseTypeReferences.ToArray()[0];
  1156. baseTypeRef.Target.ToString().ShouldEqual("global::C0+C1");
  1157. }
  1158. // class A3 : N1.N1C0
  1159. {
  1160. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A3");
  1161. var baseTypeRef = classEntity.BaseTypeReferences.ToArray()[0];
  1162. baseTypeRef.Target.ToString().ShouldEqual("global::N1.N1C0");
  1163. }
  1164. // class A4 : N1.N2.N2C0
  1165. {
  1166. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A4");
  1167. var baseTypeRef = classEntity.BaseTypeReferences.ToArray()[0];
  1168. baseTypeRef.Target.ToString().ShouldEqual("global::N1.N2.N2C0");
  1169. }
  1170. // class A5 : N1.N2.N2C0.N2C1
  1171. {
  1172. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A5");
  1173. var baseTypeRef = classEntity.BaseTypeReferences.ToArray()[0];
  1174. baseTypeRef.Target.ToString().ShouldEqual("global::N1.N2.N2C0+N2C1");
  1175. }
  1176. // class N3C1 : N3C2
  1177. {
  1178. var baseTypeRef = project.SemanticGraph.GlobalNamespace.GetChildNamespace("N3").ChildTypes.ToList()[0].BaseTypeReferences.ToArray()[0];
  1179. baseTypeRef.Target.ToString().ShouldEqual("global::N3.N3C2");
  1180. }
  1181. // class N5C1 : N4C1
  1182. {
  1183. var baseTypeRef = project.SemanticGraph.GlobalNamespace.GetChildNamespace("N4").ChildNamespaces[0].ChildTypes.ToList()[0].BaseTypeReferences.ToArray()[0];
  1184. baseTypeRef.Target.ToString().ShouldEqual("global::N4.N4C1");
  1185. }
  1186. // class N5C2 : N6.N6C1
  1187. {
  1188. var baseTypeRef = project.SemanticGraph.GlobalNamespace.GetChildNamespace("N4").ChildNamespaces[0].ChildTypes.ToList()[1].BaseTypeReferences.ToArray()[0];
  1189. baseTypeRef.Target.ToString().ShouldEqual("global::N4.N6.N6C1");
  1190. }
  1191. // class N5C2C1 : N5C1
  1192. {
  1193. var baseTypeRef = ((ClassEntity)project.SemanticGraph.GlobalNamespace.GetChildNamespace("N4").ChildNamespaces[0].ChildTypes.ToList()[1])
  1194. .ChildTypes.ToList()[0].BaseTypeReferences.ToArray()[0];
  1195. baseTypeRef.Target.ToString().ShouldEqual("global::N4.N5.N5C1");
  1196. }
  1197. // class N5C2C2 : N4C1
  1198. {
  1199. var baseTypeRef = ((ClassEntity)project.SemanticGraph.GlobalNamespace.GetChildNamespace("N4").ChildNamespaces[0].ChildTypes.ToList()[1])
  1200. .ChildTypes.ToList()[1].BaseTypeReferences.ToArray()[0];
  1201. baseTypeRef.Target.ToString().ShouldEqual("global::N4.N4C1");
  1202. }
  1203. // class N5C2C3 : N5C2C1
  1204. {
  1205. var baseTypeRef = ((ClassEntity)project.SemanticGraph.GlobalNamespace.GetChildNamespace("N4").ChildNamespaces[0].ChildTypes.ToList()[1])
  1206. .ChildTypes.ToList()[2].BaseTypeReferences.ToArray()[0];
  1207. baseTypeRef.Target.ToString().ShouldEqual("global::N4.N5.N5C2+N5C2C1");
  1208. }
  1209. }
  1210. // ----------------------------------------------------------------------------------------------
  1211. /// <summary>
  1212. /// Tests the resolution of generic base types
  1213. /// </summary>
  1214. // ----------------------------------------------------------------------------------------------
  1215. [TestMethod]
  1216. public void GenericBaseTypes()
  1217. {
  1218. var project = new CSharpProject(WorkingFolder);
  1219. project.AddFile(@"TypeResolution\GenericBaseTypes.cs");
  1220. InvokeParser(project).ShouldBeTrue();
  1221. // class A1<T1> : A3<T1, A2<T1>>, I1<A1<T1>>
  1222. {
  1223. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A1", 1);
  1224. classEntity.BaseClass.ToString().ShouldEqual("global::A3`2[global::A1`1.T1,global::A2`1[global::A1`1.T1]]");
  1225. classEntity.BaseInterfaces.Count.ShouldEqual(1);
  1226. classEntity.BaseInterfaces[0].ToString().ShouldEqual("global::I1`1[global::A1`1[global::A1`1.T1]]");
  1227. }
  1228. // class A2<T2> : A3<int, long>, I1<int>
  1229. {
  1230. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A2", 1);
  1231. classEntity.BaseClass.ToString().ShouldEqual("global::A3`2[global::System.Int32,global::System.Int64]");
  1232. classEntity.BaseInterfaces.Count.ShouldEqual(1);
  1233. classEntity.BaseInterfaces[0].ToString().ShouldEqual("global::I1`1[global::System.Int32]");
  1234. }
  1235. // class A3<T3, T4>
  1236. {
  1237. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A3", 2);
  1238. classEntity.BaseClass.ToString().ShouldEqual("global::System.Object");
  1239. classEntity.BaseInterfaces.Count.ShouldEqual(0);
  1240. }
  1241. }
  1242. // ----------------------------------------------------------------------------------------------
  1243. /// <summary>
  1244. /// Tests the resolution of reflected base types
  1245. /// </summary>
  1246. // ----------------------------------------------------------------------------------------------
  1247. [TestMethod]
  1248. public void ReflectedBaseTypes()
  1249. {
  1250. var project = new CSharpProject(WorkingFolder);
  1251. project.AddFile(@"TypeResolution\ReflectedBaseTypes.cs");
  1252. InvokeParser(project).ShouldBeTrue();
  1253. // class A1 : System.Object
  1254. {
  1255. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A1");
  1256. var baseTypeRef = classEntity.BaseTypeReferences.ToArray()[0];
  1257. baseTypeRef.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1258. baseTypeRef.Target.ToString().ShouldEqual("global::System.Object");
  1259. }
  1260. // class A2 : System.Collections.Generic.Dictionary<int,long>
  1261. {
  1262. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A2");
  1263. var baseTypeRef = classEntity.BaseTypeReferences.ToArray()[0];
  1264. baseTypeRef.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1265. baseTypeRef.Target.ToString().ShouldEqual("global::System.Collections.Generic.Dictionary`2[global::System.Int32,global::System.Int64]");
  1266. }
  1267. }
  1268. // ----------------------------------------------------------------------------------------------
  1269. /// <summary>
  1270. /// Tests the resolution of implicit base types
  1271. /// </summary>
  1272. // ----------------------------------------------------------------------------------------------
  1273. [TestMethod]
  1274. public void ImplicitBaseTypes()
  1275. {
  1276. var project = new CSharpProject(WorkingFolder);
  1277. project.AddFile(@"TypeResolution\ImplicitBaseTypes.cs");
  1278. InvokeParser(project).ShouldBeTrue();
  1279. // class A1 // implicitly : System.Object
  1280. {
  1281. var entity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A1");
  1282. entity.BaseClass.FullyQualifiedName.ShouldEqual("System.Object");
  1283. }
  1284. // struct A2 // implicitly: System.ValueType
  1285. {
  1286. var entity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<StructEntity>("A2");
  1287. entity.BaseClass.FullyQualifiedName.ShouldEqual("System.ValueType");
  1288. }
  1289. // enum A3 // implicitly: System.Enum
  1290. {
  1291. var entity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<EnumEntity>("A3");
  1292. entity.BaseClass.FullyQualifiedName.ShouldEqual("System.Enum");
  1293. }
  1294. // delegate void A4(); // implicitly: System.MulticastDelegate
  1295. {
  1296. var entity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<DelegateEntity>("A4");
  1297. entity.BaseClass.FullyQualifiedName.ShouldEqual("System.MulticastDelegate");
  1298. }
  1299. // class A5<T>
  1300. {
  1301. var entity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<TypeEntity>("A5", 1);
  1302. entity.BaseClass.FullyQualifiedName.ShouldEqual("System.Object");
  1303. }
  1304. // struct A6<T>
  1305. {
  1306. var entity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<TypeEntity>("A6", 1);
  1307. entity.BaseClass.FullyQualifiedName.ShouldEqual("System.ValueType");
  1308. }
  1309. // A5<int> a5;
  1310. {
  1311. var entity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A8");
  1312. var field = entity.GetOwnMember<FieldEntity>("a5");
  1313. field.Type.BaseClass.FullyQualifiedName.ShouldEqual("System.Object");
  1314. }
  1315. // A6<int> a6;
  1316. {
  1317. var entity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A8");
  1318. var field = entity.GetOwnMember<FieldEntity>("a6");
  1319. field.Type.BaseClass.FullyQualifiedName.ShouldEqual("System.ValueType");
  1320. }
  1321. }
  1322. // ----------------------------------------------------------------------------------------------
  1323. /// <summary>
  1324. /// Test the resolution of base types of types imported from mscorlib.dll
  1325. /// </summary>
  1326. // ----------------------------------------------------------------------------------------------
  1327. [TestMethod]
  1328. public void ResolveMscorlibBaseTypes()
  1329. {
  1330. var project = new CSharpProject(WorkingFolder);
  1331. var factory = new MetadataImporterSemanticEntityFactory(project, project.SemanticGraph);
  1332. factory.ImportTypesIntoSemanticGraph(Assembly.GetAssembly(typeof(int)).Location, "global");
  1333. project.SemanticGraph.AcceptVisitor(new TypeResolverPass1SemanticGraphVisitor(project, project.SemanticGraph));
  1334. project.Warnings.Count.ShouldEqual(0);
  1335. project.Errors.Count.ShouldEqual(0);
  1336. var collection = project.SemanticGraph.GlobalNamespace.GetChildNamespace("System")
  1337. .GetChildNamespace("Collections").GetChildNamespace("ObjectModel")
  1338. .GetSingleChildType<TypeEntity>("Collection", 1);
  1339. var keyedCollection = project.SemanticGraph.GlobalNamespace.GetChildNamespace("System")
  1340. .GetChildNamespace("Collections").GetChildNamespace("ObjectModel")
  1341. .GetSingleChildType<TypeEntity>("KeyedCollection", 2);
  1342. keyedCollection.ToString().ShouldEqual("global::System.Collections.ObjectModel.KeyedCollection`2");
  1343. keyedCollection.BaseClass.DirectGenericTemplate.ShouldEqual(collection);
  1344. }
  1345. // ----------------------------------------------------------------------------------------------
  1346. /// <summary>
  1347. /// Test the resolution of builtin type aliases to types defined in mscorlib.
  1348. /// </summary>
  1349. // ----------------------------------------------------------------------------------------------
  1350. [TestMethod]
  1351. public void ResolveAliasesToMscorlibTypes()
  1352. {
  1353. var project = new CSharpProject(WorkingFolder);
  1354. var factory = new MetadataImporterSemanticEntityFactory(project, project.SemanticGraph);
  1355. factory.ImportTypesIntoSemanticGraph(Assembly.GetAssembly(typeof(int)).Location, "global");
  1356. project.SemanticGraph.AcceptVisitor(new TypeResolverPass1SemanticGraphVisitor(project, project.SemanticGraph));
  1357. project.Warnings.Count.ShouldEqual(0);
  1358. project.Errors.Count.ShouldEqual(0);
  1359. // Checking only one if the builtin types whether it resolved to the right system type.
  1360. project.SemanticGraph.GetTypeEntityByBuiltInType(BuiltInType.Int).FullyQualifiedName.ShouldEqual("System.Int32");
  1361. }
  1362. // ----------------------------------------------------------------------------------------------
  1363. /// <summary>
  1364. /// Error CS0246: The type or namespace name 'A' could not be found (are you missing a using directive or an assembly reference?)
  1365. /// </summary>
  1366. // ----------------------------------------------------------------------------------------------
  1367. [TestMethod]
  1368. public void CS0246_TypeNameCouldNotBeFound()
  1369. {
  1370. var project = new CSharpProject(WorkingFolder);
  1371. project.AddFile(@"TypeResolution\CS0246_TypeNameCouldNotBeFound.cs");
  1372. InvokeParser(project).ShouldBeFalse();
  1373. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("B");
  1374. var baseTypeRef = classEntity.BaseTypeReferences.ToArray()[0];
  1375. baseTypeRef.ResolutionState.ShouldEqual(ResolutionState.Unresolvable);
  1376. project.Errors.Count.ShouldEqual(1);
  1377. project.Errors[0].Code.ShouldEqual("CS0246");
  1378. }
  1379. // ----------------------------------------------------------------------------------------------
  1380. /// <summary>
  1381. /// error CS0138: A using namespace directive can only be applied to namespaces; 'A' is a type not a namespace
  1382. /// </summary>
  1383. // ----------------------------------------------------------------------------------------------
  1384. [TestMethod]
  1385. public void CS0138_UsingNamespaceWithTypeName()
  1386. {
  1387. var project = new CSharpProject(WorkingFolder);
  1388. project.AddFile(@"TypeResolution\CS0138_UsingNamespaceWithTypeName.cs");
  1389. InvokeParser(project).ShouldBeFalse();
  1390. project.Errors.Count.ShouldEqual(1);
  1391. project.Errors[0].Code.ShouldEqual("CS0138");
  1392. project.Warnings.Count.ShouldEqual(0);
  1393. }
  1394. // ----------------------------------------------------------------------------------------------
  1395. /// <summary>
  1396. /// error CS1681: You cannot redefine the global extern alias
  1397. /// </summary>
  1398. // ----------------------------------------------------------------------------------------------
  1399. [TestMethod]
  1400. public void CS1681_ExternAliasCannotBeGlobal()
  1401. {
  1402. var project = new CSharpProject(WorkingFolder);
  1403. project.AddFile(@"TypeResolution\CS1681_ExternAliasCannotBeGlobal.cs");
  1404. InvokeParser(project).ShouldBeFalse();
  1405. project.Errors.Count.ShouldEqual(1);
  1406. project.Errors[0].Code.ShouldEqual("CS1681");
  1407. project.Warnings.Count.ShouldEqual(0);
  1408. }
  1409. // ----------------------------------------------------------------------------------------------
  1410. /// <summary>
  1411. /// error CS0430: The extern alias 'MyExternAlias' was not specified in a /reference option
  1412. /// </summary>
  1413. // ----------------------------------------------------------------------------------------------
  1414. [TestMethod]
  1415. public void CS0430_ExternAliasNotResolved()
  1416. {
  1417. var project = new CSharpProject(WorkingFolder);
  1418. project.AddFile(@"TypeResolution\ExternAlias.cs");
  1419. InvokeParser(project).ShouldBeFalse();
  1420. project.Errors.Count.ShouldEqual(1);
  1421. project.Errors[0].Code.ShouldEqual("CS0430");
  1422. project.Warnings.Count.ShouldEqual(0);
  1423. }
  1424. // ----------------------------------------------------------------------------------------------
  1425. /// <summary>
  1426. /// Extern alias resolved.
  1427. /// </summary>
  1428. // ----------------------------------------------------------------------------------------------
  1429. [TestMethod]
  1430. public void ExternAlias()
  1431. {
  1432. var project = new CSharpProject(WorkingFolder);
  1433. project.AddFile(@"TypeResolution\ExternAlias.cs");
  1434. project.AddAliasedAssemblyReference("MyExternAlias", TestAssemblyPathAndFilename);
  1435. InvokeParser(project).ShouldBeTrue();
  1436. project.SemanticGraph.RootNamespaces.ToList().Count.ShouldEqual(2);
  1437. var namespaceRef = project.SemanticGraph.GlobalNamespace.ExternAliases.ToArray()[0].RootNamespaceReference;
  1438. namespaceRef.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1439. namespaceRef.Target.ShouldEqual(project.SemanticGraph.GetRootNamespaceByName("MyExternAlias"));
  1440. }
  1441. // ----------------------------------------------------------------------------------------------
  1442. /// <summary>
  1443. /// Error CS0576: Namespace 'namespace' contains a definition conflicting with alias 'identifier' (extern alias)
  1444. /// </summary>
  1445. // ----------------------------------------------------------------------------------------------
  1446. [TestMethod]
  1447. public void CS0576_ExternAliasConflictsWithNamespaceDeclaration()
  1448. {
  1449. var project = new CSharpProject(WorkingFolder);
  1450. project.AddFile(@"TypeResolution\CS0576_ExternAliasConflictsWithNamespaceDeclaration.cs");
  1451. project.AddAliasedAssemblyReference("MyExternAlias", TestAssemblyPathAndFilename);
  1452. InvokeParser(project).ShouldBeFalse();
  1453. project.Errors.Count.ShouldEqual(1);
  1454. project.Errors[0].Code.ShouldEqual("CS0576");
  1455. project.Warnings.Count.ShouldEqual(0);
  1456. }
  1457. // ----------------------------------------------------------------------------------------------
  1458. /// <summary>
  1459. /// Error CS0576: Namespace 'namespace' contains a definition conflicting with alias 'identifier' (extern alias)
  1460. /// </summary>
  1461. // ----------------------------------------------------------------------------------------------
  1462. [TestMethod]
  1463. public void CS0576_ExternAliasConflictsWithTypeDeclaration()
  1464. {
  1465. var project = new CSharpProject(WorkingFolder);
  1466. project.AddFile(@"TypeResolution\CS0576_ExternAliasConflictsWithTypeDeclaration.cs");
  1467. project.AddAliasedAssemblyReference("MyExternAlias", TestAssemblyPathAndFilename);
  1468. InvokeParser(project).ShouldBeFalse();
  1469. project.Errors.Count.ShouldEqual(1);
  1470. project.Errors[0].Code.ShouldEqual("CS0576");
  1471. project.Warnings.Count.ShouldEqual(0);
  1472. }
  1473. // ----------------------------------------------------------------------------------------------
  1474. /// <summary>
  1475. /// The same using namespace directive specified in the same namespace but in different source regions
  1476. /// </summary>
  1477. // ----------------------------------------------------------------------------------------------
  1478. [TestMethod]
  1479. public void SameUsingSameNamespaceDifferentRegions()
  1480. {
  1481. var project = new CSharpProject(WorkingFolder);
  1482. project.AddFile(@"TypeResolution\SameUsingSameNamespaceDifferentRegions.cs");
  1483. InvokeParser(project).ShouldBeTrue();
  1484. project.SemanticGraph.GlobalNamespace.GetChildNamespace("A").UsingNamespaces.ToList().Count.ShouldEqual(2);
  1485. }
  1486. // ----------------------------------------------------------------------------------------------
  1487. /// <summary>
  1488. /// The same using alias directive specified in the same namespace but in different source regions
  1489. /// </summary>
  1490. // ----------------------------------------------------------------------------------------------
  1491. [TestMethod]
  1492. public void SameUsingAliasSameNamespaceDifferentRegions()
  1493. {
  1494. var project = new CSharpProject(WorkingFolder);
  1495. project.AddFile(@"TypeResolution\SameUsingAliasSameNamespaceDifferentRegions.cs");
  1496. InvokeParser(project).ShouldBeTrue();
  1497. project.SemanticGraph.GlobalNamespace.GetChildNamespace("A").UsingAliases.ToList().Count.ShouldEqual(2);
  1498. }
  1499. // ----------------------------------------------------------------------------------------------
  1500. /// <summary>
  1501. /// The same extern alias directive specified in the same namespace but in different source regions
  1502. /// </summary>
  1503. // ----------------------------------------------------------------------------------------------
  1504. [TestMethod]
  1505. public void SameExternAliasSameNamespaceDifferentRegions()
  1506. {
  1507. var project = new CSharpProject(WorkingFolder);
  1508. project.AddFile(@"TypeResolution\SameExternAliasSameNamespaceDifferentRegions.cs");
  1509. project.AddAliasedAssemblyReference("MyExternAlias", TestAssemblyPathAndFilename);
  1510. InvokeParser(project).ShouldBeTrue();
  1511. project.SemanticGraph.GlobalNamespace.GetChildNamespace("A").ExternAliases.ToList().Count.ShouldEqual(2);
  1512. }
  1513. // ----------------------------------------------------------------------------------------------
  1514. /// <summary>
  1515. /// error CS0246: global qualified type not found
  1516. /// </summary>
  1517. // ----------------------------------------------------------------------------------------------
  1518. [TestMethod]
  1519. public void CS0246_GlobalQualifiedTypeNotFound()
  1520. {
  1521. var project = new CSharpProject(WorkingFolder);
  1522. project.AddFile(@"TypeResolution\CS0246_GlobalQualifiedTypeNotFound.cs");
  1523. InvokeParser(project).ShouldBeFalse();
  1524. project.Errors.Count.ShouldEqual(1);
  1525. project.Errors[0].Code.ShouldEqual("CS0246");
  1526. project.Warnings.Count.ShouldEqual(0);
  1527. }
  1528. // ----------------------------------------------------------------------------------------------
  1529. /// <summary>
  1530. /// Namespace and type references with global qualifier.
  1531. /// </summary>
  1532. // ----------------------------------------------------------------------------------------------
  1533. [TestMethod]
  1534. public void GlobalQualifiedNames()
  1535. {
  1536. var project = new CSharpProject(WorkingFolder);
  1537. project.AddFile(@"TypeResolution\GlobalQualifiedNames.cs");
  1538. InvokeParser(project).ShouldBeTrue();
  1539. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A");
  1540. int i = 0;
  1541. // global::A x1;
  1542. {
  1543. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1544. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1545. fieldEntity.TypeReference.Target.ToString().ShouldEqual("global::A");
  1546. }
  1547. // global::B<int> x2;
  1548. {
  1549. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1550. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1551. fieldEntity.TypeReference.Target.ToString().ShouldEqual("global::B`1[global::System.Int32]");
  1552. }
  1553. // global::C.D x3;
  1554. {
  1555. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1556. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1557. fieldEntity.TypeReference.Target.ToString().ShouldEqual("global::C.D");
  1558. }
  1559. // global::C.E<int> x4;
  1560. {
  1561. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1562. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1563. fieldEntity.TypeReference.Target.ToString().ShouldEqual("global::C.E`1[global::System.Int32]");
  1564. }
  1565. // global::C.E<int>.F<long> x5;
  1566. {
  1567. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1568. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1569. fieldEntity.TypeReference.Target.ToString().ShouldEqual("global::C.E`1[global::System.Int32]+F`1[global::System.Int64]");
  1570. }
  1571. }
  1572. // ----------------------------------------------------------------------------------------------
  1573. /// <summary>
  1574. /// error CS0431: Cannot use alias 'C' with '::' since the alias references a type. Use '.' instead.
  1575. /// </summary>
  1576. // ----------------------------------------------------------------------------------------------
  1577. [TestMethod]
  1578. public void CS0431_QualifierRefersToType()
  1579. {
  1580. var project = new CSharpProject(WorkingFolder);
  1581. project.AddFile(@"TypeResolution\CS0431_QualifierRefersToType.cs");
  1582. InvokeParser(project).ShouldBeFalse();
  1583. project.Errors.Count.ShouldEqual(1);
  1584. project.Errors[0].Code.ShouldEqual("CS0431");
  1585. project.Warnings.Count.ShouldEqual(0);
  1586. }
  1587. // ----------------------------------------------------------------------------------------------
  1588. /// <summary>
  1589. /// Namespace and type references with extern alias qualifier.
  1590. /// </summary>
  1591. // ----------------------------------------------------------------------------------------------
  1592. [TestMethod]
  1593. public void ExternAliasQualifiedNames()
  1594. {
  1595. var project = new CSharpProject(WorkingFolder);
  1596. project.AddFile(@"TypeResolution\ExternAliasQualifiedNames.cs");
  1597. project.AddAliasedAssemblyReference("MyExternAlias", TestAssemblyPathAndFilename);
  1598. InvokeParser(project).ShouldBeTrue();
  1599. int i = 0;
  1600. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A");
  1601. // MyExternAlias::Class0 x0;
  1602. {
  1603. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1604. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1605. fieldEntity.TypeReference.Target.ShouldEqual(
  1606. project.SemanticGraph.GetRootNamespaceByName("MyExternAlias").GetSingleChildType<ClassEntity>("Class0"));
  1607. }
  1608. // MyExternAlias::A.B.Class1 x1;
  1609. {
  1610. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1611. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1612. fieldEntity.TypeReference.Target.ShouldEqual(
  1613. project.SemanticGraph.GetRootNamespaceByName("MyExternAlias").GetChildNamespace("A")
  1614. .GetChildNamespace("B").GetSingleChildType<ClassEntity>("Class1"));
  1615. }
  1616. // MyExternAlias::A.B.Generic1<int,long> x2;
  1617. {
  1618. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1619. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1620. fieldEntity.TypeReference.Target.ToString().ShouldEqual("MyExternAlias::A.B.Generic1`2[global::System.Int32,global::System.Int64]");
  1621. }
  1622. i = 0;
  1623. classEntity = project.SemanticGraph.GlobalNamespace.GetChildNamespace("B").GetChildNamespace("C")
  1624. .GetSingleChildType<ClassEntity>("A");
  1625. // MyExternAlias::Class0 x0;
  1626. {
  1627. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1628. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1629. fieldEntity.TypeReference.Target.ShouldEqual(
  1630. project.SemanticGraph.GetRootNamespaceByName("MyExternAlias").GetSingleChildType<ClassEntity>("Class0"));
  1631. }
  1632. // MyExternAlias::A.B.Class1 x1;
  1633. {
  1634. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1635. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1636. fieldEntity.TypeReference.Target.ShouldEqual(
  1637. project.SemanticGraph.GetRootNamespaceByName("MyExternAlias").GetChildNamespace("A")
  1638. .GetChildNamespace("B").GetSingleChildType<ClassEntity>("Class1"));
  1639. }
  1640. // MyExternAlias::A.B.Generic1<int,long> x2;
  1641. {
  1642. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1643. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1644. fieldEntity.TypeReference.Target.ToString().ShouldEqual("MyExternAlias::A.B.Generic1`2[global::System.Int32,global::System.Int64]");
  1645. }
  1646. }
  1647. // ----------------------------------------------------------------------------------------------
  1648. /// <summary>
  1649. /// Using alias resolved.
  1650. /// </summary>
  1651. // ----------------------------------------------------------------------------------------------
  1652. [TestMethod]
  1653. public void UsingAlias()
  1654. {
  1655. var project = new CSharpProject(WorkingFolder);
  1656. project.AddFile(@"TypeResolution\UsingAlias.cs");
  1657. InvokeParser(project).ShouldBeTrue();
  1658. var global = project.SemanticGraph.GlobalNamespace;
  1659. var namespaceA = global.GetChildNamespace("A");
  1660. var classB = namespaceA.GetSingleChildType<ClassEntity>("B");
  1661. var namespaceC = global.GetChildNamespace("C");
  1662. var classD = namespaceC.GetSingleChildType<ClassEntity>("D");
  1663. var usingAliasE = namespaceC.GetUsingAliasByNameAndSourcePoint("E", classD.SyntaxNodes[0].SourcePoint);
  1664. usingAliasE.AliasedNamespace.ShouldEqual(namespaceA);
  1665. usingAliasE.AliasedType.ShouldBeNull();
  1666. classD.BaseClass.ShouldEqual(classB);
  1667. }
  1668. // ----------------------------------------------------------------------------------------------
  1669. /// <summary>
  1670. /// Namespace and type references with using alias qualifier.
  1671. /// </summary>
  1672. // ----------------------------------------------------------------------------------------------
  1673. [TestMethod]
  1674. public void UsingAliasQualifiedNames()
  1675. {
  1676. var project = new CSharpProject(WorkingFolder);
  1677. project.AddFile(@"TypeResolution\UsingAliasQualifiedNames.cs");
  1678. InvokeParser(project).ShouldBeTrue();
  1679. int i = 0;
  1680. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<TypeEntity>("A");
  1681. // X::Y1 x0;
  1682. {
  1683. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1684. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1685. fieldEntity.TypeReference.Target.ToString().ShouldEqual("global::Y.Y1");
  1686. }
  1687. // X::V.W.Y2 x1;
  1688. {
  1689. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1690. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1691. fieldEntity.TypeReference.Target.ToString().ShouldEqual("global::Y.V.W.Y2");
  1692. }
  1693. // X::Y3<int,long> x2;
  1694. {
  1695. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1696. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1697. fieldEntity.TypeReference.Target.ToString().ShouldEqual("global::Y.Y3`2[global::System.Int32,global::System.Int64]");
  1698. }
  1699. i = 0;
  1700. classEntity = project.SemanticGraph.GlobalNamespace.GetChildNamespace("B").GetChildNamespace("C").ChildTypes.ToList()[0];
  1701. // X::Y1 x0;
  1702. {
  1703. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1704. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1705. fieldEntity.TypeReference.Target.ToString().ShouldEqual("global::Y.Y1");
  1706. }
  1707. // X::V.W.Y2 x1;
  1708. {
  1709. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1710. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1711. fieldEntity.TypeReference.Target.ToString().ShouldEqual("global::Y.V.W.Y2");
  1712. }
  1713. // X::Y3<int,long> x2;
  1714. {
  1715. var fieldEntity = classEntity.OwnMembers.ToArray()[i++] as FieldEntity;
  1716. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1717. fieldEntity.TypeReference.Target.ToString().ShouldEqual("global::Y.Y3`2[global::System.Int32,global::System.Int64]");
  1718. }
  1719. }
  1720. // ----------------------------------------------------------------------------------------------
  1721. /// <summary>
  1722. /// Enum underlying type resolution.
  1723. /// </summary>
  1724. // ----------------------------------------------------------------------------------------------
  1725. [TestMethod]
  1726. public void EnumUnderlyingType()
  1727. {
  1728. var project = new CSharpProject(WorkingFolder);
  1729. project.AddFile(@"TypeResolution\EnumUnderlyingType.cs");
  1730. InvokeParser(project).ShouldBeTrue();
  1731. {
  1732. var enumEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<EnumEntity>("A");
  1733. enumEntity.UnderlyingTypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1734. enumEntity.UnderlyingTypeReference.Target.FullyQualifiedName.ShouldEqual("System.Int32");
  1735. (enumEntity.OwnMembers.ToList()[0] as EnumMemberEntity).TypeReference.ShouldEqual(enumEntity.UnderlyingTypeReference);
  1736. }
  1737. {
  1738. var enumEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<EnumEntity>("B");
  1739. enumEntity.UnderlyingTypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1740. enumEntity.UnderlyingTypeReference.Target.FullyQualifiedName.ShouldEqual("System.Int64");
  1741. (enumEntity.OwnMembers.ToList()[0] as EnumMemberEntity).TypeReference.ShouldEqual(enumEntity.UnderlyingTypeReference);
  1742. }
  1743. }
  1744. // ----------------------------------------------------------------------------------------------
  1745. /// <summary>
  1746. /// Delegate return type.
  1747. /// </summary>
  1748. // ----------------------------------------------------------------------------------------------
  1749. [TestMethod]
  1750. public void DelegateType()
  1751. {
  1752. var project = new CSharpProject(WorkingFolder);
  1753. project.AddFile(@"TypeResolution\DelegateType.cs");
  1754. InvokeParser(project).ShouldBeTrue();
  1755. {
  1756. var delegateEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<DelegateEntity>("A");
  1757. delegateEntity.ReturnTypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1758. delegateEntity.ReturnType.FullyQualifiedName.ShouldEqual("System.Int32");
  1759. }
  1760. {
  1761. var delegateEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<DelegateEntity>("B");
  1762. delegateEntity.ReturnTypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1763. delegateEntity.ReturnType.FullyQualifiedName.ShouldEqual("System.Void");
  1764. }
  1765. }
  1766. // ----------------------------------------------------------------------------------------------
  1767. /// <summary>
  1768. /// error CS1008: Type byte, sbyte, short, ushort, int, uint, long, or ulong expect
  1769. /// </summary>
  1770. // ----------------------------------------------------------------------------------------------
  1771. [TestMethod]
  1772. public void CS1008_EnumBaseNonIntegral()
  1773. {
  1774. var project = new CSharpProject(WorkingFolder);
  1775. project.AddFile(@"TypeResolution\CS1008_EnumBaseNonIntegral.cs");
  1776. InvokeParser(project).ShouldBeFalse();
  1777. project.Errors.Count.ShouldEqual(2);
  1778. project.Errors[0].Code.ShouldEqual("CS1008");
  1779. project.Errors[1].Code.ShouldEqual("CS1008");
  1780. project.Warnings.Count.ShouldEqual(0);
  1781. }
  1782. // ----------------------------------------------------------------------------------------------
  1783. /// <summary>
  1784. /// Property type resolution.
  1785. /// </summary>
  1786. // ----------------------------------------------------------------------------------------------
  1787. [TestMethod]
  1788. public void Property()
  1789. {
  1790. var project = new CSharpProject(WorkingFolder);
  1791. project.AddFile(@"TypeResolution\Property.cs");
  1792. InvokeParser(project).ShouldBeTrue();
  1793. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A");
  1794. int i = 0;
  1795. // int B { get; set; }
  1796. {
  1797. var propertyEntity = classEntity.OwnMembers.ToList()[i] as PropertyEntity;
  1798. propertyEntity.IsInvocable.ShouldBeFalse();
  1799. // Check property type resolution
  1800. propertyEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1801. propertyEntity.Type.FullyQualifiedName.ShouldEqual("System.Int32");
  1802. propertyEntity.AutoImplementedField.Type.FullyQualifiedName.ShouldEqual("System.Int32");
  1803. // Check explicitly implemented interface resolution
  1804. propertyEntity.InterfaceReference.ShouldBeNull();
  1805. propertyEntity.Interface.ShouldBeNull();
  1806. // Check that the property can be retrieved by name.
  1807. classEntity.GetOwnMember<PropertyEntity>(propertyEntity.Name).ShouldEqual(propertyEntity);
  1808. }
  1809. i++;
  1810. // int I.B { get; set; }
  1811. {
  1812. var propertyEntity = classEntity.OwnMembers.ToList()[i] as PropertyEntity;
  1813. // Check property type resolution
  1814. propertyEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1815. propertyEntity.Type.FullyQualifiedName.ShouldEqual("System.Int32");
  1816. propertyEntity.AutoImplementedField.Type.FullyQualifiedName.ShouldEqual("System.Int32");
  1817. // Check explicitly implemented interface resolution
  1818. propertyEntity.InterfaceReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1819. propertyEntity.Interface.ToString().ShouldEqual("global::C.I`1[global::System.Int32]");
  1820. // Check that the property can be retrieved by name.
  1821. classEntity.GetExplicitlyImplementedMember<PropertyEntity>(propertyEntity.Name, propertyEntity.Interface).ShouldEqual(propertyEntity);
  1822. }
  1823. i++;
  1824. // D DP { get; set; } // D is a delegate, so DP is invocable
  1825. {
  1826. var propertyEntity = classEntity.OwnMembers.ToList()[i] as PropertyEntity;
  1827. propertyEntity.IsInvocable.ShouldBeTrue();
  1828. }
  1829. }
  1830. // ----------------------------------------------------------------------------------------------
  1831. /// <summary>
  1832. /// Field type resolution.
  1833. /// </summary>
  1834. // ----------------------------------------------------------------------------------------------
  1835. [TestMethod]
  1836. public void Field()
  1837. {
  1838. var project = new CSharpProject(WorkingFolder);
  1839. project.AddFile(@"TypeResolution\Field.cs");
  1840. InvokeParser(project).ShouldBeTrue();
  1841. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A");
  1842. int i = 0;
  1843. // int a;
  1844. {
  1845. var fieldEntity = classEntity.OwnMembers.ToList()[i] as FieldEntity;
  1846. fieldEntity.IsInvocable.ShouldBeFalse();
  1847. // Check member type resolution
  1848. fieldEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1849. fieldEntity.Type.FullyQualifiedName.ShouldEqual("System.Int32");
  1850. // Check that the member can be retrieved by name.
  1851. classEntity.GetOwnMember<FieldEntity>(fieldEntity.Name).ShouldEqual(fieldEntity);
  1852. }
  1853. i++;
  1854. // D d; // D is a delegate, so "d" is invocable
  1855. {
  1856. var fieldEntity = classEntity.OwnMembers.ToList()[i] as FieldEntity;
  1857. fieldEntity.IsInvocable.ShouldBeTrue();
  1858. }
  1859. }
  1860. // ----------------------------------------------------------------------------------------------
  1861. /// <summary>
  1862. /// ConstantMember type resolution.
  1863. /// </summary>
  1864. // ----------------------------------------------------------------------------------------------
  1865. [TestMethod]
  1866. public void ConstantMember()
  1867. {
  1868. var project = new CSharpProject(WorkingFolder);
  1869. project.AddFile(@"TypeResolution\ConstantMember.cs");
  1870. InvokeParser(project).ShouldBeTrue();
  1871. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A");
  1872. int i = 0;
  1873. // const int a = 0, b = 1;
  1874. {
  1875. {
  1876. var constantEntity = classEntity.OwnMembers.ToList()[i] as ConstantMemberEntity;
  1877. constantEntity.ToString().ShouldEqual("global::A_a");
  1878. constantEntity.IsInvocable.ShouldBeFalse();
  1879. // Check member type resolution
  1880. constantEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1881. constantEntity.Type.FullyQualifiedName.ShouldEqual("System.Int32");
  1882. // Check that the member can be retrieved by name.
  1883. classEntity.GetOwnMember<ConstantMemberEntity>(constantEntity.Name).ShouldEqual(constantEntity);
  1884. }
  1885. i++;
  1886. {
  1887. var constantEntity = classEntity.OwnMembers.ToList()[i] as ConstantMemberEntity;
  1888. constantEntity.ToString().ShouldEqual("global::A_b");
  1889. constantEntity.IsInvocable.ShouldBeFalse();
  1890. // Check member type resolution
  1891. constantEntity.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1892. constantEntity.Type.FullyQualifiedName.ShouldEqual("System.Int32");
  1893. // Check that the member can be retrieved by name.
  1894. classEntity.GetOwnMember<ConstantMemberEntity>(constantEntity.Name).ShouldEqual(constantEntity);
  1895. }
  1896. }
  1897. i++;
  1898. // const D d = null; // D is a delegate, so "d" is invocable
  1899. {
  1900. var constantEntity = classEntity.OwnMembers.ToList()[i] as ConstantMemberEntity;
  1901. constantEntity.IsInvocable.ShouldBeTrue();
  1902. }
  1903. }
  1904. // ----------------------------------------------------------------------------------------------
  1905. /// <summary>
  1906. /// Method type resolution.
  1907. /// </summary>
  1908. // ----------------------------------------------------------------------------------------------
  1909. [TestMethod]
  1910. public void Method()
  1911. {
  1912. var project = new CSharpProject(WorkingFolder);
  1913. project.AddFile(@"TypeResolution\Method.cs");
  1914. InvokeParser(project).ShouldBeTrue();
  1915. var classEntity = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A",2);
  1916. var members = classEntity.OwnMembers.ToList();
  1917. int i = 0;
  1918. // void B<T2, T3>(A<int, long> a, T1 t1, T2 t2, T3 t3) { }
  1919. {
  1920. var methodEntity = members[i] as MethodEntity;
  1921. // Check return type resolution
  1922. methodEntity.ReturnTypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1923. methodEntity.ReturnType.ToString().ShouldEqual("T3");
  1924. // Check explicitly implemented interface resolution
  1925. methodEntity.InterfaceReference.ShouldBeNull();
  1926. methodEntity.Interface.ShouldBeNull();
  1927. // Check parameter type resolution
  1928. var parameters = methodEntity.Parameters.ToList();
  1929. parameters[0].TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1930. (parameters[0].Type as ClassEntity).DirectGenericTemplate.ShouldEqual(classEntity);
  1931. parameters[1].TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1932. parameters[1].Type.ShouldEqual(classEntity.GetOwnTypeParameterByName("T1"));
  1933. parameters[2].TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1934. parameters[2].Type.ShouldEqual(methodEntity.GetOwnTypeParameterByName("T2"));
  1935. parameters[3].TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1936. parameters[3].Type.ShouldEqual(methodEntity.GetOwnTypeParameterByName("T3"));
  1937. classEntity.GetOwnMethod(methodEntity.Signature).ShouldEqual(methodEntity);
  1938. // Check TypeParameterMap
  1939. var typeParameterMap = methodEntity.TypeParameterMap;
  1940. typeParameterMap.Count.ShouldEqual(4);
  1941. var typeParameters = typeParameterMap.TypeParameters.ToList();
  1942. typeParameters[0].ToString().ShouldEqual("global::A`2.T1");
  1943. typeParameters[1].ToString().ShouldEqual("global::A`2.T2");
  1944. typeParameters[2].ToString().ShouldEqual("T2");
  1945. typeParameters[3].ToString().ShouldEqual("T3");
  1946. var typeArguments = typeParameterMap.TypeArguments.ToList();
  1947. typeArguments[0].ShouldBeNull();
  1948. typeArguments[1].ShouldBeNull();
  1949. typeArguments[2].ShouldBeNull();
  1950. typeArguments[3].ShouldBeNull();
  1951. }
  1952. i++;
  1953. // void C() {}
  1954. {
  1955. var methodEntity = members[i] as MethodEntity;
  1956. // Check return type resolution
  1957. methodEntity.ReturnTypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1958. methodEntity.ReturnType.ToString().ShouldEqual("global::System.Void");
  1959. // Check explicitly implemented interface resolution
  1960. methodEntity.InterfaceReference.ShouldBeNull();
  1961. methodEntity.Interface.ShouldBeNull();
  1962. // Check parameter type resolution
  1963. methodEntity.Parameters.ToList().Count.ShouldEqual(0);
  1964. classEntity.GetOwnMethod(methodEntity.Signature).ShouldEqual(methodEntity);
  1965. }
  1966. i++;
  1967. // void I<T1, T2>.B<T2, T3>(A<int, long> a, T1 t1, T2 t2, T3 t3) { }
  1968. {
  1969. var methodEntity = members[i] as MethodEntity;
  1970. // Check return type resolution
  1971. methodEntity.ReturnTypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1972. methodEntity.ReturnType.ToString().ShouldEqual("T3");
  1973. // Check explicitly implemented interface resolution
  1974. methodEntity.InterfaceReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1975. methodEntity.Interface.ToString().ShouldEqual("global::I`2[global::A`2.T1,global::A`2.T2]");
  1976. // Check parameter type resolution
  1977. var parameters = methodEntity.Parameters.ToList();
  1978. parameters[0].TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1979. parameters[0].Type.DirectGenericTemplate.ShouldEqual(classEntity);
  1980. parameters[1].TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1981. parameters[1].Type.ShouldEqual(classEntity.GetOwnTypeParameterByName("T1"));
  1982. parameters[2].TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1983. parameters[2].Type.ShouldEqual(methodEntity.GetOwnTypeParameterByName("T2"));
  1984. parameters[3].TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1985. parameters[3].Type.ShouldEqual(methodEntity.GetOwnTypeParameterByName("T3"));
  1986. // Check that explicitly implemented interface members are not registered into the declaration space,
  1987. // but can be retrieved by specifying the interface too.
  1988. classEntity.GetOwnMethod(methodEntity.Signature).ShouldBeNull();
  1989. classEntity.GetExplicitlyImplementedMethod(methodEntity.Signature, methodEntity.Interface).ShouldEqual(members[2]);
  1990. }
  1991. i++;
  1992. // void global::I<T1, T2>.C() { }
  1993. {
  1994. var methodEntity = members[i] as MethodEntity;
  1995. // Check return type resolution
  1996. methodEntity.ReturnTypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  1997. methodEntity.ReturnType.ToString().ShouldEqual("global::System.Void");
  1998. // Check explicitly implemented interface resolution
  1999. methodEntity.InterfaceReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  2000. methodEntity.Interface.ToString().ShouldEqual("global::I`2[global::A`2.T1,global::A`2.T2]");
  2001. // Check parameter type resolution
  2002. methodEntity.Parameters.ToList().Count.ShouldEqual(0);
  2003. // Without specifying the interface, the method's signature can be confused with void C().
  2004. classEntity.GetOwnMethod(methodEntity.Signature).ShouldEqual(members[1]);
  2005. classEntity.GetExplicitlyImplementedMethod(methodEntity.Signature, methodEntity.Interface).ShouldEqual(members[3]);
  2006. }
  2007. }
  2008. // ----------------------------------------------------------------------------------------------
  2009. /// <summary>
  2010. /// This test case was introduced because of a problem in the name resolution process.
  2011. /// During the resolution process type argument AST nodes are separated from the AST tree,
  2012. /// and their parent becomes null. Unfortunately, determining the compilation unit is using the
  2013. /// parent property, and using namespaces can be used in the resolution only if the
  2014. /// compilation unit of the AST node is known.
  2015. /// </summary>
  2016. // ----------------------------------------------------------------------------------------------
  2017. [TestMethod]
  2018. [Ignore]
  2019. public void TypeArgumentCanBeResolvedWithUsingNamespace()
  2020. {
  2021. var project = new CSharpProject(WorkingFolder);
  2022. project.AddFile(@"TypeResolution\TypeArgumentCanBeResolvedWithUsingNamespace.cs");
  2023. InvokeParser(project).ShouldBeTrue();
  2024. }
  2025. // ----------------------------------------------------------------------------------------------
  2026. /// <summary>
  2027. /// error CS0122: 'N.InternalClass' is inaccessible due to its protection level.
  2028. /// Testing with a qualified reference: "using X2 = N.InternalClass;"
  2029. /// </summary>
  2030. // ----------------------------------------------------------------------------------------------
  2031. [TestMethod]
  2032. public void CS0122_ClassInaccessible_Qualified()
  2033. {
  2034. var project = new CSharpProject(WorkingFolder);
  2035. project.AddFile(@"TypeResolution\CS0122_ClassInaccessible_Qualified.cs");
  2036. project.AddAssemblyReference(TestAssemblyPathAndFilename);
  2037. InvokeParser(project).ShouldBeFalse();
  2038. project.Errors.Count.ShouldEqual(1);
  2039. project.Errors[0].Code.ShouldEqual("CS0122");
  2040. project.Warnings.Count.ShouldEqual(0);
  2041. }
  2042. // ----------------------------------------------------------------------------------------------
  2043. /// <summary>
  2044. /// error CS0122: 'N.InternalClass' is inaccessible due to its protection level.
  2045. /// Testing with an unqualified reference: "using X2 = InternalClass;"
  2046. /// </summary>
  2047. // ----------------------------------------------------------------------------------------------
  2048. [TestMethod]
  2049. public void CS0122_ClassInaccessible_Unqualified()
  2050. {
  2051. var project = new CSharpProject(WorkingFolder);
  2052. project.AddFile(@"TypeResolution\CS0122_ClassInaccessible_Unqualified.cs");
  2053. project.AddAssemblyReference(TestAssemblyPathAndFilename);
  2054. InvokeParser(project).ShouldBeFalse();
  2055. project.Errors.Count.ShouldEqual(1);
  2056. project.Errors[0].Code.ShouldEqual("CS0122");
  2057. project.Warnings.Count.ShouldEqual(0);
  2058. }
  2059. // ----------------------------------------------------------------------------------------------
  2060. /// <summary>
  2061. /// Testing that when looking for a nested type in base classes, the accessible one
  2062. /// beats the inaccessible even if it's in the less derived class.
  2063. /// </summary>
  2064. // ----------------------------------------------------------------------------------------------
  2065. [TestMethod]
  2066. public void NestedAccessibleType()
  2067. {
  2068. var project = new CSharpProject(WorkingFolder);
  2069. project.AddFile(@"TypeResolution\NestedAccessibleType.cs");
  2070. InvokeParser(project).ShouldBeTrue();
  2071. var global = project.SemanticGraph.GlobalNamespace;
  2072. var classA = global.GetSingleChildType<ClassEntity>("A");
  2073. var member = classA.GetOwnMember<FieldEntity>("a");
  2074. member.Type.ShouldEqual(global.GetSingleChildType<ClassEntity>("C").GetSingleChildType<ClassEntity>("Nested"));
  2075. }
  2076. // ----------------------------------------------------------------------------------------------
  2077. /// <summary>
  2078. /// Testing that when only an inaccessible type is found then CS0122 is reported.
  2079. /// </summary>
  2080. // ----------------------------------------------------------------------------------------------
  2081. [TestMethod]
  2082. [Ignore] // TODO: CS0246 is reported which seems like conforming to the spec, but csc.exe reports CS0122.
  2083. public void NestedInaccessibleType_Unresolvable()
  2084. {
  2085. var project = new CSharpProject(WorkingFolder);
  2086. project.AddFile(@"TypeResolution\NestedInaccessibleType_Unresolvable.cs");
  2087. InvokeParser(project).ShouldBeFalse();
  2088. project.Errors.Count.ShouldEqual(1);
  2089. project.Errors[0].Code.ShouldEqual("CS0122");
  2090. project.Warnings.Count.ShouldEqual(0);
  2091. }
  2092. // ----------------------------------------------------------------------------------------------
  2093. /// <summary>
  2094. /// Testing that when an inaccessible type is found but also an imported type is found with the
  2095. /// same name, then the imported type wins.
  2096. /// </summary>
  2097. // ----------------------------------------------------------------------------------------------
  2098. [TestMethod]
  2099. public void NestedInaccessibleType_Resolvable()
  2100. {
  2101. var project = new CSharpProject(WorkingFolder);
  2102. project.AddFile(@"TypeResolution\NestedInaccessibleType_Resolvable.cs");
  2103. InvokeParser(project).ShouldBeTrue();
  2104. var global = project.SemanticGraph.GlobalNamespace;
  2105. var classA = global.GetSingleChildType<ClassEntity>("A");
  2106. var member = classA.GetOwnMember<FieldEntity>("a");
  2107. member.Type.ShouldEqual(global.GetChildNamespace("N").GetSingleChildType<ClassEntity>("Nested"));
  2108. }
  2109. // ----------------------------------------------------------------------------------------------
  2110. /// <summary>
  2111. /// error CS0547: 'a': property or indexer cannot have void type
  2112. /// </summary>
  2113. // ----------------------------------------------------------------------------------------------
  2114. [TestMethod]
  2115. public void CS0547_VoidProperty()
  2116. {
  2117. var project = new CSharpProject(WorkingFolder);
  2118. project.AddFile(@"TypeResolution\CS0547_VoidProperty.cs");
  2119. InvokeParser(project).ShouldBeFalse();
  2120. project.Errors.Count.ShouldEqual(1);
  2121. project.Errors[0].Code.ShouldEqual("CS0547");
  2122. project.Warnings.Count.ShouldEqual(0);
  2123. }
  2124. // ----------------------------------------------------------------------------------------------
  2125. /// <summary>
  2126. /// error CS0670: Field cannot have void type
  2127. /// </summary>
  2128. // ----------------------------------------------------------------------------------------------
  2129. [TestMethod]
  2130. public void CS0670_VoidField()
  2131. {
  2132. var project = new CSharpProject(WorkingFolder);
  2133. project.AddFile(@"TypeResolution\CS0670_VoidField.cs");
  2134. InvokeParser(project).ShouldBeFalse();
  2135. project.Errors.Count.ShouldEqual(1);
  2136. project.Errors[0].Code.ShouldEqual("CS0670");
  2137. project.Warnings.Count.ShouldEqual(0);
  2138. }
  2139. // ----------------------------------------------------------------------------------------------
  2140. /// <summary>
  2141. /// error CS1547: Const member cannot be type 'void'
  2142. /// </summary>
  2143. // ----------------------------------------------------------------------------------------------
  2144. [TestMethod]
  2145. public void CS1547_VoidConst()
  2146. {
  2147. var project = new CSharpProject(WorkingFolder);
  2148. project.AddFile(@"TypeResolution\CS1547_VoidConst.cs");
  2149. InvokeParser(project).ShouldBeFalse();
  2150. project.Errors.Count.ShouldEqual(1);
  2151. project.Errors[0].Code.ShouldEqual("CS1547");
  2152. project.Warnings.Count.ShouldEqual(0);
  2153. }
  2154. // ----------------------------------------------------------------------------------------------
  2155. /// <summary>
  2156. /// Tests the resolution of types in constructed class members.
  2157. /// </summary>
  2158. // ----------------------------------------------------------------------------------------------
  2159. [TestMethod]
  2160. public void ConstructedClassMembers()
  2161. {
  2162. var project = new CSharpProject(WorkingFolder);
  2163. project.AddFile(@"TypeResolution\ConstructedClassMembers.cs");
  2164. InvokeParser(project).ShouldBeTrue();
  2165. var classA = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A", 2);
  2166. // A<int, long> a0;
  2167. {
  2168. var field = classA.GetOwnMember<FieldEntity>("a0");
  2169. var type = field.Type as ClassEntity;
  2170. type.IsGeneric.ShouldBeTrue();
  2171. type.IsUnboundGeneric.ShouldBeFalse();
  2172. type.IsGenericClone.ShouldBeTrue();
  2173. type.DirectGenericTemplate.ToString().ShouldEqual("global::A`2");
  2174. type.ToString().ShouldEqual("global::A`2[global::System.Int32,global::System.Int64]");
  2175. (type.DirectGenericTemplate as ClassEntity).BaseClass.ToString().ShouldEqual("global::B`1[global::A`2.T1]");
  2176. var baseClass = type.BaseClass;
  2177. baseClass.ToString().ShouldEqual("global::B`1[global::System.Int32]");
  2178. baseClass.TypeParameterMap.Count.ShouldEqual(1);
  2179. baseClass.TypeParameterMap.TypeParameters.First().ToString().ShouldEqual("global::B`1.T");
  2180. baseClass.TypeParameterMap.TypeArguments.First().ToString().ShouldEqual("global::System.Int32");
  2181. var typeArguments = type.TypeParameterMap.TypeArguments.ToList();
  2182. typeArguments[0].BuiltInTypeValue.ShouldEqual(BuiltInType.Int);
  2183. typeArguments[1].BuiltInTypeValue.ShouldEqual(BuiltInType.Long);
  2184. }
  2185. // T1 a1;
  2186. {
  2187. var member = classA.GetOwnMember<FieldEntity>("a1");
  2188. member.DirectGenericTemplate.ShouldBeNull();
  2189. var type = member.Type as TypeParameterEntity;
  2190. type.ToString().ShouldEqual("global::A`2.T1");
  2191. type.IsGeneric.ShouldBeFalse();
  2192. type.IsUnboundGeneric.ShouldBeFalse();
  2193. type.IsGenericClone.ShouldBeFalse();
  2194. type.DirectGenericTemplate.ShouldBeNull();
  2195. }
  2196. // B<T2> a2 { get; set; }
  2197. {
  2198. var member = classA.GetOwnMember<PropertyEntity>("a2");
  2199. member.Type.ToString().ShouldEqual("global::B`1[global::A`2.T2]");
  2200. }
  2201. // T1? a3;
  2202. {
  2203. var member = classA.GetOwnMember<FieldEntity>("a3");
  2204. member.Type.ToString().ShouldEqual("global::System.Nullable`1[global::A`2.T1]");
  2205. }
  2206. // A<int, T2> M1(T1[] p1, A<int, B<T2>> p2)
  2207. {
  2208. var member = classA.GetOwnMember<MethodEntity>("M1");
  2209. member.ReturnType.ToString().ShouldEqual("global::A`2[global::System.Int32,global::A`2.T2]");
  2210. var parameters = member.Parameters.ToList();
  2211. {
  2212. var paramType = parameters[0].Type as ArrayTypeEntity;
  2213. paramType.ToString().ShouldEqual("global::A`2.T1[]");
  2214. paramType.UnderlyingType.ToString().ShouldEqual("global::A`2.T1");
  2215. paramType.Rank.ShouldEqual(1);
  2216. paramType.IsOpen.ShouldBeTrue();
  2217. paramType.IsUnboundGeneric.ShouldBeFalse();
  2218. paramType.IsGenericClone.ShouldBeFalse();
  2219. }
  2220. {
  2221. var paramType = parameters[1].Type as ClassEntity;
  2222. paramType.ToString().ShouldEqual("global::A`2[global::System.Int32,global::B`1[global::A`2.T2]]");
  2223. paramType.IsOpen.ShouldBeTrue();
  2224. paramType.IsUnboundGeneric.ShouldBeFalse();
  2225. paramType.IsGenericClone.ShouldBeTrue();
  2226. }
  2227. }
  2228. // A<int, long> a0 --> T1 a1;
  2229. {
  2230. var member = classA.GetOwnMember<FieldEntity>("a0").Type.GetOwnMember<FieldEntity>("a1");
  2231. member.Type.ToString().ShouldEqual("global::System.Int32");
  2232. }
  2233. // A<int, long> a0 --> B<T2> a2 { get; set; }
  2234. {
  2235. var member = classA.GetOwnMember<FieldEntity>("a0").Type.GetOwnMember<PropertyEntity>("a2");
  2236. member.Type.ToString().ShouldEqual("global::B`1[global::System.Int64]");
  2237. }
  2238. // A<int, long> a0 --> T1? a3;
  2239. {
  2240. var member = classA.GetOwnMember<FieldEntity>("a0").Type.GetOwnMember<FieldEntity>("a3");
  2241. member.Type.IsNullableType.ShouldBeTrue();
  2242. member.Type.UnderlyingOfNullableType.ToString().ShouldEqual("global::System.Int32");
  2243. member.Type.ToString().ShouldEqual("global::System.Nullable`1[global::System.Int32]");
  2244. }
  2245. // A<int, long> a0 --> A<int, T2> M1(T1[] p1, A<int, B<T2>> p2)
  2246. {
  2247. var member = classA.GetOwnMember<FieldEntity>("a0").Type.GetOwnMember<MethodEntity>("M1");
  2248. member.ReturnType.ToString().ShouldEqual("global::A`2[global::System.Int32,global::System.Int64]");
  2249. var parameters = member.Parameters.ToList();
  2250. {
  2251. var paramType = parameters[0].Type as ArrayTypeEntity;
  2252. paramType.ToString().ShouldEqual("global::System.Int32[]");
  2253. paramType.UnderlyingType.ToString().ShouldEqual("global::System.Int32");
  2254. paramType.Rank.ShouldEqual(1);
  2255. paramType.IsOpen.ShouldBeFalse();
  2256. paramType.IsGenericClone.ShouldBeFalse();
  2257. }
  2258. {
  2259. var paramType = parameters[1].Type as ClassEntity;
  2260. paramType.ToString().ShouldEqual("global::A`2[global::System.Int32,global::B`1[global::System.Int64]]");
  2261. paramType.IsOpen.ShouldBeFalse();
  2262. paramType.IsUnboundGeneric.ShouldBeFalse();
  2263. paramType.IsGenericClone.ShouldBeTrue();
  2264. }
  2265. }
  2266. var classA2 = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A2", 2);
  2267. // A2<T2, T1> a1;
  2268. {
  2269. var field = classA2.GetOwnMember<FieldEntity>("a1");
  2270. var type = field.Type as ClassEntity;
  2271. type.DirectGenericTemplate.ToString().ShouldEqual("global::A2`2");
  2272. type.ToString().ShouldEqual("global::A2`2[global::A2`2.T2,global::A2`2.T1]");
  2273. }
  2274. // A2<byte, char> a2;
  2275. {
  2276. var field = classA2.GetOwnMember<FieldEntity>("a2");
  2277. var type = field.Type as ClassEntity;
  2278. type.DirectGenericTemplate.ToString().ShouldEqual("global::A2`2");
  2279. type.ToString().ShouldEqual("global::A2`2[global::System.Byte,global::System.Char]");
  2280. }
  2281. // A2<T2, T1> a1 --> A2<T2, T1> a1;
  2282. {
  2283. var member = classA2.GetOwnMember<FieldEntity>("a1").Type.GetOwnMember<FieldEntity>("a1");
  2284. member.Type.ToString().ShouldEqual("global::A2`2[global::A2`2.T1,global::A2`2.T2]");
  2285. }
  2286. // A2<byte, char> a2 --> A2<T2, T1> a1;
  2287. {
  2288. var member = classA2.GetOwnMember<FieldEntity>("a2").Type.GetOwnMember<FieldEntity>("a1");
  2289. member.Type.ToString().ShouldEqual("global::A2`2[global::System.Char,global::System.Byte]");
  2290. }
  2291. }
  2292. // ----------------------------------------------------------------------------------------------
  2293. /// <summary>
  2294. /// Tests the resolution of type references in semantic entities imported from mscorlib.
  2295. /// </summary>
  2296. // ----------------------------------------------------------------------------------------------
  2297. [TestMethod]
  2298. public void MscorlibTypeReferenceResolution()
  2299. {
  2300. var project = new CSharpProject(WorkingFolder);
  2301. InvokeParser(project).ShouldBeTrue();
  2302. project.SemanticGraph.AcceptVisitor(new UnresolvedTypeFinderSemanticGraphVisitor());
  2303. }
  2304. // ----------------------------------------------------------------------------------------------
  2305. /// <summary>
  2306. /// Tests the resolution of type references to constructed types in reflected types.
  2307. /// </summary>
  2308. // ----------------------------------------------------------------------------------------------
  2309. [TestMethod]
  2310. public void ReflectedConstructedTypes()
  2311. {
  2312. var project = new CSharpProject(WorkingFolder);
  2313. project.AddAssemblyReference(TestAssemblyPathAndFilename);
  2314. InvokeParser(project).ShouldBeTrue();
  2315. var constructedTestClass = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("ConstructedTest", 0);
  2316. {
  2317. var field = constructedTestClass.GetOwnMember<FieldEntity>("a1");
  2318. field.Type.ToString().ShouldEqual("global::NonGeneric+Generic1`2[global::System.Int32,global::System.Int64]+Generic2+Generic3`1[global::System.String]");
  2319. }
  2320. {
  2321. var field = constructedTestClass.GetOwnMember<FieldEntity>("a2");
  2322. field.Type.ToString().ShouldEqual("global::NonGeneric+Generic1`2[global::System.Int32,global::System.Int64]+Generic2");
  2323. }
  2324. {
  2325. var field = constructedTestClass.GetOwnMember<FieldEntity>("a3");
  2326. field.Type.ToString().ShouldEqual("global::NonGeneric+Generic1`2[global::System.Int32,global::System.Int64]");
  2327. }
  2328. {
  2329. var field = constructedTestClass.GetOwnMember<FieldEntity>("a4");
  2330. field.Type.ToString().ShouldEqual("global::NonGeneric+Generic1`2[global::System.Int32,global::System.Int64]+Generic2+Generic3`1[global::System.String][]");
  2331. }
  2332. {
  2333. var field = constructedTestClass.GetOwnMember<FieldEntity>("a5");
  2334. field.Type.ToString().ShouldEqual("global::NonGeneric+Generic1`2[global::System.Int32,global::System.Int64]+Generic2[]");
  2335. }
  2336. {
  2337. var field = constructedTestClass.GetOwnMember<FieldEntity>("a6");
  2338. field.Type.ToString().ShouldEqual("global::NonGeneric+Generic1`2[global::System.Int32,global::System.Int64][]");
  2339. }
  2340. {
  2341. var field = constructedTestClass.GetOwnMember<FieldEntity>("a7");
  2342. field.Type.ToString().ShouldEqual("global::NonGeneric[]");
  2343. }
  2344. {
  2345. var field = constructedTestClass.GetOwnMember<FieldEntity>("a8");
  2346. field.Type.ToString().ShouldEqual("global::System.Int32*");
  2347. }
  2348. {
  2349. var field = constructedTestClass.GetOwnMember<FieldEntity>("a9");
  2350. field.Type.ToString().ShouldEqual("global::System.Int32*[]");
  2351. }
  2352. }
  2353. // ----------------------------------------------------------------------------------------------
  2354. /// <summary>
  2355. /// Local variable type resolution.
  2356. /// </summary>
  2357. // ----------------------------------------------------------------------------------------------
  2358. [TestMethod]
  2359. public void LocalVariable()
  2360. {
  2361. var project = new CSharpProject(WorkingFolder);
  2362. project.AddFile(@"TypeResolution\LocalVariable.cs");
  2363. InvokeParser(project).ShouldBeTrue();
  2364. var class_A = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A");
  2365. var method_M = class_A.GetMember<MethodEntity>("M");
  2366. var declaration = method_M.Body.Statements.ToList()[0] as LocalVariableDeclarationStatementEntity;
  2367. int i = 0;
  2368. // a1
  2369. {
  2370. var variable = declaration.LocalVariables.ToList()[i];
  2371. variable.Name.ShouldEqual("a1");
  2372. variable.FullyQualifiedName.ShouldEqual("a1");
  2373. variable.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  2374. variable.Type.ToString().ShouldEqual("global::System.Int32");
  2375. variable.Initializer.ShouldBeNull();
  2376. }
  2377. i++;
  2378. // a2 = 2
  2379. {
  2380. var variable = declaration.LocalVariables.ToList()[i];
  2381. variable.Name.ShouldEqual("a2");
  2382. variable.FullyQualifiedName.ShouldEqual("a2");
  2383. variable.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  2384. variable.Type.ToString().ShouldEqual("global::System.Int32");
  2385. variable.Initializer.ShouldNotBeNull();
  2386. }
  2387. i++;
  2388. }
  2389. // ----------------------------------------------------------------------------------------------
  2390. /// <summary>
  2391. /// Local constant type resolution.
  2392. /// </summary>
  2393. // ----------------------------------------------------------------------------------------------
  2394. [TestMethod]
  2395. public void LocalConstant()
  2396. {
  2397. var project = new CSharpProject(WorkingFolder);
  2398. project.AddFile(@"TypeResolution\LocalConstant.cs");
  2399. InvokeParser(project).ShouldBeTrue();
  2400. var class_A = project.SemanticGraph.GlobalNamespace.GetSingleChildType<ClassEntity>("A");
  2401. var method_M = class_A.GetMember<MethodEntity>("M");
  2402. var declaration = method_M.Body.Statements.ToList()[0] as LocalConstantDeclarationStatementEntity;
  2403. int i = 0;
  2404. // a1 = 1
  2405. {
  2406. var variable = declaration.LocalConstants.ToList()[i];
  2407. variable.Name.ShouldEqual("a1");
  2408. variable.FullyQualifiedName.ShouldEqual("a1");
  2409. variable.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  2410. variable.Type.ToString().ShouldEqual("global::System.Int32");
  2411. variable.Initializer.ShouldNotBeNull();
  2412. }
  2413. i++;
  2414. // a2 = 2
  2415. {
  2416. var variable = declaration.LocalConstants.ToList()[i];
  2417. variable.Name.ShouldEqual("a2");
  2418. variable.FullyQualifiedName.ShouldEqual("a2");
  2419. variable.TypeReference.ResolutionState.ShouldEqual(ResolutionState.Resolved);
  2420. variable.Type.ToString().ShouldEqual("global::System.Int32");
  2421. variable.Initializer.ShouldNotBeNull();
  2422. }
  2423. i++;
  2424. }
  2425. }
  2426. }