diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
index 278b8326da138..85670a039b6bd 100644
--- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
+++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
@@ -3260,7 +3260,9 @@ private BoundNode BindSimpleProgramCompilationUnit(CompilationUnitSyntax compila
}
}
- return FinishBindBlockParts(compilationUnit, boundStatements.ToImmutableAndFree(), diagnostics);
+ return new BoundNonConstructorMethodBody(compilationUnit,
+ FinishBindBlockParts(compilationUnit, boundStatements.ToImmutableAndFree(), diagnostics).MakeCompilerGenerated(),
+ expressionBody: null);
}
private BoundNode BindConstructorBody(ConstructorDeclarationSyntax constructor, DiagnosticBag diagnostics)
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index 54c10b3220ea9..da0468cefad01 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -6067,4 +6067,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
Top-level statements must precede namespace and type declarations.
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
\ No newline at end of file
diff --git a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs
index 4dd089d69735e..2adf7117fce0b 100644
--- a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs
+++ b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs
@@ -1546,17 +1546,10 @@ internal bool DeclaresTheObjectClass
EntryPoint? entryPoint = null;
MethodSymbol? simpleProgramEntryPointSymbol = SimpleProgramNamedTypeSymbol.GetSimpleProgramEntryPoint(this);
- if (this.Options.MainTypeName != null)
+ if (this.Options.MainTypeName != null && !this.Options.MainTypeName.IsValidClrTypeName())
{
- if (simpleProgramEntryPointSymbol is object)
- {
- // PROTOTYPE(SimplePrograms): Report an error that MainTypeName shouldn't be specified
- }
- else if (!this.Options.MainTypeName.IsValidClrTypeName())
- {
- Debug.Assert(!this.Options.Errors.IsDefaultOrEmpty);
- entryPoint = new EntryPoint(null, ImmutableArray.Empty);
- }
+ Debug.Assert(!this.Options.Errors.IsDefaultOrEmpty);
+ entryPoint = new EntryPoint(null, ImmutableArray.Empty);
}
if (entryPoint is null)
@@ -1566,6 +1559,13 @@ internal bool DeclaresTheObjectClass
entryPoint = new EntryPoint(entryPointMethod, diagnostics);
}
+ if (this.Options.MainTypeName != null && simpleProgramEntryPointSymbol is object)
+ {
+ var diagnostics = DiagnosticBag.GetInstance();
+ diagnostics.Add(ErrorCode.ERR_SimpleProgramDisallowsMainType, NoLocation.Singleton);
+ entryPoint = new EntryPoint(entryPoint.MethodSymbol, entryPoint.Diagnostics.Concat(diagnostics.ToReadOnlyAndFree()));
+ }
+
Interlocked.CompareExchange(ref _lazyEntryPoint, entryPoint, null);
}
@@ -1585,7 +1585,7 @@ internal bool DeclaresTheObjectClass
NamespaceSymbol globalNamespace = this.SourceModule.GlobalNamespace;
var scriptClass = this.ScriptClass;
- if (simpleProgramEntryPointSymbol is null && mainTypeName != null)
+ if (mainTypeName != null)
{
// Global code is the entry point, ignore all other Mains.
if (scriptClass is object)
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index b4460e24619f1..3d141ed8ea3be 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -1776,6 +1776,7 @@ internal enum ErrorCode
ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement = 9000,
ERR_SimpleProgramMultipleUnitsWithTopLevelStatements = 9001,
ERR_TopLevelStatementAfterNamespaceOrType = 9002,
+ ERR_SimpleProgramDisallowsMainType = 9003,
// Note: you will need to re-generate compiler code after adding warnings (eng\generate-compiler-code.cmd)
}
diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
index 38ed8ec573e88..cd46f70d9043a 100644
--- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
+++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
@@ -2088,6 +2088,7 @@ private MemberDeclarationSyntax ParseMemberDeclarationOrStatementCore(SyntaxKind
// All modifiers that might start an expression are processed above.
this.ParseModifiers(modifiers, forAccessors: false);
bool haveModifiers = (modifiers.Count > 0);
+ MemberDeclarationSyntax result;
// Check for constructor form
if (this.CurrentToken.Kind == SyntaxKind.IdentifierToken && this.PeekToken(1).Kind == SyntaxKind.OpenParenToken)
@@ -2100,7 +2101,7 @@ private MemberDeclarationSyntax ParseMemberDeclarationOrStatementCore(SyntaxKind
// missing ';'
//
// Unless modifiers or attributes are present this is more likely to be a method call than a method definition.
- if ((haveAttributes && IsScript) || haveModifiers)
+ if (haveAttributes || haveModifiers)
{
var token = SyntaxFactory.MissingToken(SyntaxKind.VoidKeyword);
token = this.AddError(token, ErrorCode.ERR_MemberNeedsType);
@@ -2108,16 +2109,23 @@ private MemberDeclarationSyntax ParseMemberDeclarationOrStatementCore(SyntaxKind
var identifier = this.EatToken();
- // PROTOTYPE(SimplePrograms): Should we parse this as a local function for Simple Programs in some scenarios?
- return this.ParseMethodDeclaration(attributes, modifiers, voidType, explicitInterfaceOpt: null, identifier: identifier, typeParameterList: null);
+ if (!IsScript)
+ {
+ if (tryParseLocalDeclarationStatementFromStartPoint(attributes, ref afterAttributesPoint, out result))
+ {
+ return result;
+ }
+ }
+ else
+ {
+ return this.ParseMethodDeclaration(attributes, modifiers, voidType, explicitInterfaceOpt: null, identifier: identifier, typeParameterList: null);
+ }
}
}
// Destructors are disallowed in global code, skipping check for them.
// TODO: better error messages for script
- MemberDeclarationSyntax result;
-
// Check for constant
if (this.CurrentToken.Kind == SyntaxKind.ConstKeyword)
{
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SimpleProgramNamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SimpleProgramNamedTypeSymbol.cs
index 7e6ab3868a5b7..e1fd37a1e2c8f 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SimpleProgramNamedTypeSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SimpleProgramNamedTypeSymbol.cs
@@ -87,7 +87,7 @@ protected override Location GetCorrespondingBaseListLocation(NamedTypeSymbol @ba
}
internal override NamedTypeSymbol BaseTypeNoUseSiteDiagnostics
- => this.DeclaringCompilation.GetSpecialType(Microsoft.CodeAnalysis.SpecialType.System_Object); // PROTOTYPE(SimplePrograms): Test with missing Object type.
+ => this.DeclaringCompilation.GetSpecialType(Microsoft.CodeAnalysis.SpecialType.System_Object);
protected override void CheckBase(DiagnosticBag diagnostics)
{
@@ -95,7 +95,7 @@ protected override void CheckBase(DiagnosticBag diagnostics)
var info = this.DeclaringCompilation.GetSpecialType(SpecialType.System_Object).GetUseSiteDiagnostic();
if (info != null)
{
- Symbol.ReportUseSiteDiagnostic(info, diagnostics, Locations[0]);
+ Symbol.ReportUseSiteDiagnostic(info, diagnostics, NoLocation.Singleton);
}
}
diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedSimpleProgramEntryPointSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedSimpleProgramEntryPointSymbol.cs
index 7552e4f864561..53ffa7851c9b0 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedSimpleProgramEntryPointSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedSimpleProgramEntryPointSymbol.cs
@@ -36,12 +36,10 @@ internal SynthesizedSimpleProgramEntryPointSymbol(SimpleProgramNamedTypeSymbol c
if (hasAwait)
{
- // PROTOTYPE(SimplePrograms): Test with missing Task type.
_returnType = Binder.GetWellKnownType(containingType.DeclaringCompilation, WellKnownType.System_Threading_Tasks_Task, diagnostics, NoLocation.Singleton);
}
else
{
- // PROTOTYPE(SimplePrograms): Test with missing Void type.
_returnType = Binder.GetSpecialType(containingType.DeclaringCompilation, SpecialType.System_Void, NoLocation.Singleton, diagnostics);
}
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index 17260e4458571..c3350abcc8508 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -437,6 +437,11 @@
Cílový modul runtime nepodporuje pro člena rozhraní přístupnost na úrovni Protected, Protected internal nebo Private protected.
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
+ Cannot use local variable or local function '{0}' declared in a top-level statement in this context.Cannot use local variable or local function '{0}' declared in a top-level statement in this context.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index f76007a5e54d1..c48e614abff38 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -437,6 +437,11 @@
Die Zugriffsoptionen "protected", "protected internal" oder "private protected" werden von der Zielruntime für einen Member einer Schnittstelle nicht unterstützt.
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
+ Cannot use local variable or local function '{0}' declared in a top-level statement in this context.Cannot use local variable or local function '{0}' declared in a top-level statement in this context.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index b532b18f54ba1..968b65a05a76c 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -437,6 +437,11 @@
El entorno de ejecución de destino no admite la accesibilidad protegida, protegida interna o protegida privada para un miembro de una interfaz.
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
+ Cannot use local variable or local function '{0}' declared in a top-level statement in this context.Cannot use local variable or local function '{0}' declared in a top-level statement in this context.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index 6ea553b844a31..df269213d32c1 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -437,6 +437,11 @@
Le runtime cible ne prend pas en charge l'accessibilité 'protected', 'protected internal' ou 'private protected' d'un membre d'interface.
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
+ Cannot use local variable or local function '{0}' declared in a top-level statement in this context.Cannot use local variable or local function '{0}' declared in a top-level statement in this context.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index c8e42d65d317a..40bdbb229f087 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -437,6 +437,11 @@
Il runtime di destinazione non supporta l'accessibilità 'protected', 'protected internal' o 'private protected' per un membro di un'interfaccia.
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
+ Cannot use local variable or local function '{0}' declared in a top-level statement in this context.Cannot use local variable or local function '{0}' declared in a top-level statement in this context.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index 06b321d02b3aa..d5b3e1f99ade4 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -437,6 +437,11 @@
ターゲット ランタイムは、インターフェイスのメンバーに対して 'protected'、'protected internal'、'private protected' アクセシビリティをサポートしていません。
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
+ Cannot use local variable or local function '{0}' declared in a top-level statement in this context.Cannot use local variable or local function '{0}' declared in a top-level statement in this context.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index 67b4316ea9654..3173e39601462 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -437,6 +437,11 @@
대상 런타임이 인터페이스 멤버의 'protected', 'protected internal' 또는 'private protected' 접근성을 지원하지 않습니다.
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
+ Cannot use local variable or local function '{0}' declared in a top-level statement in this context.Cannot use local variable or local function '{0}' declared in a top-level statement in this context.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index 4e81689c10a3a..0a120339107c7 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -437,6 +437,11 @@
Docelowe środowisko uruchomieniowe nie obsługuje specyfikatorów dostępu „protected”, „protected internal” i „private protected” dla składowej interfejsu.
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
+ Cannot use local variable or local function '{0}' declared in a top-level statement in this context.Cannot use local variable or local function '{0}' declared in a top-level statement in this context.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index a8631d9b143fc..243ac2dfc9e12 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -437,6 +437,11 @@
O runtime de destino não é compatível com a acessibilidade 'protected', 'protected internal' ou 'private protected' para um membro de uma interface.
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
+ Cannot use local variable or local function '{0}' declared in a top-level statement in this context.Cannot use local variable or local function '{0}' declared in a top-level statement in this context.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index f17a1a27e9d34..3fba5b9bc0e57 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -437,6 +437,11 @@
Целевая среда выполнения не поддерживает специальные возможности "защищенный", "внутренний защищенный" или "частный защищенный" для члена интерфейса.
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
+ Cannot use local variable or local function '{0}' declared in a top-level statement in this context.Cannot use local variable or local function '{0}' declared in a top-level statement in this context.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index 54024ab3db765..387a990b13c05 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -437,6 +437,11 @@
Hedef çalışma zamanı, bir arabirim üyesi için 'protected', 'protected internal' veya 'private protected' erişilebilirliğini desteklemez.
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
+ Cannot use local variable or local function '{0}' declared in a top-level statement in this context.Cannot use local variable or local function '{0}' declared in a top-level statement in this context.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index 850d0764bf8c6..bb466a8db0228 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -437,6 +437,11 @@
目标运行时不支持对接口的成员使用 "protected"、"protected internal" 或 "private protected" 辅助功能。
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
+ Cannot use local variable or local function '{0}' declared in a top-level statement in this context.Cannot use local variable or local function '{0}' declared in a top-level statement in this context.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index a3db41f17b678..bb63ec5321beb 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -437,6 +437,11 @@
目標執行階段不支援介面成員的 'protected'、'protected internal' 或 'private protected' 存取權。
+
+ Cannot specify /main if there is a compilation unit with top-level statements.
+ Cannot specify /main if there is a compilation unit with top-level statements.
+
+ Cannot use local variable or local function '{0}' declared in a top-level statement in this context.Cannot use local variable or local function '{0}' declared in a top-level statement in this context.
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SimpleProgramsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SimpleProgramsTests.cs
index 5a3fd7a23bf4a..6ed065f327020 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/SimpleProgramsTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SimpleProgramsTests.cs
@@ -170,32 +170,36 @@ static void verifyModel(CSharpCompilation comp, SyntaxTree tree1, bool nullableE
Assert.NotNull(operation1);
Assert.IsAssignableFrom(operation1);
- Assert.NotNull(ControlFlowGraph.Create((IBlockOperation)operation1.Parent.Parent));
+ Assert.NotNull(ControlFlowGraph.Create((IMethodBodyOperation)((IBlockOperation)operation1.Parent.Parent).Parent));
model1.VerifyOperationTree(unit1,
@"
-IBlockOperation (2 statements) (OperationKind.Block, Type: null) (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)')
+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 System.Console.WriteLine(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... riteLine(2)')
+ IInvocationOperation (void local()) (OperationKind.Invocation, Type: System.Void) (Syntax: 'local()')
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
+ 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().Single();
var declSymbol = model1.GetDeclaredSymbol(localDecl);
@@ -294,17 +298,21 @@ static void verifyModel(CSharpCompilation comp, SyntaxTree tree1, SyntaxTree tre
Assert.NotNull(operation1);
Assert.IsAssignableFrom(operation1);
- Assert.NotNull(ControlFlowGraph.Create((IBlockOperation)operation1.Parent.Parent));
+ Assert.NotNull(ControlFlowGraph.Create((IMethodBodyOperation)((IBlockOperation)operation1.Parent.Parent).Parent));
model1.VerifyOperationTree(unit1,
@"
-IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsInvalid) (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)
+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);
@@ -328,28 +336,32 @@ static void verifyModel(CSharpCompilation comp, SyntaxTree tree1, SyntaxTree tre
Assert.NotNull(operation2);
Assert.IsAssignableFrom(operation2);
- Assert.NotNull(ControlFlowGraph.Create((IBlockOperation)operation2.Parent));
+ Assert.NotNull(ControlFlowGraph.Create((IMethodBodyOperation)((IBlockOperation)operation2.Parent).Parent));
var isInvalid = comp.SyntaxTrees[1] == tree2 ? ", IsInvalid" : "";
model2.VerifyOperationTree(unit2,
@"
-IBlockOperation (1 statements) (OperationKind.Block, Type: null" + isInvalid + @") (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:
+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
- 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)
@@ -4399,6 +4411,68 @@ public static async Task Wait()
);
}
+ [Fact]
+ public void ExplicitMain_10()
+ {
+ var text = @"
+using System.Threading.Tasks;
+
+System.Console.Write(""Hi!"");
+
+class Program
+{
+ static void Main()
+ {
+ }
+
+ static async Task Main(string[] args)
+ {
+ await Task.Factory.StartNew(() => 5);
+ }
+}
+
+class Program2
+{
+ static void Main(string[] args)
+ {
+ }
+}
+";
+
+ var comp = CreateCompilation(text, options: TestOptions.DebugExe.WithMainTypeName("Program"), parseOptions: DefaultParseOptions);
+
+ comp.VerifyEmitDiagnostics(
+ // error CS9003: Cannot specify /main if there is a compilation unit with top-level statements.
+ Diagnostic(ErrorCode.ERR_SimpleProgramDisallowsMainType).WithLocation(1, 1)
+ );
+ }
+
+ [Fact]
+ public void ExplicitMain_11()
+ {
+ var text = @"
+using System.Threading.Tasks;
+
+System.Console.Write(""Hi!"");
+
+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),
+ // error CS9003: Cannot specify /main if there is a compilation unit with top-level statements.
+ Diagnostic(ErrorCode.ERR_SimpleProgramDisallowsMainType).WithLocation(1, 1)
+ );
+ }
+
[Fact]
public void Yield_01()
{
@@ -4753,9 +4827,18 @@ public MyAttribute(int x) {}
// (12,1): error CS7014: Attributes are not valid in this context.
// [MyAttribute(i + 3)]
Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[MyAttribute(i + 3)]").WithLocation(12, 1),
- // (15,1): error CS7014: Attributes are not valid in this context.
- // [MyAttribute(i + 4)]
- Diagnostic(ErrorCode.ERR_AttributesNotAllowed, "[MyAttribute(i + 4)]").WithLocation(15, 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];
@@ -6114,5 +6197,41 @@ private void Handle2(OperationAnalysisContext context)
}
}
+ [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),
+ // error CS0518: Predefined type 'System.Object' is not defined or imported
+ Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound).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)
+ );
+ }
+
+ [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: '' has the wrong signature to be an entry point
+ // await Test();
+ Diagnostic(ErrorCode.WRN_InvalidMainSig, "await Test();").WithArguments("").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)
+ );
+ }
+
}
}
diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/SimpleProgramsParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/SimpleProgramsParsingTests.cs
index c8f218244285b..189e6b6d04487 100644
--- a/src/Compilers/CSharp/Test/Syntax/Parsing/SimpleProgramsParsingTests.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Parsing/SimpleProgramsParsingTests.cs
@@ -2452,5 +2452,141 @@ public void Repro611177()
}
EOF();
}
+
+ [Fact]
+ public void ConstructorLike_01()
+ {
+ var test = @"local() {}";
+
+ UsingTree(test,
+ // (1,9): error CS1002: ; expected
+ // local() {}
+ Diagnostic(ErrorCode.ERR_SemicolonExpected, "{").WithLocation(1, 9)
+ );
+
+ N(SyntaxKind.CompilationUnit);
+ {
+ N(SyntaxKind.GlobalStatement);
+ {
+ N(SyntaxKind.ExpressionStatement);
+ {
+ N(SyntaxKind.InvocationExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "local");
+ }
+ N(SyntaxKind.ArgumentList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.CloseParenToken);
+ }
+ }
+ M(SyntaxKind.SemicolonToken);
+ }
+ }
+ N(SyntaxKind.GlobalStatement);
+ {
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ N(SyntaxKind.EndOfFileToken);
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void ConstructorLike_02()
+ {
+ var test = @"static local() {}";
+
+ UsingTree(test,
+ // (1,13): error CS1001: Identifier expected
+ // static local() {}
+ Diagnostic(ErrorCode.ERR_IdentifierExpected, "(").WithLocation(1, 13)
+ );
+
+ N(SyntaxKind.CompilationUnit);
+ {
+ N(SyntaxKind.GlobalStatement);
+ {
+ N(SyntaxKind.LocalFunctionStatement);
+ {
+ N(SyntaxKind.StaticKeyword);
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "local");
+ }
+ M(SyntaxKind.IdentifierToken);
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ N(SyntaxKind.EndOfFileToken);
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void ConstructorLike_03()
+ {
+ var test = @"[attribute] local() {}";
+
+ UsingTree(test,
+ // (1,18): error CS1001: Identifier expected
+ // [attribute] local() {}
+ Diagnostic(ErrorCode.ERR_IdentifierExpected, "(").WithLocation(1, 18)
+ );
+
+ N(SyntaxKind.CompilationUnit);
+ {
+ N(SyntaxKind.GlobalStatement);
+ {
+ N(SyntaxKind.LocalFunctionStatement);
+ {
+ N(SyntaxKind.AttributeList);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.Attribute);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "attribute");
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "local");
+ }
+ M(SyntaxKind.IdentifierToken);
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ N(SyntaxKind.EndOfFileToken);
+ }
+ EOF();
+ }
}
}