PageRenderTime 35ms CodeModel.GetById 2ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Compilers/CSharp/Test/Symbol/Symbols/Source/DeclaringSyntaxNodeTests.cs

https://github.com/EkardNT/Roslyn
C# | 726 lines | 609 code | 83 blank | 34 comment | 45 complexity | 9e96692b75addba099ebfd92d5136230 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
  3using System;
  4using System.Collections.Immutable;
  5using System.Linq;
  6using Microsoft.CodeAnalysis.CSharp.Symbols;
  7using Microsoft.CodeAnalysis.CSharp.Syntax;
  8using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
  9using Microsoft.CodeAnalysis.Text;
 10using Roslyn.Test.Utilities;
 11using Xunit;
 12
 13namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols.Source
 14{
 15    public class DeclaringSyntaxNodeTests : CSharpTestBase
 16    {
 17        // Check that the given symbol has the expected number of declaring syntax nodes.
 18        // and that each declared node goes back to the given symbol.
 19        private ImmutableArray<SyntaxReference> CheckDeclaringSyntaxNodes(CSharpCompilation compilation,
 20                                               Symbol symbol,
 21                                               int expectedNumber)
 22        {
 23            var declaringReferences = symbol.DeclaringSyntaxReferences;
 24            Assert.Equal(expectedNumber, declaringReferences.Length);
 25
 26            if (expectedNumber == 0)
 27            {
 28                Assert.True(!symbol.IsFromCompilation(compilation) || symbol.IsImplicitlyDeclared, "non-implicitly declares source symbol should have declaring location");
 29            }
 30            else
 31            {
 32                Assert.True(symbol.IsFromCompilation(compilation) || symbol is MergedNamespaceSymbol, "symbol with declaration should be in source, except for merged namespaces");
 33                Assert.False(symbol.IsImplicitlyDeclared);
 34
 35                foreach (var node in declaringReferences.Select(d => d.GetSyntax()))
 36                {
 37                    // Make sure GetDeclaredSymbol gets back to the symbol for each node.
 38
 39                    SyntaxTree tree = node.SyntaxTree;
 40                    SemanticModel model = compilation.GetSemanticModel(tree);
 41                    Assert.Equal(symbol.OriginalDefinition, model.GetDeclaredSymbol(node));
 42                }
 43            }
 44
 45            return declaringReferences;
 46        }
 47
 48        private ImmutableArray<SyntaxReference> CheckDeclaringSyntaxNodesIncludingParameters(CSharpCompilation compilation,
 49                                               Symbol symbol,
 50                                               int expectedNumber)
 51        {
 52            var nodes = CheckDeclaringSyntaxNodes(compilation, symbol, expectedNumber);
 53
 54            MethodSymbol meth = symbol as MethodSymbol;
 55            if (meth != null)
 56            {
 57                foreach (ParameterSymbol p in meth.Parameters)
 58                    CheckDeclaringSyntaxNodes(compilation, p, meth.IsAccessor() ? 0 : expectedNumber);
 59            }
 60
 61            PropertySymbol prop = symbol as PropertySymbol;
 62            if (prop != null)
 63            {
 64                foreach (ParameterSymbol p in prop.Parameters)
 65                    CheckDeclaringSyntaxNodes(compilation, p, expectedNumber);
 66            }
 67
 68            return nodes;
 69        }
 70
 71        // Check that the given symbol has the expected number of declaring syntax nodes.
 72        // and that the syntax has the expected kind. Does NOT test GetDeclaringSymbol
 73        private ImmutableArray<SyntaxReference> CheckDeclaringSyntaxNodesWithoutGetDeclaredSymbol(CSharpCompilation compilation,
 74                                               Symbol symbol,
 75                                               int expectedNumber,
 76                                               SyntaxKind expectedSyntaxKind)
 77        {
 78            var declaringReferences = symbol.DeclaringSyntaxReferences;
 79            Assert.Equal(expectedNumber, declaringReferences.Length);
 80
 81            if (expectedNumber == 0)
 82            {
 83                Assert.True(!symbol.IsFromCompilation(compilation) || symbol.IsImplicitlyDeclared, "non-implicitly declares source symbol should have declaring location");
 84            }
 85            else
 86            {
 87                Assert.True(symbol.IsFromCompilation(compilation) || symbol is MergedNamespaceSymbol, "symbol with declaration should be in source, except for merged namespaces");
 88
 89                if (symbol.Kind == SymbolKind.Namespace && ((NamespaceSymbol)symbol).IsGlobalNamespace)
 90                {
 91                    Assert.True(symbol.IsImplicitlyDeclared);
 92                }
 93                else
 94                {
 95                    Assert.False(symbol.IsImplicitlyDeclared);
 96                }
 97
 98                foreach (var node in declaringReferences.Select(d => d.GetSyntax()))
 99                {
100                    // Make sure each node is of the expected kind.
101                    Assert.Equal(expectedSyntaxKind, node.CSharpKind());
102                }
103            }
104
105            return declaringReferences;
106        }
107
108        private void AssertDeclaringSyntaxNodes(Symbol symbol, CSharpCompilation compilation, params SyntaxNode[] expectedSyntaxNodes)
109        {
110            int expectedNumber = expectedSyntaxNodes.Length;
111            var declaringReferences = symbol.DeclaringSyntaxReferences;
112            Assert.Equal(expectedNumber, declaringReferences.Length);
113
114            if (expectedNumber == 0)
115            {
116                Assert.True(!symbol.IsFromCompilation(compilation) || symbol.IsImplicitlyDeclared, "non-implicitly declares source symbol should have declaring location");
117            }
118            else
119            {
120                Assert.True(symbol.IsFromCompilation(compilation) || symbol is MergedNamespaceSymbol, "symbol with declaration should be in source, except for merged namespaces");
121                Assert.False(symbol.IsImplicitlyDeclared);
122
123                for (int i = 0; i < expectedNumber; i++)
124                {
125                    Assert.Same(expectedSyntaxNodes[i], declaringReferences[i].GetSyntax());
126                }
127            }
128        }
129
130        private void CheckDeclaringSyntax<TNode>(CSharpCompilation comp, SyntaxTree tree, string name, SymbolKind kind)
131            where TNode : CSharpSyntaxNode
132        {
133            var model = comp.GetSemanticModel(tree);
134            string code = tree.GetText().ToString();
135            int position = code.IndexOf(name);
136            var node = tree.GetRoot().FindToken(position).Parent.FirstAncestorOrSelf<TNode>();
137            var sym = (Symbol)model.GetDeclaredSymbol(node);
138
139            Assert.Equal(kind, sym.Kind);
140            Assert.Equal(name, sym.Name);
141
142            CheckDeclaringSyntaxNodes(comp, sym, 1);
143        }
144
145        private void CheckLambdaDeclaringSyntax<TNode>(CSharpCompilation comp, SyntaxTree tree, string textToSearchFor)
146            where TNode : ExpressionSyntax
147        {
148            var model = comp.GetSemanticModel(tree);
149            string code = tree.GetText().ToString();
150            int position = code.IndexOf(textToSearchFor);
151            var node = tree.GetCompilationUnitRoot().FindToken(position).Parent.FirstAncestorOrSelf<TNode>();
152            MethodSymbol sym = model.GetSymbolInfo(node).Symbol as MethodSymbol;
153
154            Assert.NotNull(sym);
155            Assert.Equal(MethodKind.AnonymousFunction, sym.MethodKind);
156
157            var nodes = CheckDeclaringSyntaxNodesWithoutGetDeclaredSymbol(comp, sym, 1, node.Kind);
158            Assert.Equal(nodes[0].GetSyntax(), node);
159
160            foreach (ParameterSymbol p in sym.Parameters)
161            {
162                CheckDeclaringSyntaxNodes(comp, p, 1);
163            }
164        }
165
166        [Fact]
167        public void SourceNamedTypeDeclaringSyntax()
168        {
169            var text =
170@"
171namespace N1 {
172    class C1<T> {
173        class Nested<U> {}
174        delegate int NestedDel(string s);
175    }
176    public struct S1 {
177        C1<int> f;
178    }
179    internal interface I1 {}
180    enum E1 { Red }
181    delegate void D1(int i);
182
183}
184";
185            var comp = CreateCompilationWithMscorlib(text);
186            var global = comp.GlobalNamespace;
187            var n1 = global.GetMembers("N1").Single() as NamespaceSymbol;
188
189            Assert.False(n1.IsImplicitlyDeclared);
190            Assert.True(comp.SourceModule.GlobalNamespace.IsImplicitlyDeclared);
191
192            var types = n1.GetTypeMembers();
193            foreach (Symbol s in types)
194            {
195                CheckDeclaringSyntaxNodes(comp, s, 1);
196            }
197
198            var c1 = n1.GetTypeMembers("C1").Single() as NamedTypeSymbol;
199            var s1 = n1.GetTypeMembers("S1").Single() as NamedTypeSymbol;
200            var f = s1.GetMembers("f").Single() as FieldSymbol;
201
202            CheckDeclaringSyntaxNodes(comp, f.Type, 1);  // constructed type C1<int>.
203
204            // Nested types.
205            foreach (Symbol s in c1.GetTypeMembers())
206            {
207                CheckDeclaringSyntaxNodes(comp, s, 1);
208            }
209        }
210
211        [Fact]
212        public void NonSourceTypeDeclaringSyntax()
213        {
214            var text =
215@"
216namespace N1 {
217    class C1 {
218        object o;
219        int i;
220        System.Collections.Generic.List<string> lst;
221        dynamic dyn;
222        C1[] arr;
223        C1[,] arr2d;
224        ErrType err;
225        ConsErrType<object> consErr;
226    }
227}
228";
229            var comp = CreateCompilationWithMscorlib(text);
230            var global = comp.GlobalNamespace;
231            var n1 = global.GetMembers("N1").Single() as NamespaceSymbol;
232            var c1 = n1.GetTypeMembers("C1").Single() as NamedTypeSymbol;
233
234            // Check types of each field in C1; should not have declaring syntax node.
235            foreach (FieldSymbol f in c1.GetMembers().OfType<FieldSymbol>())
236            {
237                CheckDeclaringSyntaxNodes(comp, f.Type, 0);
238            }
239        }
240
241        [Fact]
242        public void AnonTypeDeclaringSyntax()
243        {
244            var text =
245@"
246class C1 {
247    void f()
248    {
249        var a1 = new { a = 5, b = ""hi"" };
250        var a2 = new {};
251    }
252}
253";
254            var tree = Parse(text);
255            var comp = CreateCompilationWithMscorlib(tree);
256            var model = comp.GetSemanticModel(tree);
257            var global = comp.GlobalNamespace;
258            int posA1 = text.IndexOf("a1");
259
260            var declaratorA1 = tree.GetCompilationUnitRoot().FindToken(posA1).Parent.FirstAncestorOrSelf<VariableDeclaratorSyntax>();
261            var localA1 = (LocalSymbol)model.GetDeclaredSymbol(declaratorA1);
262            var localA1Type = localA1.Type;
263            Assert.True(localA1Type.IsAnonymousType);
264
265            // Anonymous types don't support GetDeclaredSymbol.
266            CheckDeclaringSyntaxNodesWithoutGetDeclaredSymbol(comp, localA1Type, 1, SyntaxKind.AnonymousObjectCreationExpression);
267
268            // Check members of the anonymous type.
269            foreach (Symbol memb in localA1Type.GetMembers())
270            {
271                int expectedDeclaringNodes = 0;
272
273                if (memb is PropertySymbol)
274                {
275                    expectedDeclaringNodes = 1;  // declared property 
276                }
277
278                CheckDeclaringSyntaxNodes(comp, memb, expectedDeclaringNodes);
279            }
280
281        }
282
283        [WorkItem(543829, "DevDiv")]
284        [Fact]
285        public void AnonymousTypeSymbolWithExplicitNew()
286        {
287            var text =
288@"
289class C1 {
290    void f()
291    {
292        var q = new { y = 2 };
293        var x = new { y = 5 };
294        var z = x;
295    }
296}
297";
298            var tree = Parse(text);
299            var comp = CreateCompilationWithMscorlib(tree);
300            var model = comp.GetSemanticModel(tree);
301            var global = comp.GlobalNamespace;
302
303            // check 'q'
304            int posQ = text.IndexOf("q");
305            var declaratorQ = tree.GetCompilationUnitRoot().FindToken(posQ).Parent.FirstAncestorOrSelf<VariableDeclaratorSyntax>();
306            CheckAnonymousType(model,
307                (LocalSymbol)model.GetDeclaredSymbol(declaratorQ),
308                (AnonymousObjectCreationExpressionSyntax)declaratorQ.Initializer.Value);
309
310            // check 'x'
311            int posX = text.IndexOf("x");
312            var declaratorX = tree.GetCompilationUnitRoot().FindToken(posX).Parent.FirstAncestorOrSelf<VariableDeclaratorSyntax>();
313            CheckAnonymousType(model,
314                (LocalSymbol)model.GetDeclaredSymbol(declaratorX),
315                (AnonymousObjectCreationExpressionSyntax)declaratorX.Initializer.Value);
316
317            // check 'z' --> 'x'
318            int posZ = text.IndexOf("z");
319            var declaratorZ = tree.GetCompilationUnitRoot().FindToken(posZ).Parent.FirstAncestorOrSelf<VariableDeclaratorSyntax>();
320            CheckAnonymousType(model,
321                (LocalSymbol)model.GetDeclaredSymbol(declaratorZ),
322                (AnonymousObjectCreationExpressionSyntax)declaratorX.Initializer.Value);
323
324        }
325
326        private void CheckAnonymousType(SemanticModel model, LocalSymbol local, AnonymousObjectCreationExpressionSyntax anonObjectCreation)
327        {
328            var localType = local.Type;
329            Assert.True(localType.IsAnonymousType);
330
331            // IsImplicitlyDeclared: Return false. The new { } clause 
332            //                       serves as the declaration.
333            Assert.False(localType.IsImplicitlyDeclared);
334
335            // DeclaringSyntaxNodes: Return the AnonymousObjectCreationExpression from the particular 
336            //                       anonymous type definition that flowed to this usage.
337            AssertDeclaringSyntaxNodes(localType, (CSharpCompilation)model.Compilation, anonObjectCreation);
338
339            // SemanticModel.GetDeclaredSymbol: Return this symbol when applied to the 
340            //                                  AnonymousObjectCreationExpression in the new { } declaration.
341            var symbol = model.GetDeclaredSymbol(anonObjectCreation);
342            Assert.NotNull(symbol);
343            Assert.Equal<ISymbol>(localType, symbol);
344            Assert.Same(localType.DeclaringSyntaxReferences[0].GetSyntax(), symbol.DeclaringSyntaxReferences[0].GetSyntax());
345
346            // Locations: Return the Span of that particular 
347            //            AnonymousObjectCreationExpression's NewKeyword.
348            Assert.Equal(1, localType.Locations.Length);
349            Assert.Equal(localType.Locations[0], anonObjectCreation.NewKeyword.GetLocation());
350
351            // Members check
352            int propIndex = 0;
353            foreach (var member in localType.GetMembers())
354            {
355                if (member.Kind == SymbolKind.Property)
356                {
357                    // Equals: Return true when comparing same-named members of 
358                    //         structurally-equivalent anonymous type symbols.
359                    var members = symbol.GetMembers(member.Name);
360                    Assert.Equal(1, members.Length);
361                    Assert.Equal(member, members[0]);
362
363                    // IsImplicitlyDeclared: Return false. The foo = bar clause in 
364                    //                       the new { } clause serves as the declaration.
365                    Assert.False(member.IsImplicitlyDeclared);
366
367                    // DeclaringSyntaxNodes: Return the AnonymousObjectMemberDeclarator from the 
368                    //                       particular property definition that flowed to this usage.
369                    var propertyInitializer = anonObjectCreation.Initializers[propIndex];
370                    Assert.Equal(1, member.DeclaringSyntaxReferences.Length);
371                    Assert.Same(propertyInitializer, member.DeclaringSyntaxReferences[0].GetSyntax());
372
373                    // SemanticModel.GetDeclaredSymbol: Return this symbol when applied to its new { } 
374                    //                                  declaration's AnonymousObjectMemberDeclarator.
375                    var propSymbol = model.GetDeclaredSymbol(propertyInitializer);
376                    Assert.Equal<ISymbol>(member, propSymbol);
377                    Assert.Same(propertyInitializer, propSymbol.DeclaringSyntaxReferences[0].GetSyntax());
378
379                    // Locations: Return the Span of that particular 
380                    //            AnonymousObjectMemberDeclarator's IdentifierToken.
381                    Assert.Equal(1, member.Locations.Length);
382                    Assert.Equal(member.Locations[0], propertyInitializer.NameEquals.Name.GetLocation());
383
384                    propIndex++;
385                }
386            }
387        }
388
389        [Fact]
390        public void NamespaceDeclaringSyntax()
391        {
392            var text =
393@"
394namespace N1 {
395    namespace N2 {
396        namespace N3 {}
397    }
398}
399
400namespace N1.N2 {
401    namespace N3 {}
402}
403
404namespace System {}
405";
406            var comp = CreateCompilationWithMscorlib(text);
407            var global = comp.GlobalNamespace;
408            var system = global.GetMembers("System").Single() as NamespaceSymbol;
409            var n1 = global.GetMembers("N1").Single() as NamespaceSymbol;
410            var n2 = n1.GetMembers("N2").Single() as NamespaceSymbol;
411            var n3 = n2.GetMembers("N3").Single() as NamespaceSymbol;
412
413            CheckDeclaringSyntaxNodes(comp, n2, 2);
414            CheckDeclaringSyntaxNodes(comp, n3, 2);
415            CheckDeclaringSyntaxNodes(comp, system, 1);
416
417            // Can't use GetDeclaredSymbol for N1 or global.
418            CheckDeclaringSyntaxNodesWithoutGetDeclaredSymbol(comp, n1, 2, SyntaxKind.NamespaceDeclaration);
419            CheckDeclaringSyntaxNodesWithoutGetDeclaredSymbol(comp, global, 1, SyntaxKind.CompilationUnit);
420        }
421
422        [Fact]
423        public void TypeParameterDeclaringSyntax()
424        {
425            var text =
426@"
427using System;
428using System.Collections.Generic;
429
430namespace N1 {
431    class C1<T, U> {
432        class C2<W> {
433            public C1<int, string>.C2<W> f1;
434            public void m<R, S>();
435        }
436        class C3<W> {
437            IEnumerable<U> f2;
438            Foo<Bar> f3;
439        }
440    }
441
442    class M {
443    }
444}
445";
446            var comp = CreateCompilationWithMscorlib(text);
447            var global = comp.GlobalNamespace;
448            var n1 = global.GetMembers("N1").Single() as NamespaceSymbol;
449            var c1 = n1.GetTypeMembers("C1").Single() as NamedTypeSymbol;
450            var c2 = c1.GetTypeMembers("C2").Single() as NamedTypeSymbol;
451            var c3 = c1.GetTypeMembers("C3").Single() as NamedTypeSymbol;
452
453            foreach (Symbol s in c1.TypeParameters)
454            {
455                CheckDeclaringSyntaxNodes(comp, s, 1);
456            }
457
458            foreach (FieldSymbol f in c2.GetMembers().OfType<FieldSymbol>())
459            {
460                foreach (TypeParameterSymbol tp in ((NamedTypeSymbol)f.Type).TypeParameters)
461                {
462                    CheckDeclaringSyntaxNodes(comp, tp, 1);
463                }
464            }
465
466            foreach (MethodSymbol m in c2.GetMembers().OfType<MethodSymbol>())
467            {
468                foreach (TypeParameterSymbol tp in m.TypeParameters)
469                {
470                    CheckDeclaringSyntaxNodes(comp, tp, 1);
471                }
472            }
473
474            foreach (FieldSymbol f in c3.GetMembers().OfType<FieldSymbol>())
475            {
476                foreach (TypeParameterSymbol tp in ((NamedTypeSymbol)f.Type).TypeParameters)
477                {
478                    CheckDeclaringSyntaxNodes(comp, tp, 0);
479                }
480            }
481
482        }
483
484        [Fact]
485        public void MemberDeclaringSyntax()
486        {
487            var text =
488@"
489using System;
490using System.Collections.Generic;
491
492namespace N1 {
493    enum E1 {Red, Blue = 5, Green };
494    class C1<T> {
495        C1<int> t, w, x;
496        const int q = 4, r = 7;
497        C1(int i) {}
498        static C1() {}
499        int m(T t, int y = 3) { return 3; }
500        int P {get { return 0; } set {}}
501        abstract int Prop2 {get; set; }
502        int Prop3 {get; set; }
503        string this[int i] {get { return ""; } set {}}
504        abstract string this[int i, int j] {get; set;}
505        event EventHandler ev1;
506        event EventHandler ev2 { add {} remove {} }
507    }
508    class C2<U>
509    {
510         static int x = 7;
511    }
512}
513";
514            var comp = CreateCompilationWithMscorlib(text);
515            var global = comp.GlobalNamespace;
516            var n1 = global.GetMembers("N1").Single() as NamespaceSymbol;
517            var c1 = n1.GetTypeMembers("C1").Single() as NamedTypeSymbol;
518            var c2 = n1.GetTypeMembers("C2").Single() as NamedTypeSymbol;
519            var e1 = n1.GetTypeMembers("E1").Single() as NamedTypeSymbol;
520
521            foreach (Symbol memb in e1.GetMembers())
522            {
523                if (memb.Kind == SymbolKind.Method && ((MethodSymbol)memb).MethodKind == MethodKind.Constructor)
524                    CheckDeclaringSyntaxNodesIncludingParameters(comp, memb, 0);  // implicit constructor
525                else
526                    CheckDeclaringSyntaxNodesIncludingParameters(comp, memb, 1);
527            }
528
529            var ev1 = c1.GetMembers("ev1").Single() as EventSymbol;
530            var prop3 = c1.GetMembers("Prop3").Single() as PropertySymbol;
531
532            foreach (Symbol memb in c1.GetMembers())
533            {
534                int expectedDeclaringNodes = 1;
535
536                if (memb is MethodSymbol)
537                {
538                    MethodSymbol meth = (MethodSymbol)memb;
539                    if (meth.AssociatedSymbol != null && meth.AssociatedSymbol.OriginalDefinition.Equals(ev1))
540                        expectedDeclaringNodes = 0;  // implicit accessor.
541                }
542                if (memb is FieldSymbol)
543                {
544                    FieldSymbol fld = (FieldSymbol)memb;
545                    if (fld.AssociatedSymbol != null && fld.AssociatedSymbol.OriginalDefinition.Equals(prop3))
546                        expectedDeclaringNodes = 0;  // auto-prop backing field.
547                }
548
549                CheckDeclaringSyntaxNodesIncludingParameters(comp, memb, expectedDeclaringNodes);
550            }
551
552            var fieldT = c1.GetMembers("t").Single() as FieldSymbol;
553            var constructedC1 = fieldT.Type;
554
555            foreach (Symbol memb in constructedC1.GetMembers())
556            {
557                int expectedDeclaringNodes = 1;
558
559                if (memb is MethodSymbol)
560                {
561                    MethodSymbol meth = (MethodSymbol)memb;
562                    if (meth.AssociatedSymbol != null && meth.AssociatedSymbol.OriginalDefinition.Equals(ev1))
563                        expectedDeclaringNodes = 0;  // implicit accessor.
564                }
565                if (memb is FieldSymbol)
566                {
567                    FieldSymbol fld = (FieldSymbol)memb;
568                    if (fld.AssociatedSymbol != null && fld.AssociatedSymbol.OriginalDefinition.Equals(prop3))
569                        expectedDeclaringNodes = 0;  // auto-prop backing field.
570                }
571
572                CheckDeclaringSyntaxNodesIncludingParameters(comp, memb, expectedDeclaringNodes);
573            }
574
575            foreach (Symbol memb in c2.GetMembers())
576            {
577                if (memb.Kind == SymbolKind.Method)
578                    CheckDeclaringSyntaxNodesIncludingParameters(comp, memb, 0);
579            }
580        }
581
582        [Fact]
583        public void LocalDeclaringSyntax()
584        {
585            var text =
586@"
587using System;
588using System.Collections.Generic;
589
590class C1
591{
592    void m()
593    {
594        int loc1, loc2 = 4, loc3;
595        const int loc4 = 6, loc5 = 7;
596        using (IDisposable loc6 = foo()) {}
597        for (int loc7 = 0; loc7 < 10; ++loc7) {}
598        foreach (int loc8 in new int[] {1,3,4}) {}
599    }
600}
601";
602            var tree = Parse(text);
603            var comp = CreateCompilationWithMscorlib(tree);
604            CheckDeclaringSyntax<VariableDeclaratorSyntax>(comp, tree, "loc1", SymbolKind.Local);
605            CheckDeclaringSyntax<VariableDeclaratorSyntax>(comp, tree, "loc2", SymbolKind.Local);
606            CheckDeclaringSyntax<VariableDeclaratorSyntax>(comp, tree, "loc3", SymbolKind.Local);
607            CheckDeclaringSyntax<VariableDeclaratorSyntax>(comp, tree, "loc4", SymbolKind.Local);
608            CheckDeclaringSyntax<VariableDeclaratorSyntax>(comp, tree, "loc5", SymbolKind.Local);
609            CheckDeclaringSyntax<VariableDeclaratorSyntax>(comp, tree, "loc6", SymbolKind.Local);
610            CheckDeclaringSyntax<VariableDeclaratorSyntax>(comp, tree, "loc7", SymbolKind.Local);
611            CheckDeclaringSyntax<ForEachStatementSyntax>(comp, tree, "loc8", SymbolKind.Local);
612        }
613
614        [Fact]
615        public void LabelDeclaringSyntax()
616        {
617            var text =
618@"
619using System;
620using System.Collections.Generic;
621
622class C1
623{
624    void m(int i)
625    {
626        lab1: ;
627        lab2: lab3: Console.WriteLine();
628        switch (i) {
629            case 4: case 3:
630               break;
631            default:
632               break;
633        }
634    }
635}
636";
637            var tree = Parse(text);
638            var comp = CreateCompilationWithMscorlib(tree);
639            CheckDeclaringSyntax<LabeledStatementSyntax>(comp, tree, "lab1", SymbolKind.Label);
640            CheckDeclaringSyntax<LabeledStatementSyntax>(comp, tree, "lab2", SymbolKind.Label);
641            CheckDeclaringSyntax<LabeledStatementSyntax>(comp, tree, "lab3", SymbolKind.Label);
642            CheckDeclaringSyntax<SwitchLabelSyntax>(comp, tree, "case 4:", SymbolKind.Label);
643            CheckDeclaringSyntax<SwitchLabelSyntax>(comp, tree, "case 3:", SymbolKind.Label);
644            CheckDeclaringSyntax<SwitchLabelSyntax>(comp, tree, "default:", SymbolKind.Label);
645        }
646
647
648        [Fact]
649        public void AliasDeclaringSyntax()
650        {
651            var text =
652@"
653using System;
654using System.Collections.Generic;
655using ConsoleAlias=System.Console;
656using ListOfIntAlias=System.Collections.Generic.List<int>;
657
658namespace N1
659{
660    using FooAlias=Con;
661}
662";
663            var tree = Parse(text);
664            var comp = CreateCompilationWithMscorlib(tree);
665            CheckDeclaringSyntax<UsingDirectiveSyntax>(comp, tree, "ConsoleAlias", SymbolKind.Alias);
666            CheckDeclaringSyntax<UsingDirectiveSyntax>(comp, tree, "ListOfIntAlias", SymbolKind.Alias);
667            CheckDeclaringSyntax<UsingDirectiveSyntax>(comp, tree, "FooAlias", SymbolKind.Alias);
668        }
669
670        [Fact]
671        public void RangeVariableDeclaringSyntax()
672        {
673            var text =
674@"
675using System;
676using System.Collections.Generic;
677using System.Linq;
678
679class C
680{
681    void f()
682    {
683        IEnumerable<int> a = null;
684        var y1 = from range1 in a let range2 = a.ToString() select range1 into range3 select range3 + 1;
685        var y2 = from range4 in a join range5 in a on range4.ToString() equals range5.ToString() into range6 select range6;
686    }
687}
688";
689            var tree = Parse(text);
690            var comp = CreateCompilationWithMscorlib(tree);
691            CheckDeclaringSyntax<QueryClauseSyntax>(comp, tree, "range1", SymbolKind.RangeVariable);
692            CheckDeclaringSyntax<QueryClauseSyntax>(comp, tree, "range2", SymbolKind.RangeVariable);
693            CheckDeclaringSyntax<QueryContinuationSyntax>(comp, tree, "range3", SymbolKind.RangeVariable);
694            CheckDeclaringSyntax<QueryClauseSyntax>(comp, tree, "range4", SymbolKind.RangeVariable);
695            CheckDeclaringSyntax<QueryClauseSyntax>(comp, tree, "range5", SymbolKind.RangeVariable);
696            CheckDeclaringSyntax<JoinIntoClauseSyntax>(comp, tree, "range6", SymbolKind.RangeVariable);
697        }
698
699        [Fact]
700        public void LambdaDeclaringSyntax()
701        {
702            var text =
703@"
704using System;
705using System.Collections.Generic;
706using System.Linq;
707
708class C
709{
710    void f()
711    {
712        Func<int, int, int> f1 = (a,b) => /*1*/ a + b;
713        Func<int, int, int> f1 = a => /*2*/ a + 1;
714        Func<int, int, int> f1 = delegate(int a, int b) /*3*/ { return a + b; };
715    }
716}
717";
718            var tree = Parse(text);
719            var comp = CreateCompilationWithMscorlib(tree);
720            CheckLambdaDeclaringSyntax<ParenthesizedLambdaExpressionSyntax>(comp, tree, "/*1*/");
721            CheckLambdaDeclaringSyntax<SimpleLambdaExpressionSyntax>(comp, tree, "/*2*/");
722            CheckLambdaDeclaringSyntax<AnonymousMethodExpressionSyntax>(comp, tree, "/*3*/");
723        }
724
725    }
726}