/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Symbol/Symbols/Source/UsingAliasTests.cs
1 076 строк
43 KB
Jan Jones
Unsafe evolution: make pointers safe regardless of memory safety rules version (#83133)
21 апр 2026, 11:27
Не верифицирован
21 апр 2026, 11:27
fca0128
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System; using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols.Source { public class UsingAliasTests : SemanticModelTestBase { [Fact] public void GetSemanticInfo() { var text = @"using O = System.Object; partial class A : O {} partial class A : object {} partial class A : System.Object {} partial class A : Object {} "; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var a1 = root.Members[0] as TypeDeclarationSyntax; var a2 = root.Members[1] as TypeDeclarationSyntax; var a3 = root.Members[2] as TypeDeclarationSyntax; var a4 = root.Members[3] as TypeDeclarationSyntax; var base1 = a1.BaseList.Types[0].Type; var base2 = a2.BaseList.Types[0].Type; var base3 = a3.BaseList.Types[0].Type; var base4 = a4.BaseList.Types[0].Type; var model = comp.GetSemanticModel(tree); var info1 = model.GetSemanticInfoSummary(base1); Assert.NotNull(info1.Symbol); var alias1 = model.GetAliasInfo((IdentifierNameSyntax)base1); Assert.NotNull(alias1); Assert.Equal(SymbolKind.Alias, alias1.Kind); Assert.Equal("O", alias1.ToDisplayString()); Assert.Equal("O=System.Object", alias1.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal(info1.Symbol, alias1.Target); var info2 = model.GetSemanticInfoSummary(base2); Assert.NotNull(info2.Symbol); var b2 = info2.Symbol; Assert.Equal("System.Object", b2.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal("System.Object", info2.Type.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var info3 = model.GetSemanticInfoSummary(base3); Assert.NotNull(info3.Symbol); var b3 = info3.Symbol; Assert.Equal("System.Object", b3.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal("System.Object", info3.Type.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var info4 = model.GetSemanticInfoSummary(base4); Assert.Null(info4.Symbol); // no "using System;" Assert.Equal(0, info4.CandidateSymbols.Length); var alias4 = model.GetAliasInfo((IdentifierNameSyntax)base4); Assert.Null(alias4); } [Fact] public void GetSemanticInfo_PrimitiveType() { var text = @"using O = object; partial class A : O {} partial class A : object {} partial class A : System.Object {} partial class A : Object {} "; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var a1 = root.Members[0] as TypeDeclarationSyntax; var a2 = root.Members[1] as TypeDeclarationSyntax; var a3 = root.Members[2] as TypeDeclarationSyntax; var a4 = root.Members[3] as TypeDeclarationSyntax; var base1 = a1.BaseList.Types[0].Type; var base2 = a2.BaseList.Types[0].Type; var base3 = a3.BaseList.Types[0].Type; var base4 = a4.BaseList.Types[0].Type; var model = comp.GetSemanticModel(tree); var usingAliasType = model.GetTypeInfo(usingAlias.NamespaceOrType).Type; Assert.Equal(SpecialType.System_Object, usingAliasType.SpecialType); var info1 = model.GetSemanticInfoSummary(base1); Assert.NotNull(info1.Symbol); var alias1 = model.GetAliasInfo((IdentifierNameSyntax)base1); Assert.NotNull(alias1); Assert.Equal(SymbolKind.Alias, alias1.Kind); Assert.Equal("O", alias1.ToDisplayString()); Assert.Equal("O=System.Object", alias1.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal(info1.Symbol, alias1.Target); var info2 = model.GetSemanticInfoSummary(base2); Assert.NotNull(info2.Symbol); var b2 = info2.Symbol; Assert.Equal("System.Object", b2.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal("System.Object", info2.Type.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var info3 = model.GetSemanticInfoSummary(base3); Assert.NotNull(info3.Symbol); var b3 = info3.Symbol; Assert.Equal("System.Object", b3.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal("System.Object", info3.Type.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var info4 = model.GetSemanticInfoSummary(base4); Assert.Null(info4.Symbol); // no "using System;" Assert.Equal(0, info4.CandidateSymbols.Length); var alias4 = model.GetAliasInfo((IdentifierNameSyntax)base4); Assert.Null(alias4); } [Fact] public void GetSymbolInfoInParent() { var text = @"using O = System.Object; partial class A : O {} partial class A : object {} partial class A : System.Object {} partial class A : Object {} "; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var a1 = root.Members[0] as TypeDeclarationSyntax; var a2 = root.Members[1] as TypeDeclarationSyntax; var a3 = root.Members[2] as TypeDeclarationSyntax; var a4 = root.Members[3] as TypeDeclarationSyntax; var base1 = a1.BaseList.Types[0].Type; var base2 = a2.BaseList.Types[0].Type; var base3 = a3.BaseList.Types[0].Type; var base4 = a4.BaseList.Types[0].Type; var model = comp.GetSemanticModel(tree); var info1 = model.GetSemanticInfoSummary(base1); Assert.Equal("System.Object", info1.Type.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var alias1 = model.GetAliasInfo((IdentifierNameSyntax)base1); Assert.NotNull(alias1); Assert.Equal(SymbolKind.Alias, alias1.Kind); Assert.Equal("O=System.Object", alias1.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var info2 = model.GetSemanticInfoSummary(base2); Assert.NotNull(info2.Symbol); var b2 = info2.Symbol; Assert.Equal("System.Object", b2.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal("System.Object", info2.Type.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var info3 = model.GetSemanticInfoSummary(base3); Assert.NotNull(info3.Symbol); var b3 = info3.Symbol; Assert.Equal("System.Object", b3.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal("System.Object", info3.Type.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var info4 = model.GetSemanticInfoSummary(base4); Assert.Null(info4.Symbol); // no "using System;" Assert.Equal(0, info4.CandidateSymbols.Length); var alias4 = model.GetAliasInfo((IdentifierNameSyntax)base4); Assert.Null(alias4); } [Fact] public void GetSymbolInfoInParent_Primitive() { var text = @"using O = object; partial class A : O {} partial class A : object {} partial class A : System.Object {} partial class A : Object {} "; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var a1 = root.Members[0] as TypeDeclarationSyntax; var a2 = root.Members[1] as TypeDeclarationSyntax; var a3 = root.Members[2] as TypeDeclarationSyntax; var a4 = root.Members[3] as TypeDeclarationSyntax; var base1 = a1.BaseList.Types[0].Type; var base2 = a2.BaseList.Types[0].Type; var base3 = a3.BaseList.Types[0].Type; var base4 = a4.BaseList.Types[0].Type; var model = comp.GetSemanticModel(tree); var usingAliasType = model.GetTypeInfo(usingAlias.NamespaceOrType).Type; Assert.Equal(SpecialType.System_Object, usingAliasType.SpecialType); var info1 = model.GetSemanticInfoSummary(base1); Assert.Equal("System.Object", info1.Type.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var alias1 = model.GetAliasInfo((IdentifierNameSyntax)base1); Assert.NotNull(alias1); Assert.Equal(SymbolKind.Alias, alias1.Kind); Assert.Equal("O=System.Object", alias1.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var info2 = model.GetSemanticInfoSummary(base2); Assert.NotNull(info2.Symbol); var b2 = info2.Symbol; Assert.Equal("System.Object", b2.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal("System.Object", info2.Type.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var info3 = model.GetSemanticInfoSummary(base3); Assert.NotNull(info3.Symbol); var b3 = info3.Symbol; Assert.Equal("System.Object", b3.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal("System.Object", info3.Type.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var info4 = model.GetSemanticInfoSummary(base4); Assert.Null(info4.Symbol); // no "using System;" Assert.Equal(0, info4.CandidateSymbols.Length); var alias4 = model.GetAliasInfo((IdentifierNameSyntax)base4); Assert.Null(alias4); } [Theory] [InlineData("(int a, int b)", "(System.Int32 a, System.Int32 b)")] [InlineData("int[]", "System.Int32[]")] [InlineData("int?", "System.Int32?")] [InlineData("int*", "System.Int32*")] [InlineData("delegate*<int,int>", "delegate*<System.Int32, System.Int32>")] [InlineData("dynamic", "dynamic")] [InlineData("nint", "System.IntPtr")] public void GetAliasTypeInfo(string aliasType, string expected) { // Should get the same results in the semantic model regardless of whether the using has the 'unsafe' // keyword or not. getAliasTypeInfoHelper(""); getAliasTypeInfoHelper("unsafe"); void getAliasTypeInfoHelper(string unsafeString) { var text = $"using {unsafeString} O = {aliasType};"; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var model = comp.GetSemanticModel(tree); var usingAliasType = model.GetTypeInfo(usingAlias.NamespaceOrType).Type; AssertEx.Equal(expected, usingAliasType.ToDisplayString(SymbolDisplayFormat.TestFormat)); var alias = model.GetDeclaredSymbol(usingAlias); Assert.Equal(alias.Target, usingAliasType); } } [Fact] public void BindType() { var text = @"using O = System.Object; partial class A : O {} partial class A : object {} partial class A : System.Object {} partial class A : Object {} "; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var a1 = root.Members[0] as TypeDeclarationSyntax; var a2 = root.Members[1] as TypeDeclarationSyntax; var a3 = root.Members[2] as TypeDeclarationSyntax; var a4 = root.Members[3] as TypeDeclarationSyntax; var base1 = a1.BaseList.Types[0].Type; var base2 = a2.BaseList.Types[0].Type; var base3 = a3.BaseList.Types[0].Type; var base4 = a4.BaseList.Types[0].Type; var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSpeculativeSymbolInfo(base2.SpanStart, base2, SpeculativeBindingOption.BindAsTypeOrNamespace); var info2 = symbolInfo.Symbol as ITypeSymbol; Assert.NotNull(info2); Assert.Equal("System.Object", info2.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal("System.Object", info2.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); symbolInfo = model.GetSpeculativeSymbolInfo(base3.SpanStart, base3, SpeculativeBindingOption.BindAsTypeOrNamespace); var info3 = symbolInfo.Symbol as ITypeSymbol; Assert.NotNull(info3); Assert.Equal("System.Object", info3.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal("System.Object", info3.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); symbolInfo = model.GetSpeculativeSymbolInfo(base4.SpanStart, base4, SpeculativeBindingOption.BindAsTypeOrNamespace); var info4 = symbolInfo.Symbol as ITypeSymbol; Assert.Null(info4); // no "using System;" } [Fact] public void BindType_Primitive() { var text = @"using O = object; partial class A : O {} partial class A : object {} partial class A : System.Object {} partial class A : Object {} "; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var a1 = root.Members[0] as TypeDeclarationSyntax; var a2 = root.Members[1] as TypeDeclarationSyntax; var a3 = root.Members[2] as TypeDeclarationSyntax; var a4 = root.Members[3] as TypeDeclarationSyntax; var base1 = a1.BaseList.Types[0].Type; var base2 = a2.BaseList.Types[0].Type; var base3 = a3.BaseList.Types[0].Type; var base4 = a4.BaseList.Types[0].Type; var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSpeculativeSymbolInfo(base2.SpanStart, base2, SpeculativeBindingOption.BindAsTypeOrNamespace); var info2 = symbolInfo.Symbol as ITypeSymbol; Assert.NotNull(info2); Assert.Equal("System.Object", info2.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal("System.Object", info2.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); symbolInfo = model.GetSpeculativeSymbolInfo(base3.SpanStart, base3, SpeculativeBindingOption.BindAsTypeOrNamespace); var info3 = symbolInfo.Symbol as ITypeSymbol; Assert.NotNull(info3); Assert.Equal("System.Object", info3.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); Assert.Equal("System.Object", info3.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); symbolInfo = model.GetSpeculativeSymbolInfo(base4.SpanStart, base4, SpeculativeBindingOption.BindAsTypeOrNamespace); var info4 = symbolInfo.Symbol as ITypeSymbol; Assert.Null(info4); // no "using System;" } [Fact] public void GetDeclaredSymbol01() { var text = @"using O = System.Object; "; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var model = comp.GetSemanticModel(tree); var alias = model.GetDeclaredSymbol(usingAlias); Assert.Equal("O", alias.ToDisplayString()); Assert.Equal("O=System.Object", alias.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var global = (INamespaceSymbol)alias.ContainingSymbol; Assert.Equal(NamespaceKind.Module, global.NamespaceKind); } [Fact] public void GetDeclaredSymbol01_Primitive() { var text = @"using O = object; "; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var model = comp.GetSemanticModel(tree); var alias = model.GetDeclaredSymbol(usingAlias); Assert.Equal("O", alias.ToDisplayString()); Assert.Equal("O=System.Object", alias.ToDisplayString(format: SymbolDisplayFormat.TestFormat)); var global = (INamespaceSymbol)alias.ContainingSymbol; Assert.Equal(NamespaceKind.Module, global.NamespaceKind); } [Fact] public void GetDeclaredSymbol02() { var text = "using System;"; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var model = comp.GetSemanticModel(tree); var alias = model.GetDeclaredSymbol(usingAlias); Assert.Null(alias); } [Fact] public void LookupNames() { var text = @"using O = System.Object; class C {} "; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var model = comp.GetSemanticModel(tree); var names = model.LookupNames(root.Members[0].SpanStart); Assert.Contains("O", names); } [Fact] public void LookupNames_Primitive() { var text = @"using O = object; class C {} "; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var model = comp.GetSemanticModel(tree); var names = model.LookupNames(root.Members[0].SpanStart); Assert.Contains("O", names); } [Fact] public void LookupSymbols() { var text = @"using O = System.Object; class C {} "; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var model = comp.GetSemanticModel(tree); var symbols = model.LookupSymbols(root.Members[0].SpanStart, name: "O"); Assert.Equal(1, symbols.Length); Assert.Equal(SymbolKind.Alias, symbols[0].Kind); Assert.Equal("O=System.Object", symbols[0].ToDisplayString(format: SymbolDisplayFormat.TestFormat)); } [Fact] public void LookupSymbols_Primitive() { var text = @"using O = object; class C {} "; var tree = Parse(text); var root = tree.GetCompilationUnitRoot(); var comp = CreateCompilation(tree); var usingAlias = root.Usings[0]; var model = comp.GetSemanticModel(tree); var symbols = model.LookupSymbols(root.Members[0].SpanStart, name: "O"); Assert.Equal(1, symbols.Length); Assert.Equal(SymbolKind.Alias, symbols[0].Kind); Assert.Equal("O=System.Object", symbols[0].ToDisplayString(format: SymbolDisplayFormat.TestFormat)); } [WorkItem(537401, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537401")] [Fact] public void EventEscapedIdentifier() { var text = @" using @for = @foreach; namespace @foreach { } "; SyntaxTree syntaxTree = Parse(text); CSharpCompilation comp = CreateCompilation(syntaxTree); UsingDirectiveSyntax usingAlias = syntaxTree.GetCompilationUnitRoot().Usings.First(); var alias = comp.GetSemanticModel(syntaxTree).GetDeclaredSymbol(usingAlias); Assert.Equal("for", alias.Name); Assert.Equal("@for", alias.ToString()); } [WorkItem(541937, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541937")] [Fact] public void LocalDeclaration() { var text = @" using GIBBERISH = System.Int32; class Program { static void Main() { /*<bind>*/GIBBERISH/*</bind>*/ x; } }"; SyntaxTree syntaxTree = Parse(text); CSharpCompilation comp = CreateCompilation(syntaxTree); var model = comp.GetSemanticModel(syntaxTree); IdentifierNameSyntax exprSyntaxToBind = (IdentifierNameSyntax)GetExprSyntaxForBinding(GetExprSyntaxList(syntaxTree)); Assert.Equal(SymbolKind.Alias, model.GetAliasInfo(exprSyntaxToBind).Kind); } [WorkItem(541937, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541937")] [Fact] public void LocalDeclaration_Primitive() { var text = @" using GIBBERISH = int; class Program { static void Main() { /*<bind>*/GIBBERISH/*</bind>*/ x; } }"; SyntaxTree syntaxTree = Parse(text); CSharpCompilation comp = CreateCompilation(syntaxTree); var model = comp.GetSemanticModel(syntaxTree); IdentifierNameSyntax exprSyntaxToBind = (IdentifierNameSyntax)GetExprSyntaxForBinding(GetExprSyntaxList(syntaxTree)); Assert.Equal(SymbolKind.Alias, model.GetAliasInfo(exprSyntaxToBind).Kind); } [Fact, WorkItem(541937, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541937")] public void LocalDeclaration_Array() { var text = @" using GIBBERISH = int[]; class Program { static void Main() { /*<bind>*/GIBBERISH/*</bind>*/ x; } }"; SyntaxTree syntaxTree = Parse(text); CSharpCompilation comp = CreateCompilation(syntaxTree); var model = comp.GetSemanticModel(syntaxTree); IdentifierNameSyntax exprSyntaxToBind = (IdentifierNameSyntax)GetExprSyntaxForBinding(GetExprSyntaxList(syntaxTree)); Assert.Equal(SymbolKind.Alias, model.GetAliasInfo(exprSyntaxToBind).Kind); Assert.Equal("System.Int32[]", model.GetAliasInfo(exprSyntaxToBind).Target.ToTestDisplayString()); } [Fact, WorkItem(541937, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541937")] public void LocalDeclaration_Tuple() { var text = @" using GIBBERISH = (int, int); class Program { static void Main() { /*<bind>*/GIBBERISH/*</bind>*/ x; } }"; SyntaxTree syntaxTree = Parse(text); CSharpCompilation comp = CreateCompilation(syntaxTree); var model = comp.GetSemanticModel(syntaxTree); IdentifierNameSyntax exprSyntaxToBind = (IdentifierNameSyntax)GetExprSyntaxForBinding(GetExprSyntaxList(syntaxTree)); Assert.Equal(SymbolKind.Alias, model.GetAliasInfo(exprSyntaxToBind).Kind); Assert.Equal("(System.Int32, System.Int32)", model.GetAliasInfo(exprSyntaxToBind).Target.ToTestDisplayString()); } [WorkItem(576809, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/576809")] [Fact] public void AsClause() { var text = @" using N = System.Nullable<int>; class Program { static void Main() { object x = 1; var y = x as /*<bind>*/N/*</bind>*/ + 1; } } "; SyntaxTree syntaxTree = Parse(text); CSharpCompilation comp = CreateCompilation(syntaxTree); var model = comp.GetSemanticModel(syntaxTree); IdentifierNameSyntax exprSyntaxToBind = (IdentifierNameSyntax)GetExprSyntaxForBinding(GetExprSyntaxList(syntaxTree)); Assert.Equal("System.Int32?", model.GetAliasInfo(exprSyntaxToBind).Target.ToTestDisplayString()); } [WorkItem(576809, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/576809")] [Fact] public void AsClause_Nullable() { var text = @" using N = int?; class Program { static void Main() { object x = 1; var y = x as /*<bind>*/N/*</bind>*/ + 1; } } "; SyntaxTree syntaxTree = Parse(text); CSharpCompilation comp = CreateCompilation(syntaxTree); var model = comp.GetSemanticModel(syntaxTree); IdentifierNameSyntax exprSyntaxToBind = (IdentifierNameSyntax)GetExprSyntaxForBinding(GetExprSyntaxList(syntaxTree)); Assert.Equal("System.Int32?", model.GetAliasInfo(exprSyntaxToBind).Target.ToTestDisplayString()); } [WorkItem(542552, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542552")] [Fact] public void IncompleteDuplicateAlias() { var text = @"namespace namespace1 { } namespace namespace2 { } namespace prog { using ns = namespace1; using ns ="; SyntaxTree syntaxTree = Parse(text); CSharpCompilation comp = CreateCompilation(syntaxTree); var discarded = comp.GetDiagnostics(); } [ClrOnlyFact, WorkItem(2805, "https://github.com/dotnet/roslyn/issues/2805")] public void AliasWithAnError() { var text = @" namespace NS { using Short = LongNamespace; class Test { public object Method1() { return (new Short.MyClass()).Prop; } } }"; var compilation = CreateCompilation(text); compilation.VerifyDiagnostics( // (4,19): error CS0246: The type or namespace name 'LongNamespace' could not be found (are you missing a using directive or an assembly reference?) // using Short = LongNamespace; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "LongNamespace").WithArguments("LongNamespace").WithLocation(4, 19) ); var tree = compilation.SyntaxTrees.Single(); var node = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "Short").Skip(1).Single(); Assert.Equal("Short.MyClass", node.Parent.ToString()); var model = compilation.GetSemanticModel(tree); var alias = model.GetAliasInfo(node); Assert.Equal("Short=LongNamespace", alias.ToTestDisplayString()); Assert.Equal(SymbolKind.ErrorType, alias.Target.Kind); Assert.Equal("LongNamespace", alias.Target.ToTestDisplayString()); var symbolInfo = model.GetSymbolInfo(node); Assert.Null(symbolInfo.Symbol); Assert.Equal(0, symbolInfo.CandidateSymbols.Length); Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason); } [ClrOnlyFact, WorkItem(2805, "https://github.com/dotnet/roslyn/issues/2805")] public void AliasWithAnErrorFileScopedNamespace() { var text = @" namespace NS; using Short = LongNamespace; class Test { public object Method1() { return (new Short.MyClass()).Prop; } } "; var compilation = CreateCompilation(text, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview)); compilation.VerifyDiagnostics( // (3,15): error CS0246: The type or namespace name 'LongNamespace' could not be found (are you missing a using directive or an assembly reference?) // using Short = LongNamespace; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "LongNamespace").WithArguments("LongNamespace").WithLocation(3, 15)); var tree = compilation.SyntaxTrees.Single(); var node = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "Short").Skip(1).Single(); Assert.Equal("Short.MyClass", node.Parent.ToString()); var model = compilation.GetSemanticModel(tree); var alias = model.GetAliasInfo(node); Assert.Equal("Short=LongNamespace", alias.ToTestDisplayString()); Assert.Equal(SymbolKind.ErrorType, alias.Target.Kind); Assert.Equal("LongNamespace", alias.Target.ToTestDisplayString()); var symbolInfo = model.GetSymbolInfo(node); Assert.Null(symbolInfo.Symbol); Assert.Equal(0, symbolInfo.CandidateSymbols.Length); Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67281")] public void TestAliasToGenericWithPointer_NoElementAccess() { var text = @" // Legal in C# 11 using X = System.Collections.Generic.List<int*[]>; class C { void M(X x) { } } "; CreateCompilation(text, parseOptions: TestOptions.Regular11).VerifyDiagnostics( // (7,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // void M(X x) Diagnostic(ErrorCode.ERR_UnsafeNeeded, "X").WithLocation(7, 12)); CreateCompilation(text, parseOptions: TestOptions.Regular14, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics( // (3,43): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // using X = System.Collections.Generic.List<int*[]>; Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(3, 43), // (7,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // void M(X x) Diagnostic(ErrorCode.ERR_UnsafeNeeded, "X").WithLocation(7, 12)); CreateCompilation(text, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics(); CreateCompilation(text, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67281")] public void TestAliasToGenericWithPointer_ElementAccess1() { var text = @" // Legal in C# 11 using X = System.Collections.Generic.List<int*[]>; class C { void M(X x) { var y = x[0]; } } "; CreateCompilation(text, parseOptions: TestOptions.Regular11).VerifyDiagnostics( // (7,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // void M(X x) Diagnostic(ErrorCode.ERR_UnsafeNeeded, "X").WithLocation(7, 12), // (9,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // var y = x[0]; Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(9, 17), // (9,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // var y = x[0]; Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x[0]").WithLocation(9, 17)); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67281")] public void TestAliasToGenericWithPointer_ElementAccess2() { var text = @" // Legal in C# 11 using X = System.Collections.Generic.List<int*[]>; class C { void M(X x) { var y = x[0][0]; } } "; CreateCompilation(text, parseOptions: TestOptions.Regular11).VerifyDiagnostics( // (7,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // void M(X x) Diagnostic(ErrorCode.ERR_UnsafeNeeded, "X").WithLocation(7, 12), // (9,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // var y = x[0][0]; Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(9, 17), // (9,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // var y = x[0][0]; Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x[0]").WithLocation(9, 17), // (9,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // var y = x[0][0]; Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x[0][0]").WithLocation(9, 17)); CreateCompilation(text, parseOptions: TestOptions.Regular14, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics( // (3,43): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // using X = System.Collections.Generic.List<int*[]>; Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(3, 43), // (7,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // void M(X x) Diagnostic(ErrorCode.ERR_UnsafeNeeded, "X").WithLocation(7, 12), // (9,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // var y = x[0][0]; Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x").WithLocation(9, 17), // (9,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // var y = x[0][0]; Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x[0]").WithLocation(9, 17), // (9,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // var y = x[0][0]; Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x[0][0]").WithLocation(9, 17)); CreateCompilation(text, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics(); CreateCompilation(text, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67281")] public void TestAliasToGenericWithPointer() { var text = @" using X = System.Collections.Generic.List<int*[]>; class C { void M(X x) { } } "; CreateCompilation(text, parseOptions: TestOptions.Regular11).VerifyDiagnostics( // (6,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // void M(X x) Diagnostic(ErrorCode.ERR_UnsafeNeeded, "X").WithLocation(6, 12)); var expected = new[] { // (2,43): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // using X = System.Collections.Generic.List<int*[]>; Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(2, 43), // (6,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // void M(X x) Diagnostic(ErrorCode.ERR_UnsafeNeeded, "X").WithLocation(6, 12) }; CreateCompilation(text, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expected); CreateCompilation(text, parseOptions: TestOptions.Regular14).VerifyDiagnostics(expected); CreateCompilation(text).VerifyDiagnostics(); CreateCompilation(text, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67281")] public void TestAliasToGenericWithPointer_UnsafeAlias() { var text = @" using unsafe X = System.Collections.Generic.List<int*[]>; class C { unsafe void M(X x) { } } "; CreateCompilation(text).VerifyDiagnostics( // (2,7): error CS0227: Unsafe code may only appear if compiling with /unsafe // using unsafe X = System.Collections.Generic.List<int*[]>; Diagnostic(ErrorCode.ERR_IllegalUnsafe, "unsafe").WithLocation(2, 7), // (6,17): error CS0227: Unsafe code may only appear if compiling with /unsafe // unsafe void M(X x) Diagnostic(ErrorCode.ERR_IllegalUnsafe, "M").WithLocation(6, 17)); CreateCompilation(text, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67989")] public void AliasToPointerReferencedInExpression() { CreateCompilation(""" using unsafe Alias = int*; namespace N { internal unsafe class C { const int Factor = 3; void M() { _ = Alias * Factor; } } } """, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics( // (11,17): error CS0119: 'int*' is a type, which is not valid in the given context // _ = Alias * Factor; Diagnostic(ErrorCode.ERR_BadSKunknown, "Alias").WithArguments("int*", "type").WithLocation(11, 17)); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67989")] public void AliasToTupleReferencedInExpression() { CreateCompilation(""" using Alias = (int, int); internal class C { void M() { Alias.Equals(null, null); } } """).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67989")] public void AliasToPointerReferencedInNameof() { CreateCompilation(""" using Alias = (int, int); internal class C { void M() { System.Console.WriteLine(nameof(Alias)); } } """).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68546")] public void AliasToArrayReferencedInUsingStatic() { CreateCompilation(""" using A = int[]; namespace N { using static A; } """).VerifyDiagnostics( // (5,5): hidden CS8019: Unnecessary using directive. // using static A; Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using static A;").WithLocation(5, 5), // (5,18): error CS9137: 'array' type is not valid for 'using static'. Only a class, struct, interface, enum, delegate or namespace can be used. // using static A; Diagnostic(ErrorCode.ERR_BadUsingStaticType, "A").WithArguments("array").WithLocation(5, 18)); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68546")] public void AliasToPointerReferencedInUsingStatic() { CreateCompilation(""" using unsafe A = int*; namespace N { using static A; } """, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics( // (5,5): hidden CS8019: Unnecessary using directive. // using static A; Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using static A;").WithLocation(5, 5), // (5,18): error CS9137: 'pointer' type is not valid for 'using static'. Only a class, struct, interface, enum, delegate or namespace can be used. // using static A; Diagnostic(ErrorCode.ERR_BadUsingStaticType, "A").WithArguments("pointer").WithLocation(5, 18)); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68546")] public void AliasToFunctionPointerReferencedInUsingStatic() { CreateCompilation(""" using unsafe A = delegate*<int,int>; namespace N { using static A; } """, options: TestOptions.UnsafeDebugDll).VerifyDiagnostics( // (5,5): hidden CS8019: Unnecessary using directive. // using static A; Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using static A;").WithLocation(5, 5), // (5,18): error CS9137: 'function pointer' type is not valid for 'using static'. Only a class, struct, interface, enum, delegate or namespace can be used. // using static A; Diagnostic(ErrorCode.ERR_BadUsingStaticType, "A").WithArguments("function pointer").WithLocation(5, 18)); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68546")] public void AliasToDynamicReferencedInUsingStatic() { CreateCompilation(""" using A = dynamic; namespace N { using static A; } """).VerifyDiagnostics( // (5,5): hidden CS8019: Unnecessary using directive. // using static A; Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using static A;").WithLocation(5, 5), // (5,18): error CS9137: 'dynamic' type is not valid for 'using static'. Only a class, struct, interface, enum, delegate or namespace can be used. // using static A; Diagnostic(ErrorCode.ERR_BadUsingStaticType, "A").WithArguments("dynamic").WithLocation(5, 18)); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68546")] public void AliasToTupleReferencedInUsingStatic() { // Allowed, as it's the same as `using A = System.ValueTuple<int, int>;` CreateCompilation(""" using A = (int, int); namespace N { using static A; } """).VerifyDiagnostics( // (5,5): hidden CS8019: Unnecessary using directive. // using static A; Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using static A;").WithLocation(5, 5)); } } }