/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Semantic/Semantics/TopLevelStatementsTests.cs
10 300 строк
418 KB
Pierre Fiser
Report CS8802 on every file with top-level statements (#83916)
07 авг 2026, 04:20
Не верифицирован
07 авг 2026, 04:20
8cd4945
Код
Авторство
О чём код?
// 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.Immutable; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.FlowAnalysis; using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Roslyn.Test.Utilities.TestGenerators; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { [CompilerTrait(CompilerFeature.TopLevelStatements)] public class TopLevelStatementsTests : CompilingTestBase { private static CSharpParseOptions DefaultParseOptions => TestOptions.Regular9; private static bool IsNullableAnalysisEnabled(CSharpCompilation compilation) { var type = compilation.GlobalNamespace.GetTypeMember("Program"); var methods = type.GetMembers().OfType<SynthesizedSimpleProgramEntryPointSymbol>(); return methods.Any(m => m.IsNullableAnalysisEnabled()); } [Fact] public void Simple_01() { var text = @"System.Console.WriteLine(""Hi!"");"; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Void", entryPoint.ReturnType.ToTestDisplayString()); Assert.True(entryPoint.ReturnsVoid); AssertEntryPointParameter(entryPoint); CompileAndVerify(comp, expectedOutput: "Hi!"); Assert.Same(entryPoint, comp.GetEntryPoint(default)); Assert.False(entryPoint.CanBeReferencedByName); Assert.True(entryPoint.ContainingType.CanBeReferencedByName); Assert.Equal("<Main>$", entryPoint.Name); Assert.Equal("Program", entryPoint.ContainingType.Name); } private static void AssertEntryPointParameter(SynthesizedSimpleProgramEntryPointSymbol entryPoint) { Assert.Equal(1, entryPoint.ParameterCount); ParameterSymbol parameter = entryPoint.Parameters.Single(); Assert.Equal("System.String[] args", parameter.ToTestDisplayString(includeNonNullable: true)); Assert.True(parameter.IsImplicitlyDeclared); Assert.Same(entryPoint, parameter.ContainingSymbol); } [Fact] public void Simple_02() { var text = @" using System; using System.Threading.Tasks; Console.Write(""hello ""); await Task.Factory.StartNew(() => 5); Console.Write(""async main""); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Threading.Tasks.Task", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnsVoid); AssertEntryPointParameter(entryPoint); CompileAndVerify(comp, expectedOutput: "hello async main"); } [Fact] public void Simple_03() { var text1 = @" System.Console.Write(""1""); "; var text2 = @" // System.Console.Write(""2""); System.Console.WriteLine(); System.Console.WriteLine(); "; var text3 = @" // // System.Console.Write(""3""); System.Console.WriteLine(); System.Console.WriteLine(); "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS8802: Only one compilation unit can have top-level statements. // System.Console.Write("1"); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "System").WithLocation(2, 1), // (3,1): error CS8802: Only one compilation unit can have top-level statements. // System.Console.Write("2"); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "System").WithLocation(3, 1) ); comp = CreateCompilation(new[] { text1, text2, text3 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS8802: Only one compilation unit can have top-level statements. // System.Console.Write("1"); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "System").WithLocation(2, 1), // (3,1): error CS8802: Only one compilation unit can have top-level statements. // System.Console.Write("2"); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "System").WithLocation(3, 1), // (4,1): error CS8802: Only one compilation unit can have top-level statements. // System.Console.Write("3"); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "System").WithLocation(4, 1) ); } [Fact] public void Simple_04() { var text = @" Type.M(); static class Type { public static void M() { System.Console.WriteLine(""Hi!""); } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void Simple_05() { var text1 = @" Type.M(); "; var text2 = @" static class Type { public static void M() { System.Console.WriteLine(""Hi!""); } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); comp = CreateCompilation(new[] { text2, text1 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void Simple_06_01() { var text1 = @" local(); void local() => System.Console.WriteLine(2); "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); CompileAndVerify(comp, expectedOutput: "2"); verifyModel(comp, comp.SyntaxTrees[0]); comp = CreateCompilation(text1, options: TestOptions.DebugExe.WithNullableContextOptions(NullableContextOptions.Enable), parseOptions: DefaultParseOptions); verifyModel(comp, comp.SyntaxTrees[0], nullableEnabled: true); static void verifyModel(CSharpCompilation comp, SyntaxTree tree1, bool nullableEnabled = false) { Assert.Equal(nullableEnabled, IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var model1 = comp.GetSemanticModel(tree1); verifyModelForGlobalStatements(tree1, model1); var unit1 = (CompilationUnitSyntax)tree1.GetRoot(); var localRef = unit1.DescendantNodes().OfType<IdentifierNameSyntax>().First(); var refSymbol = model1.GetSymbolInfo(localRef).Symbol; Assert.Equal("void local()", refSymbol.ToTestDisplayString()); Assert.Contains(refSymbol.Name, model1.LookupNames(localRef.SpanStart)); Assert.Contains(refSymbol, model1.LookupSymbols(localRef.SpanStart)); Assert.Same(refSymbol, model1.LookupSymbols(localRef.SpanStart, name: refSymbol.Name).Single()); var operation1 = model1.GetOperation(localRef.Parent); Assert.NotNull(operation1); Assert.IsAssignableFrom<IInvocationOperation>(operation1); Assert.NotNull(ControlFlowGraph.Create((IMethodBodyOperation)((IBlockOperation)operation1.Parent.Parent).Parent)); model1.VerifyOperationTree(unit1, @" IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'local(); ... iteLine(2);') BlockBody: IBlockOperation (2 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 'local(); ... iteLine(2);') IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'local();') Expression: IInvocationOperation (void local()) (OperationKind.Invocation, Type: System.Void) (Syntax: 'local()') Instance Receiver: null Arguments(0) ILocalFunctionOperation (Symbol: void local()) (OperationKind.LocalFunction, Type: null) (Syntax: 'void local( ... iteLine(2);') IBlockOperation (2 statements) (OperationKind.Block, Type: null) (Syntax: '=> System.C ... riteLine(2)') IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: 'System.Cons ... riteLine(2)') Expression: IInvocationOperation (void System.Console.WriteLine(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... riteLine(2)') Instance Receiver: null Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '2') ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 2) (Syntax: '2') InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: '=> System.C ... riteLine(2)') ReturnedValue: null ExpressionBody: null "); var localDecl = unit1.DescendantNodes().OfType<LocalFunctionStatementSyntax>().Single(); var declSymbol = model1.GetDeclaredSymbol(localDecl); Assert.Same(declSymbol.ContainingSymbol, model1.GetDeclaredSymbol(unit1)); Assert.Same(declSymbol.ContainingSymbol, model1.GetDeclaredSymbol((SyntaxNode)unit1)); Assert.Same(refSymbol, declSymbol); Assert.Contains(declSymbol.Name, model1.LookupNames(localDecl.SpanStart)); Assert.Contains(declSymbol, model1.LookupSymbols(localDecl.SpanStart)); Assert.Same(declSymbol, model1.LookupSymbols(localDecl.SpanStart, name: declSymbol.Name).Single()); var operation2 = model1.GetOperation(localDecl); Assert.NotNull(operation2); Assert.IsAssignableFrom<ILocalFunctionOperation>(operation2); static void verifyModelForGlobalStatements(SyntaxTree tree1, SemanticModel model1) { var symbolInfo = model1.GetSymbolInfo(tree1.GetRoot()); Assert.Null(symbolInfo.Symbol); Assert.Empty(symbolInfo.CandidateSymbols); Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason); var typeInfo = model1.GetTypeInfo(tree1.GetRoot()); Assert.Null(typeInfo.Type); Assert.Null(typeInfo.ConvertedType); foreach (var globalStatement in tree1.GetRoot().DescendantNodes().OfType<GlobalStatementSyntax>()) { symbolInfo = model1.GetSymbolInfo(globalStatement); Assert.Null(model1.GetOperation(globalStatement)); Assert.Null(symbolInfo.Symbol); Assert.Empty(symbolInfo.CandidateSymbols); Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason); typeInfo = model1.GetTypeInfo(globalStatement); Assert.Null(typeInfo.Type); Assert.Null(typeInfo.ConvertedType); } } } } [Fact] public void Simple_06_02() { var text1 = @"local();"; var text2 = @"void local() => System.Console.WriteLine(2);"; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,1): error CS8802: Only one compilation unit can have top-level statements. // local(); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "local").WithLocation(1, 1), // (1,1): error CS8802: Only one compilation unit can have top-level statements. // void local() => System.Console.WriteLine(2); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "void").WithLocation(1, 1), // (1,1): error CS0103: The name 'local' does not exist in the current context // local(); Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(1, 1), // (1,6): warning CS8321: The local function 'local' is declared but never used // void local() => System.Console.WriteLine(2); Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(1, 6) ); verifyModel(comp, comp.SyntaxTrees[0], comp.SyntaxTrees[1]); comp = CreateCompilation(new[] { text2, text1 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,1): error CS8802: Only one compilation unit can have top-level statements. // void local() => System.Console.WriteLine(2); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "void").WithLocation(1, 1), // (1,1): error CS8802: Only one compilation unit can have top-level statements. // local(); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "local").WithLocation(1, 1), // (1,1): error CS0103: The name 'local' does not exist in the current context // local(); Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(1, 1), // (1,6): warning CS8321: The local function 'local' is declared but never used // void local() => System.Console.WriteLine(2); Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(1, 6) ); verifyModel(comp, comp.SyntaxTrees[1], comp.SyntaxTrees[0]); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe.WithNullableContextOptions(NullableContextOptions.Enable), parseOptions: DefaultParseOptions); verifyModel(comp, comp.SyntaxTrees[0], comp.SyntaxTrees[1], nullableEnabled: true); static void verifyModel(CSharpCompilation comp, SyntaxTree tree1, SyntaxTree tree2, bool nullableEnabled = false) { Assert.Equal(nullableEnabled, IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var model1 = comp.GetSemanticModel(tree1); verifyModelForGlobalStatements(tree1, model1); var unit1 = (CompilationUnitSyntax)tree1.GetRoot(); var localRef = unit1.DescendantNodes().OfType<IdentifierNameSyntax>().Single(); var refSymbol = model1.GetSymbolInfo(localRef).Symbol; var refMethod = model1.GetDeclaredSymbol(unit1); Assert.NotNull(refMethod); Assert.Null(refSymbol); var name = localRef.Identifier.ValueText; Assert.DoesNotContain(name, model1.LookupNames(localRef.SpanStart)); Assert.Empty(model1.LookupSymbols(localRef.SpanStart).Where(s => s.Name == name)); Assert.Empty(model1.LookupSymbols(localRef.SpanStart, name: name)); var operation1 = model1.GetOperation(localRef.Parent); Assert.NotNull(operation1); Assert.IsAssignableFrom<IInvalidOperation>(operation1); Assert.NotNull(ControlFlowGraph.Create((IMethodBodyOperation)((IBlockOperation)operation1.Parent.Parent).Parent)); model1.VerifyOperationTree(unit1, @" IMethodBodyOperation (OperationKind.MethodBody, Type: null, IsInvalid) (Syntax: 'local();') BlockBody: IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsInvalid, IsImplicit) (Syntax: 'local();') IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsInvalid) (Syntax: 'local();') Expression: IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'local()') Children(1): IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'local') Children(0) ExpressionBody: null "); SyntaxTreeSemanticModel syntaxTreeModel = ((SyntaxTreeSemanticModel)model1); MemberSemanticModel mm = syntaxTreeModel.TestOnlyMemberModels[unit1]; var model2 = comp.GetSemanticModel(tree2); verifyModelForGlobalStatements(tree2, model2); var unit2 = (CompilationUnitSyntax)tree2.GetRoot(); var declMethod = model2.GetDeclaredSymbol(unit2); var localDecl = unit2.DescendantNodes().OfType<LocalFunctionStatementSyntax>().Single(); var declSymbol = model2.GetDeclaredSymbol(localDecl); Assert.Equal("void local()", declSymbol.ToTestDisplayString()); Assert.Same(declSymbol.ContainingSymbol, declMethod); Assert.NotEqual(refMethod, declMethod); Assert.Contains(declSymbol.Name, model2.LookupNames(localDecl.SpanStart)); Assert.Contains(declSymbol, model2.LookupSymbols(localDecl.SpanStart)); Assert.Same(declSymbol, model2.LookupSymbols(localDecl.SpanStart, name: declSymbol.Name).Single()); var operation2 = model2.GetOperation(localDecl); Assert.NotNull(operation2); Assert.IsAssignableFrom<ILocalFunctionOperation>(operation2); Assert.NotNull(ControlFlowGraph.Create((IMethodBodyOperation)((IBlockOperation)operation2.Parent).Parent)); model2.VerifyOperationTree(unit2, @" IMethodBodyOperation (OperationKind.MethodBody, Type: null, IsInvalid) (Syntax: 'void local( ... iteLine(2);') BlockBody: IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsInvalid, IsImplicit) (Syntax: 'void local( ... iteLine(2);') ILocalFunctionOperation (Symbol: void local()) (OperationKind.LocalFunction, Type: null, IsInvalid) (Syntax: 'void local( ... iteLine(2);') IBlockOperation (2 statements) (OperationKind.Block, Type: null) (Syntax: '=> System.C ... riteLine(2)') IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: 'System.Cons ... riteLine(2)') Expression: IInvocationOperation (void System.Console.WriteLine(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... riteLine(2)') Instance Receiver: null Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '2') ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 2) (Syntax: '2') InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: '=> System.C ... riteLine(2)') ReturnedValue: null ExpressionBody: null "); static void verifyModelForGlobalStatements(SyntaxTree tree1, SemanticModel model1) { var symbolInfo = model1.GetSymbolInfo(tree1.GetRoot()); Assert.Null(symbolInfo.Symbol); Assert.Empty(symbolInfo.CandidateSymbols); Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason); var typeInfo = model1.GetTypeInfo(tree1.GetRoot()); Assert.Null(typeInfo.Type); Assert.Null(typeInfo.ConvertedType); foreach (var globalStatement in tree1.GetRoot().DescendantNodes().OfType<GlobalStatementSyntax>()) { symbolInfo = model1.GetSymbolInfo(globalStatement); Assert.Null(model1.GetOperation(globalStatement)); Assert.Null(symbolInfo.Symbol); Assert.Empty(symbolInfo.CandidateSymbols); Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason); typeInfo = model1.GetTypeInfo(globalStatement); Assert.Null(typeInfo.Type); Assert.Null(typeInfo.ConvertedType); } } } } [Fact] public void Simple_07() { var text1 = @" var i = 1; local(); "; var text2 = @" void local() => System.Console.WriteLine(i); "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS8802: Only one compilation unit can have top-level statements. // var i = 1; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "var").WithLocation(2, 1), // (2,1): error CS8802: Only one compilation unit can have top-level statements. // void local() => System.Console.WriteLine(i); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "void").WithLocation(2, 1), // (2,5): warning CS0219: The variable 'i' is assigned but its value is never used // var i = 1; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "i").WithArguments("i").WithLocation(2, 5), // (2,6): warning CS8321: The local function 'local' is declared but never used // void local() => System.Console.WriteLine(i); Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(2, 6), // (2,42): error CS0103: The name 'i' does not exist in the current context // void local() => System.Console.WriteLine(i); Diagnostic(ErrorCode.ERR_NameNotInContext, "i").WithArguments("i").WithLocation(2, 42), // (3,1): error CS0103: The name 'local' does not exist in the current context // local(); Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(3, 1) ); verifyModel(comp, comp.SyntaxTrees[0], comp.SyntaxTrees[1]); comp = CreateCompilation(new[] { text2, text1 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS8802: Only one compilation unit can have top-level statements. // void local() => System.Console.WriteLine(i); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "void").WithLocation(2, 1), // (2,1): error CS8802: Only one compilation unit can have top-level statements. // var i = 1; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "var").WithLocation(2, 1), // (2,5): warning CS0219: The variable 'i' is assigned but its value is never used // var i = 1; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "i").WithArguments("i").WithLocation(2, 5), // (2,6): warning CS8321: The local function 'local' is declared but never used // void local() => System.Console.WriteLine(i); Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(2, 6), // (2,42): error CS0103: The name 'i' does not exist in the current context // void local() => System.Console.WriteLine(i); Diagnostic(ErrorCode.ERR_NameNotInContext, "i").WithArguments("i").WithLocation(2, 42), // (3,1): error CS0103: The name 'local' does not exist in the current context // local(); Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(3, 1) ); verifyModel(comp, comp.SyntaxTrees[1], comp.SyntaxTrees[0]); static void verifyModel(CSharpCompilation comp, SyntaxTree tree1, SyntaxTree tree2) { Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var model1 = comp.GetSemanticModel(tree1); var localDecl = tree1.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Single(); var declSymbol = model1.GetDeclaredSymbol(localDecl); Assert.Equal("System.Int32 i", declSymbol.ToTestDisplayString()); Assert.Contains(declSymbol.Name, model1.LookupNames(localDecl.SpanStart)); Assert.Contains(declSymbol, model1.LookupSymbols(localDecl.SpanStart)); Assert.Same(declSymbol, model1.LookupSymbols(localDecl.SpanStart, name: declSymbol.Name).Single()); Assert.NotNull(model1.GetOperation(tree1.GetRoot())); var operation1 = model1.GetOperation(localDecl); Assert.NotNull(operation1); Assert.IsAssignableFrom<IVariableDeclaratorOperation>(operation1); var localFuncRef = tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "local").Single(); Assert.Contains(declSymbol.Name, model1.LookupNames(localFuncRef.SpanStart)); Assert.Contains(declSymbol, model1.LookupSymbols(localFuncRef.SpanStart)); Assert.Same(declSymbol, model1.LookupSymbols(localFuncRef.SpanStart, name: declSymbol.Name).Single()); Assert.DoesNotContain(declSymbol, model1.AnalyzeDataFlow(localDecl.Ancestors().OfType<StatementSyntax>().First()).DataFlowsOut); var model2 = comp.GetSemanticModel(tree2); var localRef = tree2.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "i").Single(); var refSymbol = model2.GetSymbolInfo(localRef).Symbol; Assert.Null(refSymbol); var name = localRef.Identifier.ValueText; Assert.DoesNotContain(name, model2.LookupNames(localRef.SpanStart)); Assert.Empty(model2.LookupSymbols(localRef.SpanStart).Where(s => s.Name == name)); Assert.Empty(model2.LookupSymbols(localRef.SpanStart, name: name)); Assert.NotNull(model2.GetOperation(tree2.GetRoot())); var operation2 = model2.GetOperation(localRef); Assert.NotNull(operation2); Assert.IsAssignableFrom<IInvalidOperation>(operation2); Assert.DoesNotContain(declSymbol, model2.AnalyzeDataFlow(localRef).DataFlowsIn); } } [Fact] public void Simple_08() { var text1 = @" var i = 1; System.Console.Write(i++); System.Console.Write(i); "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); CompileAndVerify(comp, expectedOutput: "12"); var tree1 = comp.SyntaxTrees[0]; Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var model1 = comp.GetSemanticModel(tree1); var localDecl = tree1.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Single(); var declSymbol = model1.GetDeclaredSymbol(localDecl); Assert.Equal("System.Int32 i", declSymbol.ToTestDisplayString()); Assert.Contains(declSymbol.Name, model1.LookupNames(localDecl.SpanStart)); Assert.Contains(declSymbol, model1.LookupSymbols(localDecl.SpanStart)); Assert.Same(declSymbol, model1.LookupSymbols(localDecl.SpanStart, name: declSymbol.Name).Single()); var localRefs = tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "i").ToArray(); Assert.Equal(2, localRefs.Length); foreach (var localRef in localRefs) { var refSymbol = model1.GetSymbolInfo(localRef).Symbol; Assert.Same(declSymbol, refSymbol); Assert.Contains(declSymbol.Name, model1.LookupNames(localRef.SpanStart)); Assert.Contains(declSymbol, model1.LookupSymbols(localRef.SpanStart)); Assert.Same(declSymbol, model1.LookupSymbols(localRef.SpanStart, name: declSymbol.Name).Single()); } } [Fact] public void Simple_09() { var text1 = @" var i = 1; local(); void local() => System.Console.WriteLine(i); "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); CompileAndVerify(comp, expectedOutput: "1"); verifyModel(comp, comp.SyntaxTrees[0]); static void verifyModel(CSharpCompilation comp, SyntaxTree tree1) { Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var model1 = comp.GetSemanticModel(tree1); var localDecl = tree1.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Single(); var declSymbol = model1.GetDeclaredSymbol(localDecl); Assert.Equal("System.Int32 i", declSymbol.ToTestDisplayString()); Assert.Contains(declSymbol.Name, model1.LookupNames(localDecl.SpanStart)); Assert.Contains(declSymbol, model1.LookupSymbols(localDecl.SpanStart)); Assert.Same(declSymbol, model1.LookupSymbols(localDecl.SpanStart, name: declSymbol.Name).Single()); Assert.NotNull(model1.GetOperation(tree1.GetRoot())); var operation1 = model1.GetOperation(localDecl); Assert.NotNull(operation1); Assert.IsAssignableFrom<IVariableDeclaratorOperation>(operation1); var localFuncRef = tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "local").Single(); Assert.Contains(declSymbol.Name, model1.LookupNames(localFuncRef.SpanStart)); Assert.Contains(declSymbol, model1.LookupSymbols(localFuncRef.SpanStart)); Assert.Same(declSymbol, model1.LookupSymbols(localFuncRef.SpanStart, name: declSymbol.Name).Single()); Assert.Contains(declSymbol, model1.AnalyzeDataFlow(localDecl.Ancestors().OfType<StatementSyntax>().First()).DataFlowsOut); var localRef = tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "i").Single(); var refSymbol = model1.GetSymbolInfo(localRef).Symbol; Assert.Same(declSymbol, refSymbol); Assert.Contains(refSymbol.Name, model1.LookupNames(localRef.SpanStart)); Assert.Contains(refSymbol, model1.LookupSymbols(localRef.SpanStart)); Assert.Same(refSymbol, model1.LookupSymbols(localRef.SpanStart, name: refSymbol.Name).Single()); var operation2 = model1.GetOperation(localRef); Assert.NotNull(operation2); Assert.IsAssignableFrom<ILocalReferenceOperation>(operation2); // The following assert fails due to https://github.com/dotnet/roslyn/issues/41853, enable once the issue is fixed. //Assert.Contains(declSymbol, model1.AnalyzeDataFlow(localRef).DataFlowsIn); } } [Fact] public void LanguageVersion_01() { var text = @"System.Console.WriteLine(""Hi!"");"; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular8); comp.VerifyDiagnostics( // (1,1): error CS8400: Feature 'top-level statements' is not available in C# 8.0. Please use language version 9.0 or greater. // System.Console.WriteLine("Hi!"); Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, @"System.Console.WriteLine(""Hi!"");").WithArguments("top-level statements", "9.0").WithLocation(1, 1) ); } [Fact] public void WithinType_01() { var text = @" class Test { System.Console.WriteLine(""Hi!""); } "; var comp = CreateCompilation(text, parseOptions: DefaultParseOptions); var expected = new[] { // (4,29): error CS1519: Invalid token '(' in class, record, struct, or interface member declaration // System.Console.WriteLine("Hi!"); Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "(").WithArguments("(").WithLocation(4, 29), // (4,30): error CS1031: Type expected // System.Console.WriteLine("Hi!"); Diagnostic(ErrorCode.ERR_TypeExpected, @"""Hi!""").WithLocation(4, 30), // (4,30): error CS8124: Tuple must contain at least two elements. // System.Console.WriteLine("Hi!"); Diagnostic(ErrorCode.ERR_TupleTooFewElements, @"""Hi!""").WithLocation(4, 30), // (4,30): error CS1026: ) expected // System.Console.WriteLine("Hi!"); Diagnostic(ErrorCode.ERR_CloseParenExpected, @"""Hi!""").WithLocation(4, 30), // (4,30): error CS1519: Invalid token '"Hi!"' in class, record, struct, or interface member declaration // System.Console.WriteLine("Hi!"); Diagnostic(ErrorCode.ERR_InvalidMemberDecl, @"""Hi!""").WithArguments(@"""Hi!""").WithLocation(4, 30) }; comp.GetDiagnostics(CompilationStage.Parse, includeEarlierStages: false, symbolFilter: null, cancellationToken: default).Verify(expected); comp.VerifyDiagnostics(expected); } [Fact] public void WithinNamespace_01() { var text = @" namespace Test { System.Console.WriteLine(""Hi!""); } "; var comp = CreateCompilation(text, parseOptions: DefaultParseOptions); var expected = new[] { // (4,20): error CS0116: A namespace cannot directly contain members such as fields or methods // System.Console.WriteLine("Hi!"); Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "WriteLine").WithLocation(4, 20), // (4,30): error CS1026: ) expected // System.Console.WriteLine("Hi!"); Diagnostic(ErrorCode.ERR_CloseParenExpected, @"""Hi!""").WithLocation(4, 30), // (4,30): error CS1022: Type or namespace definition, or end-of-file expected // System.Console.WriteLine("Hi!"); Diagnostic(ErrorCode.ERR_EOFExpected, @"""Hi!""").WithLocation(4, 30) }; comp.GetDiagnostics(CompilationStage.Parse, includeEarlierStages: false, symbolFilter: null, cancellationToken: default).Verify(expected); comp.VerifyDiagnostics(expected); } [Fact] public void LocalDeclarationStatement_01() { var text = @" string s = ""Hi!""; System.Console.WriteLine(s); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var declarator = tree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Single(); var reference = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "s").Single(); var local = model.GetDeclaredSymbol(declarator); Assert.Same(local, model.GetSymbolInfo(reference).Symbol); Assert.Equal("System.String s", local.ToTestDisplayString()); Assert.Equal(SymbolKind.Local, local.Kind); Assert.Equal(SymbolKind.Method, local.ContainingSymbol.Kind); Assert.False(local.ContainingSymbol.IsImplicitlyDeclared); Assert.Equal(SymbolKind.NamedType, local.ContainingSymbol.ContainingSymbol.Kind); Assert.Equal("Program", local.ContainingSymbol.ContainingSymbol.Name); Assert.False(local.ContainingSymbol.ContainingSymbol.IsImplicitlyDeclared); Assert.True(((INamespaceSymbol)local.ContainingSymbol.ContainingSymbol.ContainingSymbol).IsGlobalNamespace); } [Fact] public void LocalDeclarationStatement_02() { var text = @" new string a = ""Hi!""; System.Console.WriteLine(a); public string b = ""Hi!""; System.Console.WriteLine(b); static string c = ""Hi!""; System.Console.WriteLine(c); readonly string d = ""Hi!""; System.Console.WriteLine(d); volatile string e = ""Hi!""; System.Console.WriteLine(e); [System.Obsolete()] string f = ""Hi!""; System.Console.WriteLine(f); [System.Obsolete()] const string g = ""Hi!""; System.Console.WriteLine(g); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,12): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // new string a = "Hi!"; Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "a").WithLocation(2, 12), // (2,12): warning CS0109: The member '<invalid-global-code>.a' does not hide an accessible member. The new keyword is not required. // new string a = "Hi!"; Diagnostic(ErrorCode.WRN_NewNotRequired, "a").WithArguments("<invalid-global-code>.a").WithLocation(2, 12), // (3,26): error CS0103: The name 'a' does not exist in the current context // System.Console.WriteLine(a); Diagnostic(ErrorCode.ERR_NameNotInContext, "a").WithArguments("a").WithLocation(3, 26), // (4,15): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // public string b = "Hi!"; Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "b").WithLocation(4, 15), // (5,26): error CS0103: The name 'b' does not exist in the current context // System.Console.WriteLine(b); Diagnostic(ErrorCode.ERR_NameNotInContext, "b").WithArguments("b").WithLocation(5, 26), // (6,1): error CS0106: The modifier 'static' is not valid for this item // static string c = "Hi!"; Diagnostic(ErrorCode.ERR_BadMemberFlag, "static").WithArguments("static").WithLocation(6, 1), // (8,1): error CS0106: The modifier 'readonly' is not valid for this item // readonly string d = "Hi!"; Diagnostic(ErrorCode.ERR_BadMemberFlag, "readonly").WithArguments("readonly").WithLocation(8, 1), // (10,1): error CS0106: The modifier 'volatile' is not valid for this item // volatile string e = "Hi!"; Diagnostic(ErrorCode.ERR_BadMemberFlag, "volatile").WithArguments("volatile").WithLocation(10, 1), // (12,1): error CS7014: Attributes are not valid in this context. // [System.Obsolete()] Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[System.Obsolete()]").WithLocation(12, 1), // (15,1): error CS7014: Attributes are not valid in this context. // [System.Obsolete()] Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[System.Obsolete()]").WithLocation(15, 1) ); } [Fact] public void LocalDeclarationStatement_03() { var text = @" string a = ""1""; string a = ""2""; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,8): warning CS0219: The variable 'a' is assigned but its value is never used // string a = "1"; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "a").WithArguments("a").WithLocation(2, 8), // (3,8): error CS0128: A local variable or function named 'a' is already defined in this scope // string a = "2"; Diagnostic(ErrorCode.ERR_LocalDuplicate, "a").WithArguments("a").WithLocation(3, 8), // (3,8): warning CS0219: The variable 'a' is assigned but its value is never used // string a = "2"; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "a").WithArguments("a").WithLocation(3, 8) ); } [Fact] public void LocalDeclarationStatement_04() { var text = @" using System; using System.Threading.Tasks; var s = await local(); System.Console.WriteLine(s); async Task<string> local() { await Task.Factory.StartNew(() => 5); return ""Hi!""; } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void LocalDeclarationStatement_05() { var text = @" const string s = ""Hi!""; System.Console.WriteLine(s); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void LocalDeclarationStatement_06() { var text = @" a.ToString(); string a = ""2""; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS0841: Cannot use local variable 'a' before it is declared // a.ToString(); Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "a").WithArguments("a").WithLocation(2, 1) ); } [Fact] public void LocalDeclarationStatement_07() { var text1 = @" string x = ""1""; System.Console.Write(x); "; var text2 = @" int x = 1; System.Console.Write(x); "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS8802: Only one compilation unit can have top-level statements. // string x = "1"; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "string").WithLocation(2, 1), // (2,1): error CS8802: Only one compilation unit can have top-level statements. // int x = 1; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "int").WithLocation(2, 1) ); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var symbol1 = model1.GetDeclaredSymbol(tree1.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Single()); Assert.Equal("System.String x", symbol1.ToTestDisplayString()); Assert.Same(symbol1, model1.GetSymbolInfo(tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "x").Single()).Symbol); var tree2 = comp.SyntaxTrees[1]; var model2 = comp.GetSemanticModel(tree2); var symbol2 = model2.GetDeclaredSymbol(tree2.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Single()); Assert.Equal("System.Int32 x", symbol2.ToTestDisplayString()); Assert.Same(symbol2, model2.GetSymbolInfo(tree2.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "x").Single()).Symbol); } [Fact] public void LocalDeclarationStatement_08() { var text = @" int a = 0; int b = 0; int c = -100; ref int d = ref c; d = 300; d = ref local(true, ref a, ref b); d = 100; d = ref local(false, ref a, ref b); d = 200; System.Console.Write(a); System.Console.Write(' '); System.Console.Write(b); System.Console.Write(' '); System.Console.Write(c); ref int local(bool flag, ref int a, ref int b) { return ref flag ? ref a : ref b; } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "100 200 300", verify: Verification.Skipped); } [Fact] public void LocalDeclarationStatement_09() { var text = @" using var a = new MyDisposable(); System.Console.Write(1); class MyDisposable : System.IDisposable { public void Dispose() { System.Console.Write(2); } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "12", verify: Verification.Skipped); } [Fact] public void LocalDeclarationStatement_10() { string source = @" await using var x = new C(); System.Console.Write(""body ""); class C : System.IAsyncDisposable, System.IDisposable { public System.Threading.Tasks.ValueTask DisposeAsync() { System.Console.Write(""DisposeAsync""); return new System.Threading.Tasks.ValueTask(System.Threading.Tasks.Task.CompletedTask); } public void Dispose() { System.Console.Write(""IGNORED""); } } "; var comp = CreateCompilationWithTasksExtensions(new[] { source, IAsyncDisposableDefinition }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); CompileAndVerify(comp, expectedOutput: "body DisposeAsync"); } [Fact] public void LocalDeclarationStatement_11() { var text1 = @" string x = ""1""; System.Console.Write(x); int x = 1; System.Console.Write(x); "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (4,5): error CS0128: A local variable or function named 'x' is already defined in this scope // int x = 1; Diagnostic(ErrorCode.ERR_LocalDuplicate, "x").WithArguments("x").WithLocation(4, 5), // (4,5): warning CS0219: The variable 'x' is assigned but its value is never used // int x = 1; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "x").WithArguments("x").WithLocation(4, 5) ); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var symbol1 = model1.GetDeclaredSymbol(tree1.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().First()); Assert.Equal("System.String x", symbol1.ToTestDisplayString()); Assert.Same(symbol1, model1.GetSymbolInfo(tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "x").First()).Symbol); var symbol2 = model1.GetDeclaredSymbol(tree1.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Skip(1).Single()); Assert.Equal("System.Int32 x", symbol2.ToTestDisplayString()); Assert.Same(symbol1, model1.GetSymbolInfo(tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "x").Skip(1).Single()).Symbol); } [Fact] public void LocalDeclarationStatement_12() { var text = @" (int x, int y) = (1, 2); System.Console.WriteLine(x+y); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "3"); } [Fact] public void LocalDeclarationStatement_13() { var text = @" var (x, y) = (1, 2); System.Console.WriteLine(x+y); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "3"); } [Fact] public void LocalDeclarationStatement_14() { var text1 = @" string args = ""1""; System.Console.Write(args); "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,8): error CS0136: A local or parameter named 'args' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // string args = "1"; Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "args").WithArguments("args").WithLocation(2, 8) ); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var symbol1 = model1.GetDeclaredSymbol(tree1.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().First()); Assert.Equal("System.String args", symbol1.ToTestDisplayString()); Assert.Same(symbol1, model1.GetSymbolInfo(tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "args").Single()).Symbol); } [Fact] public void LocalDeclarationStatement_15() { var text1 = @" using System.Linq; string x = null; _ = from x in new object[0] select x; System.Console.Write(x); "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (4,10): error CS1931: The range variable 'x' conflicts with a previous declaration of 'x' // _ = from x in new object[0] select x; Diagnostic(ErrorCode.ERR_QueryRangeVariableOverrides, "x").WithArguments("x").WithLocation(4, 10) ); } [Fact] public void LocalDeclarationStatement_16() { var text = @" System.Console.WriteLine(); string await = ""Hi!""; System.Console.WriteLine(await); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (3,8): error CS4003: 'await' cannot be used as an identifier within an async method or lambda expression // string await = "Hi!"; Diagnostic(ErrorCode.ERR_BadAwaitAsIdentifier, "await").WithLocation(3, 8), // (3,8): warning CS0219: The variable 'await' is assigned but its value is never used // string await = "Hi!"; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "await").WithArguments("await").WithLocation(3, 8), // (4,31): error CS1525: Invalid expression term ')' // System.Console.WriteLine(await); Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(4, 31) ); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Threading.Tasks.Task", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnType.IsErrorType()); AssertEntryPointParameter(entryPoint); } [Fact] public void LocalDeclarationStatement_17() { var text = @" string async = ""Hi!""; System.Console.WriteLine(async); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/80313")] public void LocalDeclarationStatement_18() { var text = @" int c = -100; ref int d = ref c; System.Console.Write(d); await System.Threading.Tasks.Task.Yield(); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (3,9): error CS8773: Feature 'ref and unsafe in async and iterator methods' is not available in C# 9.0. Please use language version 13.0 or greater. // ref int d = ref c; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion9, "d").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(3, 9) ); comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular12); comp.VerifyDiagnostics( // (3,9): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater. // ref int d = ref c; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "d").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(3, 9) ); comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular13); comp.VerifyEmitDiagnostics(); comp = CreateCompilation(text, options: TestOptions.DebugExe); comp.VerifyEmitDiagnostics(); comp = CreateRuntimeAsyncCompilation(text); var verifier = CompileAndVerify(comp, expectedOutput: RuntimeAsyncTestHelpers.ExpectedOutput("-100"), verify: Verification.Fails with { ILVerifyMessage = "[<Main>$]: Return value missing on the stack. { Offset = 0x2f }" }, sourceSymbolValidator: validator); verifier.VerifyIL("<top-level-statements-entry-point>", """ { // Code size 48 (0x30) .maxstack 1 .locals init (int V_0, //c System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter V_1, System.Runtime.CompilerServices.YieldAwaitable V_2) IL_0000: ldc.i4.s -100 IL_0002: stloc.0 IL_0003: ldloca.s V_0 IL_0005: ldind.i4 IL_0006: call "void System.Console.Write(int)" IL_000b: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" IL_0010: stloc.2 IL_0011: ldloca.s V_2 IL_0013: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" IL_0018: stloc.1 IL_0019: ldloca.s V_1 IL_001b: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" IL_0020: brtrue.s IL_0028 IL_0022: ldloc.1 IL_0023: call "void System.Runtime.CompilerServices.AsyncHelpers.UnsafeAwaitAwaiter<System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter>(System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter)" IL_0028: ldloca.s V_1 IL_002a: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" IL_002f: ret } """); static void validator(ModuleSymbol module) { var program = module.GlobalNamespace.GetTypeMember("Program"); Assert.NotNull(program); var main = program.GetMethod("<Main>$"); Assert.NotNull(main); Assert.Equal(MethodImplAttributes.Async, main.ImplementationAttributes & MethodImplAttributes.Async); } } [Fact] public void UsingStatement_01() { string source = @" await using (var x = new C()) { System.Console.Write(""body ""); } class C : System.IAsyncDisposable, System.IDisposable { public System.Threading.Tasks.ValueTask DisposeAsync() { System.Console.Write(""DisposeAsync""); return new System.Threading.Tasks.ValueTask(System.Threading.Tasks.Task.CompletedTask); } public void Dispose() { System.Console.Write(""IGNORED""); } } "; var comp = CreateCompilationWithTasksExtensions(new[] { source, IAsyncDisposableDefinition }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); CompileAndVerify(comp, expectedOutput: "body DisposeAsync"); } [Fact] public void UsingStatement_02() { string source = @" await using (new C()) { System.Console.Write(""body ""); } class C : System.IAsyncDisposable, System.IDisposable { public System.Threading.Tasks.ValueTask DisposeAsync() { System.Console.Write(""DisposeAsync""); return new System.Threading.Tasks.ValueTask(System.Threading.Tasks.Task.CompletedTask); } public void Dispose() { System.Console.Write(""IGNORED""); } } "; var comp = CreateCompilationWithTasksExtensions(new[] { source, IAsyncDisposableDefinition }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); CompileAndVerify(comp, expectedOutput: "body DisposeAsync"); } [Fact] public void UsingStatement_03() { string source = @" using (new C()) { System.Console.Write(""body ""); } class C : System.IDisposable { public void Dispose() { System.Console.Write(""Dispose""); } } "; var comp = CreateCompilationWithTasksExtensions(new[] { source, IAsyncDisposableDefinition }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); CompileAndVerify(comp, expectedOutput: "body Dispose"); } [Fact] public void ForeachStatement_01() { string source = @" using System.Threading.Tasks; await foreach (var i in new C()) { } System.Console.Write(""Done""); class C { public Enumerator GetAsyncEnumerator() { return new Enumerator(); } public sealed class Enumerator { public async Task<bool> MoveNextAsync() { System.Console.Write(""MoveNextAsync ""); await Task.Yield(); return false; } public int Current { get => throw null; } public async Task DisposeAsync() { System.Console.Write(""DisposeAsync ""); await Task.Yield(); } } } "; var comp = CreateCompilationWithTasksExtensions(new[] { source, s_IAsyncEnumerable }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); CompileAndVerify(comp, expectedOutput: "MoveNextAsync DisposeAsync Done"); } [Fact] public void ForeachStatement_02() { var text = @" int i = 0; foreach (var j in new [] {2, 3}) { i += j; } System.Console.WriteLine(i); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "5"); } [Fact] public void ForeachStatement_03() { var text = @" int i = 0; foreach (var (j, k) in new [] {(2,200), (3,300)}) { i += j; } System.Console.WriteLine(i); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "5"); } [Fact] public void LocalUsedBeforeDeclaration_01() { var text1 = @" const string x = y; System.Console.Write(x); "; var text2 = @" const string y = x; System.Console.Write(y); "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS8802: Only one compilation unit can have top-level statements. // const string x = y; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "const").WithLocation(2, 1), // (2,1): error CS8802: Only one compilation unit can have top-level statements. // const string y = x; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "const").WithLocation(2, 1), // (2,18): error CS0103: The name 'y' does not exist in the current context // const string x = y; Diagnostic(ErrorCode.ERR_NameNotInContext, "y").WithArguments("y").WithLocation(2, 18), // (2,18): error CS0103: The name 'x' does not exist in the current context // const string y = x; Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(2, 18) ); comp = CreateCompilation(new[] { "System.Console.WriteLine();", text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,1): error CS8802: Only one compilation unit can have top-level statements. // System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "System").WithLocation(1, 1), // (2,1): error CS8802: Only one compilation unit can have top-level statements. // const string x = y; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "const").WithLocation(2, 1), // (2,1): error CS8802: Only one compilation unit can have top-level statements. // const string y = x; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "const").WithLocation(2, 1), // (2,18): error CS0103: The name 'y' does not exist in the current context // const string x = y; Diagnostic(ErrorCode.ERR_NameNotInContext, "y").WithArguments("y").WithLocation(2, 18), // (2,18): error CS0103: The name 'x' does not exist in the current context // const string y = x; Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(2, 18) ); } [Fact] public void LocalUsedBeforeDeclaration_02() { var text1 = @" var x = y; System.Console.Write(x); "; var text2 = @" var y = x; System.Console.Write(y); "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS8802: Only one compilation unit can have top-level statements. // var x = y; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "var").WithLocation(2, 1), // (2,1): error CS8802: Only one compilation unit can have top-level statements. // var y = x; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "var").WithLocation(2, 1), // (2,9): error CS0103: The name 'y' does not exist in the current context // var x = y; Diagnostic(ErrorCode.ERR_NameNotInContext, "y").WithArguments("y").WithLocation(2, 9), // (2,9): error CS0103: The name 'x' does not exist in the current context // var y = x; Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(2, 9) ); comp = CreateCompilation(new[] { "System.Console.WriteLine();", text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,1): error CS8802: Only one compilation unit can have top-level statements. // System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "System").WithLocation(1, 1), // (2,1): error CS8802: Only one compilation unit can have top-level statements. // var x = y; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "var").WithLocation(2, 1), // (2,1): error CS8802: Only one compilation unit can have top-level statements. // var y = x; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "var").WithLocation(2, 1), // (2,9): error CS0103: The name 'y' does not exist in the current context // var x = y; Diagnostic(ErrorCode.ERR_NameNotInContext, "y").WithArguments("y").WithLocation(2, 9), // (2,9): error CS0103: The name 'x' does not exist in the current context // var y = x; Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(2, 9) ); } [Fact] public void LocalUsedBeforeDeclaration_03() { var text1 = @" string x = ""x""; System.Console.Write(x); "; var text2 = @" class C1 { void Test() { System.Console.Write(x); } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,30): error CS8801: Cannot use local variable or local function 'x' declared in a top-level statement in this context. // System.Console.Write(x); Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "x").WithArguments("x").WithLocation(6, 30) ); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree2 = comp.SyntaxTrees[1]; var model2 = comp.GetSemanticModel(tree2); var nameRef = tree2.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "x").Single(); var symbol2 = model2.GetSymbolInfo(nameRef).Symbol; Assert.Equal("System.String x", symbol2.ToTestDisplayString()); Assert.Equal("System.String", model2.GetTypeInfo(nameRef).Type.ToTestDisplayString()); Assert.Null(model2.GetOperation(tree2.GetRoot())); comp = CreateCompilation(new[] { text2, text1 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,30): error CS8801: Cannot use local variable or local function 'x' declared in a top-level statement in this context. // System.Console.Write(x); Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "x").WithArguments("x").WithLocation(6, 30) ); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel tree2 = comp.SyntaxTrees[0]; model2 = comp.GetSemanticModel(tree2); nameRef = tree2.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "x").Single(); symbol2 = model2.GetSymbolInfo(nameRef).Symbol; Assert.Equal("System.String x", symbol2.ToTestDisplayString()); Assert.Equal("System.String", model2.GetTypeInfo(nameRef).Type.ToTestDisplayString()); Assert.Null(model2.GetOperation(tree2.GetRoot())); } [Fact] public void LocalUsedBeforeDeclaration_04() { var text1 = @" string x = ""x""; local(); "; var text2 = @" void local() { System.Console.Write(x); } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS8802: Only one compilation unit can have top-level statements. // string x = "x"; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "string").WithLocation(2, 1), // (2,1): error CS8802: Only one compilation unit can have top-level statements. // void local() Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "void").WithLocation(2, 1), // (2,6): warning CS8321: The local function 'local' is declared but never used // void local() Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(2, 6), // (2,8): warning CS0219: The variable 'x' is assigned but its value is never used // string x = "x"; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "x").WithArguments("x").WithLocation(2, 8), // (3,1): error CS0103: The name 'local' does not exist in the current context // local(); Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(3, 1), // (4,26): error CS0103: The name 'x' does not exist in the current context // System.Console.Write(x); Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(4, 26) ); comp = CreateCompilation(new[] { text2, text1 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS8802: Only one compilation unit can have top-level statements. // void local() Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "void").WithLocation(2, 1), // (2,1): error CS8802: Only one compilation unit can have top-level statements. // string x = "x"; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "string").WithLocation(2, 1), // (2,6): warning CS8321: The local function 'local' is declared but never used // void local() Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(2, 6), // (2,8): warning CS0219: The variable 'x' is assigned but its value is never used // string x = "x"; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "x").WithArguments("x").WithLocation(2, 8), // (3,1): error CS0103: The name 'local' does not exist in the current context // local(); Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(3, 1), // (4,26): error CS0103: The name 'x' does not exist in the current context // System.Console.Write(x); Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(4, 26) ); } [Fact] public void FlowAnalysis_01() { var text = @" #nullable enable string a = ""1""; string? b; System.Console.WriteLine(b); string? c = null; c.ToString(); d: System.Console.WriteLine(); string e() => ""1""; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (3,8): warning CS0219: The variable 'a' is assigned but its value is never used // string a = "1"; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "a").WithArguments("a").WithLocation(3, 8), // (5,26): error CS0165: Use of unassigned local variable 'b' // System.Console.WriteLine(b); Diagnostic(ErrorCode.ERR_UseDefViolation, "b").WithArguments("b").WithLocation(5, 26), // (7,1): warning CS8602: Dereference of a possibly null reference. // c.ToString(); Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c").WithLocation(7, 1), // (8,1): warning CS0164: This label has not been referenced // d: System.Console.WriteLine(); Diagnostic(ErrorCode.WRN_UnreferencedLabel, "d").WithLocation(8, 1), // (9,8): warning CS8321: The local function 'e' is declared but never used // string e() => "1"; Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "e").WithArguments("e").WithLocation(9, 8) ); var tree = comp.SyntaxTrees.Single(); var reference = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "c").Single(); var model1 = comp.GetSemanticModel(tree); Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, model1.GetTypeInfo(reference).Nullability.FlowState); var model2 = comp.GetSemanticModel(tree); Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, model1.GetTypeInfo(reference).Nullability.FlowState); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/80487")] public void FlowAnalysis_02() { var text = @" System.Console.WriteLine(); if (args.Length == 0) { return 10; } "; CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions).VerifyDiagnostics( // (2,1): error CS0161: '<top-level-statements-entry-point>': not all code paths return a value // System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_ReturnExpected, "System.Console.WriteLine();").WithArguments("<top-level-statements-entry-point>").WithLocation(2, 1)); } [Fact] public void NullableRewrite_01() { var text1 = @" void local1() { System.Console.WriteLine(""local1 - "" + s); } "; var text2 = @" using System; string s = ""Hello world!""; foreach (var c in s) { Console.Write(c); } goto label1; label1: Console.WriteLine(); local1(); local2(); "; var text3 = @" void local2() { System.Console.WriteLine(""local2 - "" + s); } "; var comp = CreateCompilation(new[] { text1, text2, text3 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var tree = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree); foreach (var id in tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>()) { _ = model1.GetTypeInfo(id).Nullability; } var model2 = comp.GetSemanticModel(tree); foreach (var id in tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>()) { _ = model2.GetTypeInfo(id).Nullability; } } [Fact] public void Scope_01() { var text = @" using alias1 = Test; string Test = ""1""; System.Console.WriteLine(Test); class Test {} class Derived : Test { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test); // 1 Test.ToString(); // 2 Test.EndsWith(null); // 3 _ = nameof(Test); // 4 } } namespace N1 { using alias2 = Test; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test); // 5 Test.ToString(); // 6 Test.EndsWith(null); // 7 _ = nameof(Test); // 8 } } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (16,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 34), // (17,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(17, 9), // (18,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 9), // (19,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(19, 20), // (34,38): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(34, 38), // (35,13): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.ToString(); // 6 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(35, 13), // (36,13): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.EndsWith(null); // 7 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(36, 13), // (37,24): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 8 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(37, 24) ); var getHashCode = ((Compilation)comp).GetMember("System.Object." + nameof(GetHashCode)); var testType = ((Compilation)comp).GetTypeByMetadataName("Test"); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var localDecl = tree1.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().First(); var declSymbol = model1.GetDeclaredSymbol(localDecl); Assert.Equal("System.String Test", declSymbol.ToTestDisplayString()); var names = model1.LookupNames(localDecl.SpanStart); Assert.Contains(getHashCode.Name, names); var symbols = model1.LookupSymbols(localDecl.SpanStart); Assert.Contains(getHashCode, symbols); Assert.Same(getHashCode, model1.LookupSymbols(localDecl.SpanStart, name: getHashCode.Name).Single()); Assert.Contains("Test", names); Assert.DoesNotContain(testType, symbols); Assert.Contains(declSymbol, symbols); Assert.Same(declSymbol, model1.LookupSymbols(localDecl.SpanStart, name: "Test").Single()); symbols = model1.LookupNamespacesAndTypes(localDecl.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model1.LookupNamespacesAndTypes(localDecl.SpanStart, name: "Test").Single()); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var nameRefs = tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "Test").ToArray(); var nameRef = nameRefs[1]; Assert.Equal("System.Console.WriteLine(Test)", nameRef.Parent.Parent.Parent.ToString()); Assert.Same(declSymbol, model1.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model1, nameRef); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); nameRef = nameRefs[0]; Assert.Equal("using alias1 = Test;", nameRef.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); names = model.LookupNames(nameRef.SpanStart); Assert.DoesNotContain(getHashCode.Name, names); Assert.Contains("Test", names); symbols = model.LookupSymbols(nameRef.SpanStart); Assert.DoesNotContain(getHashCode, symbols); Assert.Empty(model.LookupSymbols(nameRef.SpanStart, name: getHashCode.Name)); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model.LookupSymbols(nameRef.SpanStart, name: "Test").Single()); nameRef = nameRefs[2]; Assert.Equal(": Test", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); Assert.DoesNotContain(getHashCode.Name, model.LookupNames(nameRef.SpanStart)); verifyModel(declSymbol, model, nameRef); nameRef = nameRefs[4]; Assert.Equal("System.Console.WriteLine(Test)", nameRef.Parent.Parent.Parent.ToString()); Assert.Same(declSymbol, model.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model, nameRef); nameRef = nameRefs[8]; Assert.Equal("using alias2 = Test;", nameRef.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model, nameRef); nameRef = nameRefs[9]; Assert.Equal(": Test", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); Assert.DoesNotContain(getHashCode.Name, model.LookupNames(nameRef.SpanStart)); verifyModel(declSymbol, model, nameRef); nameRef = nameRefs[11]; Assert.Equal("System.Console.WriteLine(Test)", nameRef.Parent.Parent.Parent.ToString()); Assert.Same(declSymbol, model.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model, nameRef); void verifyModel(ISymbol declSymbol, SemanticModel model, IdentifierNameSyntax nameRef) { var names = model.LookupNames(nameRef.SpanStart); Assert.Contains("Test", names); var symbols = model.LookupSymbols(nameRef.SpanStart); Assert.DoesNotContain(testType, symbols); Assert.Contains(declSymbol, symbols); Assert.Same(declSymbol, model.LookupSymbols(nameRef.SpanStart, name: "Test").Single()); symbols = model.LookupNamespacesAndTypes(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model.LookupNamespacesAndTypes(nameRef.SpanStart, name: "Test").Single()); } } [Fact] public void Scope_02() { var text1 = @" string Test = ""1""; System.Console.WriteLine(Test); "; var text2 = @" using alias1 = Test; class Test {} class Derived : Test { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test); // 1 Test.ToString(); // 2 Test.EndsWith(null); // 3 _ = nameof(Test); // 4 } } namespace N1 { using alias2 = Test; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test); // 5 Test.ToString(); // 6 Test.EndsWith(null); // 7 _ = nameof(Test); // 8 } } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (13,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(13, 34), // (14,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(14, 9), // (15,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(15, 9), // (16,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 20), // (31,38): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(31, 38), // (32,13): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.ToString(); // 6 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(32, 13), // (33,13): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.EndsWith(null); // 7 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(33, 13), // (34,24): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 8 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(34, 24) ); var getHashCode = ((Compilation)comp).GetMember("System.Object." + nameof(GetHashCode)); var testType = ((Compilation)comp).GetTypeByMetadataName("Test"); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var localDecl = tree1.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Single(); var declSymbol = model1.GetDeclaredSymbol(localDecl); Assert.Equal("System.String Test", declSymbol.ToTestDisplayString()); var names = model1.LookupNames(localDecl.SpanStart); Assert.Contains(getHashCode.Name, names); var symbols = model1.LookupSymbols(localDecl.SpanStart); Assert.Contains(getHashCode, symbols); Assert.Same(getHashCode, model1.LookupSymbols(localDecl.SpanStart, name: getHashCode.Name).Single()); Assert.Contains("Test", names); Assert.DoesNotContain(testType, symbols); Assert.Contains(declSymbol, symbols); Assert.Same(declSymbol, model1.LookupSymbols(localDecl.SpanStart, name: "Test").Single()); symbols = model1.LookupNamespacesAndTypes(localDecl.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model1.LookupNamespacesAndTypes(localDecl.SpanStart, name: "Test").Single()); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree2 = comp.SyntaxTrees[1]; var model2 = comp.GetSemanticModel(tree2); Assert.Null(model2.GetDeclaredSymbol((CompilationUnitSyntax)tree2.GetRoot())); var nameRefs = tree2.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "Test").ToArray(); var nameRef = nameRefs[0]; Assert.Equal("using alias1 = Test;", nameRef.Parent.ToString()); Assert.Same(testType, model2.GetSymbolInfo(nameRef).Symbol); names = model2.LookupNames(nameRef.SpanStart); Assert.DoesNotContain(getHashCode.Name, names); Assert.Contains("Test", names); symbols = model2.LookupSymbols(nameRef.SpanStart); Assert.DoesNotContain(getHashCode, symbols); Assert.Empty(model2.LookupSymbols(nameRef.SpanStart, name: getHashCode.Name)); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model2.LookupSymbols(nameRef.SpanStart, name: "Test").Single()); nameRef = nameRefs[1]; Assert.Equal(": Test", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model2.GetSymbolInfo(nameRef).Symbol); Assert.DoesNotContain(getHashCode.Name, model2.LookupNames(nameRef.SpanStart)); verifyModel(declSymbol, model2, nameRef); nameRef = nameRefs[3]; Assert.Equal("System.Console.WriteLine(Test)", nameRef.Parent.Parent.Parent.ToString()); Assert.Same(declSymbol, model2.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model2, nameRef); nameRef = nameRefs[7]; Assert.Equal("using alias2 = Test;", nameRef.Parent.ToString()); Assert.Same(testType, model2.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model2, nameRef); nameRef = nameRefs[8]; Assert.Equal(": Test", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model2.GetSymbolInfo(nameRef).Symbol); Assert.DoesNotContain(getHashCode.Name, model2.LookupNames(nameRef.SpanStart)); verifyModel(declSymbol, model2, nameRef); nameRef = nameRefs[10]; Assert.Equal("System.Console.WriteLine(Test)", nameRef.Parent.Parent.Parent.ToString()); Assert.Same(declSymbol, model2.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model2, nameRef); void verifyModel(ISymbol declSymbol, SemanticModel model2, IdentifierNameSyntax nameRef) { var names = model2.LookupNames(nameRef.SpanStart); Assert.Contains("Test", names); var symbols = model2.LookupSymbols(nameRef.SpanStart); Assert.DoesNotContain(testType, symbols); Assert.Contains(declSymbol, symbols); Assert.Same(declSymbol, model2.LookupSymbols(nameRef.SpanStart, name: "Test").Single()); symbols = model2.LookupNamespacesAndTypes(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model2.LookupNamespacesAndTypes(nameRef.SpanStart, name: "Test").Single()); } } [Fact] public void Scope_03() { var text1 = @" string Test = ""1""; System.Console.WriteLine(Test); "; var text2 = @" class Test {} class Derived : Test { void M() { int Test = 0; System.Console.WriteLine(Test++); } } namespace N1 { class Derived : Test { void M() { int Test = 1; System.Console.WriteLine(Test++); } } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); comp = CreateCompilation(text1 + text2, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); Assert.Throws<System.ArgumentException>(() => CreateCompilation(new[] { Parse(text1, filename: "text1", DefaultParseOptions), Parse(text1, filename: "text2", TestOptions.Regular6) }, options: TestOptions.DebugExe)); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7); comp.VerifyDiagnostics( // (2,1): error CS8107: Feature 'top-level statements' is not available in C# 7.0. Please use language version 9.0 or greater. // string Test = "1"; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, @"string Test = ""1"";").WithArguments("top-level statements", "9.0").WithLocation(2, 1) ); } [Fact] public void Scope_04() { var text = @" using alias1 = Test; string Test() => ""1""; System.Console.WriteLine(Test()); class Test {} class Derived : Test { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test()); // 1 Test().ToString(); // 2 Test().EndsWith(null); // 3 System.Func<string> d = Test; // 4 d(); _ = nameof(Test); // 5 } } namespace N1 { using alias2 = Test; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test()); // 6 Test().ToString(); // 7 Test().EndsWith(null); // 8 var d = new System.Func<string>(Test); // 9 d(); _ = nameof(Test); // 10 } } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (16,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 34), // (17,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(17, 9), // (18,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 9), // (19,33): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Func<string> d = Test; // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(19, 33), // (21,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(21, 20), // (36,38): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 6 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(36, 38), // (37,13): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 7 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(37, 13), // (38,13): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 8 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(38, 13), // (39,45): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // var d = new System.Func<string>(Test); // 9 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(39, 45), // (41,24): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 10 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(41, 24) ); var testType = ((Compilation)comp).GetTypeByMetadataName("Test"); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var localDecl = tree1.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().Single(); var declSymbol = model1.GetDeclaredSymbol(localDecl); Assert.Equal("System.String Test()", declSymbol.ToTestDisplayString()); var names = model1.LookupNames(localDecl.SpanStart); var symbols = model1.LookupSymbols(localDecl.SpanStart); Assert.Contains("Test", names); Assert.DoesNotContain(testType, symbols); Assert.Contains(declSymbol, symbols); Assert.Same(declSymbol, model1.LookupSymbols(localDecl.SpanStart, name: "Test").Single()); symbols = model1.LookupNamespacesAndTypes(localDecl.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model1.LookupNamespacesAndTypes(localDecl.SpanStart, name: "Test").Single()); var nameRefs = tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "Test").ToArray(); var nameRef = nameRefs[0]; Assert.Equal("using alias1 = Test;", nameRef.Parent.ToString()); Assert.Same(testType, model1.GetSymbolInfo(nameRef).Symbol); names = model1.LookupNames(nameRef.SpanStart); Assert.Contains("Test", names); symbols = model1.LookupSymbols(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model1.LookupSymbols(nameRef.SpanStart, name: "Test").Single()); nameRef = nameRefs[2]; Assert.Equal(": Test", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model1.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model1, nameRef); nameRef = nameRefs[4]; Assert.Equal("System.Console.WriteLine(Test())", nameRef.Parent.Parent.Parent.Parent.ToString()); Assert.Same(declSymbol, model1.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model1, nameRef); nameRef = nameRefs[9]; Assert.Equal("using alias2 = Test;", nameRef.Parent.ToString()); Assert.Same(testType, model1.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model1, nameRef); nameRef = nameRefs[10]; Assert.Equal(": Test", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model1.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model1, nameRef); nameRef = nameRefs[12]; Assert.Equal("System.Console.WriteLine(Test())", nameRef.Parent.Parent.Parent.Parent.ToString()); Assert.Same(declSymbol, model1.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model1, nameRef); void verifyModel(ISymbol declSymbol, SemanticModel model2, IdentifierNameSyntax nameRef) { var names = model2.LookupNames(nameRef.SpanStart); Assert.Contains("Test", names); var symbols = model2.LookupSymbols(nameRef.SpanStart); Assert.DoesNotContain(testType, symbols); Assert.Contains(declSymbol, symbols); Assert.Same(declSymbol, model2.LookupSymbols(nameRef.SpanStart, name: "Test").Single()); symbols = model2.LookupNamespacesAndTypes(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model2.LookupNamespacesAndTypes(nameRef.SpanStart, name: "Test").Single()); } } [Fact] public void Scope_05() { var text1 = @" string Test() => ""1""; System.Console.WriteLine(Test()); "; var text2 = @" using alias1 = Test; class Test {} class Derived : Test { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test()); // 1 Test().ToString(); // 2 Test().EndsWith(null); // 3 System.Func<string> d = Test; // 4 d(); _ = nameof(Test); // 5 } } namespace N1 { using alias2 = Test; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test()); // 6 Test().ToString(); // 7 Test().EndsWith(null); // 8 var d = new System.Func<string>(Test); // 9 d(); _ = nameof(Test); // 10 } } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (13,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(13, 34), // (14,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(14, 9), // (15,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(15, 9), // (16,33): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Func<string> d = Test; // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 33), // (18,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 20), // (33,38): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 6 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(33, 38), // (34,13): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 7 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(34, 13), // (35,13): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 8 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(35, 13), // (36,45): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // var d = new System.Func<string>(Test); // 9 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(36, 45), // (38,24): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 10 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(38, 24) ); var testType = ((Compilation)comp).GetTypeByMetadataName("Test"); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var localDecl = tree1.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().Single(); var declSymbol = model1.GetDeclaredSymbol(localDecl); Assert.Equal("System.String Test()", declSymbol.ToTestDisplayString()); var names = model1.LookupNames(localDecl.SpanStart); var symbols = model1.LookupSymbols(localDecl.SpanStart); Assert.Contains("Test", names); Assert.DoesNotContain(testType, symbols); Assert.Contains(declSymbol, symbols); Assert.Same(declSymbol, model1.LookupSymbols(localDecl.SpanStart, name: "Test").Single()); symbols = model1.LookupNamespacesAndTypes(localDecl.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model1.LookupNamespacesAndTypes(localDecl.SpanStart, name: "Test").Single()); var tree2 = comp.SyntaxTrees[1]; var model2 = comp.GetSemanticModel(tree2); var nameRefs = tree2.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "Test").ToArray(); var nameRef = nameRefs[0]; Assert.Equal("using alias1 = Test;", nameRef.Parent.ToString()); Assert.Same(testType, model2.GetSymbolInfo(nameRef).Symbol); names = model2.LookupNames(nameRef.SpanStart); Assert.Contains("Test", names); symbols = model2.LookupSymbols(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model2.LookupSymbols(nameRef.SpanStart, name: "Test").Single()); nameRef = nameRefs[1]; Assert.Equal(": Test", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model2.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model2, nameRef); nameRef = nameRefs[3]; Assert.Equal("System.Console.WriteLine(Test())", nameRef.Parent.Parent.Parent.Parent.ToString()); Assert.Same(declSymbol, model2.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model2, nameRef); nameRef = nameRefs[8]; Assert.Equal("using alias2 = Test;", nameRef.Parent.ToString()); Assert.Same(testType, model2.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model2, nameRef); nameRef = nameRefs[9]; Assert.Equal(": Test", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model2.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model2, nameRef); nameRef = nameRefs[11]; Assert.Equal("System.Console.WriteLine(Test())", nameRef.Parent.Parent.Parent.Parent.ToString()); Assert.Same(declSymbol, model2.GetSymbolInfo(nameRef).Symbol); verifyModel(declSymbol, model2, nameRef); void verifyModel(ISymbol declSymbol, SemanticModel model2, IdentifierNameSyntax nameRef) { var names = model2.LookupNames(nameRef.SpanStart); Assert.Contains("Test", names); var symbols = model2.LookupSymbols(nameRef.SpanStart); Assert.DoesNotContain(testType, symbols); Assert.Contains(declSymbol, symbols); Assert.Same(declSymbol, model2.LookupSymbols(nameRef.SpanStart, name: "Test").Single()); symbols = model2.LookupNamespacesAndTypes(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model2.LookupNamespacesAndTypes(nameRef.SpanStart, name: "Test").Single()); } } [Fact] public void Scope_06() { var text1 = @" string Test() => ""1""; System.Console.WriteLine(Test()); "; var text2 = @" class Test {} class Derived : Test { void M() { int Test() => 1; int x = Test() + 1; System.Console.WriteLine(x); } } namespace N1 { class Derived : Test { void M() { int Test() => 1; int x = Test() + 1; System.Console.WriteLine(x); } } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); comp = CreateCompilation(text1 + text2, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7); comp.VerifyDiagnostics( // (2,1): error CS8107: Feature 'top-level statements' is not available in C# 7.0. Please use language version 9.0 or greater. // string Test() => "1"; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, @"string Test() => ""1"";").WithArguments("top-level statements", "9.0").WithLocation(2, 1) ); } [Fact] public void Scope_07() { var text = @" using alias1 = Test; goto Test; Test: System.Console.WriteLine(""1""); class Test {} class Derived : Test { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); goto Test; // 1 } } namespace N1 { using alias2 = Test; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); goto Test; // 2 } } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (15,14): error CS0159: No such label 'Test' within the scope of the goto statement // goto Test; // 1 Diagnostic(ErrorCode.ERR_LabelNotFound, "Test").WithArguments("Test").WithLocation(15, 14), // (30,18): error CS0159: No such label 'Test' within the scope of the goto statement // goto Test; // 2 Diagnostic(ErrorCode.ERR_LabelNotFound, "Test").WithArguments("Test").WithLocation(30, 18) ); var testType = ((Compilation)comp).GetTypeByMetadataName("Test"); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var labelDecl = tree1.GetRoot().DescendantNodes().OfType<LabeledStatementSyntax>().Single(); var declSymbol = model1.GetDeclaredSymbol(labelDecl); Assert.Equal("Test", declSymbol.ToTestDisplayString()); Assert.Equal(SymbolKind.Label, declSymbol.Kind); var names = model1.LookupNames(labelDecl.SpanStart); var symbols = model1.LookupSymbols(labelDecl.SpanStart); Assert.Contains("Test", names); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model1.LookupSymbols(labelDecl.SpanStart, name: "Test").Single()); symbols = model1.LookupNamespacesAndTypes(labelDecl.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model1.LookupNamespacesAndTypes(labelDecl.SpanStart, name: "Test").Single()); Assert.Same(declSymbol, model1.LookupLabels(labelDecl.SpanStart).Single()); Assert.Same(declSymbol, model1.LookupLabels(labelDecl.SpanStart, name: "Test").Single()); var nameRefs = tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "Test").ToArray(); var nameRef = nameRefs[0]; Assert.Equal("using alias1 = Test;", nameRef.Parent.ToString()); Assert.Same(testType, model1.GetSymbolInfo(nameRef).Symbol); names = model1.LookupNames(nameRef.SpanStart); Assert.Contains("Test", names); symbols = model1.LookupSymbols(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model1.LookupSymbols(nameRef.SpanStart, name: "Test").Single()); Assert.Empty(model1.LookupLabels(nameRef.SpanStart)); Assert.Empty(model1.LookupLabels(nameRef.SpanStart, name: "Test")); nameRef = nameRefs[1]; Assert.Equal("goto Test;", nameRef.Parent.ToString()); Assert.Same(declSymbol, model1.GetSymbolInfo(nameRef).Symbol); names = model1.LookupNames(nameRef.SpanStart); Assert.Contains("Test", names); symbols = model1.LookupSymbols(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model1.LookupSymbols(nameRef.SpanStart, name: "Test").Single()); Assert.Same(declSymbol, model1.LookupLabels(nameRef.SpanStart).Single()); Assert.Same(declSymbol, model1.LookupLabels(nameRef.SpanStart, name: "Test").Single()); nameRef = nameRefs[2]; Assert.Equal(": Test", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model1.GetSymbolInfo(nameRef).Symbol); verifyModel(model1, nameRef); nameRef = nameRefs[4]; Assert.Equal("goto Test;", nameRef.Parent.ToString()); Assert.Null(model1.GetSymbolInfo(nameRef).Symbol); verifyModel(model1, nameRef); nameRef = nameRefs[5]; Assert.Equal("using alias2 = Test;", nameRef.Parent.ToString()); Assert.Same(testType, model1.GetSymbolInfo(nameRef).Symbol); verifyModel(model1, nameRef); nameRef = nameRefs[6]; Assert.Equal(": Test", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model1.GetSymbolInfo(nameRef).Symbol); verifyModel(model1, nameRef); nameRef = nameRefs[8]; Assert.Null(model1.GetSymbolInfo(nameRef).Symbol); Assert.Equal("goto Test;", nameRef.Parent.ToString()); verifyModel(model1, nameRef); void verifyModel(SemanticModel model2, IdentifierNameSyntax nameRef) { var names = model2.LookupNames(nameRef.SpanStart); Assert.Contains("Test", names); var symbols = model2.LookupSymbols(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model2.LookupSymbols(nameRef.SpanStart, name: "Test").Single()); symbols = model2.LookupNamespacesAndTypes(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model2.LookupNamespacesAndTypes(nameRef.SpanStart, name: "Test").Single()); Assert.Empty(model2.LookupLabels(nameRef.SpanStart)); Assert.Empty(model2.LookupLabels(nameRef.SpanStart, name: "Test")); } } [Fact] public void Scope_08() { var text = @" goto Test; Test: System.Console.WriteLine(""1""); class Test {} class Derived : Test { void M() { goto Test; Test: System.Console.WriteLine(); } } namespace N1 { class Derived : Test { void M() { goto Test; Test: System.Console.WriteLine(); } } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); } [Fact] public void Scope_09() { var text = @" string Test = ""1""; System.Console.WriteLine(Test); new void M() { int Test = 0; System.Console.WriteLine(Test++); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (5,10): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // new void M() Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "M").WithLocation(5, 10), // (5,10): warning CS0109: The member '<invalid-global-code>.M()' does not hide an accessible member. The new keyword is not required. // new void M() Diagnostic(ErrorCode.WRN_NewNotRequired, "M").WithArguments("<invalid-global-code>.M()").WithLocation(5, 10) ); } [Fact] public void Scope_10() { var text = @" string Test = ""1""; System.Console.WriteLine(Test); new int F = C1.GetInt(out var Test); class C1 { public static int GetInt(out int v) { v = 1; return v; } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (5,9): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // new int F = C1.GetInt(out var Test); Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "F").WithLocation(5, 9), // (5,9): warning CS0109: The member '<invalid-global-code>.F' does not hide an accessible member. The new keyword is not required. // new int F = C1.GetInt(out var Test); Diagnostic(ErrorCode.WRN_NewNotRequired, "F").WithArguments("<invalid-global-code>.F").WithLocation(5, 9) ); } [Fact] public void Scope_11() { var text = @" goto Test; Test: System.Console.WriteLine(); new void M() { goto Test; Test: System.Console.WriteLine(); }"; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (5,10): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // new void M() Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "M").WithLocation(5, 10), // (5,10): warning CS0109: The member '<invalid-global-code>.M()' does not hide an accessible member. The new keyword is not required. // new void M() Diagnostic(ErrorCode.WRN_NewNotRequired, "M").WithArguments("<invalid-global-code>.M()").WithLocation(5, 10) ); } [Fact] public void Scope_12() { var text = @" using alias1 = Test; string Test() => ""1""; System.Console.WriteLine(Test()); class Test {} struct Derived { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test()); // 1 Test().ToString(); // 2 Test().EndsWith(null); // 3 System.Func<string> d = Test; // 4 d(); _ = nameof(Test); // 5 } } namespace N1 { using alias2 = Test; struct Derived { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test()); // 6 Test().ToString(); // 7 Test().EndsWith(null); // 8 var d = new System.Func<string>(Test); // 9 d(); _ = nameof(Test); // 10 } } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (16,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 34), // (17,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(17, 9), // (18,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 9), // (19,33): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Func<string> d = Test; // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(19, 33), // (21,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(21, 20), // (36,38): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 6 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(36, 38), // (37,13): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 7 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(37, 13), // (38,13): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 8 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(38, 13), // (39,45): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // var d = new System.Func<string>(Test); // 9 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(39, 45), // (41,24): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 10 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(41, 24) ); } [Fact] public void Scope_13() { var text = @" using alias1 = Test; string Test() => ""1""; System.Console.WriteLine(Test()); class Test {} interface Derived { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test()); // 1 Test().ToString(); // 2 Test().EndsWith(null); // 3 System.Func<string> d = Test; // 4 d(); _ = nameof(Test); // 5 } } namespace N1 { using alias2 = Test; interface Derived { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test()); // 6 Test().ToString(); // 7 Test().EndsWith(null); // 8 var d = new System.Func<string>(Test); // 9 d(); _ = nameof(Test); // 10 } } } "; var comp = CreateCompilation(text, targetFramework: TargetFramework.NetCoreApp, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (16,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 34), // (17,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(17, 9), // (18,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 9), // (19,33): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Func<string> d = Test; // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(19, 33), // (21,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(21, 20), // (36,38): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 6 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(36, 38), // (37,13): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 7 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(37, 13), // (38,13): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 8 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(38, 13), // (39,45): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // var d = new System.Func<string>(Test); // 9 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(39, 45), // (41,24): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 10 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(41, 24) ); } [Fact] public void Scope_14() { var text = @" using alias1 = Test; string Test() => ""1""; System.Console.WriteLine(Test()); class Test {} delegate Test D(alias1 x); namespace N1 { using alias2 = Test; delegate Test D(alias2 x); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics(); } [Fact] public void Scope_15() { var text = @" const int Test = 1; System.Console.WriteLine(Test); class Test {} enum E1 { T = Test, } namespace N1 { enum E1 { T = Test, } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (9,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // T = Test, Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(9, 9), // (16,13): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // T = Test, Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 13) ); } [Fact] public void Scope_16() { var text1 = @" using alias1 = System.String; alias1 x = ""1""; alias2 y = ""1""; System.Console.WriteLine(x); System.Console.WriteLine(y); local(); "; var text2 = @" using alias2 = System.String; void local() { alias1 a = ""2""; alias2 b = ""2""; System.Console.WriteLine(a); System.Console.WriteLine(b); } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (3,1): error CS8802: Only one compilation unit can have top-level statements. // alias1 x = "1"; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "alias1").WithLocation(3, 1), // (3,1): error CS8802: Only one compilation unit can have top-level statements. // void local() Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "void").WithLocation(3, 1), // (3,6): warning CS8321: The local function 'local' is declared but never used // void local() Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(3, 6), // (4,1): error CS0246: The type or namespace name 'alias2' could not be found (are you missing a using directive or an assembly reference?) // alias2 y = "1"; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "alias2").WithArguments("alias2").WithLocation(4, 1), // (5,5): error CS0246: The type or namespace name 'alias1' could not be found (are you missing a using directive or an assembly reference?) // alias1 a = "2"; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "alias1").WithArguments("alias1").WithLocation(5, 5), // (7,1): error CS0103: The name 'local' does not exist in the current context // local(); Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(7, 1) ); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var nameRef = tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "alias1" && !id.Parent.IsKind(SyntaxKind.NameEquals)).Single(); Assert.NotEmpty(model1.LookupNamespacesAndTypes(nameRef.SpanStart, name: "alias1")); Assert.Empty(model1.LookupNamespacesAndTypes(nameRef.SpanStart, name: "alias2")); nameRef = tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "alias2").Single(); model1.GetDiagnostics(nameRef.Ancestors().OfType<StatementSyntax>().First().Span).Verify( // (4,1): error CS0246: The type or namespace name 'alias2' could not be found (are you missing a using directive or an assembly reference?) // alias2 y = "1"; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "alias2").WithArguments("alias2").WithLocation(4, 1) ); model1.GetDiagnostics().Verify( // (3,1): error CS8802: Only one compilation unit can have top-level statements. // alias1 x = "1"; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "alias1").WithLocation(3, 1), // (4,1): error CS0246: The type or namespace name 'alias2' could not be found (are you missing a using directive or an assembly reference?) // alias2 y = "1"; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "alias2").WithArguments("alias2").WithLocation(4, 1), // (7,1): error CS0103: The name 'local' does not exist in the current context // local(); Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(7, 1) ); var tree2 = comp.SyntaxTrees[1]; var model2 = comp.GetSemanticModel(tree2); nameRef = tree2.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "alias2" && !id.Parent.IsKind(SyntaxKind.NameEquals)).Single(); Assert.Empty(model2.LookupNamespacesAndTypes(nameRef.SpanStart, name: "alias1")); Assert.NotEmpty(model2.LookupNamespacesAndTypes(nameRef.SpanStart, name: "alias2")); nameRef = tree2.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "alias1").Single(); model2.GetDiagnostics(nameRef.Ancestors().OfType<StatementSyntax>().First().Span).Verify( // (5,5): error CS0246: The type or namespace name 'alias1' could not be found (are you missing a using directive or an assembly reference?) // alias1 a = "2"; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "alias1").WithArguments("alias1").WithLocation(5, 5) ); model2.GetDiagnostics().Verify( // (3,1): error CS8802: Only one compilation unit can have top-level statements. // void local() Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "void").WithLocation(3, 1), // (3,6): warning CS8321: The local function 'local' is declared but never used // void local() Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(3, 6), // (5,5): error CS0246: The type or namespace name 'alias1' could not be found (are you missing a using directive or an assembly reference?) // alias1 a = "2"; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "alias1").WithArguments("alias1").WithLocation(5, 5) ); } [Fact] public void Scope_17() { var text = @" using alias1 = N2.Test; using N2; string Test = ""1""; System.Console.WriteLine(Test); namespace N2 { class Test {} } class Derived : Test { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test); // 1 Test.ToString(); // 2 Test.EndsWith(null); // 3 _ = nameof(Test); // 4 } } namespace N1 { using alias2 = Test; using N2; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); _ = nameof(Test); } } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (16,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 34), // (17,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(17, 9), // (18,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 9), // (19,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(19, 20) ); } [Fact] public void Scope_18() { var text1 = @" string Test = ""1""; System.Console.WriteLine(Test); "; var text2 = @" using alias1 = N2.Test; using N2; namespace N2 { class Test {} } class Derived : Test { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test); // 1 Test.ToString(); // 2 Test.EndsWith(null); // 3 _ = nameof(Test); // 4 } } namespace N1 { using alias2 = Test; using N2; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); _ = nameof(Test); } } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (13,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(13, 34), // (14,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(14, 9), // (15,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(15, 9), // (16,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 20) ); } [Fact] public void Scope_19() { var text = @" using alias1 = N2.Test; using N2; string Test() => ""1""; System.Console.WriteLine(Test()); namespace N2 { class Test {} } class Derived : Test { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test()); // 1 Test().ToString(); // 2 Test().EndsWith(null); // 3 System.Func<string> d = Test; // 4 d(); _ = nameof(Test); // 5 } } namespace N1 { using alias2 = Test; using N2; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); _ = nameof(Test); } } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (16,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 34), // (17,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(17, 9), // (18,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 9), // (19,33): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Func<string> d = Test; // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(19, 33), // (21,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(21, 20) ); } [Fact] public void Scope_20() { var text1 = @" string Test() => ""1""; System.Console.WriteLine(Test()); "; var text2 = @" using alias1 = N2.Test; using N2; namespace N2 { class Test {} } class Derived : Test { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test()); // 1 Test().ToString(); // 2 Test().EndsWith(null); // 3 System.Func<string> d = Test; // 4 d(); _ = nameof(Test); // 5 } } namespace N1 { using alias2 = Test; using N2; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); _ = nameof(Test); } } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (13,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(13, 34), // (14,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(14, 9), // (15,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(15, 9), // (16,33): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Func<string> d = Test; // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 33), // (18,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 20) ); } [Fact] public void Scope_21() { var text = @" using Test = N2.Test; string Test = ""1""; System.Console.WriteLine(Test); namespace N2 { class Test {} } class Derived : Test { void M() { Test x = null; System.Console.WriteLine(x); System.Console.WriteLine(Test); // 1 Test.ToString(); // 2 Test.EndsWith(null); // 3 _ = nameof(Test); // 4 } } namespace N1 { using alias2 = Test; using Test = N2.Test; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); _ = nameof(Test); } } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (16,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 34), // (17,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(17, 9), // (18,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 9), // (19,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(19, 20) ); } [Fact] public void Scope_22() { var text1 = @" string Test = ""1""; System.Console.WriteLine(Test); "; var text2 = @" using Test = N2.Test; namespace N2 { class Test {} } class Derived : Test { void M() { Test x = null; System.Console.WriteLine(x); System.Console.WriteLine(Test); // 1 Test.ToString(); // 2 Test.EndsWith(null); // 3 _ = nameof(Test); // 4 } } namespace N1 { using alias2 = Test; using Test = N2.Test; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); _ = nameof(Test); } } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (13,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(13, 34), // (14,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(14, 9), // (15,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(15, 9), // (16,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 20) ); } [Fact] public void Scope_23() { var text = @" using Test = N2.Test; string Test() => ""1""; System.Console.WriteLine(Test()); namespace N2 { class Test {} } class Derived : Test { void M() { Test x = null; System.Console.WriteLine(x); System.Console.WriteLine(Test()); // 1 Test().ToString(); // 2 Test().EndsWith(null); // 3 System.Func<string> d = Test; // 4 d(); _ = nameof(Test); // 5 } } namespace N1 { using alias2 = Test; using Test = N2.Test; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); _ = nameof(Test); } } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (16,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 34), // (17,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(17, 9), // (18,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 9), // (19,33): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Func<string> d = Test; // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(19, 33), // (21,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(21, 20) ); } [Fact] public void Scope_24() { var text1 = @" string Test() => ""1""; System.Console.WriteLine(Test()); "; var text2 = @" using Test = N2.Test; namespace N2 { class Test {} } class Derived : Test { void M() { Test x = null; System.Console.WriteLine(x); System.Console.WriteLine(Test()); // 1 Test().ToString(); // 2 Test().EndsWith(null); // 3 System.Func<string> d = Test; // 4 d(); _ = nameof(Test); // 5 } } namespace N1 { using alias2 = Test; using Test = N2.Test; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); _ = nameof(Test); } } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (13,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(13, 34), // (14,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(14, 9), // (15,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(15, 9), // (16,33): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Func<string> d = Test; // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 33), // (18,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 20) ); } [Fact] public void Scope_25() { var text = @" using alias1 = N2.Test; using static N2; string Test = ""1""; System.Console.WriteLine(Test); class N2 { public class Test {} } class Derived : Test { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test); // 1 Test.ToString(); // 2 Test.EndsWith(null); // 3 _ = nameof(Test); // 4 } } namespace N1 { using alias2 = Test; using static N2; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); _ = nameof(Test); } } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (16,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 34), // (17,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(17, 9), // (18,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 9), // (19,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(19, 20) ); } [Fact] public void Scope_26() { var text1 = @" string Test = ""1""; System.Console.WriteLine(Test); "; var text2 = @" using alias1 = N2.Test; using static N2; class N2 { public class Test {} } class Derived : Test { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test); // 1 Test.ToString(); // 2 Test.EndsWith(null); // 3 _ = nameof(Test); // 4 } } namespace N1 { using alias2 = Test; using static N2; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); _ = nameof(Test); } } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (13,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(13, 34), // (14,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(14, 9), // (15,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test.EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(15, 9), // (16,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 20) ); } [Fact] public void Scope_27() { var text = @" using alias1 = N2.Test; using static N2; string Test() => ""1""; System.Console.WriteLine(Test()); class N2 { public class Test {} } class Derived : Test { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test()); // 1 Test().ToString(); // 2 Test().EndsWith(null); // 3 System.Func<string> d = Test; // 4 d(); _ = nameof(Test); // 5 } } namespace N1 { using alias2 = Test; using static N2; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); _ = nameof(Test); } } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (16,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 34), // (17,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(17, 9), // (18,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 9), // (19,33): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Func<string> d = Test; // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(19, 33), // (21,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(21, 20) ); } [Fact] public void Scope_28() { var text1 = @" string Test() => ""1""; System.Console.WriteLine(Test()); "; var text2 = @" using alias1 = N2.Test; using static N2; class N2 { public class Test {} } class Derived : Test { void M() { Test x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(Test()); // 1 Test().ToString(); // 2 Test().EndsWith(null); // 3 System.Func<string> d = Test; // 4 d(); _ = nameof(Test); // 5 } } namespace N1 { using alias2 = Test; using static N2; class Derived : Test { void M() { Test x = null; alias2 y = x; System.Console.WriteLine(y); _ = nameof(Test); } } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (13,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(13, 34), // (14,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(14, 9), // (15,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(15, 9), // (16,33): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Func<string> d = Test; // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 33), // (18,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 20) ); } [Fact] public void Scope_29() { var text = @" using static N2; string Test() => ""1""; System.Console.WriteLine(Test()); class N2 { public static string Test() => null; } class Derived { void M() { System.Console.WriteLine(Test()); // 1 Test().ToString(); // 2 Test().EndsWith(null); // 3 System.Func<string> d = Test; // 4 d(); _ = nameof(Test); // 5 } } namespace N1 { using static N2; class Derived { void M() { System.Console.WriteLine(Test()); Test().ToString(); Test().EndsWith(null); var d = new System.Func<string>(Test); d(); _ = nameof(Test); } } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): hidden CS8019: Unnecessary using directive. // using static N2; Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using static N2;").WithLocation(2, 1), // (13,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(13, 34), // (14,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(14, 9), // (15,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(15, 9), // (16,33): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Func<string> d = Test; // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(16, 33), // (18,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(18, 20) ); } [Fact] public void Scope_30() { var text1 = @" string Test() => ""1""; System.Console.WriteLine(Test()); "; var text2 = @" using static N2; class N2 { public static string Test() => null; } class Derived { void M() { System.Console.WriteLine(Test()); // 1 Test().ToString(); // 2 Test().EndsWith(null); // 3 System.Func<string> d = Test; // 4 d(); _ = nameof(Test); // 5 } } namespace N1 { using static N2; class Derived { void M() { System.Console.WriteLine(Test()); Test().ToString(); Test().EndsWith(null); var d = new System.Func<string>(Test); d(); _ = nameof(Test); } } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): hidden CS8019: Unnecessary using directive. // using static N2; Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using static N2;").WithLocation(2, 1), // (10,34): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Console.WriteLine(Test()); // 1 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(10, 34), // (11,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().ToString(); // 2 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(11, 9), // (12,9): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // Test().EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(12, 9), // (13,33): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // System.Func<string> d = Test; // 4 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(13, 33), // (15,20): error CS8801: Cannot use local variable or local function 'Test' declared in a top-level statement in this context. // _ = nameof(Test); // 5 Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "Test").WithArguments("Test").WithLocation(15, 20) ); } [Fact] public void Scope_31() { var text = @" using alias1 = args; System.Console.WriteLine(args); class @args {} class Derived : args { void M() { args x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(args); // 1 args.ToString(); // 2 args[0].EndsWith(null); // 3 _ = nameof(args); } } namespace N1 { using alias2 = args; class Derived : args { void M() { args x = null; alias2 y = x; System.Console.WriteLine(y); System.Console.WriteLine(args); // 4 args.ToString(); // 5 args[0].EndsWith(null); // 6 _ = nameof(args); } } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (15,34): error CS0119: 'args' is a type, which is not valid in the given context // System.Console.WriteLine(args); // 1 Diagnostic(ErrorCode.ERR_BadSKunknown, "args").WithArguments("args", "type").WithLocation(15, 34), // (16,9): error CS0120: An object reference is required for the non-static field, method, or property 'object.ToString()' // args.ToString(); // 2 Diagnostic(ErrorCode.ERR_ObjectRequired, "args.ToString").WithArguments("object.ToString()").WithLocation(16, 9), // (17,9): error CS0119: 'args' is a type, which is not valid in the given context // args[0].EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_BadSKunknown, "args").WithArguments("args", "type").WithLocation(17, 9), // (33,38): error CS0119: 'args' is a type, which is not valid in the given context // System.Console.WriteLine(args); // 4 Diagnostic(ErrorCode.ERR_BadSKunknown, "args").WithArguments("args", "type").WithLocation(33, 38), // (34,13): error CS0120: An object reference is required for the non-static field, method, or property 'object.ToString()' // args.ToString(); // 5 Diagnostic(ErrorCode.ERR_ObjectRequired, "args.ToString").WithArguments("object.ToString()").WithLocation(34, 13), // (35,13): error CS0119: 'args' is a type, which is not valid in the given context // args[0].EndsWith(null); // 6 Diagnostic(ErrorCode.ERR_BadSKunknown, "args").WithArguments("args", "type").WithLocation(35, 13) ); var testType = ((Compilation)comp).GetTypeByMetadataName("args"); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); var nameRefs = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "args").ToArray(); var nameRef = nameRefs[0]; Assert.Equal("using alias1 = args;", nameRef.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); var names = model.LookupNames(nameRef.SpanStart); Assert.Contains("args", names); var symbols = model.LookupSymbols(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.False(symbols.Any(s => s.Kind == SymbolKind.Parameter)); Assert.Same(testType, model.LookupSymbols(nameRef.SpanStart, name: "args").Single()); nameRef = nameRefs[1]; Assert.Equal("System.Console.WriteLine(args)", nameRef.Parent.Parent.Parent.ToString()); var parameter = model.GetSymbolInfo(nameRef).Symbol; Assert.Equal("System.String[] args", parameter.ToTestDisplayString()); Assert.Equal("<top-level-statements-entry-point>", parameter.ContainingSymbol.ToTestDisplayString()); names = model.LookupNames(nameRef.SpanStart); Assert.Contains("args", names); symbols = model.LookupSymbols(nameRef.SpanStart); Assert.DoesNotContain(testType, symbols); Assert.Contains(parameter, symbols); Assert.Same(parameter, model.LookupSymbols(nameRef.SpanStart, name: "args").Single()); symbols = model.LookupNamespacesAndTypes(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(parameter, symbols); Assert.Same(testType, model.LookupNamespacesAndTypes(nameRef.SpanStart, name: "args").Single()); nameRef = nameRefs[2]; Assert.Equal(": args", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); verifyModel(parameter, model, nameRef); nameRef = nameRefs[4]; Assert.Equal("System.Console.WriteLine(args)", nameRef.Parent.Parent.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); verifyModel(parameter, model, nameRef); nameRef = nameRefs[8]; Assert.Equal("using alias2 = args;", nameRef.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); verifyModel(parameter, model, nameRef); nameRef = nameRefs[9]; Assert.Equal(": args", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); verifyModel(parameter, model, nameRef); nameRef = nameRefs[11]; Assert.Equal("System.Console.WriteLine(args)", nameRef.Parent.Parent.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); verifyModel(parameter, model, nameRef); void verifyModel(ISymbol declSymbol, SemanticModel model, IdentifierNameSyntax nameRef) { var names = model.LookupNames(nameRef.SpanStart); Assert.Contains("args", names); var symbols = model.LookupSymbols(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model.LookupSymbols(nameRef.SpanStart, name: "args").Single()); symbols = model.LookupNamespacesAndTypes(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.DoesNotContain(declSymbol, symbols); Assert.Same(testType, model.LookupNamespacesAndTypes(nameRef.SpanStart, name: "args").Single()); } } [Fact] public void Scope_32() { var text1 = @" System.Console.WriteLine(args); "; var text2 = @" using alias1 = args; class @args {} class Derived : args { void M() { args x = null; alias1 y = x; System.Console.WriteLine(y); System.Console.WriteLine(args); // 1 args.ToString(); // 2 args[0].EndsWith(null); // 3 _ = nameof(args); } } namespace N1 { using alias2 = args; class Derived : args { void M() { args x = null; alias2 y = x; System.Console.WriteLine(y); System.Console.WriteLine(args); // 4 args.ToString(); // 5 args[0].EndsWith(null); // 6 _ = nameof(args); } } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (13,34): error CS0119: 'args' is a type, which is not valid in the given context // System.Console.WriteLine(args); // 1 Diagnostic(ErrorCode.ERR_BadSKunknown, "args").WithArguments("args", "type").WithLocation(13, 34), // (14,9): error CS0120: An object reference is required for the non-static field, method, or property 'object.ToString()' // args.ToString(); // 2 Diagnostic(ErrorCode.ERR_ObjectRequired, "args.ToString").WithArguments("object.ToString()").WithLocation(14, 9), // (15,9): error CS0119: 'args' is a type, which is not valid in the given context // args[0].EndsWith(null); // 3 Diagnostic(ErrorCode.ERR_BadSKunknown, "args").WithArguments("args", "type").WithLocation(15, 9), // (31,38): error CS0119: 'args' is a type, which is not valid in the given context // System.Console.WriteLine(args); // 4 Diagnostic(ErrorCode.ERR_BadSKunknown, "args").WithArguments("args", "type").WithLocation(31, 38), // (32,13): error CS0120: An object reference is required for the non-static field, method, or property 'object.ToString()' // args.ToString(); // 5 Diagnostic(ErrorCode.ERR_ObjectRequired, "args.ToString").WithArguments("object.ToString()").WithLocation(32, 13), // (33,13): error CS0119: 'args' is a type, which is not valid in the given context // args[0].EndsWith(null); // 6 Diagnostic(ErrorCode.ERR_BadSKunknown, "args").WithArguments("args", "type").WithLocation(33, 13) ); var testType = ((Compilation)comp).GetTypeByMetadataName("args"); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree = comp.SyntaxTrees[1]; var model = comp.GetSemanticModel(tree); var nameRefs = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "args").ToArray(); var nameRef = nameRefs[0]; Assert.Equal("using alias1 = args;", nameRef.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); var names = model.LookupNames(nameRef.SpanStart); Assert.Contains("args", names); var symbols = model.LookupSymbols(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.False(symbols.Any(s => s.Kind == SymbolKind.Parameter)); Assert.Same(testType, model.LookupSymbols(nameRef.SpanStart, name: "args").Single()); nameRef = nameRefs[1]; Assert.Equal(": args", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); verifyModel(model, nameRef); nameRef = nameRefs[3]; Assert.Equal("System.Console.WriteLine(args)", nameRef.Parent.Parent.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); verifyModel(model, nameRef); nameRef = nameRefs[7]; Assert.Equal("using alias2 = args;", nameRef.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); verifyModel(model, nameRef); nameRef = nameRefs[8]; Assert.Equal(": args", nameRef.Parent.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); verifyModel(model, nameRef); nameRef = nameRefs[10]; Assert.Equal("System.Console.WriteLine(args)", nameRef.Parent.Parent.Parent.ToString()); Assert.Same(testType, model.GetSymbolInfo(nameRef).Symbol); verifyModel(model, nameRef); void verifyModel(SemanticModel model, IdentifierNameSyntax nameRef) { var names = model.LookupNames(nameRef.SpanStart); Assert.Contains("args", names); var symbols = model.LookupSymbols(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.False(symbols.Any(s => s.Kind == SymbolKind.Parameter)); Assert.Same(testType, model.LookupSymbols(nameRef.SpanStart, name: "args").Single()); symbols = model.LookupNamespacesAndTypes(nameRef.SpanStart); Assert.Contains(testType, symbols); Assert.False(symbols.Any(s => s.Kind == SymbolKind.Parameter)); Assert.Same(testType, model.LookupNamespacesAndTypes(nameRef.SpanStart, name: "args").Single()); } } [Fact] public void Scope_33() { var text = @" System.Console.WriteLine(args); class Test { void M() { System.Console.WriteLine(args); } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (8,34): error CS0103: The name 'args' does not exist in the current context // System.Console.WriteLine(args); Diagnostic(ErrorCode.ERR_NameNotInContext, "args").WithArguments("args").WithLocation(8, 34) ); } [Fact] public void Scope_34() { var text1 = @" System.Console.WriteLine(args); "; var text2 = @" class Test { void M() { System.Console.WriteLine(args); } } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,34): error CS0103: The name 'args' does not exist in the current context // System.Console.WriteLine(args); Diagnostic(ErrorCode.ERR_NameNotInContext, "args").WithArguments("args").WithLocation(6, 34) ); } [Fact] public void LocalFunctionStatement_01() { var text = @" local(); void local() { System.Console.WriteLine(15); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "15"); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var declarator = tree.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().Single(); var reference = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "local").Single(); var local = model.GetDeclaredSymbol(declarator); Assert.Same(local, model.GetSymbolInfo(reference).Symbol); Assert.Equal("void local()", local.ToTestDisplayString()); Assert.Equal(MethodKind.LocalFunction, ((IMethodSymbol)local).MethodKind); Assert.Equal(SymbolKind.Method, local.ContainingSymbol.Kind); Assert.False(local.ContainingSymbol.IsImplicitlyDeclared); Assert.Equal(SymbolKind.NamedType, local.ContainingSymbol.ContainingSymbol.Kind); Assert.False(local.ContainingSymbol.ContainingSymbol.IsImplicitlyDeclared); Assert.True(((INamespaceSymbol)local.ContainingSymbol.ContainingSymbol.ContainingSymbol).IsGlobalNamespace); VerifyFlowGraph(comp, tree.GetRoot(), @" Block[B0] - Entry Statements (0) Next (Regular) Block[B1] Entering: {R1} .locals {R1} { Methods: [void local()] Block[B1] - Block Predecessors: [B0] Statements (1) IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'local();') Expression: IInvocationOperation (void local()) (OperationKind.Invocation, Type: System.Void) (Syntax: 'local()') Instance Receiver: null Arguments(0) Next (Regular) Block[B2] Leaving: {R1} { void local() Block[B0#0R1] - Entry Statements (0) Next (Regular) Block[B1#0R1] Block[B1#0R1] - Block Predecessors: [B0#0R1] Statements (1) IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Cons ... teLine(15);') Expression: IInvocationOperation (void System.Console.WriteLine(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... iteLine(15)') Instance Receiver: null Arguments(1): IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '15') ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 15) (Syntax: '15') InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Next (Regular) Block[B2#0R1] Block[B2#0R1] - Exit Predecessors: [B1#0R1] Statements (0) } } Block[B2] - Exit Predecessors: [B1] Statements (0) "); } [Fact] public void LocalFunctionStatement_02() { var text = @" local(); void local() => System.Console.WriteLine(""Hi!""); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void LocalFunctionStatement_03() { var text = @" local(); void I1.local() { System.Console.WriteLine(""Hi!""); } interface I1 { void local(); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS0103: The name 'local' does not exist in the current context // local(); Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(2, 1), // (4,1): error CS1547: Keyword 'void' cannot be used in this context // void I1.local() Diagnostic(ErrorCode.ERR_NoVoidHere, "void").WithLocation(4, 1), // (4,6): warning CS0168: The variable 'I1' is declared but never used // void I1.local() Diagnostic(ErrorCode.WRN_UnreferencedVar, "I1").WithArguments("I1").WithLocation(4, 6), // (4,8): error CS1003: Syntax error, ',' expected // void I1.local() Diagnostic(ErrorCode.ERR_SyntaxError, ".").WithArguments(",").WithLocation(4, 8), // (4,9): error CS1002: ; expected // void I1.local() Diagnostic(ErrorCode.ERR_SemicolonExpected, "local").WithLocation(4, 9), // (4,9): error CS0103: The name 'local' does not exist in the current context // void I1.local() Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(4, 9), // (4,16): error CS1002: ; expected // void I1.local() Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(4, 16) ); } [Fact] public void LocalFunctionStatement_04() { var text = @" new void localA() => System.Console.WriteLine(); localA(); public void localB() => System.Console.WriteLine(); localB(); virtual void localC() => System.Console.WriteLine(); localC(); sealed void localD() => System.Console.WriteLine(); localD(); override void localE() => System.Console.WriteLine(); localE(); abstract void localF() => System.Console.WriteLine(); localF(); partial void localG() => System.Console.WriteLine(); localG(); extern void localH() => System.Console.WriteLine(); localH(); [System.Obsolete()] void localI() => System.Console.WriteLine(); localI(); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,10): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // new void localA() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "localA").WithLocation(2, 10), // (2,10): warning CS0109: The member '<invalid-global-code>.localA()' does not hide an accessible member. The new keyword is not required. // new void localA() => System.Console.WriteLine(); Diagnostic(ErrorCode.WRN_NewNotRequired, "localA").WithArguments("<invalid-global-code>.localA()").WithLocation(2, 10), // (3,1): error CS0103: The name 'localA' does not exist in the current context // localA(); Diagnostic(ErrorCode.ERR_NameNotInContext, "localA").WithArguments("localA").WithLocation(3, 1), // (4,1): error CS0106: The modifier 'public' is not valid for this item // public void localB() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_BadMemberFlag, "public").WithArguments("public").WithLocation(4, 1), // (6,14): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // virtual void localC() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "localC").WithLocation(6, 14), // (6,14): error CS0621: '<invalid-global-code>.localC()': virtual or abstract members cannot be private // virtual void localC() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_VirtualPrivate, "localC").WithArguments("<invalid-global-code>.localC()").WithLocation(6, 14), // (7,1): error CS0103: The name 'localC' does not exist in the current context // localC(); Diagnostic(ErrorCode.ERR_NameNotInContext, "localC").WithArguments("localC").WithLocation(7, 1), // (8,13): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // sealed void localD() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "localD").WithLocation(8, 13), // (8,13): error CS0238: '<invalid-global-code>.localD()' cannot be sealed because it is not an override // sealed void localD() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_SealedNonOverride, "localD").WithArguments("<invalid-global-code>.localD()").WithLocation(8, 13), // (9,1): error CS0103: The name 'localD' does not exist in the current context // localD(); Diagnostic(ErrorCode.ERR_NameNotInContext, "localD").WithArguments("localD").WithLocation(9, 1), // (10,15): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // override void localE() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "localE").WithLocation(10, 15), // (10,15): error CS0621: '<invalid-global-code>.localE()': virtual or abstract members cannot be private // override void localE() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_VirtualPrivate, "localE").WithArguments("<invalid-global-code>.localE()").WithLocation(10, 15), // (10,15): error CS0115: '<invalid-global-code>.localE()': no suitable method found to override // override void localE() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_OverrideNotExpected, "localE").WithArguments("<invalid-global-code>.localE()").WithLocation(10, 15), // (11,1): error CS0103: The name 'localE' does not exist in the current context // localE(); Diagnostic(ErrorCode.ERR_NameNotInContext, "localE").WithArguments("localE").WithLocation(11, 1), // (12,15): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // abstract void localF() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "localF").WithLocation(12, 15), // (12,15): error CS0500: '<invalid-global-code>.localF()' cannot declare a body because it is marked abstract // abstract void localF() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_AbstractHasBody, "localF").WithArguments("<invalid-global-code>.localF()").WithLocation(12, 15), // (12,15): error CS0621: '<invalid-global-code>.localF()': virtual or abstract members cannot be private // abstract void localF() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_VirtualPrivate, "localF").WithArguments("<invalid-global-code>.localF()").WithLocation(12, 15), // (13,1): error CS0103: The name 'localF' does not exist in the current context // localF(); Diagnostic(ErrorCode.ERR_NameNotInContext, "localF").WithArguments("localF").WithLocation(13, 1), // (14,14): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // partial void localG() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "localG").WithLocation(14, 14), // (14,14): error CS0759: No defining declaration found for implementing declaration of partial method '<invalid-global-code>.localG()' // partial void localG() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_PartialMethodMustHaveLatent, "localG").WithArguments("<invalid-global-code>.localG()").WithLocation(14, 14), // (14,14): error CS0751: A partial member must be declared within a partial type // partial void localG() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_PartialMemberOnlyInPartialClass, "localG").WithLocation(14, 14), // (15,1): error CS0103: The name 'localG' does not exist in the current context // localG(); Diagnostic(ErrorCode.ERR_NameNotInContext, "localG").WithArguments("localG").WithLocation(15, 1), // (16,13): error CS0179: 'localH()' cannot be extern and declare a body // extern void localH() => System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_ExternHasBody, "localH").WithArguments("localH()").WithLocation(16, 13), // (20,1): warning CS0612: 'localI()' is obsolete // localI(); Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "localI()").WithArguments("localI()").WithLocation(20, 1) ); } [Fact] public void LocalFunctionStatement_05() { var text = @" void local1() => System.Console.Write(""1""); local1(); void local2() => System.Console.Write(""2""); local2(); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "12"); } [Fact] public void LocalFunctionStatement_06() { var text = @" local(); static void local() { System.Console.WriteLine(""Hi!""); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void LocalFunctionStatement_07() { var text1 = @" local1(1); void local1(int x) {} local2(); "; var text2 = @" void local1(byte y) {} void local2() { local1(2); } "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS8802: Only one compilation unit can have top-level statements. // local1(1); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "local1").WithLocation(2, 1), // (2,1): error CS8802: Only one compilation unit can have top-level statements. // void local1(byte y) Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "void").WithLocation(2, 1), // (5,1): error CS0103: The name 'local2' does not exist in the current context // local2(); Diagnostic(ErrorCode.ERR_NameNotInContext, "local2").WithArguments("local2").WithLocation(5, 1), // (5,6): warning CS8321: The local function 'local2' is declared but never used // void local2() Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local2").WithArguments("local2").WithLocation(5, 6) ); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var symbol1 = model1.GetDeclaredSymbol(tree1.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().Single()); Assert.Equal("void local1(System.Int32 x)", symbol1.ToTestDisplayString()); Assert.Same(symbol1, model1.GetSymbolInfo(tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "local1").Single()).Symbol); var tree2 = comp.SyntaxTrees[1]; var model2 = comp.GetSemanticModel(tree2); var symbol2 = model2.GetDeclaredSymbol(tree2.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().First()); Assert.Equal("void local1(System.Byte y)", symbol2.ToTestDisplayString()); Assert.Same(symbol2, model2.GetSymbolInfo(tree2.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "local1").Single()).Symbol); } [Fact] public void LocalFunctionStatement_08() { var text = @" void local() { System.Console.WriteLine(""Hi!""); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,6): warning CS8321: The local function 'local' is declared but never used // void local() Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(2, 6) ); CompileAndVerify(comp, expectedOutput: ""); } [Fact] public void LocalFunctionStatement_09() { var text1 = @" local1(1); void local1(int x) {} local2(); void local1(byte y) {} void local2() { local1(2); } "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (7,6): error CS0128: A local variable or function named 'local1' is already defined in this scope // void local1(byte y) Diagnostic(ErrorCode.ERR_LocalDuplicate, "local1").WithArguments("local1").WithLocation(7, 6), // (7,6): warning CS8321: The local function 'local1' is declared but never used // void local1(byte y) Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local1").WithArguments("local1").WithLocation(7, 6) ); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var symbol1 = model1.GetDeclaredSymbol(tree1.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().First()); Assert.Equal("void local1(System.Int32 x)", symbol1.ToTestDisplayString()); Assert.Same(symbol1, model1.GetSymbolInfo(tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "local1").First()).Symbol); var symbol2 = model1.GetDeclaredSymbol(tree1.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().Skip(1).First()); Assert.Equal("void local1(System.Byte y)", symbol2.ToTestDisplayString()); Assert.Same(symbol1, model1.GetSymbolInfo(tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "local1").Skip(1).Single()).Symbol); } [Fact] public void LocalFunctionStatement_10() { var text = @" int i = 1; local(); System.Console.WriteLine(i); void local() { i++; } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "2"); } [Fact] public void LocalFunctionStatement_11() { var text1 = @" args(1); void args(int x) {} "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (3,6): error CS0136: A local or parameter named 'args' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // void args(int x) Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "args").WithArguments("args").WithLocation(3, 6) ); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var symbol1 = model1.GetDeclaredSymbol(tree1.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().First()); Assert.Equal("void args(System.Int32 x)", symbol1.ToTestDisplayString()); Assert.Same(symbol1, model1.GetSymbolInfo(tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "args").Single()).Symbol); } [Fact] public void LocalFunctionStatement_12() { var text1 = @" local(1); void local<args>(args x) { System.Console.WriteLine(x); } "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "1"); } [Fact] public void LocalFunctionStatement_13() { var text1 = @" local(); void local() { var args = 2; System.Console.WriteLine(args); } "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "2"); } [Fact] public void LocalFunctionStatement_14() { var text1 = @" local(3); void local(int args) { System.Console.WriteLine(args); } "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "3"); } [Fact] public void LocalFunctionStatement_15() { var text1 = @" local(); void local() { args(4); void args(int x) { System.Console.WriteLine(x); } } "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "4"); } [Fact] public void LocalFunctionStatement_16() { var text1 = @" using System.Linq; _ = from local in new object[0] select local; local(); void local() {} "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (3,10): error CS1931: The range variable 'local' conflicts with a previous declaration of 'local' // _ = from local in new object[0] select local; Diagnostic(ErrorCode.ERR_QueryRangeVariableOverrides, "local").WithArguments("local").WithLocation(3, 10) ); } [Fact] public void LocalFunctionStatement_17() { var text = @" System.Console.WriteLine(); string await() => ""Hi!""; System.Console.WriteLine(await()); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (3,8): error CS4003: 'await' cannot be used as an identifier within an async method or lambda expression // string await() => "Hi!"; Diagnostic(ErrorCode.ERR_BadAwaitAsIdentifier, "await").WithLocation(3, 8), // (3,8): warning CS8321: The local function 'await' is declared but never used // string await() => "Hi!"; Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "await").WithArguments("await").WithLocation(3, 8), // (4,32): error CS1525: Invalid expression term ')' // System.Console.WriteLine(await()); Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(4, 32) ); } [Fact] public void LocalFunctionStatement_18() { var text = @" string async() => ""Hi!""; System.Console.WriteLine(async()); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void Lambda_01() { var text = @" int i = 1; System.Action l = () => i++; l(); System.Console.WriteLine(i); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "2"); } [Fact] public void PropertyDeclaration_01() { var text = @" _ = local; int local => 1; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,5): error CS0103: The name 'local' does not exist in the current context // _ = local; Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(2, 5), // (4,5): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // int local => 1; Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "local").WithLocation(4, 5) ); } [Fact] public void PropertyDeclaration_02() { var text = @" _ = local; int local { get => 1; } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,5): error CS0103: The name 'local' does not exist in the current context // _ = local; Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(2, 5), // (4,5): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // int local { get => 1; } Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "local").WithLocation(4, 5) ); } [Fact] public void PropertyDeclaration_03() { var text = @" _ = local; int local { get { return 1; } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,5): error CS0103: The name 'local' does not exist in the current context // _ = local; Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(2, 5), // (4,5): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // int local { get { return 1; } } Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "local").WithLocation(4, 5) ); } [Fact] public void EventDeclaration_01() { var text = @" local += null; event System.Action local; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS0103: The name 'local' does not exist in the current context // local += null; Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(2, 1), // (4,21): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // event System.Action local; Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "local").WithLocation(4, 21) ); } [Fact] public void EventDeclaration_02() { var text = @" local -= null; event System.Action local { add {} remove {} } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS0103: The name 'local' does not exist in the current context // local -= null; Diagnostic(ErrorCode.ERR_NameNotInContext, "local").WithArguments("local").WithLocation(2, 1), // (4,21): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // event System.Action local Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "local").WithLocation(4, 21) ); } [Fact] public void LabeledStatement_01() { var text = @" goto label1; label1: System.Console.WriteLine(""Hi!""); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var declarator = tree.GetRoot().DescendantNodes().OfType<LabeledStatementSyntax>().Single(); var reference = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "label1").Single(); var label = model.GetDeclaredSymbol(declarator); Assert.Same(label, model.GetSymbolInfo(reference).Symbol); Assert.Equal("label1", label.ToTestDisplayString()); Assert.Equal(SymbolKind.Label, label.Kind); Assert.Equal(SymbolKind.Method, label.ContainingSymbol.Kind); Assert.False(label.ContainingSymbol.IsImplicitlyDeclared); Assert.Equal(SymbolKind.NamedType, label.ContainingSymbol.ContainingSymbol.Kind); Assert.False(label.ContainingSymbol.ContainingSymbol.IsImplicitlyDeclared); Assert.True(((INamespaceSymbol)label.ContainingSymbol.ContainingSymbol.ContainingSymbol).IsGlobalNamespace); } [Fact] public void LabeledStatement_02() { var text = @" goto label1; label1: System.Console.WriteLine(""Hi!""); label1: System.Console.WriteLine(); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (4,1): error CS0140: The label 'label1' is a duplicate // label1: System.Console.WriteLine(); Diagnostic(ErrorCode.ERR_DuplicateLabel, "label1").WithArguments("label1").WithLocation(4, 1) ); } [Fact] public void LabeledStatement_03() { var text1 = @" goto label1; label1: System.Console.Write(1); "; var text2 = @" label1: System.Console.Write(2); goto label1; "; var comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS8802: Only one compilation unit can have top-level statements. // goto label1; Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "goto").WithLocation(2, 1), // (2,1): error CS8802: Only one compilation unit can have top-level statements. // label1: System.Console.Write(2); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "label1").WithLocation(2, 1) ); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var symbol1 = model1.GetDeclaredSymbol(tree1.GetRoot().DescendantNodes().OfType<LabeledStatementSyntax>().Single()); Assert.Equal("label1", symbol1.ToTestDisplayString()); Assert.Same(symbol1, model1.GetSymbolInfo(tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "label1").Single()).Symbol); var tree2 = comp.SyntaxTrees[1]; var model2 = comp.GetSemanticModel(tree2); var symbol2 = model2.GetDeclaredSymbol(tree2.GetRoot().DescendantNodes().OfType<LabeledStatementSyntax>().Single()); Assert.Equal("label1", symbol2.ToTestDisplayString()); Assert.NotEqual(symbol1, symbol2); Assert.Same(symbol2, model2.GetSymbolInfo(tree2.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "label1").Single()).Symbol); } [Fact] public void LabeledStatement_04() { var text = @" goto args; args: System.Console.WriteLine(""Hi!""); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); Assert.False(IsNullableAnalysisEnabled(comp)); // To make sure we test incremental binding for SemanticModel var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var declarator = tree.GetRoot().DescendantNodes().OfType<LabeledStatementSyntax>().Single(); var reference = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "args").Single(); var label = model.GetDeclaredSymbol(declarator); Assert.Same(label, model.GetSymbolInfo(reference).Symbol); Assert.Equal("args", label.ToTestDisplayString()); Assert.Equal(SymbolKind.Label, label.Kind); Assert.Equal(SymbolKind.Method, label.ContainingSymbol.Kind); Assert.False(label.ContainingSymbol.IsImplicitlyDeclared); Assert.Equal(SymbolKind.NamedType, label.ContainingSymbol.ContainingSymbol.Kind); Assert.False(label.ContainingSymbol.ContainingSymbol.IsImplicitlyDeclared); Assert.True(((INamespaceSymbol)label.ContainingSymbol.ContainingSymbol.ContainingSymbol).IsGlobalNamespace); } [Fact] public void ExplicitMain_01() { var text = @" static void Main() {} System.Console.Write(""Hi!""); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,13): warning CS7022: The entry point of the program is global code; ignoring 'Main()' entry point. // static void Main() Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Main()").WithLocation(2, 13), // (2,13): warning CS8321: The local function 'Main' is declared but never used // static void Main() Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Main").WithArguments("Main").WithLocation(2, 13) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_02() { var text = @" System.Console.Write(""H""); Main(); System.Console.Write(""!""); static void Main() { System.Console.Write(""i""); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,13): warning CS7022: The entry point of the program is global code; ignoring 'Main()' entry point. // static void Main() Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Main()").WithLocation(6, 13) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_03() { var text = @" using System; using System.Threading.Tasks; System.Console.Write(""Hi!""); partial class Program { static async Task Main() { Console.Write(""hello ""); await Task.Factory.StartNew(() => 5); Console.Write(""async main""); } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (9,23): warning CS7022: The entry point of the program is global code; ignoring 'Program.Main()' entry point. // static async Task Main() Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Program.Main()").WithLocation(9, 23) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_04() { var text = @" using System; using System.Threading.Tasks; await Task.Factory.StartNew(() => 5); System.Console.Write(""Hi!""); partial class Program { static async Task Main() { Console.Write(""hello ""); await Task.Factory.StartNew(() => 5); Console.Write(""async main""); } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (10,23): warning CS7022: The entry point of the program is global code; ignoring 'Program.Main()' entry point. // static async Task Main() Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Program.Main()").WithLocation(10, 23) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_05() { var text = @" using System; using System.Threading.Tasks; await Task.Factory.StartNew(() => 5); System.Console.Write(""Hi!""); partial class Program { static void Main() { Console.Write(""hello ""); } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (10,17): warning CS7022: The entry point of the program is global code; ignoring 'Program.Main()' entry point. // static void Main() Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Program.Main()").WithLocation(10, 17) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_06() { var text = @" System.Console.Write(""Hi!""); partial class Program { static void Main() { System.Console.Write(""hello ""); } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,17): warning CS7022: The entry point of the program is global code; ignoring 'Program.Main()' entry point. // static void Main() Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Program.Main()").WithLocation(6, 17) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_07() { var text = @" using System; using System.Threading.Tasks; System.Console.Write(""Hi!""); class Program2 { static void Main(string[] args) { Console.Write(""hello ""); } static async Task Main() { Console.Write(""hello ""); await Task.Factory.StartNew(() => 5); Console.Write(""async main""); } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (9,17): warning CS7022: The entry point of the program is global code; ignoring 'Program2.Main(string[])' entry point. // static void Main(string[] args) Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Program2.Main(string[])").WithLocation(9, 17), // (14,23): warning CS7022: The entry point of the program is global code; ignoring 'Program2.Main()' entry point. // static async Task Main() Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Program2.Main()").WithLocation(14, 23) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_08() { var text = @" using System; using System.Threading.Tasks; await Task.Factory.StartNew(() => 5); System.Console.Write(""Hi!""); class Program2 { static void Main() { Console.Write(""hello ""); } static async Task Main(string[] args) { await Task.Factory.StartNew(() => 5); Console.Write(""async main""); } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (10,17): warning CS7022: The entry point of the program is global code; ignoring 'Program2.Main()' entry point. // static void Main() Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Program2.Main()").WithLocation(10, 17), // (15,23): warning CS7022: The entry point of the program is global code; ignoring 'Program2.Main(string[])' entry point. // static async Task Main(string[] args) Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Program2.Main(string[])").WithLocation(15, 23) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_09() { var text1 = @" using System; using System.Threading.Tasks; string s = ""Hello world!""; foreach (var c in s) { await N1.Helpers.Wait(); Console.Write(c); } Console.WriteLine(); namespace N1 { class Helpers { static void Main() { } public static async Task Wait() { await Task.Delay(500); } } }"; var text4 = @" using System.Threading.Tasks; class Helpers { public static async Task Wait() { await Task.Delay(500); } } "; var comp = CreateCompilation(new[] { text1, text4 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics( // (19,21): warning CS7022: The entry point of the program is global code; ignoring 'Helpers.Main()' entry point. // static void Main() Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("N1.Helpers.Main()").WithLocation(19, 21) ); } [Fact] public void ExplicitMain_10() { var text = @" using System.Threading.Tasks; System.Console.Write(""Hi!""); class Program2 { static void Main() { System.Console.Write(""Program2""); } static async Task Main(string[] args) { System.Console.Write(""Program2Async""); await Task.Factory.StartNew(() => 5); } } class Program3 { static void Main(string[] args) { System.Console.Write(""Program3""); } } "; CompileAndVerify(text, options: TestOptions.DebugExe.WithMainTypeName("Program2"), parseOptions: DefaultParseOptions, expectedOutput: "Program2").VerifyDiagnostics( // (13,23): warning CS8892: Method 'Program2.Main(string[])' will not be used as an entry point because a synchronous entry point 'Program2.Main()' was found. // static async Task Main(string[] args) Diagnostic(ErrorCode.WRN_SyncAndAsyncEntryPoints, "Main").WithArguments("Program2.Main(string[])", "Program2.Main()").WithLocation(13, 23) ); } [Fact] public void ExplicitMain_11() { var text = @" using System.Threading.Tasks; System.Console.Write(""Hi!""); partial class Program { static void Main() { } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe.WithMainTypeName(""), parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics( // error CS7088: Invalid 'MainTypeName' value: ''. Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("MainTypeName", "").WithLocation(1, 1) ); } [Fact] public void ExplicitMain_12() { var text = @" System.Console.Write(""H""); Main(); System.Console.Write(""!""); void Main() { System.Console.Write(""i""); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics(); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_13() { var text = @" System.Console.Write(""H""); Main(""""); System.Console.Write(""!""); static void Main(string args) { System.Console.Write(""i""); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics(); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_14() { var text = @" System.Console.Write(""H""); Main(); System.Console.Write(""!""); static long Main() { System.Console.Write(""i""); return 0; } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics(); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_15() { var text = @" System.Console.Write(""H""); Main(); System.Console.Write(""!""); static int Main() { System.Console.Write(""i""); return 0; } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,12): warning CS7022: The entry point of the program is global code; ignoring 'Main()' entry point. // static int Main() Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Main()").WithLocation(6, 12) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_16() { var text = @" System.Console.Write(""H""); Main(null); System.Console.Write(""!""); static void Main(string[] args) { System.Console.Write(""i""); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,13): warning CS7022: The entry point of the program is global code; ignoring 'Main(string[])' entry point. // static void Main(string[] args) Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Main(string[])").WithLocation(6, 13) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_17() { var text = @" System.Console.Write(""H""); Main(null); System.Console.Write(""!""); static int Main(string[] args) { System.Console.Write(""i""); return 0; } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,12): warning CS7022: The entry point of the program is global code; ignoring 'Main(string[])' entry point. // static int Main(string[] args) Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Main(string[])").WithLocation(6, 12) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_18() { var text = @" using System.Threading.Tasks; System.Console.Write(""H""); await Main(); System.Console.Write(""!""); async static Task Main() { System.Console.Write(""i""); await Task.Yield(); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (8,19): warning CS7022: The entry point of the program is global code; ignoring 'Main()' entry point. // async static Task Main() Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Main()").WithLocation(8, 19) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_19() { var text = @" using System.Threading.Tasks; System.Console.Write(""H""); await Main(); System.Console.Write(""!""); static async Task<int> Main() { System.Console.Write(""i""); await Task.Yield(); return 0; } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (8,24): warning CS7022: The entry point of the program is global code; ignoring 'Main()' entry point. // static async Task<int> Main() Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Main()").WithLocation(8, 24) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_20() { var text = @" using System.Threading.Tasks; System.Console.Write(""H""); await Main(null); System.Console.Write(""!""); static async Task Main(string[] args) { System.Console.Write(""i""); await Task.Yield(); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (8,19): warning CS7022: The entry point of the program is global code; ignoring 'Main(string[])' entry point. // static async Task Main(string[] args) Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Main(string[])").WithLocation(8, 19) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_21() { var text = @" using System.Threading.Tasks; System.Console.Write(""H""); await Main(null); System.Console.Write(""!""); static async Task<int> Main(string[] args) { System.Console.Write(""i""); await Task.Yield(); return 0; } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (8,24): warning CS7022: The entry point of the program is global code; ignoring 'Main(string[])' entry point. // static async Task<int> Main(string[] args) Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Main(string[])").WithLocation(8, 24) ); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_22() { var text = @" System.Console.Write(""H""); Main<int>(); System.Console.Write(""!""); static void Main<T>() { System.Console.Write(""i""); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics(); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_23() { var text = @" System.Console.Write(""H""); local(); System.Console.Write(""!""); static void local() { Main(); static void Main() { System.Console.Write(""i""); } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics(); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void ExplicitMain_24() { var text = @" System.Console.Write(42); partial class Program { static partial void Main(string[] args); } "; var comp = CreateCompilation(text); var verifier = CompileAndVerify(comp, expectedOutput: "42"); verifier.VerifyDiagnostics(); } [Fact] public void ExplicitMain_25() { string source = """ System.Console.WriteLine("tls"); class C { static void Main() { System.Console.WriteLine("main"); } } """; CompileAndVerify(source, expectedOutput: "main", options: TestOptions.DebugExe.WithMainTypeName("C"), parseOptions: DefaultParseOptions); } [Fact] public void ExplicitMain_26() { string source = """ System.Console.WriteLine("tls"); partial class Program { static void Main() { System.Console.WriteLine("main"); } } """; CompileAndVerify(source, expectedOutput: "main", options: TestOptions.DebugExe.WithMainTypeName("Program"), parseOptions: DefaultParseOptions); } [Fact] public void ExplicitMain_27() { string source = """ System.Console.WriteLine("tls"); """; CreateCompilation(source, options: TestOptions.DebugExe.WithMainTypeName("Program"), parseOptions: DefaultParseOptions).VerifyDiagnostics( // (1,1): error CS1558: 'Program' does not have a suitable static 'Main' method // System.Console.WriteLine("tls"); Diagnostic(ErrorCode.ERR_NoMainInClass, "System").WithArguments("Program").WithLocation(1, 1)); } [Fact] public void Yield_01() { var text = @"yield break;"; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,1): error CS1624: The body of '<top-level-statements-entry-point>' cannot be an iterator block because 'void' is not an iterator interface type // yield break; Diagnostic(ErrorCode.ERR_BadIteratorReturn, "yield break;").WithArguments("<top-level-statements-entry-point>", "void").WithLocation(1, 1) ); } [Fact] public void Yield_02() { var text = @"{yield return 0;}"; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,1): error CS1624: The body of '<top-level-statements-entry-point>' cannot be an iterator block because 'void' is not an iterator interface type // {yield return 0;} Diagnostic(ErrorCode.ERR_BadIteratorReturn, "{yield return 0;}").WithArguments("<top-level-statements-entry-point>", "void").WithLocation(1, 1) ); } [Fact] public void OutOfOrder_01() { var text = @" class C {} System.Console.WriteLine(1); System.Console.WriteLine(2); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (4,1): error CS8803: Top-level statements must precede namespace and type declarations. // System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "System.Console.WriteLine(1);").WithLocation(4, 1) ); } [Fact] public void OutOfOrder_02() { var text = @" System.Console.WriteLine(0); namespace C {} System.Console.WriteLine(1); System.Console.WriteLine(2); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,1): error CS8803: Top-level statements must precede namespace and type declarations. // System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "System.Console.WriteLine(1);").WithLocation(6, 1) ); } [Fact] public void OutOfOrder_03() { var text = @" class C {} System.Console.WriteLine(1); System.Console.WriteLine(2); class D {} System.Console.WriteLine(3); System.Console.WriteLine(4); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (4,1): error CS8803: Top-level statements must precede namespace and type declarations. // System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "System.Console.WriteLine(1);").WithLocation(4, 1) ); } [Fact] public void OutOfOrder_04() { var text = @" System.Console.WriteLine(0); namespace C {} System.Console.WriteLine(1); System.Console.WriteLine(2); namespace D {} System.Console.WriteLine(3); System.Console.WriteLine(4); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,1): error CS8803: Top-level statements must precede namespace and type declarations. // System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "System.Console.WriteLine(1);").WithLocation(6, 1) ); } [Fact] public void OutOfOrder_05() { var text = @" System.Console.WriteLine(0); struct S {} System.Console.WriteLine(1); System.Console.WriteLine(2); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,1): error CS8803: Top-level statements must precede namespace and type declarations. // System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "System.Console.WriteLine(1);").WithLocation(6, 1) ); } [Fact] public void OutOfOrder_06() { var text = @" System.Console.WriteLine(0); enum C { V } System.Console.WriteLine(1); System.Console.WriteLine(2); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,1): error CS8803: Top-level statements must precede namespace and type declarations. // System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "System.Console.WriteLine(1);").WithLocation(6, 1) ); } [Fact] public void OutOfOrder_07() { var text = @" System.Console.WriteLine(0); interface C {} System.Console.WriteLine(1); System.Console.WriteLine(2); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,1): error CS8803: Top-level statements must precede namespace and type declarations. // System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "System.Console.WriteLine(1);").WithLocation(6, 1) ); } [Fact] public void OutOfOrder_08() { var text = @" System.Console.WriteLine(0); delegate void D (); System.Console.WriteLine(1); System.Console.WriteLine(2); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,1): error CS8803: Top-level statements must precede namespace and type declarations. // System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "System.Console.WriteLine(1);").WithLocation(6, 1) ); } [Fact] public void OutOfOrder_09() { var text = @" System.Console.WriteLine(0); using System; Console.WriteLine(1); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (4,1): error CS1529: A using clause must precede all other elements defined in the namespace except extern alias declarations // using System; Diagnostic(ErrorCode.ERR_UsingAfterElements, "using System;").WithLocation(4, 1), // (6,1): error CS0103: The name 'Console' does not exist in the current context // Console.WriteLine(1); Diagnostic(ErrorCode.ERR_NameNotInContext, "Console").WithArguments("Console").WithLocation(6, 1) ); } [Fact] public void OutOfOrder_10() { var text = @" System.Console.WriteLine(0); [module: MyAttribute] class MyAttribute : System.Attribute {} "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (4,2): error CS1730: Assembly and module attributes must precede all other elements defined in a file except using clauses and extern alias declarations // [module: MyAttribute] Diagnostic(ErrorCode.ERR_GlobalAttributesNotFirst, "module").WithLocation(4, 2) ); } [Fact] public void OutOfOrder_11() { var text = @" System.Console.WriteLine(0); extern alias A; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (4,1): error CS0439: An extern alias declaration must precede all other elements defined in the namespace // extern alias A; Diagnostic(ErrorCode.ERR_ExternAfterElements, "extern").WithLocation(4, 1) ); } [Fact] public void OutOfOrder_12() { var text = @" extern alias A; using System; [module: MyAttribute] Console.WriteLine(1); class MyAttribute : System.Attribute {} "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): hidden CS8020: Unused extern alias. // extern alias A; Diagnostic(ErrorCode.HDN_UnusedExternAlias, "extern alias A;").WithLocation(2, 1), // (2,14): error CS0430: The extern alias 'A' was not specified in a /reference option // extern alias A; Diagnostic(ErrorCode.ERR_BadExternAlias, "A").WithArguments("A").WithLocation(2, 14) ); } [Fact] public void OutOfOrder_13() { var text = @" local(); class C {} void local() => System.Console.WriteLine(1); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (6,1): error CS8803: Top-level statements must precede namespace and type declarations. // void local() => System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "void local() => System.Console.WriteLine(1);").WithLocation(6, 1) ); } [Fact] public void Attributes_01() { var text1 = @" [MyAttribute(i)] const int i = 1; [MyAttribute(i + 1)] System.Console.Write(i); [MyAttribute(i + 2)] int j = i; System.Console.Write(j); [MyAttribute(i + 3)] new MyAttribute(i); [MyAttribute(i + 4)] local(); [MyAttribute(i + 5)] void local() {} class MyAttribute : System.Attribute { public MyAttribute(int x) {} } "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,1): error CS7014: Attributes are not valid in this context. // [MyAttribute(i)] Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[MyAttribute(i)]").WithLocation(2, 1), // (5,1): error CS7014: Attributes are not valid in this context. // [MyAttribute(i + 1)] Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[MyAttribute(i + 1)]").WithLocation(5, 1), // (8,1): error CS7014: Attributes are not valid in this context. // [MyAttribute(i + 2)] Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[MyAttribute(i + 2)]").WithLocation(8, 1), // (12,1): error CS7014: Attributes are not valid in this context. // [MyAttribute(i + 3)] Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[MyAttribute(i + 3)]").WithLocation(12, 1), // (16,1): error CS0246: The type or namespace name 'local' could not be found (are you missing a using directive or an assembly reference?) // local(); Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "local").WithArguments("local").WithLocation(16, 1), // (16,6): error CS1001: Identifier expected // local(); Diagnostic(ErrorCode.ERR_IdentifierExpected, "(").WithLocation(16, 6), // (16,6): error CS8112: Local function '()' must declare a body because it is not marked 'static extern'. // local(); Diagnostic(ErrorCode.ERR_LocalFunctionMissingBody, "").WithArguments("()").WithLocation(16, 6), // (19,6): warning CS8321: The local function 'local' is declared but never used // void local() {} Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "local").WithArguments("local").WithLocation(19, 6) ); var tree1 = comp.SyntaxTrees[0]; var model1 = comp.GetSemanticModel(tree1); var localDecl = tree1.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().First(); var declSymbol = model1.GetDeclaredSymbol(localDecl); Assert.Equal("System.Int32 i", declSymbol.ToTestDisplayString()); var localRefs = tree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "i").ToArray(); Assert.Equal(9, localRefs.Length); foreach (var localRef in localRefs) { var refSymbol = model1.GetSymbolInfo(localRef).Symbol; Assert.Same(declSymbol, refSymbol); Assert.Contains(declSymbol.Name, model1.LookupNames(localRef.SpanStart)); Assert.Contains(declSymbol, model1.LookupSymbols(localRef.SpanStart)); Assert.Same(declSymbol, model1.LookupSymbols(localRef.SpanStart, name: declSymbol.Name).Single()); } localDecl = tree1.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().ElementAt(1); declSymbol = model1.GetDeclaredSymbol(localDecl); Assert.Equal("System.Int32 j", declSymbol.ToTestDisplayString()); } [Fact] public void Attributes_02() { var source = @" using System.Runtime.CompilerServices; return; #pragma warning disable 8321 // Unreferenced local function [MethodImpl(MethodImplOptions.ForwardRef)] static void forwardRef() { System.Console.WriteLine(0); } [MethodImpl(MethodImplOptions.NoInlining)] static void noInlining() { System.Console.WriteLine(1); } [MethodImpl(MethodImplOptions.NoOptimization)] static void noOptimization() { System.Console.WriteLine(2); } [MethodImpl(MethodImplOptions.Synchronized)] static void synchronized() { System.Console.WriteLine(3); } [MethodImpl(MethodImplOptions.InternalCall)] extern static void internalCallStatic(); "; var verifier = CompileAndVerify( source, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: DefaultParseOptions, assemblyValidator: validateAssembly, verify: Verification.Skipped); var comp = verifier.Compilation; var syntaxTree = comp.SyntaxTrees.Single(); var semanticModel = comp.GetSemanticModel(syntaxTree); var localFunctions = syntaxTree.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().ToList(); checkImplAttributes(localFunctions[0], MethodImplAttributes.ForwardRef); checkImplAttributes(localFunctions[1], MethodImplAttributes.NoInlining); checkImplAttributes(localFunctions[2], MethodImplAttributes.NoOptimization); checkImplAttributes(localFunctions[3], MethodImplAttributes.Synchronized); checkImplAttributes(localFunctions[4], MethodImplAttributes.InternalCall); void checkImplAttributes(LocalFunctionStatementSyntax localFunctionStatement, MethodImplAttributes expectedFlags) { var localFunction = semanticModel.GetDeclaredSymbol(localFunctionStatement).GetSymbol<LocalFunctionSymbol>(); Assert.Equal(expectedFlags, localFunction.ImplementationAttributes); } void validateAssembly(PEAssembly assembly) { var peReader = assembly.GetMetadataReader(); foreach (var methodHandle in peReader.MethodDefinitions) { var methodDef = peReader.GetMethodDefinition(methodHandle); var actualFlags = methodDef.ImplAttributes; var methodName = peReader.GetString(methodDef.Name); var expectedFlags = methodName switch { "<" + WellKnownMemberNames.TopLevelStatementsEntryPointMethodName + ">g__forwardRef|0_0" => MethodImplAttributes.ForwardRef, "<" + WellKnownMemberNames.TopLevelStatementsEntryPointMethodName + ">g__noInlining|0_1" => MethodImplAttributes.NoInlining, "<" + WellKnownMemberNames.TopLevelStatementsEntryPointMethodName + ">g__noOptimization|0_2" => MethodImplAttributes.NoOptimization, "<" + WellKnownMemberNames.TopLevelStatementsEntryPointMethodName + ">g__synchronized|0_3" => MethodImplAttributes.Synchronized, "<" + WellKnownMemberNames.TopLevelStatementsEntryPointMethodName + ">g__internalCallStatic|0_4" => MethodImplAttributes.InternalCall, ".ctor" => MethodImplAttributes.IL, WellKnownMemberNames.TopLevelStatementsEntryPointMethodName => MethodImplAttributes.IL, _ => throw TestExceptionUtilities.UnexpectedValue(methodName) }; Assert.Equal(expectedFlags, actualFlags); } } } [Fact] public void Attributes_03() { var source = @" using System.Runtime.InteropServices; local1(); [DllImport( ""something.dll"", EntryPoint = ""a"", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true, PreserveSig = false, CallingConvention = CallingConvention.Cdecl, BestFitMapping = false, ThrowOnUnmappableChar = true)] static extern void local1(); "; var verifier = CompileAndVerify( source, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: DefaultParseOptions, symbolValidator: validate, sourceSymbolValidator: validate, verify: Verification.Skipped); var comp = verifier.Compilation; var syntaxTree = comp.SyntaxTrees.Single(); var semanticModel = comp.GetSemanticModel(syntaxTree); var localFunction = semanticModel .GetDeclaredSymbol(syntaxTree.GetRoot().DescendantNodes().OfType<LocalFunctionStatementSyntax>().Single()) .GetSymbol<LocalFunctionSymbol>(); Assert.Equal(new[] { "DllImportAttribute" }, GetAttributeNames(localFunction.GetAttributes())); validateLocalFunction(localFunction); void validate(ModuleSymbol module) { var fromSource = module is SourceModuleSymbol; var program = module.GlobalNamespace.GetMember<NamedTypeSymbol>(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName); var programAttributes = GetAttributeNames(program.GetAttributes().As<CSharpAttributeData>()); Assert.False(program.IsImplicitlyDeclared); if (fromSource) { Assert.Empty(programAttributes); } else { Assert.Equal(new[] { "CompilerGeneratedAttribute" }, programAttributes); } MethodSymbol method = program.GetMethod(WellKnownMemberNames.TopLevelStatementsEntryPointMethodName); Assert.Empty(method.GetAttributes()); Assert.False(method.IsImplicitlyDeclared); if (!fromSource) { var localFn1 = program.GetMethod("<" + WellKnownMemberNames.TopLevelStatementsEntryPointMethodName + ">g__local1|0_0"); Assert.Equal(new[] { "CompilerGeneratedAttribute" }, GetAttributeNames(localFn1.GetAttributes().As<CSharpAttributeData>())); validateLocalFunction(localFn1); } } static void validateLocalFunction(MethodSymbol localFunction) { Assert.True(localFunction.IsExtern); var importData = localFunction.GetDllImportData(); Assert.NotNull(importData); Assert.Equal("something.dll", importData.ModuleName); Assert.Equal("a", importData.EntryPointName); Assert.Equal(CharSet.Ansi, importData.CharacterSet); Assert.True(importData.SetLastError); Assert.True(importData.ExactSpelling); Assert.Equal(MethodImplAttributes.IL, localFunction.ImplementationAttributes); Assert.Equal(CallingConvention.Cdecl, importData.CallingConvention); Assert.False(importData.BestFitMapping); Assert.True(importData.ThrowOnUnmappableCharacter); } } [Fact] public void ModelWithIgnoredAccessibility_01() { var source = @" new A().M(); class A { A M() { return new A(); } } "; var comp = CreateCompilation(source, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,9): error CS0122: 'A.M()' is inaccessible due to its protection level // new A().M(); Diagnostic(ErrorCode.ERR_BadAccess, "M").WithArguments("A.M()").WithLocation(2, 9) ); var a = ((Compilation)comp).SourceModule.GlobalNamespace.GetTypeMember("A"); var syntaxTree = comp.SyntaxTrees.Single(); var invocation = syntaxTree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single(); var semanticModel = comp.GetSemanticModel(syntaxTree); Assert.Equal("A", semanticModel.GetTypeInfo(invocation).Type.Name); Assert.Null(semanticModel.GetSymbolInfo(invocation).Symbol); Assert.Equal("M", semanticModel.GetSymbolInfo(invocation).CandidateSymbols.Single().Name); Assert.Equal(CandidateReason.Inaccessible, semanticModel.GetSymbolInfo(invocation).CandidateReason); Assert.Empty(semanticModel.LookupSymbols(invocation.SpanStart, container: a, name: "M")); semanticModel = comp.GetSemanticModel(syntaxTree, ignoreAccessibility: true); Assert.Equal("A", semanticModel.GetTypeInfo(invocation).Type.Name); Assert.Equal("M", semanticModel.GetSymbolInfo(invocation).Symbol.Name); Assert.NotEmpty(semanticModel.LookupSymbols(invocation.SpanStart, container: a, name: "M")); } [Fact] public void ModelWithIgnoredAccessibility_02() { var source = @" var x = new A().M(); class A { A M() { x = null; return new A(); } } "; var comp = CreateCompilation(source, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (2,17): error CS0122: 'A.M()' is inaccessible due to its protection level // var x = new A().M(); Diagnostic(ErrorCode.ERR_BadAccess, "M").WithArguments("A.M()").WithLocation(2, 17), // (8,9): error CS8801: Cannot use local variable or local function 'x' declared in a top-level statement in this context. // x = null; Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "x").WithArguments("x").WithLocation(8, 9) ); var a = ((Compilation)comp).SourceModule.GlobalNamespace.GetTypeMember("A"); var syntaxTree = comp.SyntaxTrees.Single(); var localDecl = syntaxTree.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Single(); var localRef = syntaxTree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "x").Single(); var semanticModel = comp.GetSemanticModel(syntaxTree, ignoreAccessibility: true); var x = semanticModel.GetDeclaredSymbol(localDecl); Assert.Same(x, semanticModel.LookupSymbols(localDecl.SpanStart, name: "x").Single()); Assert.Same(x, semanticModel.GetSymbolInfo(localRef).Symbol); Assert.Same(x, semanticModel.LookupSymbols(localRef.SpanStart, name: "x").Single()); } [Fact] public void ModelWithIgnoredAccessibility_03() { var source = @" var x = new B().M(1); class A { public long M(long i) => i; } class B : A { protected int M(int i) { _ = x; return i; } } "; var comp = CreateCompilation(source, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (13,13): error CS8801: Cannot use local variable or local function 'x' declared in a top-level statement in this context. // _ = x; Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "x").WithArguments("x").WithLocation(13, 13) ); var a = ((Compilation)comp).SourceModule.GlobalNamespace.GetTypeMember("A"); var syntaxTree1 = comp.SyntaxTrees.Single(); var localDecl = syntaxTree1.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Single(); var localRef = syntaxTree1.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "x").Single(); verifyModel(ignoreAccessibility: true, "System.Int32"); verifyModel(ignoreAccessibility: false, "System.Int64"); void verifyModel(bool ignoreAccessibility, string expectedType) { var semanticModel1 = comp.GetSemanticModel(syntaxTree1, ignoreAccessibility); var xDecl = semanticModel1.GetDeclaredSymbol(localDecl); Assert.Same(xDecl, semanticModel1.LookupSymbols(localDecl.SpanStart, name: "x").Single()); var xRef = semanticModel1.GetSymbolInfo(localRef).Symbol; Assert.Same(xRef, semanticModel1.LookupSymbols(localRef.SpanStart, name: "x").Single()); Assert.Equal(expectedType, ((ILocalSymbol)xRef).Type.ToTestDisplayString()); Assert.Equal(expectedType, ((ILocalSymbol)xDecl).Type.ToTestDisplayString()); Assert.Same(xDecl, xRef); } } [Fact] public void ModelWithIgnoredAccessibility_04() { var source1 = @" var x = new B().M(1); "; var source2 = @" class A { public long M(long i) => i; } class B : A { protected int M(int i) { _ = x; return i; } } "; var comp = CreateCompilation(new[] { source1, source2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (11,13): error CS8801: Cannot use local variable or local function 'x' declared in a top-level statement in this context. // _ = x; Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "x").WithArguments("x").WithLocation(11, 13) ); var a = ((Compilation)comp).SourceModule.GlobalNamespace.GetTypeMember("A"); var syntaxTree1 = comp.SyntaxTrees.First(); var localDecl = syntaxTree1.GetRoot().DescendantNodes().OfType<VariableDeclaratorSyntax>().Single(); var syntaxTree2 = comp.SyntaxTrees[1]; var localRef = syntaxTree2.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "x").Single(); verifyModel(ignoreAccessibility: true, "System.Int32"); verifyModel(ignoreAccessibility: false, "System.Int64"); void verifyModel(bool ignoreAccessibility, string expectedType) { var semanticModel1 = comp.GetSemanticModel(syntaxTree1, ignoreAccessibility); var xDecl = semanticModel1.GetDeclaredSymbol(localDecl); Assert.Same(xDecl, semanticModel1.LookupSymbols(localDecl.SpanStart, name: "x").Single()); Assert.Equal(expectedType, ((ILocalSymbol)xDecl).Type.ToTestDisplayString()); var semanticModel2 = comp.GetSemanticModel(syntaxTree2, ignoreAccessibility); var xRef = semanticModel2.GetSymbolInfo(localRef).Symbol; Assert.Same(xRef, semanticModel2.LookupSymbols(localRef.SpanStart, name: "x").Single()); Assert.Equal(expectedType, ((ILocalSymbol)xRef).Type.ToTestDisplayString()); Assert.Same(xDecl, xRef); } } [Fact] public void AnalyzerActions_01() { var text1 = @"System.Console.WriteLine(1);"; var analyzer = new AnalyzerActions_01_Analyzer(); var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(0, analyzer.FireCount2); Assert.Equal(1, analyzer.FireCount3); Assert.Equal(0, analyzer.FireCount4); var text2 = @"System.Console.WriteLine(2);"; analyzer = new AnalyzerActions_01_Analyzer(); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); Assert.Equal(1, analyzer.FireCount3); Assert.Equal(1, analyzer.FireCount4); } private class AnalyzerActions_01_Analyzer : DiagnosticAnalyzer { public int FireCount1; public int FireCount2; public int FireCount3; public int FireCount4; private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.RegisterSyntaxNodeAction(Handle1, SyntaxKind.GlobalStatement); context.RegisterSyntaxNodeAction(Handle2, SyntaxKind.CompilationUnit); } private void Handle1(SyntaxNodeAnalysisContext context) { var model = context.SemanticModel; var globalStatement = (GlobalStatementSyntax)context.Node; var syntaxTreeModel = ((SyntaxTreeSemanticModel)model); switch (globalStatement.ToString()) { case "System.Console.WriteLine(1);": Interlocked.Increment(ref FireCount1); break; case "System.Console.WriteLine(2);": Interlocked.Increment(ref FireCount2); break; default: Assert.True(false); break; } Assert.Equal("<top-level-statements-entry-point>", context.ContainingSymbol.ToTestDisplayString()); Assert.Same(globalStatement.SyntaxTree, context.ContainingSymbol.DeclaringSyntaxReferences.Single().SyntaxTree); Assert.True(syntaxTreeModel.TestOnlyMemberModels.ContainsKey(globalStatement.Parent)); MemberSemanticModel mm = syntaxTreeModel.TestOnlyMemberModels[globalStatement.Parent]; Assert.False(mm.TestOnlyTryGetBoundNodesFromMap(globalStatement.Statement).IsEmpty); Assert.Same(mm, syntaxTreeModel.GetMemberModel(globalStatement.Statement)); } private void Handle2(SyntaxNodeAnalysisContext context) { var model = context.SemanticModel; var unit = (CompilationUnitSyntax)context.Node; var syntaxTreeModel = ((SyntaxTreeSemanticModel)model); switch (unit.ToString()) { case "System.Console.WriteLine(1);": Interlocked.Increment(ref FireCount3); break; case "System.Console.WriteLine(2);": Interlocked.Increment(ref FireCount4); break; default: Assert.True(false); break; } switch (context.ContainingSymbol.ToTestDisplayString()) { case "<global namespace>": break; default: Assert.True(false); break; } } } [Fact] public void AnalyzerActions_02() { var text1 = @"System.Console.WriteLine(1);"; var analyzer = new AnalyzerActions_02_Analyzer(); var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(0, analyzer.FireCount2); var text2 = @"System.Console.WriteLine(2);"; analyzer = new AnalyzerActions_02_Analyzer(); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); } private class AnalyzerActions_02_Analyzer : DiagnosticAnalyzer { public int FireCount1; public int FireCount2; private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.RegisterSymbolAction(Handle, SymbolKind.Method); } private void Handle(SymbolAnalysisContext context) { Assert.Equal("<top-level-statements-entry-point>", context.Symbol.ToTestDisplayString()); switch (context.Symbol.DeclaringSyntaxReferences.Single().GetSyntax().ToString()) { case "System.Console.WriteLine(1);": Interlocked.Increment(ref FireCount1); break; case "System.Console.WriteLine(2);": Interlocked.Increment(ref FireCount2); break; default: Assert.True(false); break; } } } [Fact] public void AnalyzerActions_03() { var text1 = @"System.Console.WriteLine(1);"; var analyzer = new AnalyzerActions_03_Analyzer(); var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(0, analyzer.FireCount2); Assert.Equal(1, analyzer.FireCount3); Assert.Equal(1, analyzer.FireCount4); Assert.Equal(0, analyzer.FireCount5); Assert.Equal(1, analyzer.FireCount6); Assert.Equal(0, analyzer.FireCount7); Assert.Equal(1, analyzer.FireCount8); var text2 = @"System.Console.WriteLine(2);"; analyzer = new AnalyzerActions_03_Analyzer(); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); Assert.Equal(1, analyzer.FireCount3); Assert.Equal(1, analyzer.FireCount4); Assert.Equal(1, analyzer.FireCount5); Assert.Equal(1, analyzer.FireCount6); Assert.Equal(1, analyzer.FireCount7); Assert.Equal(1, analyzer.FireCount8); } private class AnalyzerActions_03_Analyzer : DiagnosticAnalyzer { public int FireCount1; public int FireCount2; public int FireCount3; public int FireCount4; public int FireCount5; public int FireCount6; public int FireCount7; public int FireCount8; private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.RegisterSymbolStartAction(Handle1, SymbolKind.Method); context.RegisterSymbolStartAction(Handle2, SymbolKind.NamedType); } private void Handle1(SymbolStartAnalysisContext context) { Assert.Equal("<top-level-statements-entry-point>", context.Symbol.ToTestDisplayString()); switch (context.Symbol.DeclaringSyntaxReferences.Single().GetSyntax().ToString()) { case "System.Console.WriteLine(1);": Interlocked.Increment(ref FireCount1); context.RegisterSymbolEndAction(Handle3); break; case "System.Console.WriteLine(2);": Interlocked.Increment(ref FireCount2); context.RegisterSymbolEndAction(Handle4); break; default: Assert.True(false); break; } } private void Handle2(SymbolStartAnalysisContext context) { Assert.Equal(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName, context.Symbol.ToTestDisplayString()); Interlocked.Increment(ref FireCount3); context.RegisterSymbolEndAction(Handle5); foreach (var syntaxReference in context.Symbol.DeclaringSyntaxReferences) { switch (syntaxReference.GetSyntax().ToString()) { case "System.Console.WriteLine(1);": Interlocked.Increment(ref FireCount4); break; case "System.Console.WriteLine(2);": Interlocked.Increment(ref FireCount5); break; default: Assert.True(false); break; } } } private void Handle3(SymbolAnalysisContext context) { Assert.Equal("<top-level-statements-entry-point>", context.Symbol.ToTestDisplayString()); Interlocked.Increment(ref FireCount6); Assert.Equal("System.Console.WriteLine(1);", context.Symbol.DeclaringSyntaxReferences.Single().GetSyntax().ToString()); } private void Handle4(SymbolAnalysisContext context) { Assert.Equal("<top-level-statements-entry-point>", context.Symbol.ToTestDisplayString()); Interlocked.Increment(ref FireCount7); Assert.Equal("System.Console.WriteLine(2);", context.Symbol.DeclaringSyntaxReferences.Single().GetSyntax().ToString()); } private void Handle5(SymbolAnalysisContext context) { Assert.Equal(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName, context.Symbol.ToTestDisplayString()); Interlocked.Increment(ref FireCount8); } } [Fact] public void AnalyzerActions_04() { var text1 = @"System.Console.WriteLine(1);"; var analyzer = new AnalyzerActions_04_Analyzer(); var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(0, analyzer.FireCount2); Assert.Equal(1, analyzer.FireCount3); Assert.Equal(0, analyzer.FireCount4); var text2 = @"System.Console.WriteLine(2);"; analyzer = new AnalyzerActions_04_Analyzer(); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); Assert.Equal(1, analyzer.FireCount3); Assert.Equal(1, analyzer.FireCount4); } private class AnalyzerActions_04_Analyzer : DiagnosticAnalyzer { public int FireCount1; public int FireCount2; public int FireCount3; public int FireCount4; private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.RegisterOperationAction(Handle1, OperationKind.Invocation); context.RegisterOperationAction(Handle2, OperationKind.Block); } private void Handle1(OperationAnalysisContext context) { Assert.Equal("<top-level-statements-entry-point>", context.ContainingSymbol.ToTestDisplayString()); Assert.Same(context.ContainingSymbol.DeclaringSyntaxReferences.Single().SyntaxTree, context.Operation.Syntax.SyntaxTree); Assert.Equal(SyntaxKind.InvocationExpression, context.Operation.Syntax.Kind()); switch (context.Operation.Syntax.ToString()) { case "System.Console.WriteLine(1)": Interlocked.Increment(ref FireCount1); break; case "System.Console.WriteLine(2)": Interlocked.Increment(ref FireCount2); break; default: Assert.True(false); break; } } private void Handle2(OperationAnalysisContext context) { Assert.Equal("<top-level-statements-entry-point>", context.ContainingSymbol.ToTestDisplayString()); Assert.Same(context.ContainingSymbol.DeclaringSyntaxReferences.Single().GetSyntax(), context.Operation.Syntax); Assert.Equal(SyntaxKind.CompilationUnit, context.Operation.Syntax.Kind()); switch (context.Operation.Syntax.ToString()) { case "System.Console.WriteLine(1);": Interlocked.Increment(ref FireCount3); break; case "System.Console.WriteLine(2);": Interlocked.Increment(ref FireCount4); break; default: Assert.True(false); break; } } } [Fact] public void AnalyzerActions_05() { var text1 = @"System.Console.WriteLine(1);"; var analyzer = new AnalyzerActions_05_Analyzer(); var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(0, analyzer.FireCount2); var text2 = @"System.Console.WriteLine(2);"; analyzer = new AnalyzerActions_05_Analyzer(); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); } private class AnalyzerActions_05_Analyzer : DiagnosticAnalyzer { public int FireCount1; public int FireCount2; private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.RegisterOperationBlockAction(Handle); } private void Handle(OperationBlockAnalysisContext context) { Assert.Equal("<top-level-statements-entry-point>", context.OwningSymbol.ToTestDisplayString()); Assert.Equal(SyntaxKind.CompilationUnit, context.OperationBlocks.Single().Syntax.Kind()); switch (context.OperationBlocks.Single().Syntax.ToString()) { case "System.Console.WriteLine(1);": Interlocked.Increment(ref FireCount1); break; case "System.Console.WriteLine(2);": Interlocked.Increment(ref FireCount2); break; default: Assert.True(false); break; } } } [Fact] public void AnalyzerActions_06() { var text1 = @"System.Console.WriteLine(1);"; var analyzer = new AnalyzerActions_06_Analyzer(); var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(0, analyzer.FireCount2); var text2 = @"System.Console.WriteLine(2);"; analyzer = new AnalyzerActions_06_Analyzer(); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); } private class AnalyzerActions_06_Analyzer : DiagnosticAnalyzer { public int FireCount1; public int FireCount2; private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.RegisterOperationBlockStartAction(Handle); } private void Handle(OperationBlockStartAnalysisContext context) { Assert.Equal("<top-level-statements-entry-point>", context.OwningSymbol.ToTestDisplayString()); Assert.Equal(SyntaxKind.CompilationUnit, context.OperationBlocks.Single().Syntax.Kind()); switch (context.OperationBlocks.Single().Syntax.ToString()) { case "System.Console.WriteLine(1);": Interlocked.Increment(ref FireCount1); break; case "System.Console.WriteLine(2);": Interlocked.Increment(ref FireCount2); break; default: Assert.True(false); break; } } } [Fact] public void AnalyzerActions_07() { var text1 = @"System.Console.WriteLine(1);"; var analyzer = new AnalyzerActions_07_Analyzer(); var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(0, analyzer.FireCount2); var text2 = @"System.Console.WriteLine(2);"; analyzer = new AnalyzerActions_07_Analyzer(); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); } private class AnalyzerActions_07_Analyzer : DiagnosticAnalyzer { public int FireCount1; public int FireCount2; private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.RegisterCodeBlockAction(Handle); } private void Handle(CodeBlockAnalysisContext context) { Assert.Equal("<top-level-statements-entry-point>", context.OwningSymbol.ToTestDisplayString()); Assert.Equal(SyntaxKind.CompilationUnit, context.CodeBlock.Kind()); switch (context.CodeBlock.ToString()) { case "System.Console.WriteLine(1);": Interlocked.Increment(ref FireCount1); break; case "System.Console.WriteLine(2);": Interlocked.Increment(ref FireCount2); break; default: Assert.True(false); break; } var model = context.SemanticModel; var unit = (CompilationUnitSyntax)context.CodeBlock; var syntaxTreeModel = ((SyntaxTreeSemanticModel)model); MemberSemanticModel mm = syntaxTreeModel.TestOnlyMemberModels[unit]; Assert.False(mm.TestOnlyTryGetBoundNodesFromMap(unit).IsEmpty); Assert.Same(mm, syntaxTreeModel.GetMemberModel(unit)); } } [Fact] public void AnalyzerActions_08() { var text1 = @"System.Console.WriteLine(1);"; var analyzer = new AnalyzerActions_08_Analyzer(); var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(0, analyzer.FireCount2); var text2 = @"System.Console.WriteLine(2);"; analyzer = new AnalyzerActions_08_Analyzer(); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); } private class AnalyzerActions_08_Analyzer : DiagnosticAnalyzer { public int FireCount1; public int FireCount2; private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.RegisterCodeBlockStartAction<SyntaxKind>(Handle); } private void Handle(CodeBlockStartAnalysisContext<SyntaxKind> context) { Assert.Equal("<top-level-statements-entry-point>", context.OwningSymbol.ToTestDisplayString()); Assert.Equal(SyntaxKind.CompilationUnit, context.CodeBlock.Kind()); switch (context.CodeBlock.ToString()) { case "System.Console.WriteLine(1);": Interlocked.Increment(ref FireCount1); break; case "System.Console.WriteLine(2);": Interlocked.Increment(ref FireCount2); break; default: Assert.True(false); break; } var model = context.SemanticModel; var unit = (CompilationUnitSyntax)context.CodeBlock; var syntaxTreeModel = ((SyntaxTreeSemanticModel)model); MemberSemanticModel mm = syntaxTreeModel.TestOnlyMemberModels[unit]; Assert.False(mm.TestOnlyTryGetBoundNodesFromMap(unit).IsEmpty); Assert.Same(mm, syntaxTreeModel.GetMemberModel(unit)); } } [Fact] public void AnalyzerActions_09() { var text1 = @" System.Console.WriteLine(""Hi!""); "; var text2 = @" class Test { void M() { M(); } } "; var analyzer = new AnalyzerActions_09_Analyzer(); var comp = CreateCompilation(text1 + text2, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); Assert.Equal(1, analyzer.FireCount3); analyzer = new AnalyzerActions_09_Analyzer(); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); Assert.Equal(2, analyzer.FireCount3); } private class AnalyzerActions_09_Analyzer : DiagnosticAnalyzer { public int FireCount1; public int FireCount2; public int FireCount3; private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.RegisterSyntaxNodeAction(Handle1, SyntaxKind.InvocationExpression); context.RegisterSyntaxNodeAction(Handle2, SyntaxKind.CompilationUnit); } private void Handle1(SyntaxNodeAnalysisContext context) { var model = context.SemanticModel; var node = (CSharpSyntaxNode)context.Node; var syntaxTreeModel = ((SyntaxTreeSemanticModel)model); switch (node.ToString()) { case @"System.Console.WriteLine(""Hi!"")": Interlocked.Increment(ref FireCount1); Assert.Equal("<top-level-statements-entry-point>", context.ContainingSymbol.ToTestDisplayString()); break; case "M()": Interlocked.Increment(ref FireCount2); Assert.Equal("void Test.M()", context.ContainingSymbol.ToTestDisplayString()); break; default: Assert.True(false); break; } var decl = (CSharpSyntaxNode)context.ContainingSymbol.DeclaringSyntaxReferences.Single().GetSyntax(); Assert.True(syntaxTreeModel.TestOnlyMemberModels.ContainsKey(decl)); MemberSemanticModel mm = syntaxTreeModel.TestOnlyMemberModels[decl]; Assert.False(mm.TestOnlyTryGetBoundNodesFromMap(node).IsEmpty); Assert.Same(mm, syntaxTreeModel.GetMemberModel(node)); } private void Handle2(SyntaxNodeAnalysisContext context) { var model = context.SemanticModel; var node = (CSharpSyntaxNode)context.Node; var syntaxTreeModel = ((SyntaxTreeSemanticModel)model); switch (context.ContainingSymbol.ToTestDisplayString()) { case "<global namespace>": Interlocked.Increment(ref FireCount3); break; default: Assert.True(false); break; } } } [Fact] public void AnalyzerActions_10() { var text1 = @" [assembly: MyAttribute(1)] "; var text2 = @" System.Console.WriteLine(""Hi!""); "; var text3 = @" [MyAttribute(2)] class Test { [MyAttribute(3)] void M() { } } class MyAttribute : System.Attribute { public MyAttribute(int x) {} } "; var analyzer = new AnalyzerActions_10_Analyzer(); var comp = CreateCompilation(text1 + text2 + text3, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); Assert.Equal(1, analyzer.FireCount3); Assert.Equal(1, analyzer.FireCount4); analyzer = new AnalyzerActions_10_Analyzer(); comp = CreateCompilation(new[] { text1, text2, text3 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); Assert.Equal(1, analyzer.FireCount3); Assert.Equal(3, analyzer.FireCount4); } private class AnalyzerActions_10_Analyzer : DiagnosticAnalyzer { public int FireCount1; public int FireCount2; public int FireCount3; public int FireCount4; private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.RegisterSyntaxNodeAction(Handle1, SyntaxKind.Attribute); context.RegisterSyntaxNodeAction(Handle2, SyntaxKind.CompilationUnit); } private void Handle1(SyntaxNodeAnalysisContext context) { var node = (CSharpSyntaxNode)context.Node; switch (node.ToString()) { case @"MyAttribute(1)": Interlocked.Increment(ref FireCount1); Assert.Equal("<global namespace>", context.ContainingSymbol.ToTestDisplayString()); break; case @"MyAttribute(2)": Interlocked.Increment(ref FireCount2); Assert.Equal("Test", context.ContainingSymbol.ToTestDisplayString()); break; case @"MyAttribute(3)": Interlocked.Increment(ref FireCount3); Assert.Equal("void Test.M()", context.ContainingSymbol.ToTestDisplayString()); break; default: Assert.True(false); break; } } private void Handle2(SyntaxNodeAnalysisContext context) { switch (context.ContainingSymbol.ToTestDisplayString()) { case @"<global namespace>": Interlocked.Increment(ref FireCount4); break; default: Assert.True(false); break; } } } [Fact] public void AnalyzerActions_11() { var text1 = @" System.Console.WriteLine(""Hi!""); "; var text2 = @" namespace N1 {} class C1 {} "; var analyzer = new AnalyzerActions_11_Analyzer(); var comp = CreateCompilation(text1 + text2, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); Assert.Equal(1, analyzer.FireCount3); Assert.Equal(1, analyzer.FireCount4); analyzer = new AnalyzerActions_11_Analyzer(); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); Assert.Equal(1, analyzer.FireCount3); Assert.Equal(1, analyzer.FireCount4); } private class AnalyzerActions_11_Analyzer : DiagnosticAnalyzer { public int FireCount1; public int FireCount2; public int FireCount3; public int FireCount4; private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.RegisterSymbolAction(Handle1, SymbolKind.Method); context.RegisterSymbolAction(Handle2, SymbolKind.Namespace); context.RegisterSymbolAction(Handle3, SymbolKind.NamedType); } private void Handle1(SymbolAnalysisContext context) { Interlocked.Increment(ref FireCount1); Assert.Equal("<top-level-statements-entry-point>", context.Symbol.ToTestDisplayString()); } private void Handle2(SymbolAnalysisContext context) { Interlocked.Increment(ref FireCount2); Assert.Equal("N1", context.Symbol.ToTestDisplayString()); } private void Handle3(SymbolAnalysisContext context) { switch (context.Symbol.ToTestDisplayString()) { case "C1": Interlocked.Increment(ref FireCount3); break; case WellKnownMemberNames.TopLevelStatementsEntryPointTypeName: Interlocked.Increment(ref FireCount4); break; default: Assert.True(false); break; } } } [Fact] public void AnalyzerActions_12() { var text1 = @"System.Console.WriteLine(1);"; var analyzer = new AnalyzerActions_12_Analyzer(); var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(0, analyzer.FireCount2); Assert.Equal(1, analyzer.FireCount3); var text2 = @"System.Console.WriteLine(2);"; analyzer = new AnalyzerActions_12_Analyzer(); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); Assert.Equal(2, analyzer.FireCount3); } private class AnalyzerActions_12_Analyzer : DiagnosticAnalyzer { public int FireCount1; public int FireCount2; public int FireCount3; private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.RegisterOperationBlockStartAction(Handle1); } private void Handle1(OperationBlockStartAnalysisContext context) { Interlocked.Increment(ref FireCount3); context.RegisterOperationBlockEndAction(Handle2); } private void Handle2(OperationBlockAnalysisContext context) { Assert.Equal("<top-level-statements-entry-point>", context.OwningSymbol.ToTestDisplayString()); Assert.Equal(SyntaxKind.CompilationUnit, context.OperationBlocks.Single().Syntax.Kind()); switch (context.OperationBlocks.Single().Syntax.ToString()) { case "System.Console.WriteLine(1);": Interlocked.Increment(ref FireCount1); break; case "System.Console.WriteLine(2);": Interlocked.Increment(ref FireCount2); break; default: Assert.True(false); break; } } } [Fact] public void AnalyzerActions_13() { var text1 = @"System.Console.WriteLine(1);"; var analyzer = new AnalyzerActions_13_Analyzer(); var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(0, analyzer.FireCount2); Assert.Equal(1, analyzer.FireCount3); var text2 = @"System.Console.WriteLine(2);"; analyzer = new AnalyzerActions_13_Analyzer(); comp = CreateCompilation(new[] { text1, text2 }, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.GetAnalyzerDiagnostics(new[] { analyzer }, null).Verify(); Assert.Equal(1, analyzer.FireCount1); Assert.Equal(1, analyzer.FireCount2); Assert.Equal(2, analyzer.FireCount3); } private class AnalyzerActions_13_Analyzer : DiagnosticAnalyzer { public int FireCount1; public int FireCount2; public int FireCount3; private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test"); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.RegisterOperationBlockStartAction(Handle1); } private void Handle1(OperationBlockStartAnalysisContext context) { Interlocked.Increment(ref FireCount3); context.RegisterOperationAction(Handle2, OperationKind.Block); } private void Handle2(OperationAnalysisContext context) { Assert.Equal("<top-level-statements-entry-point>", context.ContainingSymbol.ToTestDisplayString()); Assert.Same(context.ContainingSymbol.DeclaringSyntaxReferences.Single().GetSyntax(), context.Operation.Syntax); Assert.Equal(SyntaxKind.CompilationUnit, context.Operation.Syntax.Kind()); switch (context.Operation.Syntax.ToString()) { case "System.Console.WriteLine(1);": Interlocked.Increment(ref FireCount1); break; case "System.Console.WriteLine(2);": Interlocked.Increment(ref FireCount2); break; default: Assert.True(false); break; } } } [Fact] public void MissingTypes_01() { var text = @"return;"; var comp = CreateEmptyCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics( // warning CS8021: No value for RuntimeMetadataVersion found. No assembly containing System.Object was found nor was a value for RuntimeMetadataVersion specified through options. Diagnostic(ErrorCode.WRN_NoRuntimeMetadataVersion).WithLocation(1, 1), // (1,1): error CS0518: Predefined type 'System.Object' is not defined or imported // return; Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "return").WithArguments("System.Object").WithLocation(1, 1), // error CS0518: Predefined type 'System.Void' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Void").WithLocation(1, 1), // error CS0518: Predefined type 'System.String' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.String").WithLocation(1, 1), // (1,1): error CS1729: 'object' does not contain a constructor that takes 0 arguments // return; Diagnostic(ErrorCode.ERR_BadCtorArgCount, "return").WithArguments("object", "0").WithLocation(1, 1) ); } [Fact] public void MissingTypes_02() { var text = @"await Test();"; var comp = CreateCompilation(text, targetFramework: TargetFramework.Minimal, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics( // error CS0518: Predefined type 'System.Threading.Tasks.Task' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Threading.Tasks.Task").WithLocation(1, 1), // (1,1): warning CS0028: '<top-level-statements-entry-point>' has the wrong signature to be an entry point // await Test(); Diagnostic(ErrorCode.WRN_InvalidMainSig, "await Test();").WithArguments("<top-level-statements-entry-point>").WithLocation(1, 1), // error CS5001: Program does not contain a static 'Main' method suitable for an entry point Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1), // (1,7): error CS0103: The name 'Test' does not exist in the current context // await Test(); Diagnostic(ErrorCode.ERR_NameNotInContext, "Test").WithArguments("Test").WithLocation(1, 7) ); } [Fact] public void MissingTypes_03() { var text = @" System.Console.WriteLine(""Hi!""); return 10; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.MakeTypeMissing(SpecialType.System_Int32); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Int32[missing]", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnsVoid); comp.VerifyEmitDiagnostics( // error CS0518: Predefined type 'System.Int32' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Int32").WithLocation(1, 1), // (3,8): error CS0518: Predefined type 'System.Int32' is not defined or imported // return 10; Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "10").WithArguments("System.Int32").WithLocation(3, 8) ); } [Fact] public void MissingTypes_04() { var text = @" await System.Threading.Tasks.Task.Factory.StartNew(() => 5L); return 11; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.MakeTypeMissing(SpecialType.System_Int32); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Threading.Tasks.Task<System.Int32[missing]>", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnsVoid); comp.VerifyEmitDiagnostics( // error CS0518: Predefined type 'System.Int32' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Int32").WithLocation(1, 1), // error CS5001: Program does not contain a static 'Main' method suitable for an entry point Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1), // (2,1): warning CS0028: '<top-level-statements-entry-point>' has the wrong signature to be an entry point // await System.Threading.Tasks.Task.Factory.StartNew(() => 5L); Diagnostic(ErrorCode.WRN_InvalidMainSig, @"await System.Threading.Tasks.Task.Factory.StartNew(() => 5L); return 11; ").WithArguments("<top-level-statements-entry-point>").WithLocation(2, 1), // (2,1): error CS0518: Predefined type 'System.Int32' is not defined or imported // await System.Threading.Tasks.Task.Factory.StartNew(() => 5L); Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "await System.Threading.Tasks.Task.Factory.StartNew(() => 5L);").WithArguments("System.Int32").WithLocation(2, 1), // (2,1): error CS0518: Predefined type 'System.Int32' is not defined or imported // await System.Threading.Tasks.Task.Factory.StartNew(() => 5L); Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "await System.Threading.Tasks.Task.Factory.StartNew(() => 5L);").WithArguments("System.Int32").WithLocation(2, 1), // (2,1): error CS0518: Predefined type 'System.Int32' is not defined or imported // await System.Threading.Tasks.Task.Factory.StartNew(() => 5L); Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "await System.Threading.Tasks.Task.Factory.StartNew(() => 5L);").WithArguments("System.Int32").WithLocation(2, 1), // (2,1): error CS0518: Predefined type 'System.Int32' is not defined or imported // await System.Threading.Tasks.Task.Factory.StartNew(() => 5L); Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "await System.Threading.Tasks.Task.Factory.StartNew(() => 5L);").WithArguments("System.Int32").WithLocation(2, 1), // (3,8): error CS0518: Predefined type 'System.Int32' is not defined or imported // return 11; Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "11").WithArguments("System.Int32").WithLocation(3, 8) ); } [Fact] public void MissingTypes_05() { var text = @" await System.Threading.Tasks.Task.Factory.StartNew(() => ""5""); return 11; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.MakeTypeMissing(WellKnownType.System_Threading_Tasks_Task_T); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Threading.Tasks.Task<System.Int32>[missing]", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnsVoid); comp.VerifyEmitDiagnostics( // error CS0518: Predefined type 'System.Threading.Tasks.Task`1' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Threading.Tasks.Task`1").WithLocation(1, 1), // error CS5001: Program does not contain a static 'Main' method suitable for an entry point Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1), // (2,1): warning CS0028: '<top-level-statements-entry-point>' has the wrong signature to be an entry point // await System.Threading.Tasks.Task.Factory.StartNew(() => "5"); Diagnostic(ErrorCode.WRN_InvalidMainSig, @"await System.Threading.Tasks.Task.Factory.StartNew(() => ""5""); return 11; ").WithArguments("<top-level-statements-entry-point>").WithLocation(2, 1) ); } [Fact] public void MissingTypes_06() { var text = @" await System.Threading.Tasks.Task.Factory.StartNew(() => ""5""); return 11; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.MakeTypeMissing(SpecialType.System_Int32); comp.MakeTypeMissing(WellKnownType.System_Threading_Tasks_Task_T); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Threading.Tasks.Task<System.Int32[missing]>[missing]", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnsVoid); comp.VerifyEmitDiagnostics( // error CS0518: Predefined type 'System.Threading.Tasks.Task`1' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Threading.Tasks.Task`1").WithLocation(1, 1), // error CS0518: Predefined type 'System.Int32' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.Int32").WithLocation(1, 1), // error CS5001: Program does not contain a static 'Main' method suitable for an entry point Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1), // (2,1): warning CS0028: '<top-level-statements-entry-point>' has the wrong signature to be an entry point // await System.Threading.Tasks.Task.Factory.StartNew(() => "5"); Diagnostic(ErrorCode.WRN_InvalidMainSig, @"await System.Threading.Tasks.Task.Factory.StartNew(() => ""5""); return 11; ").WithArguments("<top-level-statements-entry-point>").WithLocation(2, 1), // (3,8): error CS0518: Predefined type 'System.Int32' is not defined or imported // return 11; Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "11").WithArguments("System.Int32").WithLocation(3, 8) ); } [Fact] public void MissingTypes_07() { var text = @" System.Console.WriteLine(); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.MakeTypeMissing(SpecialType.System_String); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.String[missing][] args", entryPoint.Parameters.Single().ToTestDisplayString()); comp.VerifyEmitDiagnostics( // error CS0518: Predefined type 'System.String' is not defined or imported Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).WithArguments("System.String").WithLocation(1, 1) ); } [Fact] public void Return_01() { var text = @" System.Console.WriteLine(args[0]); return; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Void", entryPoint.ReturnType.ToTestDisplayString()); Assert.True(entryPoint.ReturnsVoid); AssertEntryPointParameter(entryPoint); CompileAndVerify(comp, expectedOutput: "Return_01", args: new[] { "Return_01" }); if (ExecutionConditionUtil.IsWindows) { _ = ConditionalSkipReason.NativePdbRequiresDesktop; comp.VerifyPdb(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName + "." + WellKnownMemberNames.TopLevelStatementsEntryPointMethodName, @$"<symbols> <files> <file id=""1"" name="""" language=""C#"" /> </files> <entryPoint declaringType=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName)}"" methodName=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointMethodName)}"" parameterNames=""args"" /> <methods> <method containingType=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName)}"" name=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointMethodName)}"" parameterNames=""args""> <customDebugInfo> <using> <namespace usingCount=""0"" /> </using> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""2"" startColumn=""1"" endLine=""2"" endColumn=""35"" document=""1"" /> <entry offset=""0x9"" startLine=""3"" startColumn=""1"" endLine=""3"" endColumn=""8"" document=""1"" /> </sequencePoints> </method> </methods> </symbols>", options: PdbValidationOptions.SkipConversionValidation); } } private static string EscapeForXML(string toEscape) { return toEscape.Replace("<", "<").Replace(">", ">"); } [Fact] public void Return_02() { var text = @" System.Console.WriteLine(args[0]); return 10; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Int32", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnsVoid); AssertEntryPointParameter(entryPoint); CompileAndVerify(comp, expectedOutput: "Return_02", args: new[] { "Return_02" }, expectedReturnCode: 10); if (ExecutionConditionUtil.IsWindows) { _ = ConditionalSkipReason.NativePdbRequiresDesktop; comp.VerifyPdb(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName + "." + WellKnownMemberNames.TopLevelStatementsEntryPointMethodName, @$"<symbols> <files> <file id=""1"" name="""" language=""C#"" /> </files> <entryPoint declaringType=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName)}"" methodName=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointMethodName)}"" parameterNames=""args"" /> <methods> <method containingType=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName)}"" name=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointMethodName)}"" parameterNames=""args""> <customDebugInfo> <using> <namespace usingCount=""0"" /> </using> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""2"" startColumn=""1"" endLine=""2"" endColumn=""35"" document=""1"" /> <entry offset=""0x9"" startLine=""3"" startColumn=""1"" endLine=""3"" endColumn=""11"" document=""1"" /> </sequencePoints> </method> </methods> </symbols>", options: PdbValidationOptions.SkipConversionValidation); } } [Fact] public void Return_03() { var text = @" using System; using System.Threading.Tasks; Console.Write(""hello ""); await Task.Factory.StartNew(() => 5); Console.Write(args[0]); return; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Threading.Tasks.Task", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnsVoid); AssertEntryPointParameter(entryPoint); CompileAndVerify(comp, expectedOutput: "hello Return_03", args: new[] { "Return_03" }); if (ExecutionConditionUtil.IsWindows) { _ = ConditionalSkipReason.NativePdbRequiresDesktop; comp.VerifyPdb(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName + "+<" + WellKnownMemberNames.TopLevelStatementsEntryPointMethodName + ">d__0.MoveNext", @$"<symbols> <files> <file id=""1"" name="""" language=""C#"" /> </files> <entryPoint declaringType=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName)}"" methodName=""<Main>"" parameterNames=""args"" /> <methods> <method containingType=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName)}+<{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointMethodName)}>d__0"" name=""MoveNext""> <customDebugInfo> <using> <namespace usingCount=""2"" /> </using> <encLocalSlotMap> <slot kind=""27"" offset=""2"" /> <slot kind=""33"" offset=""76"" /> <slot kind=""temp"" /> <slot kind=""temp"" /> </encLocalSlotMap> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" hidden=""true"" document=""1"" /> <entry offset=""0x7"" hidden=""true"" document=""1"" /> <entry offset=""0xe"" startLine=""5"" startColumn=""1"" endLine=""5"" endColumn=""25"" document=""1"" /> <entry offset=""0x19"" startLine=""6"" startColumn=""1"" endLine=""6"" endColumn=""38"" document=""1"" /> <entry offset=""0x48"" hidden=""true"" document=""1"" /> <entry offset=""0x99"" startLine=""7"" startColumn=""1"" endLine=""7"" endColumn=""24"" document=""1"" /> <entry offset=""0xa7"" startLine=""8"" startColumn=""1"" endLine=""8"" endColumn=""8"" document=""1"" /> <entry offset=""0xa9"" hidden=""true"" document=""1"" /> <entry offset=""0xc1"" hidden=""true"" document=""1"" /> </sequencePoints> <scope startOffset=""0x0"" endOffset=""0xd6""> <namespace name=""System"" /> <namespace name=""System.Threading.Tasks"" /> </scope> <asyncInfo> <catchHandler offset=""0xa9"" /> <kickoffMethod declaringType=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName)}"" methodName=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointMethodName)}"" parameterNames=""args"" /> <await yield=""0x5a"" resume=""0x75"" declaringType=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName)}+<{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointMethodName)}>d__0"" methodName=""MoveNext"" /> </asyncInfo> </method> </methods> </symbols>", options: PdbValidationOptions.SkipConversionValidation); } } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/80313")] public void Return_04() { var text = @" using System; using System.Threading.Tasks; Console.Write(""hello ""); await Task.Factory.StartNew(() => 5); Console.Write(args[0]); return 11; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Threading.Tasks.Task<System.Int32>", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnsVoid); AssertEntryPointParameter(entryPoint); var expectedOutput = "hello Return_04"; var args = new[] { "Return_04" }; CompileAndVerify(comp, expectedOutput: expectedOutput, args: args, expectedReturnCode: 11); if (ExecutionConditionUtil.IsWindows) { _ = ConditionalSkipReason.NativePdbRequiresDesktop; comp.VerifyPdb(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName + "+<" + WellKnownMemberNames.TopLevelStatementsEntryPointMethodName + ">d__0.MoveNext", @$"<symbols> <files> <file id=""1"" name="""" language=""C#"" /> </files> <entryPoint declaringType=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName)}"" methodName=""<Main>"" parameterNames=""args"" /> <methods> <method containingType=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName)}+<{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointMethodName)}>d__0"" name=""MoveNext""> <customDebugInfo> <using> <namespace usingCount=""2"" /> </using> <encLocalSlotMap> <slot kind=""27"" offset=""2"" /> <slot kind=""20"" offset=""2"" /> <slot kind=""33"" offset=""76"" /> <slot kind=""temp"" /> <slot kind=""temp"" /> </encLocalSlotMap> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" hidden=""true"" document=""1"" /> <entry offset=""0x7"" hidden=""true"" document=""1"" /> <entry offset=""0xe"" startLine=""5"" startColumn=""1"" endLine=""5"" endColumn=""25"" document=""1"" /> <entry offset=""0x19"" startLine=""6"" startColumn=""1"" endLine=""6"" endColumn=""38"" document=""1"" /> <entry offset=""0x48"" hidden=""true"" document=""1"" /> <entry offset=""0x99"" startLine=""7"" startColumn=""1"" endLine=""7"" endColumn=""24"" document=""1"" /> <entry offset=""0xa7"" startLine=""8"" startColumn=""1"" endLine=""8"" endColumn=""11"" document=""1"" /> <entry offset=""0xac"" hidden=""true"" document=""1"" /> <entry offset=""0xc6"" hidden=""true"" document=""1"" /> </sequencePoints> <scope startOffset=""0x0"" endOffset=""0xdc""> <namespace name=""System"" /> <namespace name=""System.Threading.Tasks"" /> </scope> <asyncInfo> <catchHandler offset=""0xac"" /> <kickoffMethod declaringType=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName)}"" methodName=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointMethodName)}"" parameterNames=""args"" /> <await yield=""0x5a"" resume=""0x75"" declaringType=""{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName)}+<{EscapeForXML(WellKnownMemberNames.TopLevelStatementsEntryPointMethodName)}>d__0"" methodName=""MoveNext"" /> </asyncInfo> </method> </methods> </symbols>", options: PdbValidationOptions.SkipConversionValidation); } comp = CreateRuntimeAsyncCompilation(text); var verifier = CompileAndVerify(comp, expectedOutput: RuntimeAsyncTestHelpers.ExpectedOutput(expectedOutput), args: args, verify: Verification.Fails with { ILVerifyMessage = "[<Main>$]: Unexpected type on the stack. { Offset = 0x43, Found = Int32, Expected = ref '[System.Runtime]System.Threading.Tasks.Task`1<int32>' }" }, sourceSymbolValidator: validator); verifier.VerifyIL("<top-level-statements-entry-point>", """ { // Code size 68 (0x44) .maxstack 3 IL_0000: ldstr "hello " IL_0005: call "void System.Console.Write(string)" IL_000a: call "System.Threading.Tasks.TaskFactory System.Threading.Tasks.Task.Factory.get" IL_000f: ldsfld "System.Func<int> Program.<>c.<>9__0_0" IL_0014: dup IL_0015: brtrue.s IL_002e IL_0017: pop IL_0018: ldsfld "Program.<>c Program.<>c.<>9" IL_001d: ldftn "int Program.<>c.<<Main>$>b__0_0()" IL_0023: newobj "System.Func<int>..ctor(object, System.IntPtr)" IL_0028: dup IL_0029: stsfld "System.Func<int> Program.<>c.<>9__0_0" IL_002e: callvirt "System.Threading.Tasks.Task<int> System.Threading.Tasks.TaskFactory.StartNew<int>(System.Func<int>)" IL_0033: call "int System.Runtime.CompilerServices.AsyncHelpers.Await<int>(System.Threading.Tasks.Task<int>)" IL_0038: pop IL_0039: ldarg.0 IL_003a: ldc.i4.0 IL_003b: ldelem.ref IL_003c: call "void System.Console.Write(string)" IL_0041: ldc.i4.s 11 IL_0043: ret } """); static void validator(ModuleSymbol module) { var program = module.GlobalNamespace.GetTypeMember("Program"); Assert.NotNull(program); var main = program.GetMethod("<Main>$"); Assert.NotNull(main); Assert.Equal(MethodImplAttributes.Async, main.ImplementationAttributes & MethodImplAttributes.Async); } } [Fact] public void Return_05() { var text = @" System.Console.WriteLine(""Hi!""); return ""error""; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Int32", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnsVoid); comp.VerifyDiagnostics( // (3,8): error CS0029: Cannot implicitly convert type 'string' to 'int' // return "error"; Diagnostic(ErrorCode.ERR_NoImplicitConv, @"""error""").WithArguments("string", "int").WithLocation(3, 8) ); } [Fact] public void Return_06() { var text = @" System.Func<int, int> d = n => { System.Console.WriteLine(""Hi!""); return n; }; d(0); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Void", entryPoint.ReturnType.ToTestDisplayString()); Assert.True(entryPoint.ReturnsVoid); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void Return_07() { var text = @" System.Func<int, int> d = delegate(int n) { System.Console.WriteLine(""Hi!""); return n; }; d(0); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Void", entryPoint.ReturnType.ToTestDisplayString()); Assert.True(entryPoint.ReturnsVoid); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void Return_08() { var text = @" System.Func<int, int> d = (n) => { System.Console.WriteLine(""Hi!""); return n; }; d(0); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Void", entryPoint.ReturnType.ToTestDisplayString()); Assert.True(entryPoint.ReturnsVoid); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void Return_09() { var text = @" int local(int n) { System.Console.WriteLine(""Hi!""); return n; } local(0); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Void", entryPoint.ReturnType.ToTestDisplayString()); Assert.True(entryPoint.ReturnsVoid); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void Return_10() { var text = @" bool b = true; if (b) return 0; else return; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Int32", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnsVoid); comp.VerifyDiagnostics( // (6,5): error CS0126: An object of a type convertible to 'int' is required // return; Diagnostic(ErrorCode.ERR_RetObjectRequired, "return").WithArguments("int").WithLocation(6, 5) ); } [Fact] public void Return_11() { var text = @" bool b = true; if (b) return; else return 0; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Int32", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnsVoid); comp.VerifyDiagnostics( // (4,5): error CS0126: An object of a type convertible to 'int' is required // return; Diagnostic(ErrorCode.ERR_RetObjectRequired, "return").WithArguments("int").WithLocation(4, 5) ); } [Fact] public void Return_12() { var text = @" System.Console.WriteLine(1); return; System.Console.WriteLine(2); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Void", entryPoint.ReturnType.ToTestDisplayString()); CompileAndVerify(comp, expectedOutput: "1").VerifyDiagnostics( // (4,1): warning CS0162: Unreachable code detected // System.Console.WriteLine(2); Diagnostic(ErrorCode.WRN_UnreachableCode, "System").WithLocation(4, 1) ); } [Fact] public void Return_13() { var text = @" System.Console.WriteLine(1); return 13; System.Console.WriteLine(2); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Int32", entryPoint.ReturnType.ToTestDisplayString()); CompileAndVerify(comp, expectedOutput: "1", expectedReturnCode: 13).VerifyDiagnostics( // (4,1): warning CS0162: Unreachable code detected // System.Console.WriteLine(2); Diagnostic(ErrorCode.WRN_UnreachableCode, "System").WithLocation(4, 1) ); } [Fact] public void Return_14() { var text = @" System.Console.WriteLine(""Hi!""); return default; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Int32", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnsVoid); CompileAndVerify(comp, expectedOutput: "Hi!", expectedReturnCode: 0); } [Fact] public void Return_15() { var text = @" using System; using System.Threading.Tasks; Console.Write(""hello ""); await Task.Factory.StartNew(() => 5); Console.Write(""async main""); return default; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Threading.Tasks.Task<System.Int32>", entryPoint.ReturnType.ToTestDisplayString()); Assert.False(entryPoint.ReturnsVoid); CompileAndVerify(comp, expectedOutput: "hello async main", expectedReturnCode: 0); } [Fact] public void Dll_01() { var text = @"System.Console.WriteLine(""Hi!"");"; var comp = CreateCompilation(text, options: TestOptions.DebugDll, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics( // (1,1): error CS8805: Program using top-level statements must be an executable. // System.Console.WriteLine("Hi!"); Diagnostic(ErrorCode.ERR_SimpleProgramNotAnExecutable, @"System.Console.WriteLine(""Hi!"");").WithLocation(1, 1) ); } [Fact] public void NetModule_01() { var text = @"System.Console.WriteLine(""Hi!"");"; var comp = CreateCompilation(text, options: TestOptions.ReleaseModule, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics( // (1,1): error CS8805: Program using top-level statements must be an executable. // System.Console.WriteLine("Hi!"); Diagnostic(ErrorCode.ERR_SimpleProgramNotAnExecutable, @"System.Console.WriteLine(""Hi!"");").WithLocation(1, 1) ); } [Fact] public void ExpressionStatement_01() { // Await expression is covered in other tests var text = @" new Test(0); // ObjectCreationExpression: Test x; x = new Test(1); // SimpleAssignmentExpression: x += 1; // AddAssignmentExpression: x -= 2; // SubtractAssignmentExpression: x *= 3; // MultiplyAssignmentExpression: x /= 4; // DivideAssignmentExpression: x %= 5; // ModuloAssignmentExpression: x &= 6; // AndAssignmentExpression: x |= 7; // OrAssignmentExpression: x ^= 8; // ExclusiveOrAssignmentExpression: x <<= 9; // LeftShiftAssignmentExpression: x >>= 10; // RightShiftAssignmentExpression: x++; // PostIncrementExpression: x--; // PostDecrementExpression: ++x; // PreIncrementExpression: --x; // PreDecrementExpression: System.Console.WriteLine(x.Count); // InvocationExpression: x?.WhenNotNull(); // ConditionalAccessExpression: x = null; x ??= new Test(-1); // CoalesceAssignmentExpression: System.Console.WriteLine(x.Count); // InvocationExpression: class Test { public readonly int Count; public Test(int count) { Count = count; if (count == 0) { System.Console.WriteLine(""Test..ctor""); } } public static Test operator +(Test x, int y) { return new Test(x.Count + 1); } public static Test operator -(Test x, int y) { return new Test(x.Count + 1); } public static Test operator *(Test x, int y) { return new Test(x.Count + 1); } public static Test operator /(Test x, int y) { return new Test(x.Count + 1); } public static Test operator %(Test x, int y) { return new Test(x.Count + 1); } public static Test operator &(Test x, int y) { return new Test(x.Count + 1); } public static Test operator |(Test x, int y) { return new Test(x.Count + 1); } public static Test operator ^(Test x, int y) { return new Test(x.Count + 1); } public static Test operator <<(Test x, int y) { return new Test(x.Count + 1); } public static Test operator >>(Test x, int y) { return new Test(x.Count + 1); } public static Test operator ++(Test x) { return new Test(x.Count + 1); } public static Test operator --(Test x) { return new Test(x.Count + 1); } public void WhenNotNull() { System.Console.WriteLine(""WhenNotNull""); } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: @"Test..ctor 15 WhenNotNull -1 "); } [Fact] public void Block_01() { var text = @" { System.Console.WriteLine(""Hi!""); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void EmptyStatement_01() { var text = @" ; System.Console.WriteLine(""Hi!""); ; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void BreakStatement_01() { var text = @"break;"; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,1): error CS0139: No enclosing loop out of which to break or continue // break; Diagnostic(ErrorCode.ERR_NoBreakOrCont, "break;").WithLocation(1, 1) ); } [Fact] public void ContinueStatement_01() { var text = @"continue;"; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,1): error CS0139: No enclosing loop out of which to break or continue // continue; Diagnostic(ErrorCode.ERR_NoBreakOrCont, "continue;").WithLocation(1, 1) ); } [Fact] public void ThrowStatement_01() { var text = @"throw;"; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,1): error CS0156: A throw statement with no arguments is not allowed outside of a catch clause // throw; Diagnostic(ErrorCode.ERR_BadEmptyThrow, "throw").WithLocation(1, 1) ); } [Fact] public void ThrowStatement_02() { var text = @"throw null;"; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics(); CompileAndVerify(comp).VerifyIL("<top-level-statements-entry-point>", sequencePointDisplay: SequencePointDisplayMode.Enhanced, expectedIL: @" { // Code size 2 (0x2) .maxstack 1 // sequence point: throw null; IL_0000: ldnull IL_0001: throw } "); } [Fact] public void DoStatement_01() { var text = @" int i = 1; do { i++; } while (i < 4); System.Console.WriteLine(i); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "4"); } [Fact] public void WhileStatement_01() { var text = @" int i = 1; while (i < 4) { i++; } System.Console.WriteLine(i); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "4"); } [Fact] public void ForStatement_01() { var text = @" int i = 1; for (;i < 4;) { i++; } System.Console.WriteLine(i); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "4"); } [Fact] public void CheckedStatement_01() { var text = @" int i = 1; i++; checked { i++; } System.Console.WriteLine(i); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics(); CompileAndVerify(comp, expectedOutput: "3").VerifyIL("<top-level-statements-entry-point>", sequencePointDisplay: SequencePointDisplayMode.Enhanced, expectedIL: @" { // Code size 20 (0x14) .maxstack 2 .locals init (int V_0) //i // sequence point: int i = 1; IL_0000: ldc.i4.1 IL_0001: stloc.0 // sequence point: i++; IL_0002: ldloc.0 IL_0003: ldc.i4.1 IL_0004: add IL_0005: stloc.0 // sequence point: { IL_0006: nop // sequence point: i++; IL_0007: ldloc.0 IL_0008: ldc.i4.1 IL_0009: add.ovf IL_000a: stloc.0 // sequence point: } IL_000b: nop // sequence point: System.Console.WriteLine(i); IL_000c: ldloc.0 IL_000d: call ""void System.Console.WriteLine(int)"" IL_0012: nop IL_0013: ret } "); } [Fact] public void UncheckedStatement_01() { var text = @" int i = 1; i++; unchecked { i++; } System.Console.WriteLine(i); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe.WithOverflowChecks(true), parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics(); CompileAndVerify(comp, expectedOutput: "3").VerifyIL("<top-level-statements-entry-point>", sequencePointDisplay: SequencePointDisplayMode.Enhanced, expectedIL: @" { // Code size 20 (0x14) .maxstack 2 .locals init (int V_0) //i // sequence point: int i = 1; IL_0000: ldc.i4.1 IL_0001: stloc.0 // sequence point: i++; IL_0002: ldloc.0 IL_0003: ldc.i4.1 IL_0004: add.ovf IL_0005: stloc.0 // sequence point: { IL_0006: nop // sequence point: i++; IL_0007: ldloc.0 IL_0008: ldc.i4.1 IL_0009: add IL_000a: stloc.0 // sequence point: } IL_000b: nop // sequence point: System.Console.WriteLine(i); IL_000c: ldloc.0 IL_000d: call ""void System.Console.WriteLine(int)"" IL_0012: nop IL_0013: ret } "); } [Fact] public void UnsafeStatement_01() { var text = @" unsafe { int* p = (int*)0; p++; System.Console.WriteLine((int)p); } "; var comp = CreateCompilation(text, options: TestOptions.UnsafeDebugExe, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics(); CompileAndVerify(comp, expectedOutput: "4", verify: Verification.Skipped); } [Fact] public void FixedStatement_01() { var text = @" fixed(int *p = &new C().i) {} class C { public int i = 2; } "; var comp = CreateCompilation(text, options: TestOptions.UnsafeDebugExe, parseOptions: DefaultParseOptions); comp.VerifyEmitDiagnostics( // (2,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // fixed(int *p = &new C().i) {} Diagnostic(ErrorCode.ERR_UnsafeNeeded, "fixed(int *p = &new C().i) {}").WithLocation(2, 1), // (2,7): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // fixed(int *p = &new C().i) {} Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int *").WithLocation(2, 7), // (2,16): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // fixed(int *p = &new C().i) {} Diagnostic(ErrorCode.ERR_UnsafeNeeded, "&new C().i").WithLocation(2, 16) ); } [Fact] public void LockStatement_01() { var text = @" int i = 1; lock (new object()) { i++; } System.Console.WriteLine(i); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "2"); } [Fact] public void IfStatement_01() { var text = @" int i = 1; if (i == 1) { i++; } else { i--; } if (i != 2) { i--; } else { i++; } System.Console.WriteLine(i); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "3"); } [Fact] public void SwitchStatement_01() { var text = @" int i = 1; switch (i) { case 1: i++; break; default: i--; break; } System.Console.WriteLine(i); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "2"); } [Fact] public void TryStatement_01() { var text = @" try { System.Console.Write(1); throw null; } catch { System.Console.Write(2); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "12"); } [Fact] public void Args_01() { var text = @" #nullable enable System.Console.WriteLine(args.Length == 0 ? 0 : -args[0].Length); System.Console.Write(""""); System.Console.Write(""""); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "0").VerifyDiagnostics(); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); AssertEntryPointParameter(entryPoint); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var invocations = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().ToArray(); var symbols = model.LookupSymbols(invocations[0].Position, name: "args"); Assert.Empty(symbols); symbols = model.LookupSymbols(invocations[0].SpanStart, name: "args"); Assert.Equal("System.String[] args", symbols.Single().ToTestDisplayString()); symbols = model.LookupSymbols(invocations[1].Position, name: "args"); Assert.Equal("System.String[] args", symbols.Single().ToTestDisplayString()); symbols = model.LookupSymbols(invocations[1].SpanStart, name: "args"); Assert.Equal("System.String[] args", symbols.Single().ToTestDisplayString()); symbols = model.LookupSymbols(invocations[2].Position, name: "args"); Assert.Equal("System.String[] args", symbols.Single().ToTestDisplayString()); symbols = model.LookupSymbols(invocations[2].SpanStart, name: "args"); Assert.Equal("System.String[] args", symbols.Single().ToTestDisplayString()); } [Fact] public void Args_02() { var text1 = @" using System.Linq; _ = from args in new object[0] select args; "; var comp = CreateCompilation(text1, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (3,10): error CS1931: The range variable 'args' conflicts with a previous declaration of 'args' // _ = from args in new object[0] select args; Diagnostic(ErrorCode.ERR_QueryRangeVariableOverrides, "args").WithArguments("args").WithLocation(3, 10) ); } [Fact] public void Args_03() { var text = @" local(); void local() { System.Console.WriteLine(args[0]); } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Args_03", args: new[] { "Args_03" }).VerifyDiagnostics(); } [Fact] public void Args_04() { var text = @" System.Action lambda = () => System.Console.WriteLine(args[0]); lambda(); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Args_04", args: new[] { "Args_04" }).VerifyDiagnostics(); } [Fact] public void Args_05() { var text = @" ar "; var comp = CreateCompilation(text); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var id = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Single(); for (int i = id.SpanStart; i <= id.Span.End; i++) { var symbols = model.LookupSymbols(i, name: "args"); Assert.Equal("System.String[] args", symbols.Single().ToTestDisplayString()); } } [Fact] public void Args_06() { var text = @" ar // See https://aka.ms/new-console-template for more information Console.WriteLine(""Hello, World!""); "; var comp = CreateCompilation(text); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var id = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "ar").Single(); for (int i = id.SpanStart; i <= id.Span.End; i++) { var symbols = model.LookupSymbols(i, name: "args"); Assert.Equal("System.String[] args", symbols.Single().ToTestDisplayString()); } } [Fact] public void Args_07() { var text = @"// See https://aka.ms/new-console-template for more information Console.WriteLine(""Hello, World!""); ar "; var comp = CreateCompilation(text); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); var id = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(id => id.Identifier.ValueText == "ar").Single(); for (int i = id.SpanStart; i <= id.Span.End; i++) { var symbols = model.LookupSymbols(i, name: "args"); Assert.Equal("System.String[] args", symbols.Single().ToTestDisplayString()); } } [Fact] public void Span_01() { var comp = CreateCompilationWithMscorlibAndSpan(@" using System; Span<int> span = default; _ = new { Span = span }; ", options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (5,11): error CS0828: Cannot assign 'Span<int>' to anonymous type property // _ = new { Span = span }; Diagnostic(ErrorCode.ERR_AnonymousTypePropertyAssignedBadValue, "Span = span").WithArguments("System.Span<int>").WithLocation(5, 11) ); } [Fact] public void Span_02() { var comp = CreateCompilationWithMscorlibAndSpan(@" using System; Span<int> outer; for (Span<int> inner = stackalloc int[10];; inner = outer) { outer = inner; } ", options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (7,13): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope // outer = inner; Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(7, 13) ); } [Fact] [WorkItem(1179569, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1179569")] public void Issue1179569() { var text1 = @"Task v0123456789012345678901234567() { Console.Write(""start v0123456789012345678901234567""); await Task.Delay(2 * 1000); Console.Write(""end v0123456789012345678901234567""); } Task On01234567890123456() { return v0123456789012345678901234567(); } string return Task.WhenAll( Task.WhenAll(this.c01234567890123456789012345678.Select(v01234567 => On01234567890123456(v01234567))), Task.WhenAll(this.c01234567890123456789.Select(v01234567 => v01234567.U0123456789012345678901234()))); "; var oldTree = Parse(text: text1, options: TestOptions.RegularDefault); var text2 = @"Task v0123456789012345678901234567() { Console.Write(""start v0123456789012345678901234567""); await Task.Delay(2 * 1000); Console.Write(""end v0123456789012345678901234567""); } Task On01234567890123456() { return v0123456789012345678901234567(); } string[ return Task.WhenAll( Task.WhenAll(this.c01234567890123456789012345678.Select(v01234567 => On01234567890123456(v01234567))), Task.WhenAll(this.c01234567890123456789.Select(v01234567 => v01234567.U0123456789012345678901234()))); "; var newText = SourceText.From(text2, Encoding.UTF8, SourceHashAlgorithms.Default); using var lexer = new Syntax.InternalSyntax.Lexer(newText, TestOptions.RegularDefault); using var parser = new Syntax.InternalSyntax.LanguageParser(lexer, (CSharpSyntaxNode)oldTree.GetRoot(), new[] { new TextChangeRange(new TextSpan(282, 0), 1) }); var compilationUnit = (CompilationUnitSyntax)parser.ParseCompilationUnit().CreateRed(); var tree = CSharpSyntaxTree.Create(compilationUnit, TestOptions.RegularDefault, path: "", Encoding.UTF8, SourceHashAlgorithms.Default); Assert.Equal(text2, tree.GetText().ToString()); tree.VerifySource(); var fullParseTree = Parse(text: text2, options: TestOptions.RegularDefault); var nodes1 = tree.GetRoot().DescendantNodesAndTokensAndSelf(descendIntoTrivia: true).ToArray(); var nodes2 = fullParseTree.GetRoot().DescendantNodesAndTokensAndSelf(descendIntoTrivia: true).ToArray(); Assert.Equal(nodes1.Length, nodes2.Length); for (int i = 0; i < nodes1.Length; i++) { var node1 = nodes1[i]; var node2 = nodes2[i]; Assert.Equal(node1.RawKind, node2.RawKind); Assert.Equal(node1.Span, node2.Span); Assert.Equal(node1.FullSpan, node2.FullSpan); Assert.Equal(node1.ToString(), node2.ToString()); Assert.Equal(node1.ToFullString(), node2.ToFullString()); } } [Fact] public void TopLevelLocalReferencedInClass_IOperation() { var comp = CreateCompilation(@" int i = 1; class C { void M() /*<bind>*/{ _ = i; }/*</bind>*/ } ", options: TestOptions.ReleaseExe); var diagnostics = new[] { // (2,5): warning CS0219: The variable 'i' is assigned but its value is never used // int i = 1; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "i").WithArguments("i").WithLocation(2, 5), // (7,13): error CS8801: Cannot use local variable or local function 'i' declared in a top-level statement in this context. // _ = i; Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "i").WithArguments("i").WithLocation(7, 13) }; VerifyOperationTreeAndDiagnosticsForTest<BlockSyntax>(comp, @" IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsInvalid) (Syntax: '{ ... }') IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsInvalid) (Syntax: '_ = i;') Expression: ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: var, IsInvalid) (Syntax: '_ = i') Left: IDiscardOperation (Symbol: var _) (OperationKind.Discard, Type: var) (Syntax: '_') Right: ILocalReferenceOperation: i (OperationKind.LocalReference, Type: var, IsInvalid) (Syntax: 'i') ", diagnostics); VerifyFlowGraphForTest<BlockSyntax>(comp, @" Block[B0] - Entry Statements (0) Next (Regular) Block[B1] Block[B1] - Block Predecessors: [B0] Statements (1) IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsInvalid) (Syntax: '_ = i;') Expression: ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: var, IsInvalid) (Syntax: '_ = i') Left: IDiscardOperation (Symbol: var _) (OperationKind.Discard, Type: var) (Syntax: '_') Right: ILocalReferenceOperation: i (OperationKind.LocalReference, Type: var, IsInvalid) (Syntax: 'i') Next (Regular) Block[B2] Block[B2] - Exit Predecessors: [B1] Statements (0) "); } [Fact] public void TopLevelLocalFunctionReferencedInClass_IOperation() { var comp = CreateCompilation(@" _ = """"; static void M1() {} void M2() {} class C { void M() /*<bind>*/{ M1(); M2(); }/*</bind>*/ } ", options: TestOptions.ReleaseExe); var diagnostics = new[] { // (3,13): warning CS8321: The local function 'M1' is declared but never used // static void M1() {} Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "M1").WithArguments("M1").WithLocation(3, 13), // (4,6): warning CS8321: The local function 'M2' is declared but never used // void M2() {} Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "M2").WithArguments("M2").WithLocation(4, 6), // (9,9): error CS8801: Cannot use local variable or local function 'M1' declared in a top-level statement in this context. // M1(); Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "M1").WithArguments("M1").WithLocation(9, 9), // (10,9): error CS8801: Cannot use local variable or local function 'M2' declared in a top-level statement in this context. // M2(); Diagnostic(ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement, "M2").WithArguments("M2").WithLocation(10, 9) }; VerifyOperationTreeAndDiagnosticsForTest<BlockSyntax>(comp, @" IBlockOperation (2 statements) (OperationKind.Block, Type: null, IsInvalid) (Syntax: '{ ... }') IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsInvalid) (Syntax: 'M1();') Expression: IInvocationOperation (void M1()) (OperationKind.Invocation, Type: System.Void, IsInvalid) (Syntax: 'M1()') Instance Receiver: null Arguments(0) IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsInvalid) (Syntax: 'M2();') Expression: IInvocationOperation (void M2()) (OperationKind.Invocation, Type: System.Void, IsInvalid) (Syntax: 'M2()') Instance Receiver: null Arguments(0) ", diagnostics); VerifyFlowGraphForTest<BlockSyntax>(comp, @" Block[B0] - Entry Statements (0) Next (Regular) Block[B1] Block[B1] - Block Predecessors: [B0] Statements (2) IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsInvalid) (Syntax: 'M1();') Expression: IInvocationOperation (void M1()) (OperationKind.Invocation, Type: System.Void, IsInvalid) (Syntax: 'M1()') Instance Receiver: null Arguments(0) IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsInvalid) (Syntax: 'M2();') Expression: IInvocationOperation (void M2()) (OperationKind.Invocation, Type: System.Void, IsInvalid) (Syntax: 'M2()') Instance Receiver: null Arguments(0) Next (Regular) Block[B2] Block[B2] - Exit Predecessors: [B1] Statements (0) "); } [Fact] public void EmptyStatements_01() { var text = @";"; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,1): error CS8937: At least one top-level statement must be non-empty. // ; Diagnostic(ErrorCode.ERR_SimpleProgramIsEmpty, ";").WithLocation(1, 1) ); } [Fact] public void EmptyStatements_02() { var text = @";; ;; ;"; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,1): error CS8937: At least one top-level statement must be non-empty. // ;; Diagnostic(ErrorCode.ERR_SimpleProgramIsEmpty, ";").WithLocation(1, 1) ); } [Fact] public void EmptyStatements_03() { var text = @" System.Console.WriteLine(""Hi!""); ;; ; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void EmptyStatements_04() { var text = @" ;; ; System.Console.WriteLine(""Hi!"");"; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void EmptyStatements_05() { var text = @" ; System.Console.WriteLine(""Hi!""); ; "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); CompileAndVerify(comp, expectedOutput: "Hi!"); } [Fact] public void EmptyStatements_06() { var text = @" using System; ; class Program2 { static void Main(String[] args) {} } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (3,1): error CS8937: At least one top-level statement must be non-empty. // ; Diagnostic(ErrorCode.ERR_SimpleProgramIsEmpty, ";").WithLocation(3, 1), // (7,17): warning CS7022: The entry point of the program is global code; ignoring 'Program2.Main(string[])' entry point. // static void Main(String[] args) {} Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Program2.Main(string[])").WithLocation(7, 17) ); } [Fact] public void SpeakableEntryPoint() { var text = @" System.Console.WriteLine(""Hi!""); "; var comp = CreateCompilation(text, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All)); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Void", entryPoint.ReturnType.ToTestDisplayString()); Assert.True(entryPoint.ReturnsVoid); AssertEntryPointParameter(entryPoint); CompileAndVerify(comp, expectedOutput: "Hi!", sourceSymbolValidator: validate, symbolValidator: validate); Assert.Same(entryPoint, comp.GetEntryPoint(default)); Assert.False(entryPoint.CanBeReferencedByName); Assert.True(entryPoint.ContainingType.CanBeReferencedByName); Assert.Equal("<Main>$", entryPoint.Name); Assert.Equal("Program", entryPoint.ContainingType.Name); Assert.Equal(Accessibility.Internal, entryPoint.ContainingType.DeclaredAccessibility); Assert.Equal(Accessibility.Private, entryPoint.DeclaredAccessibility); void validate(ModuleSymbol module) { bool fromSource = module is SourceModuleSymbol; var program = module.GlobalNamespace.GetMember<NamedTypeSymbol>(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName); Assert.False(program.IsImplicitlyDeclared); if (fromSource) { Assert.Empty(program.GetAttributes().As<CSharpAttributeData>()); } else { Assert.Equal(new[] { "CompilerGeneratedAttribute" }, GetAttributeNames(program.GetAttributes().As<CSharpAttributeData>())); } Assert.Empty(program.GetMethod(WellKnownMemberNames.TopLevelStatementsEntryPointMethodName).GetAttributes()); if (fromSource) { Assert.Equal(new[] { "<top-level-statements-entry-point>", "Program..ctor()" }, program.GetMembers().ToTestDisplayStrings()); } else { Assert.Equal(new[] { "void Program.<Main>$(System.String[] args)", "Program..ctor()" }, program.GetMembers().ToTestDisplayStrings()); } } } [Fact] public void SpeakableEntryPoint_ProgramIsPartial() { var text = @" M(); public partial class Program { private static void M() { System.Console.WriteLine(""Hi!""); } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All)); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Void", entryPoint.ReturnType.ToTestDisplayString()); Assert.True(entryPoint.ReturnsVoid); AssertEntryPointParameter(entryPoint); CompileAndVerify(comp, expectedOutput: "Hi!", sourceSymbolValidator: validate, symbolValidator: validate); Assert.Same(entryPoint, comp.GetEntryPoint(default)); Assert.False(entryPoint.CanBeReferencedByName); Assert.True(entryPoint.ContainingType.CanBeReferencedByName); Assert.Equal("<Main>$", entryPoint.Name); Assert.Equal("Program", entryPoint.ContainingType.Name); Assert.Equal(Accessibility.Public, entryPoint.ContainingType.DeclaredAccessibility); Assert.Equal(Accessibility.Private, entryPoint.DeclaredAccessibility); void validate(ModuleSymbol module) { var program = module.GlobalNamespace.GetMember<NamedTypeSymbol>(WellKnownMemberNames.TopLevelStatementsEntryPointTypeName); Assert.Empty(program.GetAttributes().As<CSharpAttributeData>()); Assert.False(program.IsImplicitlyDeclared); Assert.Empty(program.GetMethod(WellKnownMemberNames.TopLevelStatementsEntryPointMethodName).GetAttributes().As<CSharpAttributeData>()); } } [Fact] public void SpeakableEntryPoint_ProgramIsNotPartial() { var text = @" M(); public class Program { private static void M() { System.Console.WriteLine(""Hi!""); } } "; var comp = CreateCompilation(text); comp.VerifyDiagnostics( // (4,14): error CS0260: Missing partial modifier on declaration of type 'Program'; another partial declaration of this type exists // public class Program Diagnostic(ErrorCode.ERR_MissingPartial, "Program").WithArguments("Program").WithLocation(4, 14) ); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal("System.Void", entryPoint.ReturnType.ToTestDisplayString()); Assert.True(entryPoint.ReturnsVoid); AssertEntryPointParameter(entryPoint); Assert.Same(entryPoint, comp.GetEntryPoint(default)); Assert.False(entryPoint.CanBeReferencedByName); Assert.True(entryPoint.ContainingType.CanBeReferencedByName); Assert.Equal("<Main>$", entryPoint.Name); Assert.Equal("Program", entryPoint.ContainingType.Name); Assert.Equal(Accessibility.Public, entryPoint.ContainingType.DeclaredAccessibility); Assert.Equal(Accessibility.Private, entryPoint.DeclaredAccessibility); } [Fact] public void SpeakableEntryPoint_ProgramIsInternal() { var text = @" M(); internal partial class Program { private static void M() { System.Console.WriteLine(""Hi!""); } } "; var comp = CreateCompilation(text); CompileAndVerify(comp, expectedOutput: "Hi!"); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal(Accessibility.Internal, entryPoint.ContainingType.DeclaredAccessibility); Assert.Equal(Accessibility.Private, entryPoint.DeclaredAccessibility); } [Fact] public void SpeakableEntryPoint_ProgramWithoutDeclaredAccessibility() { var text = @" M(); partial class Program { private static void M() { System.Console.WriteLine(""Hi!""); } } "; var comp = CreateCompilation(text); CompileAndVerify(comp, expectedOutput: "Hi!"); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal(Accessibility.Internal, entryPoint.ContainingType.DeclaredAccessibility); Assert.Equal(Accessibility.Private, entryPoint.DeclaredAccessibility); } [Fact] public void SpeakableEntryPoint_ProgramIsStruct() { var text = @" M(); partial struct Program { private static void M() { System.Console.WriteLine(""Hi!""); } } "; var comp = CreateCompilation(text); comp.VerifyDiagnostics( // (2,1): error CS0261: Partial declarations of 'Program' must be all classes, all record classes, all structs, all record structs, or all interfaces // M(); Diagnostic(ErrorCode.ERR_PartialTypeKindConflict, "M").WithArguments("Program").WithLocation(2, 1), // (2,1): error CS0103: The name 'M' does not exist in the current context // M(); Diagnostic(ErrorCode.ERR_NameNotInContext, "M").WithArguments("M").WithLocation(2, 1) ); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal(Accessibility.Internal, entryPoint.ContainingType.DeclaredAccessibility); Assert.Equal(Accessibility.Private, entryPoint.DeclaredAccessibility); Assert.True(entryPoint.ContainingType.IsReferenceType); } [Fact] public void SpeakableEntryPoint_ProgramIsRecord() { var text = @" M(); partial record Program { private static void M() { } } "; var comp = CreateCompilation(text); comp.VerifyDiagnostics( // (2,1): error CS0261: Partial declarations of 'Program' must be all classes, all record classes, all structs, all record structs, or all interfaces // M(); Diagnostic(ErrorCode.ERR_PartialTypeKindConflict, "M").WithArguments("Program").WithLocation(2, 1), // (2,1): error CS0103: The name 'M' does not exist in the current context // M(); Diagnostic(ErrorCode.ERR_NameNotInContext, "M").WithArguments("M").WithLocation(2, 1) ); } [Fact] public void SpeakableEntryPoint_ProgramIsInterface() { var text = @" System.Console.Write(42); partial interface Program { } "; var comp = CreateCompilation(text); comp.VerifyDiagnostics( // (2,1): error CS0261: Partial declarations of 'Program' must be all classes, all record classes, all structs, all record structs, or all interfaces // System.Console.Write(42); Diagnostic(ErrorCode.ERR_PartialTypeKindConflict, "System").WithArguments("Program").WithLocation(2, 1) ); } [Fact] public void SpeakableEntryPoint_ProgramCallsMain() { var text = @" M(args); partial class Program { private static void M(string[] args) { Main(); } } "; var comp = CreateCompilation(text); comp.VerifyDiagnostics( // (8,9): error CS0103: The name 'Main' does not exist in the current context // Main(); Diagnostic(ErrorCode.ERR_NameNotInContext, "Main").WithArguments("Main").WithLocation(8, 9) ); } [Fact] public void SpeakableEntryPoint_ProgramHasBaseList() { var text = @" new Program().M(); class Base { public void M() { System.Console.Write(42); } } partial class Program : Base { } "; var comp = CreateCompilation(text); var verifier = CompileAndVerify(comp, expectedOutput: "42"); verifier.VerifyDiagnostics(); var entryPoint = SynthesizedSimpleProgramEntryPointSymbol.GetSimpleProgramEntryPoint(comp); Assert.Equal(Accessibility.Private, entryPoint.DeclaredAccessibility); Assert.True(entryPoint.IsStatic); Assert.Equal("Base", entryPoint.ContainingType.BaseType().ToTestDisplayString()); Assert.Equal(Accessibility.Internal, entryPoint.ContainingType.DeclaredAccessibility); Assert.False(entryPoint.ContainingType.IsStatic); } [Fact] public void SpeakableEntryPoint_ProgramImplementsInterface() { var text = @" ((Interface)new Program()).M(); interface Interface { void M(); } partial class Program : Interface { void Interface.M() { System.Console.Write(42); } } "; var comp = CreateCompilation(text); var verifier = CompileAndVerify(comp, expectedOutput: "42"); verifier.VerifyDiagnostics(); } [Fact] public void SpeakableEntryPoint_ProgramIsAbstractPartial() { var text = @" System.Console.Write(42); abstract partial class Program { } "; var comp = CreateCompilation(text); var verifier = CompileAndVerify(comp, expectedOutput: "42"); verifier.VerifyDiagnostics(); } [Fact] public void SpeakableEntryPoint_ProgramIsSealedPartial() { var text = @" System.Console.Write(42); sealed partial class Program { } "; var comp = CreateCompilation(text); var verifier = CompileAndVerify(comp, expectedOutput: "42"); verifier.VerifyDiagnostics(); } [Fact] public void SpeakableEntryPoint_ProgramIsStaticPartial() { var text = @" System.Console.Write(42); static partial class Program { } "; var comp = CreateCompilation(text); var verifier = CompileAndVerify(comp, expectedOutput: "42"); verifier.VerifyDiagnostics(); } [Fact] public void SpeakableEntryPoint_ProgramIsObsolete() { var text = @" System.Console.Write(42); [System.Obsolete(""error"")] public partial class Program { } public class C { public Program f; } "; var comp = CreateCompilation(text); comp.VerifyDiagnostics( // (11,12): warning CS0618: 'Program' is obsolete: 'error' // public Program f; Diagnostic(ErrorCode.WRN_DeprecatedSymbolStr, "Program").WithArguments("Program", "error").WithLocation(11, 12) ); } [Fact] public void SpeakableEntryPoint_ProgramIsObsolete_UsedWithinProgram() { var text = @" Program p = new Program(); [System.Obsolete(""error"")] public partial class Program { } "; var comp = CreateCompilation(text); comp.VerifyEmitDiagnostics(); } [Fact] public void SpeakableEntryPoint_ProgramHasMain() { var text = @" System.Console.Write(42); partial class Program { public static void Main(string[] args) { } } "; var comp = CreateCompilation(text); comp.VerifyDiagnostics( // (6,24): warning CS7022: The entry point of the program is global code; ignoring 'Program.Main(string[])' entry point. // public static void Main(string[] args) { } Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Program.Main(string[])").WithLocation(6, 24) ); } [Fact] public void SpeakableEntryPoint_ProgramHasMain_DifferentSignature() { var text = @" System.Console.Write(42); partial class Program { public static void Main() { } } "; var comp = CreateCompilation(text); var verifier = CompileAndVerify(comp, expectedOutput: "42"); verifier.VerifyDiagnostics( // (6,24): warning CS7022: The entry point of the program is global code; ignoring 'Program.Main()' entry point. // public static void Main() { } Diagnostic(ErrorCode.WRN_MainIgnored, "Main").WithArguments("Program.Main()").WithLocation(6, 24) ); } [Fact] public void SpeakableEntryPoint_ProgramHasBackingField() { var text = @" System.Console.Write(42); partial class Program { public int Property { get; set; } } "; var comp = CreateCompilation(text, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All)); CompileAndVerify(comp, symbolValidator: validate, sourceSymbolValidator: validate); comp.VerifyEmitDiagnostics(); void validate(ModuleSymbol module) { bool fromSource = module is SourceModuleSymbol; var field = module.GlobalNamespace.GetMember<NamedTypeSymbol>("Program").GetField("<Property>k__BackingField"); Assert.False(field.ContainingType.IsImplicitlyDeclared); var fieldAttributes = GetAttributeNames(field.GetAttributes().As<CSharpAttributeData>()); if (fromSource) { Assert.Empty(fieldAttributes); Assert.Equal(new[] { "<top-level-statements-entry-point>", "System.Int32 Program.<Property>k__BackingField", "System.Int32 Program.Property { get; set; }", "System.Int32 Program.Property.get", "void Program.Property.set", "Program..ctor()" }, field.ContainingType.GetMembers().ToTestDisplayStrings()); } else { Assert.Equal(new[] { "CompilerGeneratedAttribute", "DebuggerBrowsableAttribute" }, fieldAttributes); Assert.Equal(new[] { "System.Int32 Program.<Property>k__BackingField", "void Program.<Main>$(System.String[] args)", "System.Int32 Program.Property.get", "void Program.Property.set", "Program..ctor()", "System.Int32 Program.Property { get; set; }" }, field.ContainingType.GetMembers().ToTestDisplayStrings()); } } } [Fact] public void SpeakableEntryPoint_XmlDoc() { var src = @" System.Console.Write(42); "; var comp = CreateCompilation(src, parseOptions: TestOptions.RegularWithDocumentationComments); comp.VerifyDiagnostics(); var cMember = comp.GetMember<NamedTypeSymbol>("Program"); Assert.Equal("", cMember.GetDocumentationCommentXml()); } [Fact] public void SpeakableEntryPoint_XmlDoc_ProgramIsPartial() { var src = @" System.Console.Write(42); /// <summary>Summary</summary> public partial class Program { } "; var comp = CreateCompilation(src, parseOptions: TestOptions.RegularWithDocumentationComments); comp.VerifyDiagnostics(); var cMember = comp.GetMember<NamedTypeSymbol>("Program"); Assert.Equal( @"<member name=""T:Program""> <summary>Summary</summary> </member> ", cMember.GetDocumentationCommentXml()); } [Fact] public void SpeakableEntryPoint_XmlDoc_ProgramIsPartial_NotCommented() { var src = @" System.Console.Write(42); public partial class Program { } "; var comp = CreateCompilation(src, parseOptions: TestOptions.RegularWithDocumentationComments); comp.VerifyDiagnostics( // (4,22): warning CS1591: Missing XML comment for publicly visible type or member 'Program' // public partial class Program { } Diagnostic(ErrorCode.WRN_MissingXMLComment, "Program").WithArguments("Program").WithLocation(4, 22) ); var cMember = comp.GetMember<NamedTypeSymbol>("Program"); Assert.Equal("", cMember.GetDocumentationCommentXml()); } [Fact] public void SpeakableEntryPoint_TypeOf() { var src = @" C.M(); public class C { public static void M() { System.Console.Write(typeof(Program)); } } "; var comp = CreateCompilation(src); var verifier = CompileAndVerify(comp, expectedOutput: "Program"); verifier.VerifyDiagnostics(); } [Fact] public void Ordering_InFileScopedNamespace_01() { var src = @" namespace NS; System.Console.Write(42); "; var comp = CreateCompilation(src); comp.VerifyDiagnostics( // (3,16): error CS0116: A namespace cannot directly contain members such as fields, methods or statements // System.Console.Write(42); Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "Write").WithLocation(3, 16), // (3,22): error CS1026: ) expected // System.Console.Write(42); Diagnostic(ErrorCode.ERR_CloseParenExpected, "42").WithLocation(3, 22), // (3,22): error CS1022: Type or namespace definition, or end-of-file expected // System.Console.Write(42); Diagnostic(ErrorCode.ERR_EOFExpected, "42").WithLocation(3, 22) ); } [Fact] public void Ordering_InFileScopedNamespace_02() { var src = @" namespace NS; var x = 1; "; var comp = CreateCompilation(src); comp.VerifyDiagnostics( // (3,1): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code // var x = 1; Diagnostic(ErrorCode.ERR_TypeVarNotFound, "var").WithLocation(3, 1), // (3,5): error CS0116: A namespace cannot directly contain members such as fields, methods or statements // var x = 1; Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "x").WithLocation(3, 5) ); } [Fact] public void Ordering_AfterNamespace() { var src = @" namespace NS { } var x = 1; "; var comp = CreateCompilation(src); comp.VerifyDiagnostics( // (6,1): error CS8803: Top-level statements must precede namespace and type declarations. // var x = 1; Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "var x = 1;").WithLocation(6, 1), // (6,5): warning CS0219: The variable 'x' is assigned but its value is never used // var x = 1; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "x").WithArguments("x").WithLocation(6, 5) ); } [Fact] [WorkItem(58521, "https://github.com/dotnet/roslyn/issues/58521")] public void BindCompilationUnitInSemanticModelWhenLocalFunctionIsAtTheTop() { var source = @" void F<T>(T t) { var f = (ref T x) => 0; } "; var compilation = CreateCompilation(source, options: TestOptions.DebugDll); var tree = compilation.SyntaxTrees[0]; var identifier = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().First(id => id.Identifier.Text == "var"); var model = compilation.GetSemanticModel(tree); model.GetOperation(identifier); Assert.Equal(OperationKind.Literal, model.GetOperation(tree.GetRoot().DescendantNodes().OfType<LiteralExpressionSyntax>().Single()).Kind); } [Fact] [WorkItem(60248, "https://github.com/dotnet/roslyn/issues/60248")] public void SpeculativeSemanticModel() { var source = @" int x = 1; System.Console.WriteLine(0); public class C { public void M() { System.Console.WriteLine(2); } } "; var compilation = CreateCompilation(source); var tree = compilation.SyntaxTrees[0]; var root = tree.GetRoot(); var model = compilation.GetSemanticModel(tree); var nodeToSpeculate = SyntaxFactory.ParseStatement("int y = x;"); // Speculate inside a valid top-level position. model.TryGetSpeculativeSemanticModel(root.DescendantNodes().Single(n => n is ExpressionStatementSyntax { Parent: GlobalStatementSyntax }).Span.End, nodeToSpeculate, out var speculativeModelInTopLevel); var conversionInTopLevel = speculativeModelInTopLevel.GetConversion(nodeToSpeculate.DescendantTokens().Single(n => n.ValueText == "x").Parent); Assert.Equal(ConversionKind.Identity, conversionInTopLevel.Kind); // Speculate outside a top-level position. model.TryGetSpeculativeSemanticModel(root.DescendantNodes().Single(n => n is ExpressionStatementSyntax { Parent: BlockSyntax }).Span.End, nodeToSpeculate, out var speculativeModelOutsideTopLevel); var conversionOutsideTopLevel = speculativeModelOutsideTopLevel.GetConversion(nodeToSpeculate.DescendantTokens().Single(n => n.ValueText == "x").Parent); Assert.Equal(ConversionKind.NoConversion, conversionOutsideTopLevel.Kind); } [Fact] [WorkItem("https://github.com/dotnet/roslyn/issues/67050")] public void EmptyLocalDeclaration() { var src = """ struct S { } partial ext X """; var comp = CreateCompilation(src); comp.VerifyDiagnostics( // (1,13): error CS1031: Type expected // struct S { } Diagnostic(ErrorCode.ERR_TypeExpected, "").WithLocation(1, 13), // (1,13): error CS1525: Invalid expression term 'partial' // struct S { } Diagnostic(ErrorCode.ERR_InvalidExprTerm, "").WithArguments("partial").WithLocation(1, 13), // (1,13): error CS1003: Syntax error, ',' expected // struct S { } Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments(",").WithLocation(1, 13), // (2,1): error CS8803: Top-level statements must precede namespace and type declarations. // partial ext X Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "partial").WithLocation(2, 1), // (2,14): error CS1002: ; expected // partial ext X Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(2, 14)); } [Fact] [WorkItem("https://github.com/dotnet/roslyn/issues/70909")] public void ExplicitBase_01() { var src1 = """ PrintLine(); """; var src2 = """ public class ProgramBase { public static void PrintLine() { System.Console.WriteLine("Done"); } } partial class Program : ProgramBase { } """; var comp = CreateCompilation(new[] { src1, src2 }, options: TestOptions.ReleaseExe); CompileAndVerify(comp, expectedOutput: "Done").VerifyDiagnostics(); comp = CreateCompilation(new[] { src2, src1 }, options: TestOptions.ReleaseExe); CompileAndVerify(comp, expectedOutput: "Done").VerifyDiagnostics(); } [Fact] [WorkItem("https://github.com/dotnet/roslyn/issues/70909")] public void ExplicitBase_02() { var src1 = """ ProgramBase.PrintLine(); """; var src2 = """ public class ProgramBase { public static void PrintLine() { System.Console.WriteLine("Done"); } } partial class Program : object { } """; var comp = CreateCompilation(new[] { src1, src2 }, options: TestOptions.ReleaseExe); CompileAndVerify(comp, expectedOutput: "Done").VerifyDiagnostics(); comp = CreateCompilation(new[] { src2, src1 }, options: TestOptions.ReleaseExe); CompileAndVerify(comp, expectedOutput: "Done").VerifyDiagnostics(); } [Fact] [WorkItem("https://github.com/dotnet/roslyn/issues/70909")] public void ExplicitBase_03() { var src1 = """ ProgramBase.PrintLine(); """; var src2 = """ public class ProgramBase { public static void PrintLine() { System.Console.WriteLine("Done"); } } partial class Program { } """; var comp = CreateCompilation(new[] { src1, src2 }, options: TestOptions.ReleaseExe); CompileAndVerify(comp, expectedOutput: "Done").VerifyDiagnostics(); comp = CreateCompilation(new[] { src2, src1 }, options: TestOptions.ReleaseExe); CompileAndVerify(comp, expectedOutput: "Done").VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestFieldInCompilationUnit() { var source = """ private int f; """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,13): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // private int f; Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "f").WithLocation(1, 13) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestFieldInNamespace() { var source = """ namespace N; private int f; """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular10); comp.VerifyDiagnostics( // (3,13): error CS0116: A namespace cannot directly contain members such as fields, methods or statements // private int f; Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "f").WithLocation(3, 13) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestPropertyInCompilationUnit() { var source = """ int P { get; set; } """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,5): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // int P { get; set; } Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "P").WithLocation(1, 5) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestPropertyInNamespace() { var source = """ namespace N; int P { get; set; } """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular10); comp.VerifyDiagnostics( // (3,5): error CS0116: A namespace cannot directly contain members such as fields, methods or statements // int P { get; set; } Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "P").WithLocation(3, 5) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestEventFieldInCompilationUnit() { var source = """ using System; event Action E; """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (3,14): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // event Action E; Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "E").WithLocation(3, 14) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestEventFieldInNamespace() { var source = """ using System; namespace N; event Action E; """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular10); comp.VerifyDiagnostics( // (5,14): error CS0116: A namespace cannot directly contain members such as fields, methods or statements // event Action E; Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "E").WithLocation(5, 14) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestEventDeclarationInCompilationUnit() { var source = """ using System; event Action E { add { } remove { } } """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (3,14): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // event Action E { add { } remove { } } Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "E").WithLocation(3, 14) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestEventDeclarationInNamespace() { var source = """ using System; namespace N; event Action E { add { } remove { } } """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular10); comp.VerifyDiagnostics( // (5,14): error CS0116: A namespace cannot directly contain members such as fields, methods or statements // event Action E { add { } remove { } } Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "E").WithLocation(5, 14) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestIndexerInCompilationUnit() { var source = """ int this[int x] => 0; """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,5): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // int this[int x] => 0; Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "this").WithLocation(1, 5) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestIndexerInNamespace() { var source = """ namespace N; int this[int x] => 0; """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular10); comp.VerifyDiagnostics( // (3,5): error CS0116: A namespace cannot directly contain members such as fields, methods or statements // int this[int x] => 0; Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "this").WithLocation(3, 5) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestConversionOperatorInCompilationUnit() { var source = """ public static implicit operator int(int d) => 0; """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,24): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // public static implicit operator int(int d) => 0; Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "operator").WithLocation(1, 24), // (1,33): error CS0556: User-defined conversion must convert to or from the enclosing type // public static implicit operator int(int d) => 0; Diagnostic(ErrorCode.ERR_ConversionNotInvolvingContainedType, "int").WithLocation(1, 33) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestConversionOperatorInNamespace() { var source = """ namespace N; public static implicit operator int(int d) => 0; """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular10); comp.VerifyDiagnostics( // (3,24): error CS0116: A namespace cannot directly contain members such as fields, methods or statements // public static implicit operator int(int d) => 0; Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "operator").WithLocation(3, 24), // (3,33): error CS0556: User-defined conversion must convert to or from the enclosing type // public static implicit operator int(int d) => 0; Diagnostic(ErrorCode.ERR_ConversionNotInvolvingContainedType, "int").WithLocation(3, 33) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestOperatorInCompilationUnit() { var source = """ public static int operator +(int operand1, int operand2) => 0; """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,19): error CS9348: A compilation unit cannot directly contain members such as fields, methods or properties // public static int operator +(int operand1, int operand2) => 0; Diagnostic(ErrorCode.ERR_CompilationUnitUnexpected, "operator").WithLocation(1, 19), // (1,28): error CS0563: One of the parameters of a binary operator must be the containing type // public static int operator +(int operand1, int operand2) => 0; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, "+").WithLocation(1, 28) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81141")] public void TestOperatorInFileScopedNamespace() { var source = """ namespace N; public static int operator +(int operand1, int operand2) => 0; """; var comp = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular10); comp.VerifyDiagnostics( // (3,19): error CS0116: A namespace cannot directly contain members such as fields, methods or statements // public static int operator +(int operand1, int operand2) => 0; Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "operator").WithLocation(3, 19), // (3,28): error CS0563: One of the parameters of a binary operator must be the containing type // public static int operator +(int operand1, int operand2) => 0; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, "+").WithLocation(3, 28) ); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/83691")] public void MultipleTopLevelStatements_ReportedInEveryFile() { var comp = CreateCompilation([("System.Console.Write(1);", "Program.cs"), ("System.Console.Write(2);", "Startup.cs")], options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); comp.VerifyDiagnostics( // (1,1): error CS8802: Only one compilation unit can have top-level statements. // System.Console.Write(1); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "System").WithLocation(1, 1), // (1,1): error CS8802: Only one compilation unit can have top-level statements. // System.Console.Write(2); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "System").WithLocation(1, 1) ); AssertEx.Equal(["Program.cs", "Startup.cs"], comp.GetDiagnostics().Select(d => d.Location.SourceTree.FilePath)); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/83691")] public void MultipleTopLevelStatements_SourceGeneratedFile() { var comp = CreateCompilation(("System.Console.Write(1);", "Program.cs"), options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); var generator = new SingleFileTestGenerator("System.Console.Write(2);", "Generated.cs"); GeneratorDriver driver = CSharpGeneratorDriver.Create([generator], parseOptions: DefaultParseOptions); driver.RunGeneratorsAndUpdateCompilation(comp, out var outputCompilation, out _); outputCompilation.VerifyDiagnostics( // (1,1): error CS8802: Only one compilation unit can have top-level statements. // System.Console.Write(1); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "System").WithLocation(1, 1), // (1,1): error CS8802: Only one compilation unit can have top-level statements. // System.Console.Write(2); Diagnostic(ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements, "System").WithLocation(1, 1) ); AssertEx.Equal(outputCompilation.SyntaxTrees, outputCompilation.GetDiagnostics().Select(d => d.Location.SourceTree)); } } }