PageRenderTime 68ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelAPITests.cs

https://github.com/EkardNT/Roslyn
C# | 3182 lines | 2664 code | 457 blank | 61 comment | 7 complexity | a419aa8711e65a8f533b53b24d32f8d5 MD5 | raw file
  1. // Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Collections.Immutable;
  5. using System.Linq;
  6. using Microsoft.CodeAnalysis.CSharp.Symbols;
  7. using Microsoft.CodeAnalysis.CSharp.Syntax;
  8. using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
  9. using Microsoft.CodeAnalysis.Test.Utilities;
  10. using Microsoft.CodeAnalysis.Text;
  11. using Roslyn.Test.Utilities;
  12. using Xunit;
  13. namespace Microsoft.CodeAnalysis.CSharp.UnitTests
  14. {
  15. public class SemanticTests : CSharpTestBase
  16. {
  17. [Fact]
  18. public void LocalSymbolsAreEquivalentAcrossSemanticModelsFromTheSameCompilation()
  19. {
  20. var text = @"public class C { public void M() { int x = 10; } }";
  21. var tree = Parse(text);
  22. var comp = CreateCompilationWithMscorlib(tree);
  23. var model1 = comp.GetSemanticModel(tree);
  24. var model2 = comp.GetSemanticModel(tree);
  25. Assert.NotEqual(model1, model2);
  26. var vardecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().First();
  27. var symbol1 = model1.GetDeclaredSymbol(vardecl);
  28. var symbol2 = model2.GetDeclaredSymbol(vardecl);
  29. Assert.NotSame(symbol1, symbol2);
  30. Assert.Equal(symbol1, symbol2);
  31. }
  32. [Fact]
  33. public void LocalSymbolsAreDifferentArossSemanticModelsFromDifferentCompilations()
  34. {
  35. var text = @"public class C { public void M() { int x = 10; } }";
  36. var tree = Parse(text);
  37. var comp1 = CreateCompilationWithMscorlib(tree);
  38. var comp2 = CreateCompilationWithMscorlib(tree);
  39. var model1 = comp1.GetSemanticModel(tree);
  40. var model2 = comp2.GetSemanticModel(tree);
  41. Assert.NotEqual(model1, model2);
  42. var vardecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().First();
  43. var symbol1 = model1.GetDeclaredSymbol(vardecl);
  44. var symbol2 = model2.GetDeclaredSymbol(vardecl);
  45. Assert.NotSame(symbol1, symbol2);
  46. Assert.NotEqual(symbol1, symbol2);
  47. }
  48. [Fact]
  49. public void RangeVariableSymbolsAreEquivalentAcrossSemanticModelsFromTheSameCompilation()
  50. {
  51. var text = @"using System.Linq; public class C { public void M() { var q = from c in string.Empty select c; } }";
  52. var tree = Parse(text);
  53. var comp = CreateCompilationWithMscorlibAndSystemCore(new[] { tree });
  54. var model1 = comp.GetSemanticModel(tree);
  55. var model2 = comp.GetSemanticModel(tree);
  56. Assert.NotEqual(model1, model2);
  57. var vardecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<QueryClauseSyntax>().First();
  58. var symbol1 = model1.GetDeclaredSymbol(vardecl);
  59. var symbol2 = model2.GetDeclaredSymbol(vardecl);
  60. Assert.NotSame(symbol1, symbol2);
  61. Assert.Equal(symbol1, symbol2);
  62. }
  63. [Fact]
  64. public void RangeVariableSymbolsAreDifferentArossSemanticModelsFromDifferentCompilations()
  65. {
  66. var text = @"using System.Linq; public class C { public void M() { var q = from c in string.Empty select c; } }";
  67. var tree = Parse(text);
  68. var comp1 = CreateCompilationWithMscorlibAndSystemCore(new[] { tree });
  69. var comp2 = CreateCompilationWithMscorlibAndSystemCore(new[] { tree });
  70. var model1 = comp1.GetSemanticModel(tree);
  71. var model2 = comp2.GetSemanticModel(tree);
  72. Assert.NotEqual(model1, model2);
  73. var vardecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<QueryClauseSyntax>().First();
  74. var symbol1 = model1.GetDeclaredSymbol(vardecl);
  75. var symbol2 = model2.GetDeclaredSymbol(vardecl);
  76. Assert.NotSame(symbol1, symbol2);
  77. Assert.NotEqual(symbol1, symbol2);
  78. }
  79. [Fact]
  80. public void LabelSymbolsAreEquivalentAcrossSemanticModelsFromSameCompilation()
  81. {
  82. var text = @"public class C { public void M() { label: goto label; } }";
  83. var tree = Parse(text);
  84. var comp = CreateCompilationWithMscorlib(tree);
  85. var model1 = comp.GetSemanticModel(tree);
  86. var model2 = comp.GetSemanticModel(tree);
  87. Assert.NotEqual(model1, model2);
  88. var statement = tree.GetCompilationUnitRoot().DescendantNodes().OfType<GotoStatementSyntax>().First();
  89. var symbol1 = model1.GetSymbolInfo(statement.Expression).Symbol;
  90. var symbol2 = model2.GetSymbolInfo(statement.Expression).Symbol;
  91. Assert.Equal(false, ReferenceEquals(symbol1, symbol2));
  92. Assert.Equal(symbol1, symbol2);
  93. }
  94. [Fact]
  95. public void LambdaParameterSymbolsAreEquivalentAcrossSemanticModelsFromSameCompilation()
  96. {
  97. var text = @"using System; public class C { public void M() { Func<int,int> f = (p) => p; } }";
  98. var tree = Parse(text);
  99. var comp = CreateCompilationWithMscorlib(tree);
  100. var model1 = comp.GetSemanticModel(tree);
  101. var model2 = comp.GetSemanticModel(tree);
  102. Assert.NotEqual(model1, model2);
  103. var paramdecl = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ParameterSyntax>().First();
  104. var symbol1 = model1.GetDeclaredSymbol(paramdecl);
  105. var symbol2 = model2.GetDeclaredSymbol(paramdecl);
  106. Assert.NotSame(symbol1, symbol2);
  107. Assert.Equal(symbol1.ContainingSymbol, symbol2.ContainingSymbol);
  108. Assert.Equal(symbol1, symbol2);
  109. }
  110. [Fact]
  111. public void LambdaParameterSymbolsAreDifferentAcrossSemanticModelsFromDifferentCompilations()
  112. {
  113. var text = @"using System; public class C { public void M() { Func<int,int> f = (p) => p; } }";
  114. var tree1 = Parse(text);
  115. var tree2 = Parse(text);
  116. var comp1 = CreateCompilationWithMscorlib(tree1);
  117. var comp2 = CreateCompilationWithMscorlib(tree2);
  118. var model1 = comp1.GetSemanticModel(tree1);
  119. var model2 = comp2.GetSemanticModel(tree2);
  120. Assert.NotEqual(model1, model2);
  121. var paramdecl1 = tree1.GetCompilationUnitRoot().DescendantNodes().OfType<ParameterSyntax>().First();
  122. var symbol1 = model1.GetDeclaredSymbol(paramdecl1);
  123. var paramdecl2 = tree2.GetCompilationUnitRoot().DescendantNodes().OfType<ParameterSyntax>().First();
  124. var symbol2 = model2.GetDeclaredSymbol(paramdecl2);
  125. Assert.NotSame(symbol1, symbol2);
  126. Assert.NotEqual(symbol1.ContainingSymbol, symbol2.ContainingSymbol);
  127. Assert.NotEqual(symbol1, symbol2);
  128. }
  129. [WorkItem(539740, "DevDiv")]
  130. [Fact]
  131. public void NamespaceWithoutName()
  132. {
  133. var text = "namespace";
  134. var tree = Parse(text);
  135. var comp = CreateCompilationWithMscorlib(tree);
  136. var model = comp.GetSemanticModel(tree);
  137. var errors = comp.GetDiagnostics().ToArray();
  138. Assert.Equal(3, errors.Length);
  139. var nsArray = tree.GetCompilationUnitRoot().DescendantNodes().Where(node => node.IsKind(SyntaxKind.NamespaceDeclaration)).ToArray();
  140. Assert.Equal(1, nsArray.Length);
  141. var nsSyntax = nsArray[0] as NamespaceDeclarationSyntax;
  142. var symbol = model.GetDeclaredSymbol(nsSyntax);
  143. Assert.Equal(string.Empty, symbol.Name);
  144. }
  145. [Fact]
  146. public void LazyBoundUsings1()
  147. {
  148. var text =
  149. @"
  150. // Peter Golde[7/19/2010]: I managed to construct the following interesting example today,
  151. // which Dev10 does compile. Interestingly, the resolution of one “using” can depend
  152. // on the resolution of another “using” later in the same namespace.
  153. using K = A.Q;
  154. using L = B.R;
  155. class B
  156. {
  157. public class R
  158. {
  159. public class Q
  160. {
  161. public class S : K { }
  162. }
  163. }
  164. }
  165. class A : L
  166. {
  167. public K.S v = null;
  168. }
  169. ";
  170. var comp = CreateCompilationWithMscorlib(text);
  171. var global = comp.GlobalNamespace;
  172. var a = global.GetTypeMembers("A", 0).Single();
  173. var abase = a.BaseType;
  174. Assert.Equal("B.R", abase.ToTestDisplayString());
  175. var b = global.GetTypeMembers("B", 0).Single();
  176. var r = b.GetTypeMembers("R", 0).Single();
  177. var q = r.GetTypeMembers("Q", 0).Single();
  178. var v = a.GetMembers("v").Single() as FieldSymbol;
  179. var s = v.Type;
  180. Assert.Equal("B.R.Q.S", s.ToTestDisplayString());
  181. var sbase = s.BaseType;
  182. Assert.Equal("B.R.Q", sbase.ToTestDisplayString());
  183. }
  184. [Fact]
  185. public void Diagnostics1()
  186. {
  187. var text =
  188. @"
  189. class A : A {}
  190. ";
  191. var tree = Parse(text);
  192. var comp = CreateCompilationWithMscorlib(tree);
  193. var errs = comp.GetSemanticModel(tree).GetDeclarationDiagnostics();
  194. Assert.Equal(1, errs.Count());
  195. }
  196. [Fact]
  197. public void DiagnosticsInOneTree()
  198. {
  199. var partial1 =
  200. @"
  201. partial class A
  202. {
  203. void foo() { int x = y; }
  204. }
  205. class C : B {}
  206. ";
  207. var partial2 =
  208. @"
  209. partial class A
  210. {
  211. int q; //an unused field in a partial type
  212. void bar() { int x = z; }
  213. }
  214. class B : NonExistent {}
  215. ";
  216. var partial1Tree = Parse(partial1);
  217. var partial2Tree = Parse(partial2);
  218. var comp = CreateCompilationWithMscorlib(new SyntaxTree[] { partial1Tree, partial2Tree });
  219. var errs = comp.GetSemanticModel(partial1Tree).GetDiagnostics();
  220. Assert.Equal(1, errs.Count());
  221. }
  222. [Fact]
  223. public void Bindings1()
  224. {
  225. var text =
  226. @"
  227. class B : A {}
  228. class A {}
  229. ";
  230. var tree = Parse(text);
  231. var comp = CreateCompilationWithMscorlib(tree);
  232. var bdecl = tree.GetCompilationUnitRoot().Members[0] as TypeDeclarationSyntax;
  233. var bbase = bdecl.BaseList.Types[0] as TypeSyntax;
  234. var model = comp.GetSemanticModel(tree);
  235. var info = model.GetSymbolInfo(bbase);
  236. Assert.NotNull(info.Symbol);
  237. var a = comp.GlobalNamespace.GetTypeMembers("A", 0).Single();
  238. Assert.Equal(a, info.Symbol);
  239. Assert.Equal(a, model.GetTypeInfo(bbase).Type);
  240. }
  241. [Fact]
  242. public void BaseScope1()
  243. {
  244. // ensure the base clause is not bound in the scope of the class
  245. var text =
  246. @"
  247. public class C : B {}
  248. public class A {
  249. public class B {}
  250. }
  251. public class B : A {}
  252. ";
  253. var tree = Parse(text);
  254. var comp = CreateCompilationWithMscorlib(tree);
  255. var cdecl = tree.GetCompilationUnitRoot().Members[0] as TypeDeclarationSyntax;
  256. var cbase = cdecl.BaseList.Types[0] as TypeSyntax;
  257. var model = comp.GetSemanticModel(tree);
  258. var info = model.GetSymbolInfo(cbase);
  259. Assert.NotNull(info.Symbol);
  260. var b = comp.GlobalNamespace.GetTypeMembers("B", 0).Single();
  261. Assert.Equal(b, info.Symbol);
  262. Assert.Equal(b, model.GetTypeInfo(cbase).Type);
  263. }
  264. [Fact]
  265. public void BaseScope2()
  266. {
  267. // ensure type parameters are in scope in the base clause
  268. var text =
  269. @"
  270. public class C<T> : A<T> { }
  271. public class A<T> : B { }
  272. public class B {
  273. public class T { }
  274. }
  275. ";
  276. var tree = Parse(text);
  277. var comp = CreateCompilationWithMscorlib(tree);
  278. var cdecl = tree.GetCompilationUnitRoot().Members[0] as TypeDeclarationSyntax;
  279. var cbase = cdecl.BaseList.Types[0] as TypeSyntax;
  280. var model = comp.GetSemanticModel(tree);
  281. var info = model.GetSymbolInfo(cbase);
  282. Assert.NotNull(info.Symbol);
  283. var cbasetype = info.Symbol as NamedTypeSymbol;
  284. var c = comp.GlobalNamespace.GetTypeMembers("C", 1).Single();
  285. Assert.Equal(c.BaseType, cbasetype);
  286. }
  287. [Fact]
  288. public void Bindings2()
  289. {
  290. var text =
  291. @"
  292. class B<T> : A<T> {}
  293. class A<T> {}
  294. ";
  295. var tree = Parse(text);
  296. var comp = CreateCompilationWithMscorlib(tree);
  297. var bdecl = tree.GetCompilationUnitRoot().Members[0] as TypeDeclarationSyntax;
  298. var bbase = bdecl.BaseList.Types[0] as TypeSyntax; // A<T>
  299. var model = comp.GetSemanticModel(tree);
  300. var info = model.GetSymbolInfo(bbase);
  301. Assert.NotNull(info.Symbol);
  302. var at2 = info.Symbol as NamedTypeSymbol;
  303. Assert.Equal(at2, model.GetTypeInfo(bbase).Type);
  304. var a = comp.GlobalNamespace.GetTypeMembers("A", 1).Single();
  305. var at = a.TypeParameters.First();
  306. var b = comp.GlobalNamespace.GetTypeMembers("B", 1).Single();
  307. var bt = b.TypeParameters.First();
  308. Assert.Equal(a.OriginalDefinition, at2.OriginalDefinition);
  309. Assert.Equal(b.TypeParameters.First(), at2.TypeArguments.First());
  310. }
  311. [Fact]
  312. public void Bindings3()
  313. {
  314. var text =
  315. @"using System;
  316. using System.Collections.Generic;
  317. using System.Linq;
  318. class Program
  319. {
  320. static Program Field;
  321. }";
  322. var tree1 = Parse(text);
  323. var compilation = CreateCompilationWithMscorlib(tree1);
  324. var tree2 = Parse(text);
  325. var classProgram = tree2.GetCompilationUnitRoot().Members[0] as TypeDeclarationSyntax;
  326. var staticProgramField = classProgram.Members[0] as FieldDeclarationSyntax;
  327. var program = staticProgramField.Declaration.Type;
  328. var model = compilation.GetSemanticModel(tree1);
  329. Assert.Throws<ArgumentException>(() =>
  330. {
  331. // tree2 not in the compilation
  332. var lookup = model.GetSymbolInfo(program);
  333. });
  334. }
  335. [Fact]
  336. public void Bindings4()
  337. {
  338. var text =
  339. @"using System;
  340. using System.Collections.Generic;
  341. using System.Linq;
  342. class Program
  343. {
  344. Program p;
  345. static void Main(string[] args)
  346. {
  347. }
  348. }";
  349. var tree1 = Parse(text);
  350. var compilation = CreateCompilationWithMscorlib(tree1);
  351. var decl = tree1.GetCompilationUnitRoot().Members[0] as TypeDeclarationSyntax;
  352. var field = decl.Members[0] as FieldDeclarationSyntax;
  353. var type = field.Declaration.Type;
  354. var model = compilation.GetSemanticModel(tree1);
  355. var info = model.GetSymbolInfo(type);
  356. Assert.Equal(compilation.GlobalNamespace.GetTypeMembers("Program", 0).Single(), info.Symbol);
  357. }
  358. [Fact]
  359. public void Bindings5()
  360. {
  361. var text =
  362. @"using System;
  363. using System.Collections.Generic;
  364. using System.Linq;
  365. class Program
  366. {
  367. static void Main(string[] args)
  368. {
  369. }
  370. }";
  371. var tree1 = Parse(text);
  372. var tree2 = Parse(text);
  373. var compilation = CreateCompilationWithMscorlib(new SyntaxTree[] { tree1, tree2 });
  374. var decl = tree1.GetCompilationUnitRoot().Members[0] as TypeDeclarationSyntax;
  375. var method = decl.Members[0] as MethodDeclarationSyntax;
  376. var type = method.ParameterList.Parameters[0].Type;
  377. var model = compilation.GetSemanticModel(tree1);
  378. var info = model.GetSymbolInfo(type);
  379. Assert.Equal<Symbol>(compilation.GetSpecialType(SpecialType.System_String), (info.Symbol as ArrayTypeSymbol).ElementType);
  380. }
  381. [Fact]
  382. public void Speculative1()
  383. {
  384. var text =
  385. @"
  386. class B {
  387. object x;
  388. }
  389. class A {}
  390. ";
  391. var tree = Parse(text);
  392. var comp = CreateCompilationWithMscorlib(tree);
  393. var bdecl = tree.GetCompilationUnitRoot().Members[0] as TypeDeclarationSyntax;
  394. var xdecl = bdecl.Members[0] as FieldDeclarationSyntax;
  395. var model = comp.GetSemanticModel(tree);
  396. TypeSyntax speculate = SyntaxFactory.IdentifierName(SyntaxFactory.Identifier("A"));
  397. var symbolInfo = model.GetSpeculativeSymbolInfo(xdecl.SpanStart, speculate, SpeculativeBindingOption.BindAsTypeOrNamespace);
  398. var lookup = symbolInfo.Symbol as TypeSymbol;
  399. Assert.NotNull(lookup);
  400. var a = comp.GlobalNamespace.GetTypeMembers("A", 0).Single();
  401. Assert.Equal(a, lookup);
  402. }
  403. [Fact]
  404. public void GetType1()
  405. {
  406. var text =
  407. @"
  408. class A {
  409. class B {}
  410. }
  411. ";
  412. var tree = Parse(text);
  413. var comp = CreateCompilationWithMscorlib(tree);
  414. var adecl = tree.GetCompilationUnitRoot().Members[0] as TypeDeclarationSyntax;
  415. var bdecl = adecl.Members[0] as TypeDeclarationSyntax;
  416. var model = comp.GetSemanticModel(tree);
  417. var a1 = model.GetDeclaredSymbol(adecl);
  418. var b1 = model.GetDeclaredSymbol(bdecl);
  419. var global = comp.GlobalNamespace;
  420. var a2 = global.GetTypeMembers("A", 0).Single();
  421. var b2 = a2.GetTypeMembers("B", 0).Single();
  422. Assert.Equal(a2, a1);
  423. Assert.Equal(b2, b1);
  424. }
  425. [Fact]
  426. public void DottedName()
  427. {
  428. var text =
  429. @"
  430. class Main {
  431. A.B x; // this refers to the B within A.
  432. }
  433. class A {
  434. public class B {}
  435. }
  436. class B {}
  437. ";
  438. var tree = Parse(text);
  439. var comp = CreateCompilationWithMscorlib(tree);
  440. var model = (CSharpSemanticModel)comp.GetSemanticModel(tree);
  441. var root = tree.GetCompilationUnitRoot();
  442. var mainDecl = root.Members[0] as TypeDeclarationSyntax;
  443. var mainType = model.GetDeclaredSymbol(mainDecl);
  444. var aDecl = root.Members[1] as TypeDeclarationSyntax;
  445. var aType = model.GetDeclaredSymbol(aDecl);
  446. var abDecl = aDecl.Members[0] as TypeDeclarationSyntax;
  447. var abType = model.GetDeclaredSymbol(abDecl);
  448. var bDecl = root.Members[2] as TypeDeclarationSyntax;
  449. var bType = model.GetDeclaredSymbol(bDecl);
  450. var xDecl = mainDecl.Members[0] as FieldDeclarationSyntax;
  451. var xSym = mainType.GetMembers("x").Single() as FieldSymbol;
  452. Assert.Equal<ISymbol>(abType, xSym.Type);
  453. var info = model.GetSymbolInfo((xDecl.Declaration.Type as QualifiedNameSyntax).Right);
  454. Assert.Equal(abType, info.Symbol);
  455. }
  456. [Fact]
  457. public void AliasQualifiedName()
  458. {
  459. var text =
  460. @"
  461. class B {}
  462. namespace N {
  463. class C : global::B {}
  464. class B {}
  465. }
  466. ";
  467. var tree = Parse(text);
  468. var comp = CreateCompilationWithMscorlib(tree);
  469. var model = comp.GetSemanticModel(tree);
  470. var root = tree.GetCompilationUnitRoot();
  471. var nDecl = root.Members[0] as NamespaceDeclarationSyntax;
  472. var n2Decl = root.Members[1] as NamespaceDeclarationSyntax;
  473. var cDecl = n2Decl.Members[0] as TypeDeclarationSyntax;
  474. var cBase = (cDecl.BaseList.Types[0] as AliasQualifiedNameSyntax).Name;
  475. var cBaseType = model.GetSymbolInfo(cBase).Symbol;
  476. var bOuter = comp.GlobalNamespace.GetTypeMembers("B", 0).Single();
  477. var bInner = (comp.GlobalNamespace.GetMembers("N").Single() as NamespaceSymbol).GetTypeMembers("B", 0).Single();
  478. Assert.Equal(bOuter, cBaseType);
  479. }
  480. [Fact, WorkItem(528655, "DevDiv")]
  481. public void ErrorSymbolForInvalidCode()
  482. {
  483. var text = @"
  484. public class A
  485. {
  486. int foo { void foo() {} } // Error
  487. static int Main() { return 1; }
  488. }
  489. ";
  490. var tree = Parse(text);
  491. var comp = CreateCompilationWithMscorlib(tree);
  492. var mems = comp.SourceModule.GlobalNamespace.GetMembers();
  493. var typeA = mems.Where(s => s.Name == "A").Select(s => s);
  494. Assert.Equal(1, typeA.Count());
  495. var invalid = mems.Where(s => s.Name == "<invalid-global-code>").Select(s => s);
  496. Assert.Equal(1, invalid.Count());
  497. }
  498. [Fact, WorkItem(543225, "DevDiv"), WorkItem(529057, "DevDiv")]
  499. public void MergePartialMethodAndParameterSymbols()
  500. {
  501. var text = @"
  502. using System;
  503. partial class PC
  504. {
  505. partial void PM(int pp);
  506. }
  507. partial class PC
  508. {
  509. partial void PM(int pp) {}
  510. }
  511. ";
  512. var tree = Parse(text);
  513. var comp = CreateCompilationWithMscorlib(tree);
  514. var pTypeSym = comp.SourceModule.GlobalNamespace.GetTypeMembers("PC").Single();
  515. var pMethodSym = pTypeSym.GetMembers("PM").Single();
  516. var model = (CSharpSemanticModel)comp.GetSemanticModel(tree);
  517. var pType01 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().First();
  518. var pType02 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().Last();
  519. Assert.NotEqual(pType01, pType02);
  520. var ptSym01 = model.GetDeclaredSymbol(pType01);
  521. var ptSym02 = model.GetDeclaredSymbol(pType02);
  522. // same partial type symbol
  523. Assert.Same(ptSym01, ptSym02);
  524. Assert.Equal(2, ptSym01.Locations.Length);
  525. var pMethod01 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().First();
  526. var pMethod02 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Last();
  527. Assert.NotEqual(pMethod01, pMethod02);
  528. var pmSym01 = model.GetDeclaredSymbol(pMethod01);
  529. var pmSym02 = model.GetDeclaredSymbol(pMethod02);
  530. // different partial method symbols:(
  531. Assert.NotSame(pmSym01, pmSym02);
  532. // the declaration one is what one can get from GetMembers()
  533. Assert.Same(pMethodSym, pmSym01);
  534. // with decl|impl point to each nother
  535. Assert.Null(pmSym01.PartialDefinitionPart);
  536. Assert.Same(pmSym02, pmSym01.PartialImplementationPart);
  537. Assert.Same(pmSym01, pmSym02.PartialDefinitionPart);
  538. Assert.Null(pmSym02.PartialImplementationPart);
  539. var pParam01 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ParameterSyntax>().First();
  540. var pParam02 = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ParameterSyntax>().Last();
  541. Assert.NotEqual(pParam01, pParam02);
  542. var ppSym01 = model.GetDeclaredSymbol(pParam01);
  543. var ppSym02 = model.GetDeclaredSymbol(pParam02);
  544. Assert.NotSame(ppSym01, ppSym02);
  545. Assert.Equal(1, ppSym01.Locations.Length);
  546. Assert.Equal(1, ppSym02.Locations.Length);
  547. }
  548. [Fact, WorkItem(544221, "DevDiv")]
  549. public void GetTypeInfoForOptionalParameterDefaultValueInDelegate()
  550. {
  551. var text = @"
  552. using System;
  553. class Test
  554. {
  555. public delegate void DFoo(byte i = 1);
  556. protected internal void MFoo(sbyte j = 2) { }
  557. }
  558. ";
  559. var tree = Parse(text);
  560. var comp = CreateCompilationWithMscorlib(tree);
  561. var model = comp.GetSemanticModel(tree);
  562. var root = tree.GetCompilationUnitRoot();
  563. var exprs = root.DescendantNodes().OfType<LiteralExpressionSyntax>().ToArray();
  564. Assert.Equal(2, exprs.Length);
  565. var type1 = model.GetTypeInfo(exprs[0]);
  566. var type2 = model.GetTypeInfo(exprs[1]);
  567. Assert.NotNull(type1.Type);
  568. Assert.Equal("System.Int32", type1.Type.ToTestDisplayString());
  569. Assert.NotNull(type2.Type);
  570. Assert.Equal("System.Int32", type2.Type.ToTestDisplayString());
  571. }
  572. [Fact, WorkItem(544231, "DevDiv")]
  573. public void GetDeclSymbolForParameterOfPartialMethod()
  574. {
  575. var text1 = @"
  576. using System;
  577. partial class Partial001
  578. {
  579. static partial void Foo(ulong x);
  580. }
  581. ";
  582. var text2 = @"
  583. using System;
  584. partial class Partial001
  585. {
  586. static partial void Foo(ulong x) { }
  587. static int Main() { return 1; }
  588. }
  589. ";
  590. var tree1 = Parse(text1);
  591. var tree2 = Parse(text2);
  592. var comp = CreateCompilationWithMscorlib(new List<SyntaxTree> {tree1, tree2});
  593. var model1 = comp.GetSemanticModel(tree1);
  594. var model2 = comp.GetSemanticModel(tree2);
  595. var root1 = tree1.GetCompilationUnitRoot();
  596. var root2 = tree1.GetCompilationUnitRoot();
  597. var para1 = tree1.GetCompilationUnitRoot().DescendantNodes().OfType<ParameterSyntax>().First();
  598. var para2 = tree2.GetCompilationUnitRoot().DescendantNodes().OfType<ParameterSyntax>().First();
  599. var sym1 = model1.GetDeclaredSymbol(para1);
  600. var sym2 = model2.GetDeclaredSymbol(para2);
  601. Assert.NotNull(sym1);
  602. Assert.NotNull(sym2);
  603. Assert.Equal("System.UInt64 x", sym1.ToTestDisplayString());
  604. Assert.Equal("System.UInt64 x", sym2.ToTestDisplayString());
  605. Assert.NotEqual(sym1.Locations[0], sym2.Locations[0]);
  606. }
  607. [Fact, WorkItem(544473, "DevDiv")]
  608. public void GetDeclSymbolForTypeParameterOfPartialMethod()
  609. {
  610. var text1 = @"
  611. using System;
  612. partial class Partial001
  613. {
  614. static partial void Foo<T>(T x);
  615. }
  616. ";
  617. var text2 = @"
  618. using System;
  619. partial class Partial001
  620. {
  621. static partial void Foo<T>(T x) { }
  622. static int Main() { return 1; }
  623. }
  624. ";
  625. var tree1 = Parse(text1);
  626. var tree2 = Parse(text2);
  627. var comp = CreateCompilationWithMscorlib(new List<SyntaxTree> { tree1, tree2 });
  628. var model1 = comp.GetSemanticModel(tree1);
  629. var model2 = comp.GetSemanticModel(tree2);
  630. var root1 = tree1.GetCompilationUnitRoot();
  631. var root2 = tree1.GetCompilationUnitRoot();
  632. var para1 = tree1.GetCompilationUnitRoot().DescendantNodes().OfType<TypeParameterSyntax>().First();
  633. var para2 = tree2.GetCompilationUnitRoot().DescendantNodes().OfType<TypeParameterSyntax>().First();
  634. var sym1 = model1.GetDeclaredSymbol(para1);
  635. var sym2 = model2.GetDeclaredSymbol(para2);
  636. Assert.NotNull(sym1);
  637. Assert.NotNull(sym2);
  638. Assert.Equal("T", sym1.ToTestDisplayString());
  639. Assert.Equal("T", sym2.ToTestDisplayString());
  640. Assert.NotEqual(sym1.Locations[0], sym2.Locations[0]);
  641. }
  642. [Fact]
  643. public void GetDeclaredSymbolForAnonymousTypeProperty01()
  644. {
  645. var text = @"
  646. using System;
  647. struct AnonTypeTest
  648. {
  649. static long Prop
  650. {
  651. get
  652. {
  653. short @short = -1;
  654. var anonType = new { id = 123, @do = ""QC"", @short, Prop };
  655. return anonType.id + anonType.@short;
  656. }
  657. }
  658. }
  659. ";
  660. var tree = Parse(text);
  661. var comp = CreateCompilationWithMscorlib(tree);
  662. var model = comp.GetSemanticModel(tree);
  663. var anonProps = tree.GetCompilationUnitRoot().DescendantNodes().OfType<AnonymousObjectMemberDeclaratorSyntax>();
  664. Assert.Equal(4, anonProps.Count());
  665. var symList = from ap in anonProps
  666. let apsym = model.GetDeclaredSymbol(ap)
  667. orderby apsym.Name
  668. select apsym.Name;
  669. var results = string.Join(", ", symList);
  670. Assert.Equal("do, id, Prop, short", results);
  671. }
  672. [Fact]
  673. public void GetDeclaredSymbolForAnonymousTypeProperty02()
  674. {
  675. var text = @"
  676. using System;
  677. class AnonTypeTest
  678. {
  679. long field = 111;
  680. void M(byte p1, ref sbyte p2, out string p3, params string[] ary)
  681. {
  682. ulong local = 12345;
  683. var anonType = new { local, this.field, p1, p2, ary };
  684. p3 = anonType.ary.Length > 0 ? anonType.ary[0] : """";
  685. }
  686. }
  687. ";
  688. var tree = Parse(text);
  689. var comp = CreateCompilationWithMscorlib(tree);
  690. var model = comp.GetSemanticModel(tree);
  691. var anonProps = tree.GetCompilationUnitRoot().DescendantNodes().OfType<AnonymousObjectMemberDeclaratorSyntax>();
  692. Assert.Equal(5, anonProps.Count());
  693. var symList = from ap in anonProps
  694. let apsym = model.GetDeclaredSymbol(ap)
  695. orderby apsym.Name
  696. select apsym.Name;
  697. var results = string.Join(", ", symList);
  698. Assert.Equal("ary, field, local, p1, p2", results);
  699. }
  700. [Fact]
  701. public void GetDeclaredSymbolForAnonymousTypeProperty03()
  702. {
  703. var text = @"
  704. using System;
  705. enum E { a, b, c }
  706. class Base
  707. {
  708. protected E baseField = E.b;
  709. protected virtual Base BaseProp { get { return this; } }
  710. public Func<string, char> deleField;
  711. }
  712. class AnonTypeTest : Base
  713. {
  714. protected override Base BaseProp { get { return null; } }
  715. char this[string @string]
  716. {
  717. get
  718. {
  719. var anonType = new { id = deleField, base.BaseProp, base.baseField, ret = @string };
  720. return anonType.id(anonType.ret);
  721. }
  722. }
  723. }
  724. ";
  725. var tree = Parse(text);
  726. var comp = CreateCompilationWithMscorlib(tree);
  727. var model = comp.GetSemanticModel(tree);
  728. var anonProps = tree.GetCompilationUnitRoot().DescendantNodes().OfType<AnonymousObjectMemberDeclaratorSyntax>();
  729. Assert.Equal(4, anonProps.Count());
  730. var symList = from ap in anonProps
  731. let apsym = model.GetDeclaredSymbol(ap)
  732. orderby apsym.Name
  733. select apsym.Name;
  734. var results = string.Join(", ", symList);
  735. Assert.Equal("baseField, BaseProp, id, ret", results);
  736. }
  737. [Fact]
  738. public void GetDeclaredSymbolForAnonymousTypeProperty04()
  739. {
  740. var text = @"
  741. using System;
  742. enum E { a, b, c }
  743. struct S
  744. {
  745. public static E sField;
  746. public interface IFoo { }
  747. public IFoo GetFoo { get; set; }
  748. public IFoo GetFoo2() { return null; }
  749. }
  750. class AnonTypeTest
  751. {
  752. event Action<ushort> Eve
  753. {
  754. add
  755. {
  756. var anonType = new { a1 = new { S.sField, ifoo = new { new S().GetFoo } } };
  757. }
  758. remove
  759. {
  760. var anonType = new { a1 = new { a2 = new { a2 = S.sField, a3 = new { a3 = new S().GetFoo2() } } } };
  761. }
  762. }
  763. }
  764. ";
  765. var tree = Parse(text);
  766. var comp = CreateCompilationWithMscorlib(tree);
  767. var model = comp.GetSemanticModel(tree);
  768. var anonProps = tree.GetCompilationUnitRoot().DescendantNodes().OfType<AnonymousObjectMemberDeclaratorSyntax>();
  769. Assert.Equal(9, anonProps.Count());
  770. var symList = from ap in anonProps
  771. let apsym = model.GetDeclaredSymbol(ap)
  772. orderby apsym.Name
  773. select apsym.Name;
  774. var results = string.Join(", ", symList);
  775. Assert.Equal("a1, a1, a2, a2, a3, a3, GetFoo, ifoo, sField", results);
  776. }
  777. [Fact(), WorkItem(542861, "DevDiv"), WorkItem(529673, "DevDiv")]
  778. public void GetSymbolInfoForAccessorParameters()
  779. {
  780. var text = @"
  781. using System;
  782. public class Test
  783. {
  784. object[] _Items = new object[3];
  785. public object this[int index]
  786. {
  787. get
  788. {
  789. return _Items[index];
  790. }
  791. set
  792. {
  793. _Items[index] = value;
  794. }
  795. }
  796. }
  797. ";
  798. var tree = Parse(text);
  799. var comp = CreateCompilationWithMscorlib(tree);
  800. var model = comp.GetSemanticModel(tree);
  801. var descendants = tree.GetCompilationUnitRoot().DescendantNodes();
  802. var paras = descendants.OfType<ParameterSyntax>();
  803. Assert.Equal(1, paras.Count());
  804. var parasym = model.GetDeclaredSymbol(paras.First());
  805. var ploc = parasym.Locations[0];
  806. var args = descendants.OfType<ArgumentSyntax>().Where(s => s.ToString() == "index").Select(s => s);
  807. Assert.Equal(2, args.Count());
  808. var argsym1 = model.GetSymbolInfo(args.First().Expression).Symbol;
  809. var argsym2 = model.GetSymbolInfo(args.Last().Expression).Symbol;
  810. Assert.NotNull(argsym1);
  811. Assert.NotNull(argsym2);
  812. Assert.Equal(ploc, argsym1.Locations[0]);
  813. Assert.Equal(ploc, argsym2.Locations[0]);
  814. Assert.Equal(parasym.Kind, argsym1.Kind);
  815. Assert.Equal(parasym.Kind, argsym2.Kind);
  816. // SourceSimpleParameterSymbol vs. SourceClonedComplexParameterSymbol
  817. Assert.NotEqual(parasym, argsym1);
  818. Assert.NotEqual(parasym, argsym2);
  819. }
  820. [WorkItem(545648, "DevDiv")]
  821. [Fact]
  822. public void AliasDeclaredSymbolWithConflict()
  823. {
  824. var source = @"
  825. using X = System;
  826. class X { }
  827. ";
  828. var comp = CreateCompilationWithMscorlib(source);
  829. var tree = comp.SyntaxTrees.Single();
  830. var model = comp.GetSemanticModel(tree);
  831. var aliasSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<UsingDirectiveSyntax>().Single();
  832. var symbol = model.GetDeclaredSymbol(aliasSyntax);
  833. Assert.Equal(symbol.Target, comp.GlobalNamespace.GetMember<NamespaceSymbol>("System"));
  834. comp.VerifyDiagnostics(
  835. // (2,1): info CS8019: Unnecessary using directive.
  836. // using X = System;
  837. Diagnostic(ErrorCode.INF_UnusedUsingDirective, "using X = System;"));
  838. }
  839. [WorkItem(529751, "DevDiv")]
  840. [Fact]
  841. public void ExternAlias()
  842. {
  843. var source = @"
  844. extern alias X;
  845. class Test
  846. {
  847. static void Main()
  848. {
  849. X::C c = null;
  850. }
  851. }
  852. ";
  853. var comp1 = CreateCompilationWithMscorlib("public class C { }");
  854. var ref1 = new MetadataImageReference(CompileAndVerify(comp1).EmittedAssemblyData, aliases: ImmutableArray.Create("X"));
  855. var comp2 = CreateCompilationWithMscorlib(source, new[] { ref1 });
  856. var tree = comp2.SyntaxTrees.Single();
  857. var model = comp2.GetSemanticModel(tree);
  858. var aliasSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ExternAliasDirectiveSyntax>().Single();
  859. // Compilation.GetExternAliasTarget defines this behavior: the target is a merged namespace
  860. // with the same name as the alias, contained in the global namespace of the compilation.
  861. var aliasSymbol = model.GetDeclaredSymbol(aliasSyntax);
  862. var aliasTarget = (NamespaceSymbol)aliasSymbol.Target;
  863. Assert.Equal(NamespaceKind.Module, aliasTarget.Extent.Kind);
  864. Assert.Equal("", aliasTarget.Name);
  865. Assert.True(aliasTarget.IsGlobalNamespace);
  866. Assert.Null(aliasTarget.ContainingNamespace);
  867. Assert.Equal(0, comp2.GlobalNamespace.GetMembers("X").Length); //Doesn't contain the alias target namespace as a child.
  868. var aliasQualifiedSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<AliasQualifiedNameSyntax>().Single();
  869. Assert.Equal(aliasSymbol, model.GetAliasInfo(aliasQualifiedSyntax.Alias));
  870. comp2.VerifyDiagnostics(
  871. // (8,14): warning CS0219: The variable 'c' is assigned but its value is never used
  872. // X::C c = null;
  873. Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "c").WithArguments("c"));
  874. }
  875. [Fact, WorkItem(546687, "DevDiv"), WorkItem(529751, "DevDiv")]
  876. public void ExternAliasWithoutTarget()
  877. {
  878. var source = @"
  879. extern alias X;
  880. class Test
  881. {
  882. static void Main()
  883. {
  884. X::C c = null;
  885. }
  886. }
  887. ";
  888. var comp = CreateCompilationWithMscorlib(source);
  889. var tree = comp.SyntaxTrees.Single();
  890. var model = comp.GetSemanticModel(tree);
  891. var aliasSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ExternAliasDirectiveSyntax>().Single();
  892. var aliasSymbol = model.GetDeclaredSymbol(aliasSyntax);
  893. Assert.IsType<MissingNamespaceSymbol>(aliasSymbol.Target);
  894. var aliasQualifiedSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<AliasQualifiedNameSyntax>().Single();
  895. Assert.Equal(aliasSymbol, model.GetAliasInfo(aliasQualifiedSyntax.Alias));
  896. comp.VerifyDiagnostics(
  897. // (2,14): error CS0430: The extern alias 'X' was not specified in a /reference option
  898. // extern alias X;
  899. Diagnostic(ErrorCode.ERR_BadExternAlias, "X").WithArguments("X"),
  900. // (8,12): error CS0234: The type or namespace name 'C' does not exist in the namespace 'X' (are you missing an assembly reference?)
  901. // X::C c = null;
  902. Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "C").WithArguments("C", "X"));
  903. }
  904. [WorkItem(545648, "DevDiv")]
  905. [Fact]
  906. public void UsingDirectiveAliasSemanticInfo()
  907. {
  908. var source = "using X = System;";
  909. var comp = CreateCompilationWithMscorlib(source);
  910. comp.VerifyDiagnostics(
  911. // (1,1): info CS8019: Unnecessary using directive.
  912. // using X = System;
  913. Diagnostic(ErrorCode.INF_UnusedUsingDirective, "using X = System;"));
  914. var tree = comp.SyntaxTrees.Single();
  915. var model = comp.GetSemanticModel(tree);
  916. var aliasSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<NameEqualsSyntax>().Single().Name;
  917. Assert.Equal(SymbolInfo.None, model.GetSymbolInfo(aliasSyntax));
  918. var usingSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<UsingDirectiveSyntax>().Single();
  919. Assert.Equal(SymbolKind.Alias, model.GetDeclaredSymbol(usingSyntax).Kind);
  920. }
  921. [WorkItem(545882, "DevDiv")]
  922. [Fact]
  923. public void SpeculativelyBindConstructorInitializerInPlaceOfActual()
  924. {
  925. var source = @"class C
  926. {
  927. C(int x) { }
  928. C() : this((int) 1) { }
  929. }";
  930. var comp = CreateCompilationWithMscorlib(source);
  931. comp.VerifyDiagnostics();
  932. var tree = comp.SyntaxTrees.Single();
  933. var model = comp.GetSemanticModel(tree);
  934. var oldSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ConstructorInitializerSyntax>().Single();
  935. var newSyntax = SyntaxFactory.ConstructorInitializer(SyntaxKind.ThisConstructorInitializer);
  936. var info = model.GetSpeculativeSymbolInfo(oldSyntax.SpanStart, newSyntax);
  937. var symbol = info.Symbol;
  938. Assert.NotNull(symbol);
  939. Assert.Equal(comp.GlobalNamespace.GetMember<NamedTypeSymbol>("C"), symbol.ContainingType);
  940. Assert.Equal(SymbolKind.Method, symbol.Kind);
  941. var method = (MethodSymbol)symbol;
  942. Assert.Equal(MethodKind.Constructor, method.MethodKind);
  943. Assert.Equal(0, method.ParameterCount);
  944. }
  945. [WorkItem(545882, "DevDiv")]
  946. [Fact]
  947. public void SpeculativelyBindConstructorInitializerInNewLocation()
  948. {
  949. var source = @"class C
  950. {
  951. C() { }
  952. }";
  953. var comp = CreateCompilationWithMscorlib(source);
  954. comp.VerifyDiagnostics();
  955. var tree = comp.SyntaxTrees.Single();
  956. var model = comp.GetSemanticModel(tree);
  957. var oldSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ConstructorDeclarationSyntax>().Single();
  958. var newSyntax = SyntaxFactory.ConstructorInitializer(SyntaxKind.ThisConstructorInitializer);
  959. var info = model.GetSpeculativeSymbolInfo(oldSyntax.ParameterList.Span.End, newSyntax);
  960. Assert.Equal(SymbolInfo.None, info);
  961. }
  962. [Fact]
  963. public void TestGetSpeculativeSemanticModelInFieldInitializer()
  964. {
  965. var compilation = CreateCompilationWithMscorlib(@"
  966. class C
  967. {
  968. object y = 1;
  969. }
  970. ");
  971. var tree = compilation.SyntaxTrees[0];
  972. var root = tree.GetCompilationUnitRoot();
  973. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  974. var fieldDecl = (FieldDeclarationSyntax)typeDecl.Members[0];
  975. var varDecl = fieldDecl.Declaration.Variables.First();
  976. var model = compilation.GetSemanticModel(tree);
  977. Assert.False(model.IsSpeculativeSemanticModel);
  978. Assert.Null(model.ParentModel);
  979. Assert.Equal(0, model.OriginalPositionForSpeculation);
  980. // Speculate on the equals value syntax (initializer)
  981. // Conversion info available, ConvertedType: Object.
  982. var equalsValue = SyntaxFactory.EqualsValueClause(SyntaxFactory.ParseExpression(@"(string)""Hello"""));
  983. var expr = equalsValue.Value;
  984. int position = varDecl.Initializer.SpanStart;
  985. SemanticModel speculativeModel;
  986. bool success = model.TryGetSpeculativeSemanticModel(position, equalsValue, out speculativeModel);
  987. Assert.True(success);
  988. Assert.NotNull(speculativeModel);
  989. Assert.True(speculativeModel.IsSpeculativeSemanticModel);
  990. Assert.Equal(model, speculativeModel.ParentModel);
  991. Assert.Equal(position, speculativeModel.OriginalPositionForSpeculation);
  992. var typeInfo = speculativeModel.GetTypeInfo(expr);
  993. Assert.NotNull(typeInfo.Type);
  994. Assert.Equal("String", typeInfo.Type.Name);
  995. Assert.Equal("Object", typeInfo.ConvertedType.Name);
  996. var constantInfo = speculativeModel.GetConstantValue(expr);
  997. Assert.True(constantInfo.HasValue, "must be a constant");
  998. Assert.Equal("Hello", constantInfo.Value);
  999. }
  1000. [Fact]
  1001. public void TestGetSpeculativeSemanticModelInEnumMember()
  1002. {
  1003. var compilation = CreateCompilationWithMscorlib(@"
  1004. enum C
  1005. {
  1006. y = 1
  1007. }
  1008. ");
  1009. var tree = compilation.SyntaxTrees[0];
  1010. var root = tree.GetCompilationUnitRoot();
  1011. var typeDecl = (EnumDeclarationSyntax)root.Members[0];
  1012. var enumMemberDecl = (EnumMemberDeclarationSyntax)typeDecl.Members[0];
  1013. var equalsValue = enumMemberDecl.EqualsValue;
  1014. var initializer = equalsValue.Value;
  1015. var model = compilation.GetSemanticModel(tree);
  1016. // Speculate on the equals value syntax (initializer)
  1017. // Conversion info available, ConvertedType: Int32.
  1018. var newEqualsValue = SyntaxFactory.EqualsValueClause(SyntaxFactory.ParseExpression("(short)0"));
  1019. var expr = newEqualsValue.Value;
  1020. SemanticModel speculativeModel;
  1021. bool success = model.TryGetSpeculativeSemanticModel(equalsValue.SpanStart, newEqualsValue, out speculativeModel);
  1022. Assert.True(success);
  1023. Assert.NotNull(speculativeModel);
  1024. var typeInfo = speculativeModel.GetTypeInfo(expr);
  1025. Assert.NotNull(typeInfo.Type);
  1026. Assert.Equal("Int16", typeInfo.Type.Name);
  1027. Assert.Equal("Int32", typeInfo.ConvertedType.Name);
  1028. var constantInfo = speculativeModel.GetConstantValue(expr);
  1029. Assert.True(constantInfo.HasValue, "must be a constant");
  1030. Assert.Equal((short)0, constantInfo.Value);
  1031. }
  1032. [Fact]
  1033. [WorkItem(648305, "DevDiv")]
  1034. public void TestGetSpeculativeSemanticModelInDefaultValueArgument()
  1035. {
  1036. var compilation = CreateCompilationWithMscorlib(@"
  1037. class C
  1038. {
  1039. void M(int x = 1)
  1040. {
  1041. string y = ""Hello"";
  1042. }
  1043. }
  1044. ");
  1045. var tree = compilation.SyntaxTrees[0];
  1046. var root = tree.GetCompilationUnitRoot();
  1047. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1048. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  1049. var equalsValue = methodDecl.ParameterList.Parameters[0].Default;
  1050. var paramDefaultArg = equalsValue.Value;
  1051. var model = compilation.GetSemanticModel(tree);
  1052. var ti = model.GetTypeInfo(paramDefaultArg);
  1053. // Speculate on the equals value syntax (initializer)
  1054. // Conversion info available, ConvertedType: Int32.
  1055. var newEqualsValue = SyntaxFactory.EqualsValueClause(SyntaxFactory.ParseExpression("(short)0"));
  1056. var expr = newEqualsValue.Value;
  1057. SemanticModel speculativeModel;
  1058. bool success = model.TryGetSpeculativeSemanticModel(equalsValue.SpanStart, newEqualsValue, out speculativeModel);
  1059. Assert.True(success);
  1060. Assert.NotNull(speculativeModel);
  1061. var typeInfo = speculativeModel.GetTypeInfo(expr);
  1062. Assert.NotNull(typeInfo.Type);
  1063. Assert.Equal("Int16", typeInfo.Type.Name);
  1064. Assert.Equal("Int32", typeInfo.ConvertedType.Name);
  1065. var constantInfo = speculativeModel.GetConstantValue(expr);
  1066. Assert.True(constantInfo.HasValue, "must be a constant");
  1067. Assert.Equal((short)0, constantInfo.Value);
  1068. }
  1069. [Fact]
  1070. [WorkItem(746002, "DevDiv")]
  1071. public void TestGetSpeculativeSemanticModelInDefaultValueArgument2()
  1072. {
  1073. var compilation = CreateCompilationWithMscorlib(@"
  1074. using System;
  1075. enum E
  1076. {
  1077. A = 1,
  1078. B = 2
  1079. }
  1080. interface I
  1081. {
  1082. void M1(E e = E.A);
  1083. }
  1084. ");
  1085. var tree = compilation.SyntaxTrees[0];
  1086. var root = tree.GetCompilationUnitRoot();
  1087. var interfaceDecl = (TypeDeclarationSyntax)root.Members[1];
  1088. var methodDecl = (MethodDeclarationSyntax)interfaceDecl.Members[0];
  1089. var param = methodDecl.ParameterList.Parameters[0];
  1090. var equalsValue = param.Default;
  1091. var paramDefaultArg = equalsValue.Value;
  1092. var model = compilation.GetSemanticModel(tree);
  1093. // Speculate on the equals value syntax (initializer) with a non-null parent
  1094. var newEqualsValue = SyntaxFactory.EqualsValueClause(SyntaxFactory.ParseExpression("E.B | E.A"));
  1095. newEqualsValue = param.ReplaceNode(equalsValue, newEqualsValue).Default;
  1096. var binaryExpr = newEqualsValue.Value;
  1097. SemanticModel speculativeModel;
  1098. bool success = model.TryGetSpeculativeSemanticModel(equalsValue.SpanStart, newEqualsValue, out speculativeModel);
  1099. Assert.True(success);
  1100. Assert.NotNull(speculativeModel);
  1101. var typeInfo = speculativeModel.GetTypeInfo(binaryExpr);
  1102. Assert.NotNull(typeInfo.Type);
  1103. Assert.Equal("E", typeInfo.Type.Name);
  1104. Assert.Equal("E", typeInfo.ConvertedType.Name);
  1105. }
  1106. [Fact]
  1107. [WorkItem(657701, "DevDiv")]
  1108. public void TestGetSpeculativeSemanticModelInConstructorDefaultValueArgument()
  1109. {
  1110. var compilation = CreateCompilationWithMscorlib(@"
  1111. class C
  1112. {
  1113. C(int x = 1)
  1114. {
  1115. string y = ""Hello"";
  1116. }
  1117. }
  1118. ");
  1119. var tree = compilation.SyntaxTrees[0];
  1120. var root = tree.GetCompilationUnitRoot();
  1121. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1122. var constructorDecl = (ConstructorDeclarationSyntax)typeDecl.Members[0];
  1123. var equalsValue = constructorDecl.ParameterList.Parameters[0].Default;
  1124. var paramDefaultArg = equalsValue.Value;
  1125. var model = compilation.GetSemanticModel(tree);
  1126. var ti = model.GetTypeInfo(paramDefaultArg);
  1127. // Speculate on the equals value syntax (initializer)
  1128. // Conversion info available, ConvertedType: Int32.
  1129. var newEqualsValue = SyntaxFactory.EqualsValueClause(SyntaxFactory.ParseExpression("(short)0"));
  1130. var expr = newEqualsValue.Value;
  1131. SemanticModel speculativeModel;
  1132. bool success = model.TryGetSpeculativeSemanticModel(equalsValue.SpanStart, newEqualsValue, out speculativeModel);
  1133. Assert.True(success);
  1134. Assert.NotNull(speculativeModel);
  1135. var typeInfo = speculativeModel.GetTypeInfo(expr);
  1136. Assert.NotNull(typeInfo.Type);
  1137. Assert.Equal("Int16", typeInfo.Type.Name);
  1138. Assert.Equal("Int32", typeInfo.ConvertedType.Name);
  1139. var constantInfo = speculativeModel.GetConstantValue(expr);
  1140. Assert.True(constantInfo.HasValue, "must be a constant");
  1141. Assert.Equal((short)0, constantInfo.Value);
  1142. }
  1143. [WorkItem(529893, "DevDiv")]
  1144. [Fact]
  1145. public void AliasCalledVar()
  1146. {
  1147. var source = @"
  1148. using var = Q;
  1149. class Q
  1150. {
  1151. var q;
  1152. }
  1153. ";
  1154. var comp = CreateCompilationWithMscorlib(source);
  1155. comp.VerifyDiagnostics(
  1156. // (6,9): warning CS0169: The field 'Q.q' is never used
  1157. // var q;
  1158. Diagnostic(ErrorCode.WRN_UnreferencedField, "q").WithArguments("Q.q"));
  1159. var classQ = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("Q");
  1160. var fieldQ = classQ.GetMember<FieldSymbol>("q");
  1161. Assert.Equal(classQ, fieldQ.Type);
  1162. var tree = comp.SyntaxTrees.Single();
  1163. var model = comp.GetSemanticModel(tree);
  1164. var aliasDecl = tree.GetRoot().DescendantNodes().OfType<UsingDirectiveSyntax>().Single();
  1165. var aliasSymbol = model.GetDeclaredSymbol(aliasDecl);
  1166. Assert.Equal(SymbolKind.Alias, aliasSymbol.Kind);
  1167. Assert.Equal(classQ, ((AliasSymbol)aliasSymbol).Target);
  1168. Assert.Equal("var", aliasSymbol.Name);
  1169. var aliasDeclInfo = model.GetSymbolInfo(aliasDecl.Alias.Name);
  1170. Assert.Null(aliasDeclInfo.Symbol);
  1171. Assert.Equal(CandidateReason.None, aliasDeclInfo.CandidateReason);
  1172. var fieldDecl = tree.GetRoot().DescendantNodes().OfType<FieldDeclarationSyntax>().Single();
  1173. var fieldSymbol = model.GetDeclaredSymbol(fieldDecl.Declaration.Variables.Single());
  1174. Assert.Equal(fieldQ, fieldSymbol);
  1175. var typeSyntax = (IdentifierNameSyntax)fieldDecl.Declaration.Type;
  1176. var fieldTypeInfo = model.GetSymbolInfo(typeSyntax);
  1177. Assert.Equal(classQ, fieldTypeInfo.Symbol);
  1178. var fieldTypeAliasInfo = model.GetAliasInfo(typeSyntax);
  1179. Assert.Equal(aliasSymbol, fieldTypeAliasInfo);
  1180. }
  1181. [Fact]
  1182. public void TestGetSpeculativeSemanticModelForStatement()
  1183. {
  1184. var compilation = CreateCompilationWithMscorlib(@"
  1185. class C
  1186. {
  1187. void M(int x)
  1188. {
  1189. int y = 1000;
  1190. }
  1191. }
  1192. ");
  1193. var statement = (BlockSyntax)SyntaxFactory.ParseStatement(@"
  1194. {
  1195. int z = 0;
  1196. M(z);
  1197. M(y);
  1198. }
  1199. ");
  1200. var tree = compilation.SyntaxTrees[0];
  1201. var root = tree.GetCompilationUnitRoot();
  1202. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1203. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  1204. var model = compilation.GetSemanticModel(tree);
  1205. SemanticModel speculativeModel;
  1206. bool success = model.TryGetSpeculativeSemanticModel(methodDecl.Body.Statements[0].SpanStart, statement, out speculativeModel);
  1207. Assert.True(success);
  1208. Assert.NotNull(speculativeModel);
  1209. var localDecl = (LocalDeclarationStatementSyntax)statement.Statements[0];
  1210. var declarator = localDecl.Declaration.Variables.First();
  1211. var local = speculativeModel.GetDeclaredSymbol(declarator);
  1212. Assert.NotNull(local);
  1213. Assert.Equal("z", local.Name);
  1214. Assert.Equal(SymbolKind.Local, local.Kind);
  1215. Assert.Equal("Int32", ((LocalSymbol)local).Type.Name);
  1216. var typeInfo = speculativeModel.GetTypeInfo(localDecl.Declaration.Type);
  1217. Assert.NotNull(typeInfo.Type);
  1218. Assert.Equal("Int32", typeInfo.Type.Name);
  1219. var call = (InvocationExpressionSyntax)((ExpressionStatementSyntax)statement.Statements[1]).Expression;
  1220. var arg = call.ArgumentList.Arguments[0].Expression;
  1221. var info = speculativeModel.GetSymbolInfo(arg);
  1222. Assert.NotNull(info.Symbol);
  1223. Assert.Equal("z", info.Symbol.Name);
  1224. Assert.Equal(SymbolKind.Local, info.Symbol.Kind);
  1225. var call2 = (InvocationExpressionSyntax)((ExpressionStatementSyntax)((BlockSyntax)statement).Statements[2]).Expression;
  1226. var arg2 = call2.ArgumentList.Arguments[0].Expression;
  1227. var info2 = speculativeModel.GetSymbolInfo(arg2);
  1228. Assert.NotNull(info2.Symbol);
  1229. Assert.Equal("y", info2.Symbol.Name);
  1230. Assert.Equal(SymbolKind.Local, info2.Symbol.Kind);
  1231. }
  1232. [Fact]
  1233. public void TestGetSpeculativeSemanticModelForStatement_DeclaredLocal()
  1234. {
  1235. var compilation = CreateCompilationWithMscorlib(@"
  1236. class C
  1237. {
  1238. void M(int x)
  1239. {
  1240. int y = 1000;
  1241. }
  1242. }
  1243. ");
  1244. var tree = compilation.SyntaxTrees[0];
  1245. var root = tree.GetCompilationUnitRoot();
  1246. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1247. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  1248. var model = compilation.GetSemanticModel(tree);
  1249. // different name local
  1250. var statement = SyntaxFactory.ParseStatement(@"int z = 0;");
  1251. SemanticModel speculativeModel;
  1252. bool success = model.TryGetSpeculativeSemanticModel(methodDecl.Body.Statements[0].SpanStart, statement, out speculativeModel);
  1253. Assert.True(success);
  1254. Assert.NotNull(speculativeModel);
  1255. var declarator = ((LocalDeclarationStatementSyntax)statement).Declaration.Variables.First();
  1256. var local = speculativeModel.GetDeclaredSymbol(declarator);
  1257. Assert.NotNull(local);
  1258. Assert.Equal("z", local.Name);
  1259. Assert.Equal(SymbolKind.Local, local.Kind);
  1260. Assert.Equal("Int32", ((LocalSymbol)local).Type.Name);
  1261. // same name local
  1262. statement = SyntaxFactory.ParseStatement(@"string y = null;");
  1263. success = model.TryGetSpeculativeSemanticModel(methodDecl.Body.Statements[0].SpanStart, statement, out speculativeModel);
  1264. Assert.True(success);
  1265. Assert.NotNull(speculativeModel);
  1266. declarator = ((LocalDeclarationStatementSyntax)statement).Declaration.Variables.First();
  1267. local = speculativeModel.GetDeclaredSymbol(declarator);
  1268. Assert.NotNull(local);
  1269. Assert.Equal("y", local.Name);
  1270. Assert.Equal(SymbolKind.Local, local.Kind);
  1271. Assert.Equal("String", ((LocalSymbol)local).Type.Name);
  1272. }
  1273. [Fact]
  1274. public void TestGetSpeculativeSemanticModelForStatement_GetDeclaredLabelSymbol()
  1275. {
  1276. var compilation = CreateCompilationWithMscorlib(@"
  1277. class C
  1278. {
  1279. void M(int x)
  1280. {
  1281. int y = 1000;
  1282. }
  1283. }
  1284. ");
  1285. var labeledStatement = SyntaxFactory.ParseStatement(@"label: y++;");
  1286. var tree = compilation.SyntaxTrees[0];
  1287. var root = tree.GetCompilationUnitRoot();
  1288. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1289. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  1290. var model = compilation.GetSemanticModel(tree);
  1291. SemanticModel statModel;
  1292. bool success = model.TryGetSpeculativeSemanticModel(methodDecl.Body.Statements[0].SpanStart, labeledStatement, out statModel);
  1293. Assert.True(success);
  1294. Assert.NotNull(statModel);
  1295. var label = statModel.GetDeclaredSymbol(labeledStatement);
  1296. Assert.NotNull(label);
  1297. Assert.Equal("label", label.Name);
  1298. Assert.Equal(SymbolKind.Label, label.Kind);
  1299. }
  1300. [Fact]
  1301. public void TestGetSpeculativeSemanticModelForStatement_GetDeclaredSwitchLabelSymbol()
  1302. {
  1303. var compilation = CreateCompilationWithMscorlib(@"
  1304. class C
  1305. {
  1306. void M(int x)
  1307. {
  1308. int y = 0;
  1309. }
  1310. }
  1311. ");
  1312. var switchStatement = (SwitchStatementSyntax)SyntaxFactory.ParseStatement(@"
  1313. switch (y)
  1314. {
  1315. case 0:
  1316. y++;
  1317. break;
  1318. }");
  1319. var switchLabel = switchStatement.Sections[0].Labels[0];
  1320. var tree = compilation.SyntaxTrees[0];
  1321. var root = tree.GetCompilationUnitRoot();
  1322. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1323. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  1324. var model = compilation.GetSemanticModel(tree);
  1325. SemanticModel statModel;
  1326. bool success = model.TryGetSpeculativeSemanticModel(methodDecl.Body.Statements[0].Span.End, switchStatement, out statModel);
  1327. Assert.True(success);
  1328. Assert.NotNull(statModel);
  1329. var symbol = statModel.GetDeclaredSymbol(switchLabel);
  1330. Assert.NotNull(symbol);
  1331. Assert.IsType<SourceLabelSymbol>(symbol);
  1332. var labelSymbol = (SourceLabelSymbol)symbol;
  1333. Assert.Equal(ConstantValue.Default(SpecialType.System_Int32), labelSymbol.SwitchCaseLabelConstant);
  1334. Assert.Equal(switchLabel, labelSymbol.IdentifierNodeOrToken.AsNode());
  1335. Assert.Equal("case 0:", labelSymbol.Name);
  1336. }
  1337. [Fact]
  1338. public void TestGetSpeculativeSemanticModelForStatement_GetDeclaredLambdaParameterSymbol()
  1339. {
  1340. var compilation = CreateCompilationWithMscorlibAndSystemCore(@"
  1341. using System.Linq;
  1342. class C
  1343. {
  1344. void M(int x)
  1345. {
  1346. int y = 0;
  1347. }
  1348. }
  1349. ");
  1350. var speculatedStatement = (LocalDeclarationStatementSyntax)SyntaxFactory.ParseStatement(@"Func<int, int> var = (z) => x + z;");
  1351. var tree = compilation.SyntaxTrees[0];
  1352. var root = tree.GetCompilationUnitRoot();
  1353. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1354. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  1355. var model = compilation.GetSemanticModel(tree);
  1356. SemanticModel speculativeModel;
  1357. bool success = model.TryGetSpeculativeSemanticModel(methodDecl.Body.Statements[0].Span.End, speculatedStatement, out speculativeModel);
  1358. Assert.True(success);
  1359. Assert.NotNull(speculativeModel);
  1360. var lambdaExpression = speculatedStatement.DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>().FirstOrDefault();
  1361. var lambdaParam = lambdaExpression.ParameterList.Parameters[0];
  1362. var parameterSymbol = speculativeModel.GetDeclaredSymbol(lambdaParam);
  1363. Assert.NotNull(parameterSymbol);
  1364. Assert.Equal("z", parameterSymbol.Name);
  1365. }
  1366. [Fact]
  1367. public void TestGetSpeculativeSemanticModelForStatement_ForEach()
  1368. {
  1369. var compilation = CreateCompilationWithMscorlib(@"
  1370. class C
  1371. {
  1372. void M(int x)
  1373. {
  1374. var a = new [] {1, 2, 3};
  1375. }
  1376. }
  1377. ");
  1378. var statement = (ForEachStatementSyntax)SyntaxFactory.ParseStatement(@"
  1379. foreach(short ele in a)
  1380. {
  1381. }
  1382. ");
  1383. var tree = compilation.SyntaxTrees[0];
  1384. var root = tree.GetCompilationUnitRoot();
  1385. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1386. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  1387. var model = compilation.GetSemanticModel(tree);
  1388. SemanticModel speculativeModel;
  1389. bool success = model.TryGetSpeculativeSemanticModel(methodDecl.Body.Statements[0].SpanStart, statement, out speculativeModel);
  1390. Assert.True(success);
  1391. Assert.NotNull(speculativeModel);
  1392. ForEachStatementInfo info = speculativeModel.GetForEachStatementInfo(statement);
  1393. Assert.NotNull(info);
  1394. Assert.Equal("System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()", info.GetEnumeratorMethod.ToTestDisplayString());
  1395. Assert.Equal("System.Object System.Collections.IEnumerator.Current.get", info.CurrentProperty.GetMethod.ToTestDisplayString());
  1396. Assert.Equal("System.Boolean System.Collections.IEnumerator.MoveNext()", info.MoveNextMethod.ToTestDisplayString());
  1397. Assert.Equal("void System.IDisposable.Dispose()", info.DisposeMethod.ToTestDisplayString());
  1398. }
  1399. [Fact]
  1400. public void TestGetSpeculativeSemanticModelInAutoPropInitializer1()
  1401. {
  1402. var source = @"class C
  1403. {
  1404. int y = 0;
  1405. int X { get; } = 1;
  1406. }";
  1407. var comp = CreateCompilationWithMscorlib(source, parseOptions: TestOptions.ExperimentalParseOptions);
  1408. var tree = comp.SyntaxTrees.Single();
  1409. var model = comp.GetSemanticModel(tree);
  1410. Assert.False(model.IsSpeculativeSemanticModel);
  1411. Assert.Null(model.ParentModel);
  1412. Assert.Equal(0, model.OriginalPositionForSpeculation);
  1413. // Speculate on the initializer
  1414. var root = tree.GetCompilationUnitRoot();
  1415. var oldSyntax = root.DescendantNodes()
  1416. .OfType<EqualsValueClauseSyntax>().ElementAt(1);
  1417. var position = oldSyntax.SpanStart;
  1418. var newSyntax = SyntaxFactory.EqualsValueClause(
  1419. SyntaxFactory.ParseExpression("this.y"));
  1420. var expr = newSyntax.Value;
  1421. SemanticModel speculativeModel;
  1422. bool success = model.TryGetSpeculativeSemanticModel(oldSyntax.SpanStart,
  1423. newSyntax, out speculativeModel);
  1424. Assert.True(success);
  1425. Assert.NotNull(speculativeModel);
  1426. Assert.True(speculativeModel.IsSpeculativeSemanticModel);
  1427. Assert.Equal(model, speculativeModel.ParentModel);
  1428. Assert.Equal(position, speculativeModel.OriginalPositionForSpeculation);
  1429. var typeInfo = speculativeModel.GetTypeInfo(expr);
  1430. Assert.NotNull(typeInfo);
  1431. Assert.Equal("Int32", typeInfo.Type.Name);
  1432. var thisSyntax = expr.DescendantNodes().OfType<ThisExpressionSyntax>().Single();
  1433. var symbolInfo = speculativeModel.GetSpeculativeSymbolInfo(
  1434. thisSyntax.SpanStart,
  1435. thisSyntax, SpeculativeBindingOption.BindAsExpression);
  1436. Assert.NotNull(symbolInfo);
  1437. var candidates = symbolInfo.CandidateSymbols;
  1438. Assert.Equal(1, candidates.Length);
  1439. Assert.IsType<ThisParameterSymbol>(candidates[0]);
  1440. Assert.Equal(CandidateReason.NotReferencable, symbolInfo.CandidateReason);
  1441. }
  1442. [Fact]
  1443. public void TestGetSpeculativeSemanticModelForConstructorInitializer()
  1444. {
  1445. var source = @"class C
  1446. {
  1447. C(int x) { }
  1448. C() : this((int) 1) { }
  1449. }";
  1450. var comp = CreateCompilationWithMscorlib(source);
  1451. comp.VerifyDiagnostics();
  1452. var tree = comp.SyntaxTrees.Single();
  1453. var parentModel = comp.GetSemanticModel(tree);
  1454. var oldSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ConstructorInitializerSyntax>().Single();
  1455. var newSyntax = SyntaxFactory.ConstructorInitializer(SyntaxKind.ThisConstructorInitializer);
  1456. SemanticModel speculativeModel;
  1457. bool success = parentModel.TryGetSpeculativeSemanticModel(oldSyntax.SpanStart, newSyntax, out speculativeModel);
  1458. Assert.True(success);
  1459. Assert.NotNull(speculativeModel);
  1460. var info = speculativeModel.GetSymbolInfo(newSyntax);
  1461. var symbol = info.Symbol;
  1462. Assert.NotNull(symbol);
  1463. Assert.Equal(comp.GlobalNamespace.GetMember<NamedTypeSymbol>("C"), symbol.ContainingType);
  1464. Assert.Equal(SymbolKind.Method, symbol.Kind);
  1465. var method = (MethodSymbol)symbol;
  1466. Assert.Equal(MethodKind.Constructor, method.MethodKind);
  1467. Assert.Equal(0, method.ParameterCount);
  1468. // test unnecessary cast removal
  1469. var newArgument = SyntaxFactory.ParseExpression("1");
  1470. newSyntax = oldSyntax.ReplaceNode(oldSyntax.DescendantNodes().OfType<CastExpressionSyntax>().Single(), newArgument);
  1471. success = parentModel.TryGetSpeculativeSemanticModel(oldSyntax.SpanStart, newSyntax, out speculativeModel);
  1472. Assert.True(success);
  1473. Assert.NotNull(speculativeModel);
  1474. info = speculativeModel.GetSymbolInfo(newSyntax);
  1475. symbol = info.Symbol;
  1476. Assert.NotNull(symbol);
  1477. Assert.Equal(comp.GlobalNamespace.GetMember<NamedTypeSymbol>("C"), symbol.ContainingType);
  1478. Assert.Equal(SymbolKind.Method, symbol.Kind);
  1479. method = (MethodSymbol)symbol;
  1480. Assert.Equal(MethodKind.Constructor, method.MethodKind);
  1481. Assert.Equal(1, method.ParameterCount);
  1482. // test incorrect cast replacement
  1483. newArgument = SyntaxFactory.ParseExpression("(string) 1");
  1484. newSyntax = oldSyntax.ReplaceNode(oldSyntax.DescendantNodes().OfType<CastExpressionSyntax>().Single(), newArgument);
  1485. success = parentModel.TryGetSpeculativeSemanticModel(oldSyntax.SpanStart, newSyntax, out speculativeModel);
  1486. Assert.True(success);
  1487. Assert.NotNull(speculativeModel);
  1488. info = speculativeModel.GetSymbolInfo(newSyntax);
  1489. symbol = info.Symbol;
  1490. Assert.Null(symbol);
  1491. Assert.Equal(CandidateReason.OverloadResolutionFailure, info.CandidateReason);
  1492. Assert.Equal(2, info.CandidateSymbols.Length);
  1493. var sortedCandidates = info.CandidateSymbols.OrderBy(s => s.ToTestDisplayString()).ToArray();
  1494. Assert.Equal("C..ctor()", sortedCandidates[0].ToTestDisplayString());
  1495. Assert.Equal(SymbolKind.Method, sortedCandidates[0].Kind);
  1496. Assert.Equal("C..ctor(System.Int32 x)", sortedCandidates[1].ToTestDisplayString());
  1497. Assert.Equal(SymbolKind.Method, sortedCandidates[1].Kind);
  1498. }
  1499. [WorkItem(545882, "DevDiv")]
  1500. [Fact]
  1501. public void TestGetSpeculativeSemanticModelForConstructorInitializer_UnsupportedLocation()
  1502. {
  1503. var source = @"class C
  1504. {
  1505. C() { }
  1506. }";
  1507. var comp = CreateCompilationWithMscorlib(source);
  1508. comp.VerifyDiagnostics();
  1509. var tree = comp.SyntaxTrees.Single();
  1510. var parentModel = comp.GetSemanticModel(tree);
  1511. var oldSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ConstructorDeclarationSyntax>().Single();
  1512. var newSyntax = SyntaxFactory.ConstructorInitializer(SyntaxKind.ThisConstructorInitializer);
  1513. SemanticModel speculativeModel;
  1514. bool success = parentModel.TryGetSpeculativeSemanticModel(oldSyntax.SpanStart, newSyntax, out speculativeModel);
  1515. Assert.False(success);
  1516. Assert.Null(speculativeModel);
  1517. }
  1518. [Fact]
  1519. public void TestArgumentsToGetSpeculativeSemanticModelAPI()
  1520. {
  1521. var compilation = CreateCompilationWithMscorlib(@"
  1522. class C
  1523. {
  1524. public C(): this(0) {}
  1525. public C(int i) {}
  1526. [System.Obsolete]
  1527. void M(int x)
  1528. {
  1529. string y = ""Hello"";
  1530. }
  1531. }
  1532. ");
  1533. var tree = compilation.SyntaxTrees[0];
  1534. var root = tree.GetCompilationUnitRoot();
  1535. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1536. var ctor1 = (ConstructorDeclarationSyntax)typeDecl.Members[0];
  1537. var ctor2 = (ConstructorDeclarationSyntax)typeDecl.Members[1];
  1538. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[2];
  1539. var model = compilation.GetSemanticModel(tree);
  1540. var statement = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
  1541. var initializer = statement.Declaration.Variables[0].Initializer;
  1542. var ctorInitializer = ctor1.Initializer;
  1543. var attribute = methodDecl.AttributeLists[0].Attributes[0];
  1544. SemanticModel speculativeModel;
  1545. Assert.Throws<ArgumentNullException>(() => model.TryGetSpeculativeSemanticModel(statement.SpanStart, statement: null, speculativeModel: out speculativeModel));
  1546. Assert.Throws<ArgumentNullException>(() => model.TryGetSpeculativeSemanticModel(statement.SpanStart, constructorInitializer: null, speculativeModel: out speculativeModel));
  1547. Assert.Throws<ArgumentNullException>(() => model.TryGetSpeculativeSemanticModel(statement.SpanStart, attribute: null, speculativeModel: out speculativeModel));
  1548. // Speculate on a node from the same syntax tree.
  1549. Assert.Throws<ArgumentException>(() => model.TryGetSpeculativeSemanticModel(statement.SpanStart, statement: statement, speculativeModel: out speculativeModel));
  1550. Assert.Throws<ArgumentException>(() => model.TryGetSpeculativeSemanticModel(ctorInitializer.SpanStart, constructorInitializer: ctorInitializer, speculativeModel: out speculativeModel));
  1551. Assert.Throws<ArgumentException>(() => model.TryGetSpeculativeSemanticModel(attribute.SpanStart, attribute: attribute, speculativeModel: out speculativeModel));
  1552. // Chaining speculative semantic model is not supported.
  1553. var speculatedStatement = statement.ReplaceNode(initializer.Value, SyntaxFactory.ParseExpression("0"));
  1554. model.TryGetSpeculativeSemanticModel(statement.SpanStart, speculatedStatement, speculativeModel: out speculativeModel);
  1555. Assert.Throws<InvalidOperationException>(() => speculativeModel.TryGetSpeculativeSemanticModel(speculatedStatement.SpanStart, speculatedStatement, speculativeModel: out speculativeModel));
  1556. }
  1557. [Fact]
  1558. public void TestGetSpeculativeSemanticModelOnSpeculativeSemanticModel()
  1559. {
  1560. var compilation = CreateCompilationWithMscorlib(@"
  1561. class C
  1562. {
  1563. public C(): this(0) {}
  1564. public C(int i) {}
  1565. [System.Obsolete]
  1566. void M(int x)
  1567. {
  1568. string y = ""Hello"";
  1569. }
  1570. }
  1571. ");
  1572. var tree = compilation.SyntaxTrees[0];
  1573. var root = tree.GetCompilationUnitRoot();
  1574. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1575. var ctor1 = (ConstructorDeclarationSyntax)typeDecl.Members[0];
  1576. var ctor2 = (ConstructorDeclarationSyntax)typeDecl.Members[1];
  1577. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[2];
  1578. var model = compilation.GetSemanticModel(tree);
  1579. var statement = (LocalDeclarationStatementSyntax)methodDecl.Body.Statements[0];
  1580. var expression = statement.Declaration.Variables[0].Initializer.Value;
  1581. var ctorInitializer = ctor1.Initializer;
  1582. var attribute = methodDecl.AttributeLists[0].Attributes[0];
  1583. var speculatedStatement = statement.ReplaceNode(expression, SyntaxFactory.ParseExpression("0"));
  1584. SemanticModel speculativeModel;
  1585. var success = model.TryGetSpeculativeSemanticModel(statement.SpanStart, speculatedStatement, out speculativeModel);
  1586. Assert.True(success);
  1587. Assert.NotNull(speculativeModel);
  1588. // Chaining speculative semantic model is not supported.
  1589. // (a) Expression
  1590. var newSpeculatedStatement = statement.ReplaceNode(expression, SyntaxFactory.ParseExpression("1.1"));
  1591. SemanticModel newModel;
  1592. Assert.Throws<InvalidOperationException>(() => speculativeModel.TryGetSpeculativeSemanticModel(speculatedStatement.SpanStart, newSpeculatedStatement, out newModel));
  1593. // (b) Statement
  1594. newSpeculatedStatement = (LocalDeclarationStatementSyntax)SyntaxFactory.ParseStatement(@"int z = 0;");
  1595. Assert.Throws<InvalidOperationException>(() => speculativeModel.TryGetSpeculativeSemanticModel(speculatedStatement.SpanStart, newSpeculatedStatement, out newModel));
  1596. }
  1597. [Fact]
  1598. public void TestGetSpeculativeSemanticModelInsideUnsafeCode()
  1599. {
  1600. var compilation = CreateCompilationWithMscorlib(@"
  1601. unsafe class C
  1602. {
  1603. void M()
  1604. {
  1605. int x;
  1606. }
  1607. }
  1608. ");
  1609. var tree = compilation.SyntaxTrees[0];
  1610. var root = tree.GetCompilationUnitRoot();
  1611. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1612. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  1613. var model = compilation.GetSemanticModel(tree);
  1614. var unsafeStatement = (LocalDeclarationStatementSyntax)SyntaxFactory.ParseStatement("int *p = &x;");
  1615. SemanticModel speculativeModel;
  1616. var success = model.TryGetSpeculativeSemanticModel(methodDecl.Body.Statements[0].Span.End, unsafeStatement, out speculativeModel);
  1617. Assert.True(success);
  1618. Assert.NotNull(speculativeModel);
  1619. var declarator = unsafeStatement.Declaration.Variables.First();
  1620. var initializer = declarator.Initializer.Value;
  1621. var binder = ((CSharpSemanticModel)speculativeModel).GetEnclosingBinder(initializer.SpanStart);
  1622. Assert.True(binder.InUnsafeRegion, "must be in unsafe code");
  1623. Assert.True(binder.IsSemanticModelBinder, "must be speculative");
  1624. var typeInfo = speculativeModel.GetTypeInfo(initializer);
  1625. Assert.Equal("System.Int32*", typeInfo.Type.ToTestDisplayString());
  1626. Assert.Equal(TypeKind.PointerType, typeInfo.Type.TypeKind);
  1627. Assert.Equal("System.Int32*", typeInfo.ConvertedType.ToTestDisplayString());
  1628. Assert.Equal(TypeKind.PointerType, typeInfo.ConvertedType.TypeKind);
  1629. var conv = speculativeModel.GetConversion(initializer);
  1630. Assert.Equal(ConversionKind.Identity, conv.Kind);
  1631. var symbol = speculativeModel.GetDeclaredSymbol(declarator);
  1632. Assert.NotNull(symbol);
  1633. Assert.Equal(SymbolKind.Local, symbol.Kind);
  1634. Assert.Equal("p", symbol.Name);
  1635. }
  1636. [WorkItem(663704, "DevDiv")]
  1637. [Fact]
  1638. public void TestGetSpeculativeSemanticModelInsideUnknownAccessor()
  1639. {
  1640. var source = @"
  1641. class C
  1642. {
  1643. C P
  1644. {
  1645. foo
  1646. {
  1647. return null;
  1648. }
  1649. }
  1650. }
  1651. ";
  1652. var comp = CreateCompilationWithMscorlib(source);
  1653. var tree = comp.SyntaxTrees.Single();
  1654. var model = comp.GetSemanticModel(tree);
  1655. var accessorSyntax = tree.GetRoot().DescendantNodes().OfType<AccessorDeclarationSyntax>().Single();
  1656. Assert.Equal(SyntaxKind.UnknownAccessorDeclaration, accessorSyntax.Kind);
  1657. var statementSyntax = tree.GetRoot().DescendantNodes().OfType<ReturnStatementSyntax>().Single();
  1658. var memberModel = ((CSharpSemanticModel)model).GetMemberModel(statementSyntax);
  1659. Assert.Null(memberModel); // No member model since no symbol.
  1660. var speculativeSyntax = SyntaxFactory.ParseStatement("return default(C);");
  1661. SemanticModel speculativeModel;
  1662. var success = model.TryGetSpeculativeSemanticModel(statementSyntax.SpanStart, speculativeSyntax, out speculativeModel);
  1663. Assert.False(success);
  1664. Assert.Null(speculativeModel);
  1665. }
  1666. [Fact]
  1667. public void TestGetSpeculativeSemanticModelForMethodBody()
  1668. {
  1669. var compilation = CreateCompilationWithMscorlib(@"
  1670. class C
  1671. {
  1672. void M(int x)
  1673. {
  1674. int y = 1000;
  1675. }
  1676. }
  1677. ");
  1678. var blockStatement = (BlockSyntax)SyntaxFactory.ParseStatement(@"
  1679. {
  1680. int z = 0;
  1681. M(z);
  1682. M(y); // Should generate error here as we are replacing the method body.
  1683. }
  1684. ");
  1685. var tree = compilation.SyntaxTrees[0];
  1686. var root = tree.GetCompilationUnitRoot();
  1687. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1688. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  1689. var model = compilation.GetSemanticModel(tree);
  1690. var speculatedMethod = methodDecl.ReplaceNode(methodDecl.Body, blockStatement);
  1691. blockStatement = speculatedMethod.Body;
  1692. SemanticModel speculativeModel;
  1693. var success = model.TryGetSpeculativeSemanticModelForMethodBody(methodDecl.Body.Statements[0].SpanStart, speculatedMethod, out speculativeModel);
  1694. Assert.True(success);
  1695. Assert.NotNull(speculativeModel);
  1696. VerifySpeculativeSemanticModelForMethodBody(blockStatement, speculativeModel);
  1697. }
  1698. private static void VerifySpeculativeSemanticModelForMethodBody(BlockSyntax blockStatement, SemanticModel speculativeModel)
  1699. {
  1700. var localDecl = (LocalDeclarationStatementSyntax)blockStatement.Statements[0];
  1701. var declarator = localDecl.Declaration.Variables.First();
  1702. var local = speculativeModel.GetDeclaredSymbol(declarator);
  1703. Assert.NotNull(local);
  1704. Assert.Equal("z", local.Name);
  1705. Assert.Equal(SymbolKind.Local, local.Kind);
  1706. Assert.Equal("Int32", ((LocalSymbol)local).Type.Name);
  1707. var typeInfo = speculativeModel.GetTypeInfo(localDecl.Declaration.Type);
  1708. Assert.NotNull(typeInfo.Type);
  1709. Assert.Equal("Int32", typeInfo.Type.Name);
  1710. var call = (InvocationExpressionSyntax)((ExpressionStatementSyntax)blockStatement.Statements[1]).Expression;
  1711. var arg = call.ArgumentList.Arguments[0].Expression;
  1712. var info = speculativeModel.GetSymbolInfo(arg);
  1713. Assert.NotNull(info.Symbol);
  1714. Assert.Equal("z", info.Symbol.Name);
  1715. Assert.Equal(SymbolKind.Local, info.Symbol.Kind);
  1716. // Shouldn't bind to local y in the original method as we are replacing the method body.
  1717. var call2 = (InvocationExpressionSyntax)((ExpressionStatementSyntax)((BlockSyntax)blockStatement).Statements[2]).Expression;
  1718. var arg2 = call2.ArgumentList.Arguments[0].Expression;
  1719. var info2 = speculativeModel.GetSymbolInfo(arg2);
  1720. Assert.Null(info2.Symbol);
  1721. }
  1722. [Fact]
  1723. public void TestGetSpeculativeSemanticModelForInexerAccessorBody()
  1724. {
  1725. var compilation = CreateCompilationWithMscorlib(@"
  1726. class C
  1727. {
  1728. private int this[int x]
  1729. {
  1730. set
  1731. {
  1732. int y = 1000;
  1733. }
  1734. }
  1735. }
  1736. ");
  1737. var blockStatement = (BlockSyntax)SyntaxFactory.ParseStatement(@"
  1738. {
  1739. int z = 0;
  1740. M(z);
  1741. M(y); // Should generate error here as we are replacing the method body.
  1742. }
  1743. ");
  1744. var tree = compilation.SyntaxTrees[0];
  1745. var root = tree.GetCompilationUnitRoot();
  1746. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1747. var indexerDecl = (IndexerDeclarationSyntax)typeDecl.Members[0];
  1748. var methodDecl = indexerDecl.AccessorList.Accessors[0];
  1749. var model = compilation.GetSemanticModel(tree);
  1750. var speculatedMethod = methodDecl.ReplaceNode(methodDecl.Body, blockStatement);
  1751. blockStatement = speculatedMethod.Body;
  1752. SemanticModel speculativeModel;
  1753. var success = model.TryGetSpeculativeSemanticModelForMethodBody(methodDecl.Body.Statements[0].SpanStart, speculatedMethod, out speculativeModel);
  1754. Assert.True(success);
  1755. Assert.NotNull(speculativeModel);
  1756. VerifySpeculativeSemanticModelForMethodBody(blockStatement, speculativeModel);
  1757. }
  1758. [Fact]
  1759. public void TestGetSpeculativeSemanticModelForPropertyAccessorBody()
  1760. {
  1761. var compilation = CreateCompilationWithMscorlib(@"
  1762. class C
  1763. {
  1764. private int M
  1765. {
  1766. set
  1767. {
  1768. int y = 1000;
  1769. }
  1770. }
  1771. }
  1772. ");
  1773. var blockStatement = (BlockSyntax)SyntaxFactory.ParseStatement(@"
  1774. {
  1775. int z = 0;
  1776. M(z);
  1777. M(y); // Should generate error here as we are replacing the method body.
  1778. }
  1779. ");
  1780. var tree = compilation.SyntaxTrees[0];
  1781. var root = tree.GetCompilationUnitRoot();
  1782. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1783. var propertyDecl = (PropertyDeclarationSyntax)typeDecl.Members[0];
  1784. var methodDecl = propertyDecl.AccessorList.Accessors[0];
  1785. var model = compilation.GetSemanticModel(tree);
  1786. var speculatedMethod = methodDecl.ReplaceNode(methodDecl.Body, blockStatement);
  1787. blockStatement = speculatedMethod.Body;
  1788. SemanticModel speculativeModel;
  1789. var success = model.TryGetSpeculativeSemanticModelForMethodBody(methodDecl.Body.Statements[0].SpanStart, speculatedMethod, out speculativeModel);
  1790. Assert.True(success);
  1791. Assert.NotNull(speculativeModel);
  1792. VerifySpeculativeSemanticModelForMethodBody(blockStatement, speculativeModel);
  1793. }
  1794. [Fact]
  1795. public void TestGetSpeculativeSemanticModelForEventAccessorBody()
  1796. {
  1797. var compilation = CreateCompilationWithMscorlib(@"
  1798. class C
  1799. {
  1800. private event System.Action E
  1801. {
  1802. add
  1803. {
  1804. int y = 1000;
  1805. }
  1806. remove
  1807. {
  1808. }
  1809. }
  1810. }
  1811. ");
  1812. var blockStatement = (BlockSyntax)SyntaxFactory.ParseStatement(@"
  1813. {
  1814. int z = 0;
  1815. M(z);
  1816. M(y); // Should generate error here as we are replacing the method body.
  1817. }
  1818. ");
  1819. var tree = compilation.SyntaxTrees[0];
  1820. var root = tree.GetCompilationUnitRoot();
  1821. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1822. var eventDecl = (EventDeclarationSyntax)typeDecl.Members[0];
  1823. var methodDecl = eventDecl.AccessorList.Accessors[0];
  1824. var model = compilation.GetSemanticModel(tree);
  1825. var speculatedMethod = methodDecl.ReplaceNode(methodDecl.Body, blockStatement);
  1826. blockStatement = speculatedMethod.Body;
  1827. SemanticModel speculativeModel;
  1828. var success = model.TryGetSpeculativeSemanticModelForMethodBody(methodDecl.Body.Statements[0].SpanStart, speculatedMethod, out speculativeModel);
  1829. Assert.True(success);
  1830. Assert.NotNull(speculativeModel);
  1831. VerifySpeculativeSemanticModelForMethodBody(blockStatement, speculativeModel);
  1832. }
  1833. [Fact]
  1834. public void TestGetSpeculativeSemanticModelForMethodBody_DeclaredLocal()
  1835. {
  1836. var compilation = CreateCompilationWithMscorlib(@"
  1837. class C
  1838. {
  1839. void M(int x)
  1840. {
  1841. int y = 1000;
  1842. }
  1843. }
  1844. ");
  1845. var tree = compilation.SyntaxTrees[0];
  1846. var root = tree.GetCompilationUnitRoot();
  1847. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1848. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  1849. var model = compilation.GetSemanticModel(tree);
  1850. // different name local
  1851. var blockStatement = (BlockSyntax)SyntaxFactory.ParseStatement(@"{ int z = 0; }");
  1852. var speculatedMethod = methodDecl.ReplaceNode(methodDecl.Body, blockStatement);
  1853. blockStatement = speculatedMethod.Body;
  1854. SemanticModel speculativeModel;
  1855. var success = model.TryGetSpeculativeSemanticModelForMethodBody(methodDecl.Body.Statements[0].SpanStart, speculatedMethod, out speculativeModel);
  1856. Assert.True(success);
  1857. Assert.NotNull(speculativeModel);
  1858. var declarator = ((LocalDeclarationStatementSyntax)blockStatement.Statements[0]).Declaration.Variables.First();
  1859. var local = speculativeModel.GetDeclaredSymbol(declarator);
  1860. Assert.NotNull(local);
  1861. Assert.Equal("z", local.Name);
  1862. Assert.Equal(SymbolKind.Local, local.Kind);
  1863. Assert.Equal("Int32", ((LocalSymbol)local).Type.Name);
  1864. // same name local
  1865. blockStatement = (BlockSyntax)SyntaxFactory.ParseStatement(@"{ string y = null; }");
  1866. speculatedMethod = methodDecl.ReplaceNode(methodDecl.Body, blockStatement);
  1867. blockStatement = speculatedMethod.Body;
  1868. success = model.TryGetSpeculativeSemanticModelForMethodBody(methodDecl.Body.Statements[0].SpanStart, speculatedMethod, out speculativeModel);
  1869. Assert.True(success);
  1870. Assert.NotNull(speculativeModel);
  1871. declarator = ((LocalDeclarationStatementSyntax)blockStatement.Statements[0]).Declaration.Variables.First();
  1872. local = speculativeModel.GetDeclaredSymbol(declarator);
  1873. Assert.NotNull(local);
  1874. Assert.Equal("y", local.Name);
  1875. Assert.Equal(SymbolKind.Local, local.Kind);
  1876. Assert.Equal("String", ((LocalSymbol)local).Type.Name);
  1877. // parameter symbol
  1878. blockStatement = (BlockSyntax)SyntaxFactory.ParseStatement(@"{ var y = x; }");
  1879. speculatedMethod = methodDecl.ReplaceNode(methodDecl.Body, blockStatement);
  1880. blockStatement = speculatedMethod.Body;
  1881. success = model.TryGetSpeculativeSemanticModelForMethodBody(methodDecl.Body.Statements[0].SpanStart, speculatedMethod, out speculativeModel);
  1882. Assert.True(success);
  1883. Assert.NotNull(speculativeModel);
  1884. declarator = ((LocalDeclarationStatementSyntax)blockStatement.Statements[0]).Declaration.Variables.First();
  1885. local = speculativeModel.GetDeclaredSymbol(declarator);
  1886. Assert.NotNull(local);
  1887. Assert.Equal("y", local.Name);
  1888. Assert.Equal(SymbolKind.Local, local.Kind);
  1889. Assert.Equal("Int32", ((LocalSymbol)local).Type.Name);
  1890. var param = speculativeModel.GetSymbolInfo(declarator.Initializer.Value).Symbol;
  1891. Assert.NotNull(param);
  1892. Assert.Equal(SymbolKind.Parameter, param.Kind);
  1893. var paramSymbol = (ParameterSymbol)param;
  1894. Assert.Equal("x", paramSymbol.Name);
  1895. Assert.Equal("Int32", paramSymbol.Type.Name);
  1896. }
  1897. [Fact]
  1898. public void TestGetSpeculativeSemanticModelForMethodBody_GetDeclaredLabelSymbol()
  1899. {
  1900. var compilation = CreateCompilationWithMscorlib(@"
  1901. class C
  1902. {
  1903. void M(int x)
  1904. {
  1905. int y = 1000;
  1906. }
  1907. }
  1908. ");
  1909. var tree = compilation.SyntaxTrees[0];
  1910. var root = tree.GetCompilationUnitRoot();
  1911. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1912. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  1913. var model = compilation.GetSemanticModel(tree);
  1914. var blockStatement = (BlockSyntax)SyntaxFactory.ParseStatement(@"{ label: y++; }");
  1915. var speculatedMethod = methodDecl.ReplaceNode(methodDecl.Body, blockStatement);
  1916. blockStatement = speculatedMethod.Body;
  1917. var labeledStatement = blockStatement.Statements[0];
  1918. SemanticModel speculativeModel;
  1919. var success = model.TryGetSpeculativeSemanticModelForMethodBody(methodDecl.Body.Statements[0].SpanStart, speculatedMethod, out speculativeModel);
  1920. Assert.True(success);
  1921. Assert.NotNull(speculativeModel);
  1922. var label = speculativeModel.GetDeclaredSymbol(labeledStatement);
  1923. Assert.NotNull(label);
  1924. Assert.Equal("label", label.Name);
  1925. Assert.Equal(SymbolKind.Label, label.Kind);
  1926. }
  1927. [Fact]
  1928. public void TestGetSpeculativeSemanticModelForMethodBody_GetDeclaredLambdaParameterSymbol()
  1929. {
  1930. var compilation = CreateCompilationWithMscorlibAndSystemCore(@"
  1931. using System.Linq;
  1932. class C
  1933. {
  1934. void M(int x)
  1935. {
  1936. int z = 0;
  1937. }
  1938. }
  1939. ");
  1940. var tree = compilation.SyntaxTrees[0];
  1941. var root = tree.GetCompilationUnitRoot();
  1942. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  1943. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  1944. var model = compilation.GetSemanticModel(tree);
  1945. var blockStatement = (BlockSyntax)SyntaxFactory.ParseStatement(@"{ Func<int, int> var = (z) => x + z; }");
  1946. var speculatedMethod = methodDecl.ReplaceNode(methodDecl.Body, blockStatement);
  1947. blockStatement = speculatedMethod.Body;
  1948. SemanticModel speculativeModel;
  1949. var success = model.TryGetSpeculativeSemanticModelForMethodBody(methodDecl.Body.Statements[0].Span.End, speculatedMethod, out speculativeModel);
  1950. Assert.True(success);
  1951. Assert.NotNull(speculativeModel);
  1952. var lambdaExpression = blockStatement.Statements[0].DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>().FirstOrDefault();
  1953. var lambdaParam = lambdaExpression.ParameterList.Parameters[0];
  1954. var parameterSymbol = speculativeModel.GetDeclaredSymbol(lambdaParam);
  1955. Assert.NotNull(parameterSymbol);
  1956. Assert.Equal("z", parameterSymbol.Name);
  1957. }
  1958. private static void TestGetSpeculativeSemanticModelForTypeSyntax_Common(
  1959. SemanticModel model,
  1960. int position,
  1961. TypeSyntax speculatedTypeSyntax,
  1962. SpeculativeBindingOption bindingOption,
  1963. SymbolKind expectedSymbolKind,
  1964. string expectedTypeDislayString)
  1965. {
  1966. Assert.False(model.IsSpeculativeSemanticModel);
  1967. Assert.Null(model.ParentModel);
  1968. Assert.Equal(0, model.OriginalPositionForSpeculation);
  1969. SemanticModel speculativeModel;
  1970. var success = model.TryGetSpeculativeSemanticModel(position, speculatedTypeSyntax, out speculativeModel, bindingOption);
  1971. Assert.True(success);
  1972. Assert.NotNull(speculativeModel);
  1973. Assert.True(speculativeModel.IsSpeculativeSemanticModel);
  1974. Assert.Equal(model, speculativeModel.ParentModel);
  1975. Assert.NotNull(speculativeModel);
  1976. Assert.Equal(position, speculativeModel.OriginalPositionForSpeculation);
  1977. var symbol = speculativeModel.GetSymbolInfo(speculatedTypeSyntax).Symbol;
  1978. Assert.NotNull(symbol);
  1979. Assert.Equal(expectedSymbolKind, symbol.Kind);
  1980. Assert.Equal(expectedTypeDislayString, symbol.ToDisplayString());
  1981. var typeSymbol = speculativeModel.GetTypeInfo(speculatedTypeSyntax).Type;
  1982. Assert.NotNull(symbol);
  1983. Assert.Equal(expectedSymbolKind, symbol.Kind);
  1984. Assert.Equal(expectedTypeDislayString, symbol.ToDisplayString());
  1985. if (speculatedTypeSyntax.Kind == SyntaxKind.QualifiedName)
  1986. {
  1987. var right = ((QualifiedNameSyntax)speculatedTypeSyntax).Right;
  1988. symbol = speculativeModel.GetSymbolInfo(right).Symbol;
  1989. Assert.NotNull(symbol);
  1990. Assert.Equal(expectedSymbolKind, symbol.Kind);
  1991. Assert.Equal(expectedTypeDislayString, symbol.ToDisplayString());
  1992. typeSymbol = speculativeModel.GetTypeInfo(right).Type;
  1993. Assert.NotNull(symbol);
  1994. Assert.Equal(expectedSymbolKind, symbol.Kind);
  1995. Assert.Equal(expectedTypeDislayString, symbol.ToDisplayString());
  1996. }
  1997. }
  1998. [Fact]
  1999. public void TestGetSpeculativeSemanticModelForMethodBody_SwitchStatement()
  2000. {
  2001. var compilation = CreateCompilationWithMscorlib(@"
  2002. using System;
  2003. class C
  2004. {
  2005. void M(int x)
  2006. {
  2007. switch(x)
  2008. {
  2009. case 0:
  2010. Console.WriteLine(x);
  2011. break;
  2012. }
  2013. }
  2014. }
  2015. ");
  2016. var tree = compilation.SyntaxTrees[0];
  2017. var root = tree.GetCompilationUnitRoot();
  2018. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  2019. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  2020. var model = compilation.GetSemanticModel(tree);
  2021. var blockStatement = (BlockSyntax)SyntaxFactory.ParseStatement(@"{
  2022. switch(x)
  2023. {
  2024. case 1:
  2025. Console.WriteLine(x);
  2026. break;
  2027. }
  2028. }");
  2029. var speculatedMethod = methodDecl.ReplaceNode(methodDecl.Body, blockStatement);
  2030. blockStatement = speculatedMethod.Body;
  2031. var switchStatement = (SwitchStatementSyntax)blockStatement.Statements[0];
  2032. SemanticModel speculativeModel;
  2033. var success = model.TryGetSpeculativeSemanticModelForMethodBody(methodDecl.Body.Statements[0].SpanStart, speculatedMethod, out speculativeModel);
  2034. Assert.True(success);
  2035. Assert.NotNull(speculativeModel);
  2036. var switchLabel = switchStatement.Sections[0].Labels[0];
  2037. var constantVal = speculativeModel.GetConstantValue(switchLabel.Value);
  2038. Assert.True(constantVal.HasValue);
  2039. Assert.Equal(1, constantVal.Value);
  2040. }
  2041. [Fact]
  2042. public void TestGetSpeculativeSemanticModelForTypeSyntax_InGlobalUsing()
  2043. {
  2044. var compilation = CreateCompilationWithMscorlib(@"using System.Runtime;");
  2045. var tree = compilation.SyntaxTrees[0];
  2046. var root = tree.GetCompilationUnitRoot();
  2047. var usingStatement = root.Usings[0];
  2048. var model = compilation.GetSemanticModel(tree);
  2049. var speculatedUsingExpression = SyntaxFactory.ParseName("System.Collections");
  2050. TestGetSpeculativeSemanticModelForTypeSyntax_Common(model, usingStatement.Name.Position,
  2051. speculatedUsingExpression, SpeculativeBindingOption.BindAsTypeOrNamespace, SymbolKind.Namespace, "System.Collections");
  2052. }
  2053. [Fact]
  2054. public void TestGetSpeculativeSemanticModelForTypeSyntax_InGlobalAlias()
  2055. {
  2056. var compilation = CreateCompilationWithMscorlib(@"using A = System.Exception;");
  2057. var tree = compilation.SyntaxTrees[0];
  2058. var root = tree.GetCompilationUnitRoot();
  2059. var usingStatement = root.Usings[0];
  2060. var model = compilation.GetSemanticModel(tree);
  2061. var speculatedUsingExpression = SyntaxFactory.ParseName("System.ArgumentException");
  2062. TestGetSpeculativeSemanticModelForTypeSyntax_Common(model, usingStatement.Name.Position,
  2063. speculatedUsingExpression, SpeculativeBindingOption.BindAsExpression, SymbolKind.NamedType, "System.ArgumentException");
  2064. }
  2065. [Fact]
  2066. public void TestGetSpeculativeSemanticModelForTypeSyntax_InBaseList()
  2067. {
  2068. var compilation = CreateCompilationWithMscorlib(@"
  2069. class MyException : System.Exception
  2070. {
  2071. }
  2072. ");
  2073. var tree = compilation.SyntaxTrees[0];
  2074. var root = tree.GetCompilationUnitRoot();
  2075. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  2076. var baseList = typeDecl.BaseList;
  2077. var model = compilation.GetSemanticModel(tree);
  2078. var speculatedTypeExpression = SyntaxFactory.ParseName("System.ArgumentException");
  2079. TestGetSpeculativeSemanticModelForTypeSyntax_Common(model, baseList.SpanStart,
  2080. speculatedTypeExpression, SpeculativeBindingOption.BindAsTypeOrNamespace, SymbolKind.NamedType, "System.ArgumentException");
  2081. }
  2082. [Fact]
  2083. public void TestGetSpeculativeSemanticModelForTypeSyntax_InMemberDeclaration()
  2084. {
  2085. var compilation = CreateCompilationWithMscorlib(@"
  2086. class Program
  2087. {
  2088. System.Exception field = null;
  2089. System.Exception Method(System.Exception param)
  2090. {
  2091. return field;
  2092. }
  2093. }
  2094. ");
  2095. var tree = compilation.SyntaxTrees[0];
  2096. var root = tree.GetCompilationUnitRoot();
  2097. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  2098. var fieldDecl = (FieldDeclarationSyntax)typeDecl.Members[0];
  2099. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[1];
  2100. var model = compilation.GetSemanticModel(tree);
  2101. var speculatedTypeExpression = SyntaxFactory.ParseName("System.ArgumentException");
  2102. TestGetSpeculativeSemanticModelForTypeSyntax_Common(model, fieldDecl.SpanStart,
  2103. speculatedTypeExpression, SpeculativeBindingOption.BindAsTypeOrNamespace, SymbolKind.NamedType, "System.ArgumentException");
  2104. TestGetSpeculativeSemanticModelForTypeSyntax_Common(model, methodDecl.ReturnType.SpanStart,
  2105. speculatedTypeExpression, SpeculativeBindingOption.BindAsTypeOrNamespace, SymbolKind.NamedType, "System.ArgumentException");
  2106. TestGetSpeculativeSemanticModelForTypeSyntax_Common(model, methodDecl.ParameterList.Parameters.First().SpanStart,
  2107. speculatedTypeExpression, SpeculativeBindingOption.BindAsTypeOrNamespace, SymbolKind.NamedType, "System.ArgumentException");
  2108. }
  2109. [Fact]
  2110. public void TestGetSpeculativeSemanticModelForTypeSyntax_AliasName()
  2111. {
  2112. var compilation = CreateCompilationWithMscorlib(@"
  2113. using A = System.ArgumentException;
  2114. class Program
  2115. {
  2116. System.Exception field = null;
  2117. }
  2118. ");
  2119. var tree = compilation.SyntaxTrees[0];
  2120. var root = tree.GetCompilationUnitRoot();
  2121. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  2122. var fieldDecl = (FieldDeclarationSyntax)typeDecl.Members[0];
  2123. var model = compilation.GetSemanticModel(tree);
  2124. var speculatedAliasName = SyntaxFactory.ParseName("A");
  2125. SemanticModel speculativeModel;
  2126. var success = model.TryGetSpeculativeSemanticModel(fieldDecl.SpanStart, speculatedAliasName, out speculativeModel);
  2127. Assert.True(success);
  2128. Assert.NotNull(speculativeModel);
  2129. var symbol = (AliasSymbol)speculativeModel.GetAliasInfo(speculatedAliasName);
  2130. Assert.NotNull(symbol);
  2131. Assert.Equal("A", symbol.ToDisplayString());
  2132. Assert.Equal("System.ArgumentException", symbol.Target.ToDisplayString());
  2133. }
  2134. [Fact]
  2135. public void TestGetSpeculativeSemanticModelForTypeCrefSyntax()
  2136. {
  2137. var compilation = CreateCompilationWithMscorlibAndDocumentationComments(@"
  2138. /// <summary>
  2139. /// <see cref=""int""/>
  2140. /// </summary>
  2141. class A { }
  2142. ");
  2143. var tree = compilation.SyntaxTrees[0];
  2144. var root = tree.GetCompilationUnitRoot();
  2145. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  2146. var cref = typeDecl.DescendantNodes(descendIntoTrivia: true).OfType<TypeCrefSyntax>().Single();
  2147. var model = (CSharpSemanticModel)compilation.GetSemanticModel(tree);
  2148. var symbol = model.GetSymbolInfo(cref.Type).Symbol;
  2149. Assert.NotNull(symbol);
  2150. Assert.Equal("int", symbol.ToDisplayString());
  2151. var speculatedCref = (TypeCrefSyntax)SyntaxFactory.ParseCref("object");
  2152. // TryGetSpeculativeSemanticModel
  2153. SemanticModel speculativeModel;
  2154. var success = model.TryGetSpeculativeSemanticModel(cref.SpanStart, speculatedCref, out speculativeModel);
  2155. Assert.True(success);
  2156. Assert.NotNull(speculativeModel);
  2157. symbol = speculativeModel.GetSymbolInfo(speculatedCref.Type).Symbol;
  2158. Assert.NotNull(symbol);
  2159. Assert.Equal(SymbolKind.NamedType, symbol.Kind);
  2160. Assert.Equal("object", symbol.ToDisplayString());
  2161. // GetSpeculativeSymbolInfo
  2162. symbol = model.GetSpeculativeSymbolInfo(cref.SpanStart, speculatedCref).Symbol;
  2163. Assert.NotNull(symbol);
  2164. Assert.Equal(SymbolKind.NamedType, symbol.Kind);
  2165. Assert.Equal("object", symbol.ToDisplayString());
  2166. }
  2167. [Fact]
  2168. public void TestGetSpeculativeSemanticModelForNameMemberCrefSyntax()
  2169. {
  2170. var compilation = CreateCompilationWithMscorlibAndDocumentationComments(@"
  2171. /// <summary>
  2172. /// <see cref=""int""/>
  2173. /// </summary>
  2174. class A { }
  2175. ");
  2176. var tree = compilation.SyntaxTrees[0];
  2177. var root = tree.GetCompilationUnitRoot();
  2178. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  2179. var cref = typeDecl.DescendantNodes(descendIntoTrivia: true).OfType<TypeCrefSyntax>().Single();
  2180. var model = (CSharpSemanticModel)compilation.GetSemanticModel(tree);
  2181. var symbol = model.GetSymbolInfo(cref.Type).Symbol;
  2182. Assert.NotNull(symbol);
  2183. Assert.Equal("int", symbol.ToDisplayString());
  2184. var speculatedCref = (NameMemberCrefSyntax)SyntaxFactory.ParseCref("A");
  2185. // TryGetSpeculativeSemanticModel
  2186. SemanticModel speculativeModel;
  2187. var success = model.TryGetSpeculativeSemanticModel(cref.SpanStart, speculatedCref, out speculativeModel);
  2188. Assert.True(success);
  2189. Assert.NotNull(speculativeModel);
  2190. symbol = speculativeModel.GetSymbolInfo(speculatedCref.Name).Symbol;
  2191. Assert.NotNull(symbol);
  2192. Assert.Equal(SymbolKind.NamedType, symbol.Kind);
  2193. Assert.Equal("A", symbol.ToDisplayString());
  2194. // GetSpeculativeSymbolInfo
  2195. symbol = model.GetSpeculativeSymbolInfo(cref.SpanStart, speculatedCref).Symbol;
  2196. Assert.NotNull(symbol);
  2197. Assert.Equal(SymbolKind.NamedType, symbol.Kind);
  2198. Assert.Equal("A", symbol.ToDisplayString());
  2199. }
  2200. [Fact]
  2201. public void TestGetSpeculativeSemanticModelForQualifiedCrefSyntax()
  2202. {
  2203. var compilation = CreateCompilationWithMscorlibAndDocumentationComments(@"
  2204. /// <summary>
  2205. /// <see cref=""int""/>
  2206. /// </summary>
  2207. class A
  2208. {
  2209. class B { }
  2210. static void M() { }
  2211. }
  2212. ");
  2213. var tree = compilation.SyntaxTrees[0];
  2214. var root = tree.GetCompilationUnitRoot();
  2215. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  2216. var cref = typeDecl.DescendantNodes(descendIntoTrivia: true).OfType<TypeCrefSyntax>().Single();
  2217. var model = (CSharpSemanticModel)compilation.GetSemanticModel(tree);
  2218. var symbol = model.GetSymbolInfo(cref.Type).Symbol;
  2219. Assert.NotNull(symbol);
  2220. Assert.Equal("int", symbol.ToDisplayString());
  2221. var speculatedCref = (QualifiedCrefSyntax)SyntaxFactory.ParseCref("A.B");
  2222. // Type member: TryGetSpeculativeSemanticModel
  2223. SemanticModel speculativeModel;
  2224. var success = model.TryGetSpeculativeSemanticModel(cref.SpanStart, speculatedCref, out speculativeModel);
  2225. Assert.True(success);
  2226. Assert.NotNull(speculativeModel);
  2227. symbol = speculativeModel.GetSymbolInfo(speculatedCref).Symbol;
  2228. Assert.NotNull(symbol);
  2229. Assert.Equal(SymbolKind.NamedType, symbol.Kind);
  2230. Assert.Equal("A.B", symbol.ToDisplayString());
  2231. symbol = speculativeModel.GetSymbolInfo(speculatedCref.Member).Symbol;
  2232. Assert.NotNull(symbol);
  2233. Assert.Equal(SymbolKind.NamedType, symbol.Kind);
  2234. Assert.Equal("A.B", symbol.ToDisplayString());
  2235. symbol = speculativeModel.GetTypeInfo(speculatedCref.Container).Type;
  2236. Assert.NotNull(symbol);
  2237. Assert.Equal(SymbolKind.NamedType, symbol.Kind);
  2238. Assert.Equal("A", symbol.ToDisplayString());
  2239. // Type member: GetSpeculativeSymbolInfo
  2240. symbol = model.GetSpeculativeSymbolInfo(cref.SpanStart, speculatedCref).Symbol;
  2241. Assert.NotNull(symbol);
  2242. Assert.Equal(SymbolKind.NamedType, symbol.Kind);
  2243. Assert.Equal("A.B", symbol.ToDisplayString());
  2244. // Method member: TryGetSpeculativeSemanticModel
  2245. speculatedCref = (QualifiedCrefSyntax)SyntaxFactory.ParseCref("A.M");
  2246. success = model.TryGetSpeculativeSemanticModel(cref.SpanStart, speculatedCref, out speculativeModel);
  2247. Assert.True(success);
  2248. Assert.NotNull(speculativeModel);
  2249. symbol = speculativeModel.GetSymbolInfo(speculatedCref).Symbol;
  2250. Assert.NotNull(symbol);
  2251. Assert.Equal(SymbolKind.Method, symbol.Kind);
  2252. Assert.Equal("A.M()", symbol.ToDisplayString());
  2253. symbol = speculativeModel.GetSymbolInfo(speculatedCref.Member).Symbol;
  2254. Assert.NotNull(symbol);
  2255. Assert.Equal(SymbolKind.Method, symbol.Kind);
  2256. Assert.Equal("A.M()", symbol.ToDisplayString());
  2257. symbol = speculativeModel.GetTypeInfo(speculatedCref.Container).Type;
  2258. Assert.NotNull(symbol);
  2259. Assert.Equal(SymbolKind.NamedType, symbol.Kind);
  2260. Assert.Equal("A", symbol.ToDisplayString());
  2261. // Method member: GetSpeculativeSymbolInfo
  2262. symbol = model.GetSpeculativeSymbolInfo(cref.SpanStart, speculatedCref).Symbol;
  2263. Assert.NotNull(symbol);
  2264. Assert.Equal(SymbolKind.Method, symbol.Kind);
  2265. Assert.Equal("A.M()", symbol.ToDisplayString());
  2266. }
  2267. [Fact]
  2268. public void TestGetSpeculativeSemanticModelForCrefSyntax_InvalidPosition()
  2269. {
  2270. var compilation = CreateCompilationWithMscorlibAndDocumentationComments(@"
  2271. /// <summary>
  2272. /// <see cref=""int""/>
  2273. /// </summary>
  2274. class A
  2275. {
  2276. static void M() { }
  2277. }
  2278. ");
  2279. var tree = compilation.SyntaxTrees[0];
  2280. var root = tree.GetCompilationUnitRoot();
  2281. var typeDecl = (TypeDeclarationSyntax)root.Members[0];
  2282. var methodDecl = (MethodDeclarationSyntax)typeDecl.Members[0];
  2283. var model = (CSharpSemanticModel)compilation.GetSemanticModel(tree);
  2284. var speculatedCref = (TypeCrefSyntax)SyntaxFactory.ParseCref("object");
  2285. // TryGetSpeculativeSemanticModel
  2286. SemanticModel speculativeModel;
  2287. var success = model.TryGetSpeculativeSemanticModel(typeDecl.SpanStart, speculatedCref, out speculativeModel);
  2288. Assert.False(success);
  2289. success = model.TryGetSpeculativeSemanticModel(methodDecl.Body.SpanStart, speculatedCref, out speculativeModel);
  2290. Assert.False(success);
  2291. // GetSpeculativeSymbolInfo
  2292. var symbolInfo = model.GetSpeculativeSymbolInfo(methodDecl.Body.SpanStart, speculatedCref);
  2293. Assert.Null(symbolInfo.Symbol);
  2294. }
  2295. [WorkItem(731108, "DevDiv")]
  2296. [Fact]
  2297. public void Repro731108()
  2298. {
  2299. var source = @"
  2300. public class C
  2301. {
  2302. static void Main()
  2303. {
  2304. M(async x => x);
  2305. }
  2306. static void M(C c)
  2307. {
  2308. }
  2309. }
  2310. ";
  2311. var comp = CreateCompilationWithMscorlib(source);
  2312. var tree = comp.SyntaxTrees.Single();
  2313. var model = comp.GetSemanticModel(tree);
  2314. var syntax = tree.GetRoot().DescendantNodes().OfType<SimpleLambdaExpressionSyntax>().Single().
  2315. Body.DescendantNodesAndSelf().OfType<IdentifierNameSyntax>().Single();
  2316. Assert.Equal("x", syntax.Identifier.ValueText);
  2317. var symbol = model.GetSymbolInfo(syntax).Symbol;
  2318. Assert.Equal(SymbolKind.Parameter, symbol.Kind);
  2319. Assert.Equal("x", symbol.Name);
  2320. Assert.Equal(TypeKind.Error, ((ParameterSymbol)symbol).Type.TypeKind);
  2321. }
  2322. [WorkItem(783566, "DevDiv")]
  2323. [Fact]
  2324. public void SpeculateAboutYieldStatement1()
  2325. {
  2326. var source = @"
  2327. class C
  2328. {
  2329. void M() // No way to infer iterator element type.
  2330. {
  2331. return;
  2332. }
  2333. }
  2334. ";
  2335. var comp = CreateCompilationWithMscorlib(source);
  2336. comp.VerifyDiagnostics();
  2337. var tree = comp.SyntaxTrees.Single();
  2338. var model = comp.GetSemanticModel(tree);
  2339. var position = source.IndexOf("return");
  2340. var yieldStatement = (YieldStatementSyntax)SyntaxFactory.ParseStatement("yield return 1;");
  2341. SemanticModel speculativeModel;
  2342. var success = model.TryGetSpeculativeSemanticModel(position, yieldStatement, out speculativeModel);
  2343. Assert.True(success);
  2344. Assert.NotNull(speculativeModel);
  2345. var info = speculativeModel.GetTypeInfo(yieldStatement.Expression);
  2346. Assert.Equal(SpecialType.System_Int32, info.Type.SpecialType);
  2347. Assert.Equal(TypeKind.Error, info.ConvertedType.TypeKind);
  2348. }
  2349. [WorkItem(783566, "DevDiv")]
  2350. [Fact]
  2351. public void SpeculateAboutYieldStatement2()
  2352. {
  2353. var source = @"
  2354. using System.Collections.Generic;
  2355. class C
  2356. {
  2357. IEnumerable<long> M() // Can infer iterator element type.
  2358. {
  2359. return null;
  2360. }
  2361. }
  2362. ";
  2363. var comp = CreateCompilationWithMscorlib(source);
  2364. comp.VerifyDiagnostics();
  2365. var tree = comp.SyntaxTrees.Single();
  2366. var model = comp.GetSemanticModel(tree);
  2367. var position = source.IndexOf("return");
  2368. var yieldStatement = (YieldStatementSyntax)SyntaxFactory.ParseStatement("yield return 1;");
  2369. SemanticModel speculativeModel;
  2370. var success = model.TryGetSpeculativeSemanticModel(position, yieldStatement, out speculativeModel);
  2371. Assert.True(success);
  2372. Assert.NotNull(speculativeModel);
  2373. var info = speculativeModel.GetTypeInfo(yieldStatement.Expression);
  2374. Assert.Equal(SpecialType.System_Int32, info.Type.SpecialType);
  2375. Assert.Equal(SpecialType.System_Int64, info.ConvertedType.SpecialType);
  2376. }
  2377. [WorkItem(791794, "DevDiv")]
  2378. [Fact]
  2379. public void SpeculateAboutOmittedArraySizeInCref()
  2380. {
  2381. var source = @"
  2382. /// <see cref=""int""/>
  2383. class C
  2384. {
  2385. }
  2386. ";
  2387. var comp = CreateCompilationWithMscorlibAndDocumentationComments(source);
  2388. comp.VerifyDiagnostics();
  2389. var tree = comp.SyntaxTrees.Single();
  2390. var model = comp.GetSemanticModel(tree);
  2391. var position = source.IndexOf("int");
  2392. var typeSyntax = SyntaxFactory.ParseTypeName("System.Collections.Generic.IEnumerable<C[]>");
  2393. SemanticModel speculativeModel;
  2394. var success = model.TryGetSpeculativeSemanticModel(position, typeSyntax, out speculativeModel);
  2395. Assert.True(success);
  2396. Assert.NotNull(speculativeModel);
  2397. var omittedArraySize = typeSyntax.DescendantNodes().OfType<OmittedArraySizeExpressionSyntax>().Single();
  2398. var info = speculativeModel.GetSymbolInfo(omittedArraySize); // Used to throw NRE.
  2399. Assert.Null(info.Symbol);
  2400. Assert.Equal(CandidateReason.None, info.CandidateReason);
  2401. Assert.Equal(0, info.CandidateSymbols.Length);
  2402. }
  2403. [WorkItem(784255, "DevDiv")]
  2404. [Fact]
  2405. public void Repro784255()
  2406. {
  2407. var source = @"
  2408. using System;
  2409. public class CategoryAttribute : Attribute
  2410. {
  2411. public CategoryAttribute(string s) { }
  2412. private CategoryAttribute() { }
  2413. }
  2414. struct S
  2415. {
  2416. }
  2417. ";
  2418. var comp = CreateCompilationWithMscorlib(source);
  2419. comp.VerifyDiagnostics();
  2420. var tree = comp.SyntaxTrees.Single();
  2421. var model = comp.GetSemanticModel(tree);
  2422. var position = source.IndexOf("struct");
  2423. var attributeSyntax = SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("Category"));
  2424. SemanticModel speculativeModel;
  2425. var success = model.TryGetSpeculativeSemanticModel(position, attributeSyntax, out speculativeModel);
  2426. Assert.True(success);
  2427. Assert.NotNull(speculativeModel);
  2428. var info = speculativeModel.GetSymbolInfo(attributeSyntax.Name);
  2429. }
  2430. [WorkItem(823791, "DevDiv")]
  2431. [Fact]
  2432. public void LambdaArgumentInBadCall_Constructor()
  2433. {
  2434. var source = @"
  2435. using System;
  2436. class Test
  2437. {
  2438. void M()
  2439. {
  2440. new Test(s => s.
  2441. }
  2442. Test(Action<string> a, int i) { }
  2443. }
  2444. ";
  2445. CheckLambdaArgumentInBadCall(source);
  2446. }
  2447. [WorkItem(823791, "DevDiv")]
  2448. [Fact]
  2449. public void LambdaArgumentInBadCall_Method()
  2450. {
  2451. var source = @"
  2452. using System;
  2453. class Test
  2454. {
  2455. void M()
  2456. {
  2457. Method(s => s.
  2458. }
  2459. void Method(Action<string> a, int i) { }
  2460. }
  2461. ";
  2462. CheckLambdaArgumentInBadCall(source);
  2463. }
  2464. [WorkItem(823791, "DevDiv")]
  2465. [Fact]
  2466. public void LambdaArgumentInBadCall_Indexer()
  2467. {
  2468. var source = @"
  2469. using System;
  2470. class Test
  2471. {
  2472. void M()
  2473. {
  2474. var t = this[s => s.
  2475. }
  2476. int this[Action<string> a, int i] { get { return 0; } }
  2477. }
  2478. ";
  2479. CheckLambdaArgumentInBadCall(source);
  2480. }
  2481. [WorkItem(823791, "DevDiv")]
  2482. [Fact]
  2483. public void LambdaArgumentInBadCall_Delegate()
  2484. {
  2485. var source = @"
  2486. using System;
  2487. class Test
  2488. {
  2489. void M()
  2490. {
  2491. d(s => s.
  2492. }
  2493. Action<Action<string>, int> d = null;
  2494. }
  2495. ";
  2496. CheckLambdaArgumentInBadCall(source);
  2497. }
  2498. [WorkItem(823791, "DevDiv")]
  2499. [Fact]
  2500. public void LambdaArgumentInBadCall_ConstructorInitializer()
  2501. {
  2502. var source = @"
  2503. using System;
  2504. class Test
  2505. {
  2506. protected Test(Action<string> a, int i) { }
  2507. }
  2508. class Derived : Test
  2509. {
  2510. Derived()
  2511. : base(s => s.
  2512. {
  2513. }
  2514. }
  2515. ";
  2516. CheckLambdaArgumentInBadCall(source);
  2517. }
  2518. private static void CheckLambdaArgumentInBadCall(string source)
  2519. {
  2520. var comp = CreateCompilationWithMscorlib(source);
  2521. var tree = comp.SyntaxTrees.Single();
  2522. Assert.NotEmpty(tree.GetDiagnostics());
  2523. var memberAccess = tree.GetRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().Single();
  2524. var identifier = (IdentifierNameSyntax)memberAccess.Expression;
  2525. Assert.Equal("s", identifier.Identifier.ValueText);
  2526. var stringType = comp.GetSpecialType(SpecialType.System_String);
  2527. var actionType = comp.GetWellKnownType(WellKnownType.System_Action_T).Construct(stringType);
  2528. var model = comp.GetSemanticModel(tree);
  2529. // Can't walk up to ArgumentListSyntax because indexers use BracketedArgumentListSyntax.
  2530. var expr = identifier.FirstAncestorOrSelf<ArgumentSyntax>().Parent.Parent;
  2531. var exprInfo = model.GetSymbolInfo(expr);
  2532. var firstParamType = ((Symbol)exprInfo.CandidateSymbols.Single()).GetParameterTypes().First();
  2533. Assert.Equal(actionType, firstParamType);
  2534. var identifierInfo = model.GetTypeInfo(identifier);
  2535. Assert.Equal(stringType, identifierInfo.Type);
  2536. Assert.Equal(stringType, identifierInfo.ConvertedType);
  2537. }
  2538. [WorkItem(850907, "DevDiv")]
  2539. [Fact]
  2540. public void ExtensionMethodViability()
  2541. {
  2542. var source = @"
  2543. static class Extensions
  2544. {
  2545. private static void ToString(this object o, int x)
  2546. {
  2547. o.ToString(1);
  2548. }
  2549. }
  2550. ";
  2551. var comp = CreateCompilationWithMscorlibAndSystemCore(source);
  2552. comp.VerifyDiagnostics();
  2553. var extensionMethod = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("Extensions").GetMember<MethodSymbol>("ToString");
  2554. var tree = comp.SyntaxTrees.Single();
  2555. var model = comp.GetSemanticModel(tree);
  2556. var callSyntax = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
  2557. var memberGroup = model.GetMemberGroup(callSyntax.Expression);
  2558. Assert.Contains(extensionMethod.ReduceExtensionMethod(), memberGroup);
  2559. }
  2560. [WorkItem(849698, "DevDiv")]
  2561. [Fact]
  2562. public void LookupExternAlias()
  2563. {
  2564. var source = @"
  2565. extern alias Alias;
  2566. class C
  2567. {
  2568. static void Main()
  2569. {
  2570. Alias::C.M();
  2571. }
  2572. ";
  2573. var libBytes = CreateCompilationWithMscorlib("", assemblyName: "lib").EmitToArray();
  2574. var comp = CreateCompilationWithMscorlib(source, new[] { new MetadataImageReference(libBytes, aliases: ImmutableArray.Create("Alias")) });
  2575. var tree = comp.SyntaxTrees.Single();
  2576. var model = comp.GetSemanticModel(tree);
  2577. var syntax = tree.GetRoot().DescendantNodes().OfType<AliasQualifiedNameSyntax>().Single();
  2578. var symbol = model.LookupSymbols(syntax.SpanStart, name: "Alias").Single();
  2579. Assert.Equal("Alias", symbol.Name);
  2580. Assert.Equal(SymbolKind.Alias, symbol.Kind);
  2581. var target = (NamespaceSymbol)((AliasSymbol)symbol).Target;
  2582. Assert.True(target.IsGlobalNamespace);
  2583. Assert.Equal("lib", target.ContainingAssembly.Name);
  2584. }
  2585. [Fact]
  2586. public void Regression01()
  2587. {
  2588. Regression(@"
  2589. using System;
  2590. class MyClass {
  2591. public protected int intI = 1;
  2592. public static int Main() {
  2593. return 1;
  2594. }
  2595. }"
  2596. );
  2597. }
  2598. [Fact]
  2599. public void Regression02()
  2600. {
  2601. Regression(@"
  2602. using System;
  2603. class Convert
  2604. {
  2605. public static void Main()
  2606. {
  2607. S s = new S();
  2608. }
  2609. }
  2610. "
  2611. );
  2612. }
  2613. [Fact]
  2614. public void Regression03()
  2615. {
  2616. Regression(@"
  2617. using System;
  2618. namespace Microsoft.Conformance.Expressions
  2619. {
  2620. using basic097LevelOne.basic097LevelTwo;
  2621. public class basic097I<A1>
  2622. {
  2623. public static int Method()
  2624. {
  2625. return 0;
  2626. }
  2627. }
  2628. namespace basic097LevelOne
  2629. {
  2630. namespace basic097LevelTwo
  2631. {
  2632. public class basic097I<A1>
  2633. {
  2634. }
  2635. }
  2636. }
  2637. }"
  2638. );
  2639. }
  2640. #region "regression helper"
  2641. private void Regression(string text)
  2642. {
  2643. var tree = Parse(text);
  2644. var compilation = CreateCompilationWithMscorlib(tree);
  2645. var model = compilation.GetSemanticModel(tree);
  2646. var exprSynList = new List<ExpressionSyntax>();
  2647. GetExpressionSyntax(tree.GetCompilationUnitRoot(), exprSynList);
  2648. // Console.WriteLine("Roslyn Symbol Info: ");
  2649. foreach (var exprSyn in exprSynList)
  2650. {
  2651. var expr = exprSyn.ToString();
  2652. // Console.WriteLine("Expression: " + expr);
  2653. var type = model.GetTypeInfo(exprSyn).Type;
  2654. // Console.WriteLine("Type: " + type);
  2655. // Console.WriteLine();
  2656. }
  2657. }
  2658. private static void GetExpressionSyntax(SyntaxNode node, List<ExpressionSyntax> exprSynList)
  2659. {
  2660. if (node is ExpressionSyntax)
  2661. exprSynList.Add(node as ExpressionSyntax);
  2662. foreach (var child in node.ChildNodesAndTokens())
  2663. if (child.IsNode)
  2664. GetExpressionSyntax(child.AsNode(), exprSynList);
  2665. }
  2666. #endregion
  2667. }
  2668. }