/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Semantic/Semantics/InteractiveUsingTests.cs
600 строк
23 KB
Youssef Victor
Remove unused private members (#61064)
12 июн 2022, 21:22
Не верифицирован
12 июн 2022, 21:22
a528fe2
Код
Авторство
О чём код?
// 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.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; using Microsoft.CodeAnalysis.Test.Utilities; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { public class InteractiveUsingTests : CSharpTestBase { [Fact] public void Using() { var sub = CreateSubmission("using System; typeof(String)"); sub.VerifyDiagnostics(); Assert.Equal(SpecialType.System_String, GetSpeculativeType(sub, "String").SpecialType); } [Fact] public void Alias() { var sub = CreateSubmission("using I = System.Int32; typeof(I)"); sub.VerifyDiagnostics(); Assert.Equal(SpecialType.System_Int32, GetSpeculativeType(sub, "I").SpecialType); } [Fact] public void UsingStatic() { var sub = CreateSubmission("using static System.Environment; NewLine"); sub.VerifyDiagnostics(); Assert.Equal(SymbolKind.Property, GetSpeculativeSymbol(sub, "NewLine").Kind); } [WorkItem(5450, "https://github.com/dotnet/roslyn/issues/5450")] [Fact] public void GlobalUsings() { var sub1 = CreateSubmission( "Combine(Environment.NewLine, Environment.NewLine)", options: TestOptions.DebugDll.WithUsings("System", "System.IO.Path")); sub1.VerifyDiagnostics(); // No global usings specified - expect to reuse previous. var sub2 = CreateSubmission( "Combine(Environment.NewLine, Environment.NewLine)", previous: sub1); sub2.VerifyDiagnostics(); // Global usings specified - expect to append to previous. var sub3 = CreateSubmission( "new StringBuilder().Append(Combine(Environment.NewLine, Environment.NewLine))", previous: sub2, options: TestOptions.DebugDll.WithUsings("System.Text")); sub3.VerifyDiagnostics(); } [WorkItem(4811, "https://github.com/dotnet/roslyn/issues/4811")] [Fact] public void AliasCurrentSubmission() { const string source = @" using T = Type; class Type { } "; var sub = (Compilation)CreateSubmission(source); sub.VerifyDiagnostics(); var typeSymbol = sub.ScriptClass.GetMember("Type"); var tree = sub.SyntaxTrees.Single(); var model = sub.GetSemanticModel(tree); var syntax = tree.GetRoot().DescendantNodes().OfType<UsingDirectiveSyntax>().Single(); var aliasSymbol = model.GetDeclaredSymbol(syntax); Assert.Equal(SymbolKind.Alias, aliasSymbol.Kind); Assert.Equal(typeSymbol, ((IAliasSymbol)aliasSymbol).Target); Assert.Equal(typeSymbol, model.GetSymbolInfo(syntax.Name).Symbol); Assert.Equal(typeSymbol, GetSpeculativeType(sub, "Type")); Assert.Equal(typeSymbol, GetSpeculativeType(sub, "T")); } [WorkItem(4811, "https://github.com/dotnet/roslyn/issues/4811")] [Fact] public void AliasPreviousSubmission() { var sub1 = CreateSubmission("class A { }"); var sub2 = CreateSubmission("class B : A { }", previous: sub1); var sub3 = CreateSubmission("class C : B { }", previous: sub2); CreateSubmission("using A1 = A;", previous: sub3).VerifyDiagnostics(); CreateSubmission("using B1 = B;", previous: sub3).VerifyDiagnostics(); var sub4 = CreateSubmission("using C1 = C; typeof(C1)", previous: sub3); sub4.VerifyDiagnostics(); var typeSymbol = ((Compilation)sub3).ScriptClass.GetMember("C"); var tree = sub4.SyntaxTrees.Single(); var model = sub4.GetSemanticModel(tree); var syntax = tree.GetRoot().DescendantNodes().OfType<UsingDirectiveSyntax>().Single(); var aliasSymbol = model.GetDeclaredSymbol(syntax); Assert.Equal(SymbolKind.Alias, aliasSymbol.Kind); Assert.Equal(typeSymbol, ((IAliasSymbol)aliasSymbol).Target); Assert.Equal(typeSymbol, model.GetSymbolInfo(syntax.Name).Symbol); Assert.Equal(typeSymbol, GetSpeculativeType(sub4, "C1")); } [Fact] public void AliasUnqualified() { const string source = @" using I = Int32; using System; "; var expectedDiagnostics = new[] { // (2,11): error CS0246: The type or namespace name 'Int32' could not be found (are you missing a using directive or an assembly reference?) // using I = Int32; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Int32").WithArguments("Int32").WithLocation(2, 11) }; CreateCompilation(source).GetDiagnostics().Where(d => d.Severity > DiagnosticSeverity.Hidden).Verify(expectedDiagnostics); CreateSubmission(source).GetDiagnostics().Verify(expectedDiagnostics); } [Fact] public void AliasUnqualified_GlobalUsing() { const string source = @" using I = Int32; "; var expectedDiagnostics = new[] { // (2,11): error CS0246: The type or namespace name 'Int32' could not be found (are you missing a using directive or an assembly reference?) // using I = Int32; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Int32").WithArguments("Int32").WithLocation(2, 11) }; var options = TestOptions.DebugDll.WithUsings("System"); CreateCompilation(source, options: options).GetDiagnostics().Where(d => d.Severity > DiagnosticSeverity.Hidden).Verify(expectedDiagnostics); CreateSubmission(source, options: options).GetDiagnostics().Verify(expectedDiagnostics); } [Fact] public void AliasOtherAlias() { const string source = @" using I = System.Int32; using J = I; "; var expectedDiagnostics = new[] { // (3,11): error CS0246: The type or namespace name 'I' could not be found (are you missing a using directive or an assembly reference?) // using J = I; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I").WithArguments("I").WithLocation(3, 11) }; CreateCompilation(source).GetDiagnostics().Where(d => d.Severity > DiagnosticSeverity.Hidden).Verify(expectedDiagnostics); CreateSubmission(source).GetDiagnostics().Verify(expectedDiagnostics); } [Fact] public void AliasHiding() { var sub1 = CreateSubmission("using A = System.Int32; typeof(A)"); Assert.Equal(SpecialType.System_Int32, GetSpeculativeType(sub1, "A").SpecialType); var sub2 = CreateSubmission("using A = System.Int16; typeof(A)", previous: sub1); Assert.Equal(SpecialType.System_Int16, GetSpeculativeType(sub2, "A").SpecialType); var sub3 = CreateSubmission("class A { }", previous: sub2); Assert.Equal(((Compilation)sub3).ScriptClass, GetSpeculativeType(sub3, "A").ContainingType); var sub4 = CreateSubmission("using A = System.Int64; typeof(A)", previous: sub3); Assert.Equal(SpecialType.System_Int64, GetSpeculativeType(sub4, "A").SpecialType); } [WorkItem(4811, "https://github.com/dotnet/roslyn/issues/4811")] [Fact] public void UsingStaticCurrentSubmission() { const string source = @" using static Type; class Type { public static readonly int Field = 1; } "; var sub = (Compilation)CreateSubmission(source); sub.VerifyDiagnostics(); Assert.Equal(sub.ScriptClass.GetMember("Type"), GetSpeculativeSymbol(sub, "Field").ContainingType); } [WorkItem(4811, "https://github.com/dotnet/roslyn/issues/4811")] [Fact] public void UsingStaticPreviousSubmission() { var sub1 = CreateSubmission("class A { public static int AA; }"); var sub2 = CreateSubmission("class B { public static int BB; }", previous: sub1); var sub3 = CreateSubmission("class C { public static int CC; }", previous: sub2); CreateSubmission("using static A;", previous: sub3).VerifyDiagnostics(); CreateSubmission("using static B;", previous: sub3).VerifyDiagnostics(); var sub4 = CreateSubmission("using static C;", previous: sub3); sub4.VerifyDiagnostics(); var typeSymbol = ((Compilation)sub3).ScriptClass.GetMember("C"); Assert.Equal(typeSymbol, GetSpeculativeSymbol(sub4, "CC").ContainingType); } [Fact] public void UsingStaticUnqualified() { const string source = @" using static Path; using System.IO; "; var expectedDiagnostics = new[] { // (2,14): error CS0246: The type or namespace name 'Path' could not be found (are you missing a using directive or an assembly reference?) // using static Path; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Path").WithArguments("Path").WithLocation(2, 14) }; CreateCompilation(source).GetDiagnostics().Where(d => d.Severity > DiagnosticSeverity.Hidden).Verify(expectedDiagnostics); CreateSubmission(source).GetDiagnostics().Verify(expectedDiagnostics); } [Fact] public void UsingStaticUnqualified_GlobalUsing() { const string source = @" using static Path; "; var expectedDiagnostics = new[] { // (2,14): error CS0246: The type or namespace name 'Path' could not be found (are you missing a using directive or an assembly reference?) // using static Path; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Path").WithArguments("Path").WithLocation(2, 14) }; var options = TestOptions.DebugDll.WithUsings("System"); CreateCompilation(source, options: options).GetDiagnostics().Where(d => d.Severity > DiagnosticSeverity.Hidden).Verify(expectedDiagnostics); CreateSubmission(source, options: options).GetDiagnostics().Verify(expectedDiagnostics); } [Fact] public void DuplicateUsing_SameSubmission() { CreateSubmission("using System; using System;").VerifyDiagnostics( // (1,21): warning CS0105: The using directive for 'System' appeared previously in this namespace // using System; using System; Diagnostic(ErrorCode.WRN_DuplicateUsing, "System").WithArguments("System").WithLocation(1, 21)); } [Fact] public void DuplicateUsing_DifferentSubmissions() { CreateSubmission("using System;", previous: CreateSubmission("using System;")).VerifyDiagnostics(); } [Fact] public void DuplicateGlobalUsing_SameSubmission() { CreateSubmission("typeof(String)", options: TestOptions.DebugDll.WithUsings("System", "System")).VerifyDiagnostics(); } [Fact] public void DuplicateGlobalUsing_PreviousSubmission() { var options = TestOptions.DebugDll.WithUsings("System"); var sub1 = CreateSubmission("typeof(String)", options: options); sub1.VerifyDiagnostics(); var sub2 = CreateSubmission("typeof(String)", options: options, previous: sub1); sub2.VerifyDiagnostics(); } [Fact] public void UsingsRebound() { const string libSourceTemplate = @" namespace A {{ public class A{0} {{ }} }} namespace B {{ public class B{0} {{ }} }} "; var lib1 = CreateCompilation(string.Format(libSourceTemplate, 1), assemblyName: "Lib1").EmitToImageReference(); var lib2 = CreateCompilation(string.Format(libSourceTemplate, 2), assemblyName: "Lib2").EmitToImageReference(); var options = TestOptions.DebugDll.WithUsings("B"); var sub1 = CreateSubmission("using A; typeof(A1) == typeof(B1)", new[] { lib1 }, options); sub1.VerifyDiagnostics(); var sub2 = CreateSubmission("typeof(A1) == typeof(B1) && typeof(A2) == typeof(B2)", new[] { lib1, lib2 }, options: options, previous: sub1); sub2.VerifyDiagnostics(); } [WorkItem(5423, "https://github.com/dotnet/roslyn/issues/5423")] [Fact] public void UsingsFromLoadedScript() { const string scriptSource = @" using static System.IO.Path; using System.IO; using F = System.IO.File; class C { } "; const string submissionSource = @" #load ""a.csx"" System.Type t; GetTempPath(); // using static not exposed t = typeof(File); // using not exposed t = typeof(F); // using alias not exposed t = typeof(C); // declaration exposed "; var resolver = TestSourceReferenceResolver.Create(new Dictionary<string, string> { { "a.csx", scriptSource } }); var compilation = CreateSubmission( submissionSource, options: TestOptions.DebugDll.WithSourceReferenceResolver(resolver)); compilation.VerifyDiagnostics( // (6,1): error CS0103: The name 'GetTempPath' does not exist in the current context // GetTempPath(); // using static not exposed Diagnostic(ErrorCode.ERR_NameNotInContext, "GetTempPath").WithArguments("GetTempPath").WithLocation(6, 1), // (7,12): error CS0246: The type or namespace name 'File' could not be found (are you missing a using directive or an assembly reference?) // t = typeof(File); // using not exposed Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "File").WithArguments("File").WithLocation(7, 12), // (8,12): error CS0246: The type or namespace name 'F' could not be found (are you missing a using directive or an assembly reference?) // t = typeof(F); // using alias not exposed Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "F").WithArguments("F").WithLocation(8, 12)); } [WorkItem(5423, "https://github.com/dotnet/roslyn/issues/5423")] [Fact] public void UsingsToLoadedScript() { const string scriptSource = @" using System.Collections.Generic; using AL = System.Collections.ArrayList; using static System.Math; class D { } System.Type t; // Previous submission GetCommandLineArgs(); // using static not exposed t = typeof(StringBuilder); // using not exposed t = typeof(P); // using alias not exposed t = typeof(B); // declaration exposed // Current submission GetTempPath(); // using static not exposed t = typeof(File); // using not exposed t = typeof(F); // using alias not exposed t = typeof(C); // declaration exposed // Current file - all available Sin(1); t = typeof(List<int>); t = typeof(AL); t = typeof(D); "; const string previousSubmissionSource = @" using static System.Environment; using System.Text; using P = System.IO.Path; class B { } "; const string submissionSource = @" #load ""a.csx"" using static System.IO.Path; using System.IO; using F = System.IO.File; class C { } "; var resolver = TestSourceReferenceResolver.Create(new Dictionary<string, string> { { "a.csx", scriptSource } }); var compilation = CreateSubmission( submissionSource, options: TestOptions.DebugDll.WithSourceReferenceResolver(resolver), previous: CreateSubmission(previousSubmissionSource)); compilation.VerifyDiagnostics( // Previous submission // a.csx(11,1): error CS0103: The name 'GetCommandLineArgs' does not exist in the current context // GetCommandLineArgs(); // using static not exposed Diagnostic(ErrorCode.ERR_NameNotInContext, "GetCommandLineArgs").WithArguments("GetCommandLineArgs").WithLocation(11, 1), // a.csx(12,12): error CS0246: The type or namespace name 'StringBuilder' could not be found (are you missing a using directive or an assembly reference?) // t = typeof(StringBuilder); // using not exposed Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "StringBuilder").WithArguments("StringBuilder").WithLocation(12, 12), // a.csx(13,12): error CS0246: The type or namespace name 'P' could not be found (are you missing a using directive or an assembly reference?) // t = typeof(P); // using alias not exposed Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "P").WithArguments("P").WithLocation(13, 12), // Current submission // a.csx(17,1): error CS0103: The name 'GetTempPath' does not exist in the current context // GetTempPath(); // using static not exposed Diagnostic(ErrorCode.ERR_NameNotInContext, "GetTempPath").WithArguments("GetTempPath").WithLocation(17, 1), // a.csx(18,12): error CS0246: The type or namespace name 'File' could not be found (are you missing a using directive or an assembly reference?) // t = typeof(File); // using not exposed Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "File").WithArguments("File").WithLocation(18, 12), // a.csx(19,12): error CS0246: The type or namespace name 'F' could not be found (are you missing a using directive or an assembly reference?) // t = typeof(F); // using alias not exposed Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "F").WithArguments("F").WithLocation(19, 12)); } [Fact] public void GlobalUsingsToLoadedScript() { const string scriptSource = @" System.Type t; GetTempPath(); // global using static exposed t = typeof(File); // global using exposed "; const string submissionSource = @" #load ""a.csx"" "; var resolver = TestSourceReferenceResolver.Create(new Dictionary<string, string> { { "a.csx", scriptSource } }); var compilation = CreateSubmission( submissionSource, options: TestOptions.DebugDll.WithSourceReferenceResolver(resolver).WithUsings("System.IO", "System.IO.Path")); compilation.VerifyDiagnostics(); } [WorkItem(4811, "https://github.com/dotnet/roslyn/issues/4811")] [ConditionalFact(typeof(NoUsedAssembliesValidation))] public void ConsumePreviousSubmissionUsings_Valid() { const string libSource = @" namespace NOuter { public class Test { } namespace NInner { public static class COuter { public static void M() { } public static class CInner { public static void N() { } } } } } "; var lib = CreateCompilation(libSource).EmitToImageReference(); var refs = new[] { lib }; var submissions = new[] { "using NOuter;", "typeof(Test)", "using NI = NOuter.NInner;", "typeof(NI.COuter)", "using static NI.COuter;", "M()", "using static NI.COuter.CInner;", "N()", }; CSharpCompilation prev = null; foreach (var submission in submissions) { var curr = CreateSubmission(submission, refs, previous: prev); curr.VerifyDiagnostics(); prev = curr; } } [ConditionalFact(typeof(NoUsedAssembliesValidation))] public void ConsumePreviousSubmissionUsings_Invalid() { const string libSource = @" namespace NOuter { public class COuter { } namespace NInner { public static class CInner { } } } "; var lib = CreateCompilation(libSource).EmitToImageReference(); var refs = new[] { lib }; CreateSubmission("using NInner;", refs, previous: CreateSubmission("using NOuter;", refs)).VerifyDiagnostics( // (1,7): error CS0246: The type or namespace name 'NInner' could not be found (are you missing a using directive or an assembly reference?) // using NInner; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "NInner").WithArguments("NInner").WithLocation(1, 7)); CreateSubmission("using NI = NInner;", refs, previous: CreateSubmission("using NOuter;", refs)).VerifyDiagnostics( // (1,12): error CS0246: The type or namespace name 'NInner' could not be found (are you missing a using directive or an assembly reference?) // using NI = NInner; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "NInner").WithArguments("NInner").WithLocation(1, 12)); CreateSubmission("using static COuter;", refs, previous: CreateSubmission("using NOuter;", refs)).VerifyDiagnostics( // (1,14): error CS0246: The type or namespace name 'COuter' could not be found (are you missing a using directive or an assembly reference?) // using static COuter; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "COuter").WithArguments("COuter").WithLocation(1, 14)); CreateSubmission("using static NInner.CInner;", refs, previous: CreateSubmission("using NOuter;", refs)).VerifyDiagnostics( // (1,14): error CS0246: The type or namespace name 'NInner' could not be found (are you missing a using directive or an assembly reference?) // using static NInner.CInner; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "NInner").WithArguments("NInner").WithLocation(1, 14)); } private static ISymbol GetSpeculativeSymbol(Compilation comp, string name) { var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); return model.GetSpeculativeSymbolInfo( tree.Length, SyntaxFactory.IdentifierName(name), SpeculativeBindingOption.BindAsExpression).Symbol; } private static ITypeSymbol GetSpeculativeType(Compilation comp, string name) { var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); return model.GetSpeculativeTypeInfo( tree.Length, SyntaxFactory.IdentifierName(name), SpeculativeBindingOption.BindAsTypeOrNamespace).Type; } } }