From b043b11b64e690bf4f442d822d5e0f70c92cb156 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Wed, 14 Sep 2016 15:20:07 -0700 Subject: [PATCH] Handle Out Variable Declarations in a Script. Fixes #13450. Fixes #13590. --- .../Portable/Binder/Binder_Expressions.cs | 104 +- .../Portable/Binder/Binder_Initializers.cs | 2 +- .../Portable/Binder/Binder_Invocation.cs | 16 +- .../Portable/Binder/Binder_Statements.cs | 2 +- .../Binder/ExpressionVariableFinder.cs | 218 +- .../OverloadResolution/OverloadResolution.cs | 4 +- .../OverloadResolutionResult.cs | 4 +- .../CSharp/Portable/BoundTree/BoundNodes.xml | 9 +- .../CSharp/Portable/BoundTree/Expression.cs | 4 +- .../CSharp/Portable/BoundTree/Formatting.cs | 2 +- .../BoundTree/OutVarLocalPendingInference.cs | 33 - .../BoundTree/OutVariablePendingInference.cs | 90 + .../CSharp/Portable/CSharpCodeAnalysis.csproj | 3 +- .../Compilation/CSharpSemanticModel.cs | 67 +- .../Compilation/SyntaxTreeSemanticModel.cs | 11 +- .../FlowAnalysis/PreciseAbstractFlowPass.cs | 7 +- .../LocalRewriter_LocalDeclaration.cs | 2 +- .../Symbols/Source/SourceEventFieldSymbol.cs | 2 +- .../Symbols/Source/SourceFixedFieldSymbol.cs | 2 +- .../Source/SourceMemberContainerSymbol.cs | 83 +- .../Symbols/Source/SourceMemberFieldSymbol.cs | 466 +- .../SourceMemberFieldSymbolFromDesignation.cs | 219 + .../Portable/Syntax/SyntaxExtensions.cs | 9 + .../CSharp/Portable/Syntax/SyntaxFacts.cs | 2 +- .../Test/Semantic/Semantics/IteratorTests.cs | 24 +- .../Test/Semantic/Semantics/OutVarTests.cs | 6998 ++++++++++++++++- .../Semantics/PatternMatchingTests.cs | 14 +- .../Semantics/ScriptSemanticsTests.cs | 46 + 28 files changed, 8015 insertions(+), 428 deletions(-) delete mode 100644 src/Compilers/CSharp/Portable/BoundTree/OutVarLocalPendingInference.cs create mode 100644 src/Compilers/CSharp/Portable/BoundTree/OutVariablePendingInference.cs create mode 100644 src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbolFromDesignation.cs diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs index fdfaa7e7213..18af0ad9c13 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs @@ -1401,7 +1401,7 @@ protected virtual BoundExpression BindRangeVariable(SimpleNameSyntax node, Range return Next.BindRangeVariable(node, qv, diagnostics); } - private BoundExpression SynthesizeReceiver(SimpleNameSyntax node, Symbol member, DiagnosticBag diagnostics) + private BoundExpression SynthesizeReceiver(CSharpSyntaxNode node, Symbol member, DiagnosticBag diagnostics) { // SPEC: Otherwise, if T is the instance type of the immediately enclosing class or // struct type, if the lookup identifies an instance member, and if the reference occurs @@ -2041,44 +2041,83 @@ private BoundExpression BindArgumentValue(DiagnosticBag diagnostics, ArgumentSyn } var declarationExpression = (DeclarationExpressionSyntax)argumentSyntax.Expression; - var declaration = (TypedVariableComponentSyntax)declarationExpression.VariableComponent; - var typeSyntax = declaration.Type; + var typeSyntax = declarationExpression.Type(); + bool isVar; + + // Is this a local? + SourceLocalSymbol localSymbol = this.LookupLocal(declarationExpression.Identifier()); - if (InConstructorInitializer || InFieldInitializer) + if ((object)localSymbol != null) { - Error(diagnostics, ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, declarationExpression); - } + if (InConstructorInitializer || InFieldInitializer) + { + Error(diagnostics, ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, declarationExpression); + } - bool isConst = false; - bool isVar; - AliasSymbol alias; - TypeSymbol declType = BindVariableType(declarationExpression, diagnostics, typeSyntax, ref isConst, out isVar, out alias); + bool isConst = false; + AliasSymbol alias; + TypeSymbol declType = BindVariableType(declarationExpression, diagnostics, typeSyntax, ref isConst, out isVar, out alias); - SourceLocalSymbol localSymbol = this.LookupLocal(declarationExpression.Identifier()); + localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); - if ((object)localSymbol == null) + if (isVar) + { + return new OutVariablePendingInference(declarationExpression, localSymbol, null); + } + + if (this.ContainingMemberOrLambda.Kind == SymbolKind.Method + && ((MethodSymbol)this.ContainingMemberOrLambda).IsAsync + && declType.IsRestrictedType()) + { + Error(diagnostics, ErrorCode.ERR_BadSpecialByRefLocal, typeSyntax, declType); + } + + return new BoundLocal(declarationExpression, localSymbol, constantValueOpt: null, type: declType); + } + + // Is this a field? + SourceMemberFieldSymbolFromDesignation expressionVariableField = LookupDeclaredField(declarationExpression.VariableDesignation()); + + if ((object)expressionVariableField == null) { // We should have the right binder in the chain, cannot continue otherwise. throw ExceptionUtilities.Unreachable; } - else - { - localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); - } - if (isVar) + BoundExpression receiver = SynthesizeReceiver(declarationExpression.VariableDesignation(), expressionVariableField, diagnostics); + + if (typeSyntax.IsVar) { - return new OutVarLocalPendingInference(declarationExpression, localSymbol); + var ignored = DiagnosticBag.GetInstance(); + BindTypeOrAlias(typeSyntax, ignored, out isVar); + ignored.Free(); + + if (isVar) + { + return new OutVariablePendingInference(declarationExpression, expressionVariableField, receiver); + } } - if (this.ContainingMemberOrLambda.Kind == SymbolKind.Method - && ((MethodSymbol)this.ContainingMemberOrLambda).IsAsync - && declType.IsRestrictedType()) + TypeSymbol fieldType = expressionVariableField.GetFieldType(this.FieldsBeingBound); + return new BoundFieldAccess(declarationExpression, + receiver, + expressionVariableField, null, LookupResultKind.Viable, fieldType); + } + + internal SourceMemberFieldSymbolFromDesignation LookupDeclaredField(SingleVariableDesignationSyntax variableDesignator) + { + foreach (Symbol member in ContainingType?.GetMembers(variableDesignator.Identifier.ValueText) ?? ImmutableArray.Empty) { - Error(diagnostics, ErrorCode.ERR_BadSpecialByRefLocal, typeSyntax, declType); + SourceMemberFieldSymbolFromDesignation field; + if (member.Kind == SymbolKind.Field && + (field = member as SourceMemberFieldSymbolFromDesignation)?.SyntaxTree == variableDesignator.SyntaxTree && + field.SyntaxNode == variableDesignator) + { + return field; + } } - return new BoundLocal(declarationExpression, localSymbol, constantValueOpt: null, type: declType); + return null; } // Bind a named/positional argument. @@ -2231,21 +2270,10 @@ private BoundExpression BindArgumentExpression(DiagnosticBag diagnostics, Expres arguments[arg] = CreateConversion(argument.Syntax, argument, kind, false, type, diagnostics); } - else if (argument.Kind == BoundKind.OutVarLocalPendingInference) + else if (argument.Kind == BoundKind.OutVariablePendingInference) { TypeSymbol parameterType = GetCorrespondingParameterType(ref result, parameters, arg); - bool hasErrors = false; - - if (this.ContainingMemberOrLambda.Kind == SymbolKind.Method - && ((MethodSymbol)this.ContainingMemberOrLambda).IsAsync - && parameterType.IsRestrictedType()) - { - var declaration = (TypedVariableComponentSyntax)((DeclarationExpressionSyntax)argument.Syntax).VariableComponent; - Error(diagnostics, ErrorCode.ERR_BadSpecialByRefLocal, declaration.Type, parameterType); - hasErrors = true; - } - - arguments[arg] = ((OutVarLocalPendingInference)argument).SetInferredType(parameterType, success: !hasErrors); + arguments[arg] = ((OutVariablePendingInference)argument).SetInferredType(parameterType, diagnostics); } else if (argument.Kind == BoundKind.OutDeconstructVarPendingInference) { @@ -6065,9 +6093,9 @@ private BoundExpression ConvertToArrayIndex(BoundExpression index, SyntaxNode no { Debug.Assert(index != null); - if (index.Kind == BoundKind.OutVarLocalPendingInference) + if (index.Kind == BoundKind.OutVariablePendingInference) { - return ((OutVarLocalPendingInference)index).FailInference(this, diagnostics); + return ((OutVariablePendingInference)index).FailInference(this, diagnostics); } var result = diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs index 11963198e7c..d5fc582b23b 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs @@ -252,7 +252,7 @@ internal struct ProcessedFieldInitializers var fieldsBeingBound = binder.FieldsBeingBound; - var sourceField = fieldSymbol as SourceMemberFieldSymbol; + var sourceField = fieldSymbol as SourceMemberFieldSymbolFromDeclarator; bool isImplicitlyTypedField = (object)sourceField != null && sourceField.FieldTypeInferred(fieldsBeingBound); // If the type is implicitly typed, the initializer diagnostics have already been reported, so ignore them here: diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs index 01b4110d47d..f84cb7b0fd2 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs @@ -114,7 +114,7 @@ private static ImmutableArray GetOriginalMethods(OverloadResolutio boundExpression.WasCompilerGenerated = true; var analyzedArguments = AnalyzedArguments.GetInstance(); - Debug.Assert(!args.Any(e => e.Kind == BoundKind.OutVarLocalPendingInference || e.Kind == BoundKind.OutDeconstructVarPendingInference)); + Debug.Assert(!args.Any(e => e.Kind == BoundKind.OutVariablePendingInference || e.Kind == BoundKind.OutDeconstructVarPendingInference)); analyzedArguments.Arguments.AddRange(args); BoundExpression result = BindInvocationExpression( node, node, methodName, boundExpression, analyzedArguments, diagnostics, queryClause, @@ -335,7 +335,7 @@ private ImmutableArray BuildArgumentsForDynamicInvocation(Analy { Debug.Assert(arguments.Arguments[i].Kind != BoundKind.OutDeconstructVarPendingInference); - if (arguments.Arguments[i].Kind == BoundKind.OutVarLocalPendingInference) + if (arguments.Arguments[i].Kind == BoundKind.OutVariablePendingInference) { var builder = ArrayBuilder.GetInstance(arguments.Arguments.Count); builder.AddRange(arguments.Arguments); @@ -344,9 +344,9 @@ private ImmutableArray BuildArgumentsForDynamicInvocation(Analy { BoundExpression argument = builder[i]; - if (argument.Kind == BoundKind.OutVarLocalPendingInference) + if (argument.Kind == BoundKind.OutVariablePendingInference) { - builder[i] = ((OutVarLocalPendingInference)argument).FailInference(this, diagnostics); + builder[i] = ((OutVariablePendingInference)argument).FailInference(this, diagnostics); } i++; @@ -1148,7 +1148,7 @@ private ImmutableArray BuildArgumentsForErrorRecovery(AnalyzedA private ImmutableArray BuildArgumentsForErrorRecovery(AnalyzedArguments analyzedArguments, IEnumerable> parameterListList) { // Since the purpose is to bind any unbound lambdas, we return early if there are none. - if (!analyzedArguments.Arguments.Any(e => e.Kind == BoundKind.UnboundLambda || e.Kind == BoundKind.OutVarLocalPendingInference || e.Kind == BoundKind.OutDeconstructVarPendingInference)) + if (!analyzedArguments.Arguments.Any(e => e.Kind == BoundKind.UnboundLambda || e.Kind == BoundKind.OutVariablePendingInference || e.Kind == BoundKind.OutDeconstructVarPendingInference)) { return analyzedArguments.Arguments.ToImmutable(); } @@ -1175,7 +1175,7 @@ private ImmutableArray BuildArgumentsForErrorRecovery(AnalyzedA // replace the unbound lambda with its best inferred bound version newArguments[i] = unboundArgument.BindForErrorRecovery(); } - else if (argument.Kind == BoundKind.OutVarLocalPendingInference) + else if (argument.Kind == BoundKind.OutVariablePendingInference) { // See if all applicable applicable parameters have the same type TypeSymbol candidateType = null; @@ -1199,11 +1199,11 @@ private ImmutableArray BuildArgumentsForErrorRecovery(AnalyzedA if ((object)candidateType == null) { - newArguments[i] = ((OutVarLocalPendingInference)argument).FailInference(this, null); + newArguments[i] = ((OutVariablePendingInference)argument).FailInference(this, null); } else { - newArguments[i] = ((OutVarLocalPendingInference)argument).SetInferredType(candidateType, success: true); + newArguments[i] = ((OutVariablePendingInference)argument).SetInferredType(candidateType, null); } } else if (argument.Kind == BoundKind.OutDeconstructVarPendingInference) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs index 3c2ad7ccd28..34b768b82ac 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs @@ -1867,7 +1867,7 @@ private BoundExpression CheckValue(BoundExpression expr, BindValueKind valueKind Debug.Assert(expr.Syntax.Kind() != SyntaxKind.Argument || valueKind == BindValueKind.RefOrOut); break; - case BoundKind.OutVarLocalPendingInference: + case BoundKind.OutVariablePendingInference: case BoundKind.OutDeconstructVarPendingInference: Debug.Assert(valueKind == BindValueKind.RefOrOut); return expr; diff --git a/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs b/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs index 21e56be765a..5d11581263b 100644 --- a/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs @@ -10,28 +10,19 @@ namespace Microsoft.CodeAnalysis.CSharp { - internal class ExpressionVariableFinder : CSharpSyntaxWalker + internal abstract class ExpressionVariableFinder : CSharpSyntaxWalker where TFieldOrLocalSymbol : Symbol { - private Binder _scopeBinder; - private Binder _enclosingBinder; - private ArrayBuilder _localsBuilder; + private ArrayBuilder _localsBuilder; private SyntaxNode _nodeToBind; - internal static void FindExpressionVariables( - Binder scopeBinder, - ArrayBuilder builder, - CSharpSyntaxNode node, - Binder enclosingBinderOpt = null) + protected void FindExpressionVariables( + ArrayBuilder builder, + CSharpSyntaxNode node) { - if (node == null) - { - return; - } + Debug.Assert(node != null); - var finder = s_poolInstance.Allocate(); - finder._scopeBinder = scopeBinder; - finder._enclosingBinder = enclosingBinderOpt ?? scopeBinder; - finder._localsBuilder = builder; + ArrayBuilder save = _localsBuilder; + _localsBuilder = builder; #if DEBUG // These are all of the kinds of nodes we should need to handle in this class. @@ -62,12 +53,9 @@ internal class ExpressionVariableFinder : CSharpSyntaxWalker } #endif - finder.VisitNodeToBind(node); + VisitNodeToBind(node); - finder._scopeBinder = null; - finder._enclosingBinder = null; - finder._localsBuilder = null; - s_poolInstance.Free(finder); + _localsBuilder = save; } public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) @@ -91,30 +79,20 @@ private void VisitNodeToBind(CSharpSyntaxNode node) _nodeToBind = previousNodeToBind; } - internal static void FindExpressionVariables( - Binder binder, - ArrayBuilder builder, + protected void FindExpressionVariables( + ArrayBuilder builder, SeparatedSyntaxList nodes) { - if (nodes.Count == 0) - { - return; - } - - var finder = s_poolInstance.Allocate(); - finder._scopeBinder = binder; - finder._enclosingBinder = binder; - finder._localsBuilder = builder; + Debug.Assert(nodes.Count > 0); + ArrayBuilder save = _localsBuilder; + _localsBuilder = builder; foreach (var n in nodes) { - finder.VisitNodeToBind(n); + VisitNodeToBind(n); } - finder._scopeBinder = null; - finder._enclosingBinder = null; - finder._localsBuilder = null; - s_poolInstance.Free(finder); + _localsBuilder = save; } public override void VisitEqualsValueClause(EqualsValueClauseSyntax node) @@ -205,18 +183,12 @@ public override void VisitSwitchStatement(SwitchStatementSyntax node) public override void VisitDeclarationPattern(DeclarationPatternSyntax node) { - _localsBuilder.Add(SourceLocalSymbol.MakeLocalSymbolWithEnclosingContext( - _scopeBinder.ContainingMemberOrLambda, - scopeBinder: _scopeBinder, - nodeBinder: _enclosingBinder, - typeSyntax: node.Type, - identifierToken: node.Identifier, - kind: LocalDeclarationKind.PatternVariable, - nodeToBind: _nodeToBind, - forbiddenZone: null)); + _localsBuilder.Add(MakePatternVariable(node, _nodeToBind)); base.VisitDeclarationPattern(node); } + protected abstract TFieldOrLocalSymbol MakePatternVariable(DeclarationPatternSyntax node, SyntaxNode nodeToBind); + public override void VisitParenthesizedLambdaExpression(ParenthesizedLambdaExpressionSyntax node) { } public override void VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node) { } public override void VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { } @@ -274,15 +246,97 @@ public override void VisitDeclarationExpression(DeclarationExpressionSyntax node { var argumentSyntax = (ArgumentSyntax)node?.Parent; var argumentListSyntax = (BaseArgumentListSyntax)argumentSyntax?.Parent; - _localsBuilder.Add(SourceLocalSymbol.MakeLocalSymbolWithEnclosingContext( - containingSymbol: _scopeBinder.ContainingMemberOrLambda, - scopeBinder: _scopeBinder, - nodeBinder: _enclosingBinder, - typeSyntax: node.Type(), - identifierToken: node.Identifier(), - kind: LocalDeclarationKind.RegularVariable, - nodeToBind: _nodeToBind, - forbiddenZone: argumentListSyntax)); + var variable = MakeOutVariable(node, argumentListSyntax, _nodeToBind); + if ((object)variable != null) + { + _localsBuilder.Add(variable); + } + } + + protected abstract TFieldOrLocalSymbol MakeOutVariable(DeclarationExpressionSyntax node, BaseArgumentListSyntax argumentListSyntax, SyntaxNode nodeToBind); + } + + internal class ExpressionVariableFinder : ExpressionVariableFinder + { + private Binder _scopeBinder; + private Binder _enclosingBinder; + + + internal static void FindExpressionVariables( + Binder scopeBinder, + ArrayBuilder builder, + CSharpSyntaxNode node, + Binder enclosingBinderOpt = null) + { + if (node == null) + { + return; + } + + var finder = s_poolInstance.Allocate(); + finder._scopeBinder = scopeBinder; + finder._enclosingBinder = enclosingBinderOpt ?? scopeBinder; + + finder.FindExpressionVariables(builder, node); + + finder._scopeBinder = null; + finder._enclosingBinder = null; + s_poolInstance.Free(finder); + } + + internal static void FindExpressionVariables( + Binder binder, + ArrayBuilder builder, + SeparatedSyntaxList nodes) + { + if (nodes.Count == 0) + { + return; + } + + var finder = s_poolInstance.Allocate(); + finder._scopeBinder = binder; + finder._enclosingBinder = binder; + + finder.FindExpressionVariables(builder, nodes); + + finder._scopeBinder = null; + finder._enclosingBinder = null; + s_poolInstance.Free(finder); + } + + protected override LocalSymbol MakePatternVariable(DeclarationPatternSyntax node, SyntaxNode nodeToBind) + { + return SourceLocalSymbol.MakeLocalSymbolWithEnclosingContext( + _scopeBinder.ContainingMemberOrLambda, + scopeBinder: _scopeBinder, + nodeBinder: _enclosingBinder, + typeSyntax: node.Type, + identifierToken: node.Identifier, + kind: LocalDeclarationKind.PatternVariable, + nodeToBind: nodeToBind, + forbiddenZone: null); + } + protected override LocalSymbol MakeOutVariable(DeclarationExpressionSyntax node, BaseArgumentListSyntax argumentListSyntax, SyntaxNode nodeToBind) + { + NamedTypeSymbol container = _scopeBinder.ContainingType; + + if ((object)container != null && container.IsScriptClass && + (object)_scopeBinder.LookupDeclaredField(node.VariableDesignation()) != null) + { + // This is a field declaration + return null; + } + + return SourceLocalSymbol.MakeLocalSymbolWithEnclosingContext( + containingSymbol: _scopeBinder.ContainingMemberOrLambda, + scopeBinder: _scopeBinder, + nodeBinder: _enclosingBinder, + typeSyntax: node.Type(), + identifierToken: node.Identifier(), + kind: LocalDeclarationKind.RegularVariable, + nodeToBind: nodeToBind, + forbiddenZone: argumentListSyntax); } #region pool @@ -294,4 +348,54 @@ public static ObjectPool CreatePool() } #endregion } + + internal class ExpressionFieldFinder : ExpressionVariableFinder + { + private SourceMemberContainerTypeSymbol _containingType; + private DeclarationModifiers _modifiers; + private FieldSymbol _containingFieldOpt; + + internal static void FindExpressionVariables( + ArrayBuilder builder, + CSharpSyntaxNode node, + SourceMemberContainerTypeSymbol containingType, + DeclarationModifiers modifiers, + FieldSymbol containingFieldOpt) + { + if (node == null) + { + return; + } + + var finder = s_poolInstance.Allocate(); + finder._containingType = containingType; + finder._modifiers = modifiers; + finder._containingFieldOpt = containingFieldOpt; + + finder.FindExpressionVariables(builder, node); + + finder._containingType = null; + finder._modifiers = DeclarationModifiers.None; + finder._containingFieldOpt = null; + s_poolInstance.Free(finder); + } + + protected override Symbol MakePatternVariable(DeclarationPatternSyntax node, SyntaxNode nodeToBind) + { + throw ExceptionUtilities.Unreachable; + } + protected override Symbol MakeOutVariable(DeclarationExpressionSyntax node, BaseArgumentListSyntax argumentListSyntax, SyntaxNode nodeToBind) + { + return SourceMemberFieldSymbolFromDesignation.Create(_containingType, node.VariableDesignation(), _modifiers, _containingFieldOpt, nodeToBind); + } + + #region pool + private static readonly ObjectPool s_poolInstance = CreatePool(); + + public static ObjectPool CreatePool() + { + return new ObjectPool(() => new ExpressionFieldFinder(), 10); + } + #endregion + } } diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs index 2bcbf7bc5dd..381dfbd83e1 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs @@ -1229,7 +1229,7 @@ private static TypeSymbol GetParameterType(int argIndex, MemberAnalysisResult re bool okToDowngradeToNeither; BetterResult r; - if (argumentKind == BoundKind.OutVarLocalPendingInference || argumentKind == BoundKind.OutDeconstructVarPendingInference) + if (argumentKind == BoundKind.OutVariablePendingInference || argumentKind == BoundKind.OutDeconstructVarPendingInference) { // If argument is an out variable that needs type inference, // neither candidate is better in this argument. @@ -2972,7 +2972,7 @@ private RefKind GetEffectiveParameterRefKind(ParameterSymbol parameter, RefKind return Conversion.ImplicitDynamic; } - if (argument.Kind == BoundKind.OutVarLocalPendingInference || argument.Kind == BoundKind.OutDeconstructVarPendingInference) + if (argument.Kind == BoundKind.OutVariablePendingInference || argument.Kind == BoundKind.OutDeconstructVarPendingInference) { Debug.Assert(argRefKind != RefKind.None); diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolutionResult.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolutionResult.cs index 2088b2bd601..dbf4436db2c 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolutionResult.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolutionResult.cs @@ -921,7 +921,7 @@ private static bool HadLambdaConversionError(DiagnosticBag diagnostics, Analyzed // If the expression is untyped because it is a lambda, anonymous method, method group or null // then we never want to report the error "you need a ref on that thing". Rather, we want to // say that you can't convert "null" to "ref int". - if (!argument.HasExpressionType() && argument.Kind != BoundKind.OutDeconstructVarPendingInference && argument.Kind != BoundKind.OutVarLocalPendingInference) + if (!argument.HasExpressionType() && argument.Kind != BoundKind.OutDeconstructVarPendingInference && argument.Kind != BoundKind.OutVariablePendingInference) { // If the problem is that a lambda isn't convertible to the given type, also report why. // The argument and parameter type might match, but may not have same in/out modifiers @@ -969,7 +969,7 @@ private static bool HadLambdaConversionError(DiagnosticBag diagnostics, Analyzed else { Debug.Assert(argument.Kind != BoundKind.OutDeconstructVarPendingInference); - Debug.Assert(argument.Kind != BoundKind.OutVarLocalPendingInference); + Debug.Assert(argument.Kind != BoundKind.OutVariablePendingInference); Debug.Assert(argument.Display != null); if (arguments.IsExtensionMethodThisArgument(arg)) diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml index 35539d72724..7afcf851d5b 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml @@ -1581,11 +1581,14 @@ - - + + - + + + + diff --git a/src/Compilers/CSharp/Portable/BoundTree/Expression.cs b/src/Compilers/CSharp/Portable/BoundTree/Expression.cs index 6834472f2b3..0c9d393c3a9 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/Expression.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/Expression.cs @@ -2974,10 +2974,10 @@ public override void Accept(OperationVisitor visitor) } /// - /// This node represents an out var local. + /// This node represents an out variable. /// It is only used temporarily during initial binding. /// - internal partial class OutVarLocalPendingInference + internal partial class OutVariablePendingInference { public override void Accept(OperationVisitor visitor) { diff --git a/src/Compilers/CSharp/Portable/BoundTree/Formatting.cs b/src/Compilers/CSharp/Portable/BoundTree/Formatting.cs index 6faf533a826..f8bd809d607 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/Formatting.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/Formatting.cs @@ -96,7 +96,7 @@ public override object Display } } - internal partial class OutVarLocalPendingInference + internal partial class OutVariablePendingInference { public override object Display { diff --git a/src/Compilers/CSharp/Portable/BoundTree/OutVarLocalPendingInference.cs b/src/Compilers/CSharp/Portable/BoundTree/OutVarLocalPendingInference.cs deleted file mode 100644 index 3919f8b09bb..00000000000 --- a/src/Compilers/CSharp/Portable/BoundTree/OutVarLocalPendingInference.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.CodeAnalysis.CSharp.Symbols; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using System.Diagnostics; - -namespace Microsoft.CodeAnalysis.CSharp -{ - internal partial class OutVarLocalPendingInference - { - public BoundLocal SetInferredType(TypeSymbol type, bool success) - { - Debug.Assert((object)type != null); - Debug.Assert(this.Syntax.Kind() == SyntaxKind.DeclarationExpression); - - this.LocalSymbol.SetType(type); - return new BoundLocal(this.Syntax, this.LocalSymbol, constantValueOpt: null, type: type, hasErrors: this.HasErrors || !success); - } - - public BoundLocal FailInference(Binder binder, DiagnosticBag diagnosticsOpt) - { - if (diagnosticsOpt != null) - { - var declaration = (DeclarationExpressionSyntax)this.Syntax; - Binder.Error( - diagnosticsOpt, ErrorCode.ERR_TypeInferenceFailedForImplicitlyTypedOutVariable, declaration.Identifier(), - declaration.Identifier().ValueText); - } - - return this.SetInferredType(binder.CreateErrorType("var"), success: false); - } - } -} \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/BoundTree/OutVariablePendingInference.cs b/src/Compilers/CSharp/Portable/BoundTree/OutVariablePendingInference.cs new file mode 100644 index 00000000000..91a8f2e8ad4 --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/OutVariablePendingInference.cs @@ -0,0 +1,90 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Roslyn.Utilities; +using System.Diagnostics; + +namespace Microsoft.CodeAnalysis.CSharp +{ + internal partial class OutVariablePendingInference + { + public BoundExpression SetInferredType(TypeSymbol type, DiagnosticBag diagnosticsOpt) + { + Debug.Assert((object)type != null); + + return SetInferredType(type, null, diagnosticsOpt); + } + + private BoundExpression SetInferredType(TypeSymbol type, Binder binderOpt, DiagnosticBag diagnosticsOpt) + { + Debug.Assert(binderOpt != null || (object)type != null); + Debug.Assert(this.Syntax.Kind() == SyntaxKind.DeclarationExpression); + + bool inferenceFailed = ((object)type == null); + + if (inferenceFailed) + { + type = binderOpt.CreateErrorType("var"); + } + + switch (this.VariableSymbol.Kind) + { + case SymbolKind.Local: + var localSymbol = (SourceLocalSymbol)this.VariableSymbol; + + if (diagnosticsOpt != null) + { + if (inferenceFailed) + { + ReportInferenceFailure(diagnosticsOpt); + } + else if (localSymbol.ContainingSymbol.Kind == SymbolKind.Method && + ((MethodSymbol)localSymbol.ContainingSymbol).IsAsync && + type.IsRestrictedType()) + { + var declaration = (TypedVariableComponentSyntax)((DeclarationExpressionSyntax)this.Syntax).VariableComponent; + Binder.Error(diagnosticsOpt, ErrorCode.ERR_BadSpecialByRefLocal, declaration.Type, type); + } + } + + localSymbol.SetType(type); + return new BoundLocal(this.Syntax, localSymbol, constantValueOpt: null, type: type, hasErrors: this.HasErrors || inferenceFailed); + + case SymbolKind.Field: + var fieldSymbol = (SourceMemberFieldSymbolFromDesignation)this.VariableSymbol; + var inferenceDiagnostics = DiagnosticBag.GetInstance(); + + if (inferenceFailed) + { + ReportInferenceFailure(inferenceDiagnostics); + } + + fieldSymbol.SetType(type, inferenceDiagnostics); + inferenceDiagnostics.Free(); + + return new BoundFieldAccess(this.Syntax, + this.ReceiverOpt, + fieldSymbol, null, LookupResultKind.Viable, type, + this.HasErrors || inferenceFailed); + + default: + throw ExceptionUtilities.Unreachable; + } + + } + + private void ReportInferenceFailure(DiagnosticBag diagnostics) + { + var declaration = (DeclarationExpressionSyntax)this.Syntax; + Binder.Error( + diagnostics, ErrorCode.ERR_TypeInferenceFailedForImplicitlyTypedOutVariable, declaration.Identifier(), + declaration.Identifier().ValueText); + } + + public BoundExpression FailInference(Binder binder, DiagnosticBag diagnosticsOpt) + { + return this.SetInferredType(null, binder, diagnosticsOpt); + } + } +} \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/CSharpCodeAnalysis.csproj b/src/Compilers/CSharp/Portable/CSharpCodeAnalysis.csproj index e55d755dc8b..000446b39a2 100644 --- a/src/Compilers/CSharp/Portable/CSharpCodeAnalysis.csproj +++ b/src/Compilers/CSharp/Portable/CSharpCodeAnalysis.csproj @@ -201,7 +201,7 @@ - + @@ -524,6 +524,7 @@ + diff --git a/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs index f5346ce33ee..7ff06b0b176 100644 --- a/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs @@ -522,11 +522,7 @@ public SymbolInfo GetSymbolInfo(ExpressionSyntax expression, CancellationToken c // Named arguments handled in special way. return this.GetNamedArgumentSymbolInfo((IdentifierNameSyntax)expression, cancellationToken); } - else if (IsOutVarType(expression, out parent)) - { - return TypeFromLocal((VariableDeclarationSyntax)parent, cancellationToken); - } - else if (SyntaxFacts.IsDeconstructionType(expression, out parent)) + else if (SyntaxFacts.IsVariableComponentType(expression, out parent)) { var declaration = (TypedVariableComponentSyntax)parent; if (declaration.Designation.Kind() != SyntaxKind.SingleVariableDesignation) @@ -534,59 +530,44 @@ public SymbolInfo GetSymbolInfo(ExpressionSyntax expression, CancellationToken c return SymbolInfo.None; } - return TypeFromLocal((SingleVariableDesignationSyntax)declaration.Designation, cancellationToken); + return TypeFromVariable((SingleVariableDesignationSyntax)declaration.Designation, cancellationToken); } return this.GetSymbolInfoWorker(expression, SymbolInfoOptions.DefaultOptions, cancellationToken); } - /// - /// Given a variable declaration, figure out its type by looking at the declared symbol of the corresponding local. - /// - private SymbolInfo TypeFromLocal(VariableDeclarationSyntax variableDeclaration, CancellationToken cancellationToken) - { - TypeSymbol variableType = (GetDeclaredSymbol(variableDeclaration.Variables.First(), cancellationToken) as LocalSymbol)?.Type; - - if (variableType?.IsErrorType() == false) - { - return new SymbolInfo(variableType); - } - - return SymbolInfo.None; - } - /// /// Given a variable designation (typically in the left-hand-side of a deconstruction declaration statement), - /// figure out its type by looking at the declared symbol of the corresponding local. + /// figure out its type by looking at the declared symbol of the corresponding variable. /// - private SymbolInfo TypeFromLocal(SingleVariableDesignationSyntax variableDesignation, CancellationToken cancellationToken) + private SymbolInfo TypeFromVariable(SingleVariableDesignationSyntax variableDesignation, CancellationToken cancellationToken) { - TypeSymbol variableType = (GetDeclaredSymbol(variableDesignation, cancellationToken) as LocalSymbol)?.Type; + var variable = GetDeclaredSymbol(variableDesignation, cancellationToken); - if (variableType?.IsErrorType() == false) + if (variable != null) { - return new SymbolInfo(variableType); - } + ITypeSymbol variableType; - return SymbolInfo.None; - } + switch (variable.Kind) + { + case SymbolKind.Local: + variableType = ((ILocalSymbol)variable).Type; + break; + case SymbolKind.Field: + variableType = ((IFieldSymbol)variable).Type; + break; + default: + variableType = null; + break; + } - /// - /// Figures out if this expression is a type in an out-var ArgumentSyntax. - /// Outputs the VariableDeclarationSyntax directly containing it, if that is the case. - /// - private static bool IsOutVarType(ExpressionSyntax expression, out SyntaxNode parent) - { - parent = null; - var variableDeclaration = expression.Parent as VariableDeclarationSyntax; - var enclosingDeclaration = variableDeclaration?.Parent as DeclarationExpressionSyntax; - if (enclosingDeclaration?.Parent?.Kind() != SyntaxKind.Argument) - { - return false; + if (variableType?.Kind != SymbolKind.ErrorType) + { + return new SymbolInfo(variableType); + } } - parent = variableDeclaration; - return variableDeclaration.Type == expression; + return SymbolInfo.None; } /// diff --git a/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs index b5aca88d66a..e687869c6f5 100644 --- a/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs @@ -1647,7 +1647,16 @@ public override ISymbol GetDeclaredSymbol(SingleVariableDesignationSyntax declar { // Might be a local variable. var memberModel = this.GetMemberModel(declarationSyntax); - return memberModel?.GetDeclaredSymbol(declarationSyntax, cancellationToken); + ISymbol local = memberModel?.GetDeclaredSymbol(declarationSyntax, cancellationToken); + + if (local != null) + { + return local; + } + + // Might be a field + Binder binder = GetEnclosingBinder(declarationSyntax.Position); + return binder?.LookupDeclaredField(declarationSyntax); } /// diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/PreciseAbstractFlowPass.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/PreciseAbstractFlowPass.cs index 880b2b51b3f..4ab11c158e5 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/PreciseAbstractFlowPass.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/PreciseAbstractFlowPass.cs @@ -2642,7 +2642,7 @@ public override BoundNode VisitDeconstructValuePlaceholder(BoundDeconstructValue return null; } - public override sealed BoundNode VisitOutVarLocalPendingInference(OutVarLocalPendingInference node) + public override sealed BoundNode VisitOutVariablePendingInference(OutVariablePendingInference node) { throw ExceptionUtilities.Unreachable; } @@ -2651,6 +2651,11 @@ public sealed override BoundNode VisitDeconstructionLocalPendingInference(Decons { throw ExceptionUtilities.Unreachable; } + + public override BoundNode VisitVoid(BoundVoid node) + { + return null; + } #endregion visitors } } diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_LocalDeclaration.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_LocalDeclaration.cs index c47752e6f24..9af493f5a62 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_LocalDeclaration.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_LocalDeclaration.cs @@ -82,7 +82,7 @@ private BoundStatement InstrumentLocalDeclarationIfNecessary(BoundLocalDeclarati return rewrittenLocalDeclaration; } - public override sealed BoundNode VisitOutVarLocalPendingInference(OutVarLocalPendingInference node) + public override sealed BoundNode VisitOutVariablePendingInference(OutVariablePendingInference node) { throw ExceptionUtilities.Unreachable; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventFieldSymbol.cs index 6fe4868d35c..7e22fcc56c5 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventFieldSymbol.cs @@ -13,7 +13,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols /// /// SourceFieldSymbol takes care of the initializer (plus "var" in the interactive case). /// - internal sealed class SourceEventFieldSymbol : SourceMemberFieldSymbol + internal sealed class SourceEventFieldSymbol : SourceMemberFieldSymbolFromDeclarator { private readonly SourceEventSymbol _associatedEvent; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFixedFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFixedFieldSymbol.cs index 7c8660edded..90e875c2915 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFixedFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFixedFieldSymbol.cs @@ -12,7 +12,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols { - internal class SourceFixedFieldSymbol : SourceMemberFieldSymbol + internal class SourceFixedFieldSymbol : SourceMemberFieldSymbolFromDeclarator { private const int FixedSizeNotInitialized = -1; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index afafc92d8bf..dcb37c4ddec 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -2885,10 +2885,18 @@ private static bool HasNonConstantInitializer(ArrayBuilder _lazyCustomModifiers; internal SourceMemberFieldSymbol( SourceMemberContainerTypeSymbol containingType, - VariableDeclaratorSyntax declarator, DeclarationModifiers modifiers, - bool modifierErrors, - DiagnosticBag diagnostics) - : base(containingType, declarator.Identifier.ValueText, declarator.GetReference(), declarator.Identifier.GetLocation()) + string name, + SyntaxReference syntax, + Location location) + : base(containingType, name, syntax, location) { _modifiers = modifiers; - _hasInitializer = declarator.Initializer != null; - - this.CheckAccessibility(diagnostics); - - if (!modifierErrors) - { - this.ReportModifiersDiagnostics(diagnostics); - } } protected sealed override DeclarationModifiers Modifiers @@ -52,7 +35,11 @@ protected sealed override DeclarationModifiers Modifiers } } - private void TypeChecks(TypeSymbol type, BaseFieldDeclarationSyntax fieldSyntax, DiagnosticBag diagnostics) + protected abstract TypeSyntax TypeSyntax { get; } + + protected abstract SyntaxTokenList ModifiersTokenList { get; } + + protected void TypeChecks(TypeSymbol type, DiagnosticBag diagnostics) { if (type.IsStatic) { @@ -61,16 +48,16 @@ private void TypeChecks(TypeSymbol type, BaseFieldDeclarationSyntax fieldSyntax, } else if (type.SpecialType == SpecialType.System_Void) { - diagnostics.Add(ErrorCode.ERR_FieldCantHaveVoidType, fieldSyntax.Declaration.Type.Location); + diagnostics.Add(ErrorCode.ERR_FieldCantHaveVoidType, TypeSyntax.Location); } else if (type.IsRestrictedType()) { - diagnostics.Add(ErrorCode.ERR_FieldCantBeRefAny, fieldSyntax.Declaration.Type.Location, type); + diagnostics.Add(ErrorCode.ERR_FieldCantBeRefAny, TypeSyntax.Location, type); } else if (IsConst && !type.CanBeConst()) { SyntaxToken constToken = default(SyntaxToken); - foreach (var modifier in fieldSyntax.Modifiers) + foreach (var modifier in ModifiersTokenList) { if (modifier.Kind() == SyntaxKind.ConstKeyword) { @@ -98,7 +85,240 @@ private void TypeChecks(TypeSymbol type, BaseFieldDeclarationSyntax fieldSyntax, diagnostics.Add(this.ErrorLocation, useSiteDiagnostics); } - public bool HasInitializer + public abstract bool HasInitializer { get; } + + internal override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder attributes) + { + base.AddSynthesizedAttributes(compilationState, ref attributes); + + var compilation = this.DeclaringCompilation; + var value = this.GetConstantValue(ConstantFieldsInProgress.Empty, earlyDecodingWellKnownAttributes: false); + + // Synthesize DecimalConstantAttribute when the default value is of type decimal + if (this.IsConst && value != null + && this.Type.SpecialType == SpecialType.System_Decimal) + { + var data = GetDecodedWellKnownAttributeData(); + + if (data == null || data.ConstValue == CodeAnalysis.ConstantValue.Unset) + { + AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDecimalConstantAttribute(value.DecimalValue)); + } + } + } + + public override Symbol AssociatedSymbol + { + get + { + return null; + } + } + + public override int FixedSize + { + get + { + Debug.Assert(!this.IsFixed, "Subclasses representing fixed fields must override"); + if (state.NotePartComplete(CompletionPart.FixedSize)) + { + // FixedSize is the last completion part for fields. + DeclaringCompilation.SymbolDeclaredEvent(this); + } + + return 0; + } + } + + internal static DeclarationModifiers MakeModifiers(NamedTypeSymbol containingType, SyntaxToken firstIdentifier, SyntaxTokenList modifiers, DiagnosticBag diagnostics, out bool modifierErrors) + { + DeclarationModifiers defaultAccess = + (containingType.IsInterface) ? DeclarationModifiers.Public : DeclarationModifiers.Private; + + DeclarationModifiers allowedModifiers = + DeclarationModifiers.AccessibilityMask | + DeclarationModifiers.Const | + DeclarationModifiers.New | + DeclarationModifiers.ReadOnly | + DeclarationModifiers.Static | + DeclarationModifiers.Volatile | + DeclarationModifiers.Fixed | + DeclarationModifiers.Unsafe | + DeclarationModifiers.Abstract; // filtered out later + + var errorLocation = new SourceLocation(firstIdentifier); + DeclarationModifiers result = ModifierUtils.MakeAndCheckNontypeMemberModifiers( + modifiers, defaultAccess, allowedModifiers, errorLocation, diagnostics, out modifierErrors); + + if ((result & DeclarationModifiers.Abstract) != 0) + { + diagnostics.Add(ErrorCode.ERR_AbstractField, errorLocation); + result &= ~DeclarationModifiers.Abstract; + } + + if ((result & DeclarationModifiers.Fixed) != 0) + { + if ((result & DeclarationModifiers.Static) != 0) + { + // The modifier 'static' is not valid for this item + diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.StaticKeyword)); + } + + if ((result & DeclarationModifiers.ReadOnly) != 0) + { + // The modifier 'readonly' is not valid for this item + diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.ReadOnlyKeyword)); + } + + if ((result & DeclarationModifiers.Const) != 0) + { + // The modifier 'const' is not valid for this item + diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.ConstKeyword)); + } + + if ((result & DeclarationModifiers.Volatile) != 0) + { + // The modifier 'volatile' is not valid for this item + diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.VolatileKeyword)); + } + + result &= ~(DeclarationModifiers.Static | DeclarationModifiers.ReadOnly | DeclarationModifiers.Const | DeclarationModifiers.Volatile); + Debug.Assert((result & ~(DeclarationModifiers.AccessibilityMask | DeclarationModifiers.Fixed | DeclarationModifiers.Unsafe | DeclarationModifiers.New)) == 0); + } + + + if ((result & DeclarationModifiers.Const) != 0) + { + if ((result & DeclarationModifiers.Static) != 0) + { + // The constant '{0}' cannot be marked static + diagnostics.Add(ErrorCode.ERR_StaticConstant, errorLocation, firstIdentifier.ValueText); + } + + if ((result & DeclarationModifiers.ReadOnly) != 0) + { + // The modifier 'readonly' is not valid for this item + diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.ReadOnlyKeyword)); + } + + if ((result & DeclarationModifiers.Volatile) != 0) + { + // The modifier 'volatile' is not valid for this item + diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.VolatileKeyword)); + } + + if ((result & DeclarationModifiers.Unsafe) != 0) + { + // The modifier 'unsafe' is not valid for this item + diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.UnsafeKeyword)); + } + + result |= DeclarationModifiers.Static; // "constants are considered static members" + } + else + { + // NOTE: always cascading on a const, so suppress. + // NOTE: we're being a bit sneaky here - we're using the containingType rather than this symbol + // to determine whether or not unsafe is allowed. Since this symbol and the containing type are + // in the same compilation, it won't make a difference. We do, however, have to pass the error + // location explicitly. + containingType.CheckUnsafeModifier(result, errorLocation, diagnostics); + } + + return result; + } + + internal sealed override void ForceComplete(SourceLocation locationOpt, CancellationToken cancellationToken) + { + while (true) + { + cancellationToken.ThrowIfCancellationRequested(); + var incompletePart = state.NextIncompletePart; + switch (incompletePart) + { + case CompletionPart.Attributes: + GetAttributes(); + break; + + case CompletionPart.Type: + GetFieldType(ConsList.Empty); + break; + + case CompletionPart.ConstantValue: + GetConstantValue(ConstantFieldsInProgress.Empty, earlyDecodingWellKnownAttributes: false); + break; + + case CompletionPart.FixedSize: + int discarded = this.FixedSize; + break; + + case CompletionPart.None: + return; + + default: + // any other values are completion parts intended for other kinds of symbols + state.NotePartComplete(CompletionPart.All & ~CompletionPart.FieldSymbolAll); + break; + } + + state.SpinWaitComplete(incompletePart, cancellationToken); + } + } + + internal override NamedTypeSymbol FixedImplementationType(PEModuleBuilder emitModule) + { + Debug.Assert(!this.IsFixed, "Subclasses representing fixed fields must override"); + return null; + } + } + + internal class SourceMemberFieldSymbolFromDeclarator : SourceMemberFieldSymbol + { + private readonly bool _hasInitializer; + + private TypeSymbol _lazyType; + + // Non-zero if the type of the field has been inferred from the type of its initializer expression + // and the errors of binding the initializer have been or are being reported to compilation diagnostics. + private int _lazyFieldTypeInferred; + + private ImmutableArray _lazyCustomModifiers; + + internal SourceMemberFieldSymbolFromDeclarator( + SourceMemberContainerTypeSymbol containingType, + VariableDeclaratorSyntax declarator, + DeclarationModifiers modifiers, + bool modifierErrors, + DiagnosticBag diagnostics) + : base(containingType, modifiers, declarator.Identifier.ValueText, declarator.GetReference(), declarator.Identifier.GetLocation()) + { + _hasInitializer = declarator.Initializer != null; + + this.CheckAccessibility(diagnostics); + + if (!modifierErrors) + { + this.ReportModifiersDiagnostics(diagnostics); + } + } + + protected sealed override TypeSyntax TypeSyntax + { + get + { + return GetFieldDeclaration(VariableDeclaratorNode).Declaration.Type; + } + } + + protected sealed override SyntaxTokenList ModifiersTokenList + { + get + { + return GetFieldDeclaration(VariableDeclaratorNode).Modifiers; + } + } + + public sealed override bool HasInitializer { get { return _hasInitializer; } } @@ -215,10 +435,6 @@ internal sealed override TypeSymbol GetFieldType(ConsList fieldsBei if (!ContainingType.IsScriptClass) { type = binder.BindType(typeSyntax, diagnosticsForFirstDeclarator); - if (IsFixed) - { - type = new PointerTypeSymbol(type); - } } else { @@ -270,6 +486,8 @@ internal sealed override TypeSymbol GetFieldType(ConsList fieldsBei if (IsFixed) { + type = new PointerTypeSymbol(type); + if (ContainingType.TypeKind != TypeKind.Struct) { diagnostics.Add(ErrorCode.ERR_FixedNotInStruct, ErrorLocation); @@ -293,7 +511,7 @@ internal sealed override TypeSymbol GetFieldType(ConsList fieldsBei // update the lazyType only if it contains value last seen by the current thread: if ((object)Interlocked.CompareExchange(ref _lazyType, type, null) == null) { - TypeChecks(type, fieldSyntax, diagnostics); + TypeChecks(type, diagnostics); // CONSIDER: SourceEventFieldSymbol would like to suppress these diagnostics. compilation.DeclarationDiagnostics.AddRange(diagnostics); @@ -325,34 +543,6 @@ internal bool FieldTypeInferred(ConsList fieldsBeingBound) return _lazyFieldTypeInferred != 0 || Volatile.Read(ref _lazyFieldTypeInferred) != 0; } - internal override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder attributes) - { - base.AddSynthesizedAttributes(compilationState, ref attributes); - - var compilation = this.DeclaringCompilation; - var value = this.GetConstantValue(ConstantFieldsInProgress.Empty, earlyDecodingWellKnownAttributes: false); - - // Synthesize DecimalConstantAttribute when the default value is of type decimal - if (this.IsConst && value != null - && this.Type.SpecialType == SpecialType.System_Decimal) - { - var data = GetDecodedWellKnownAttributeData(); - - if (data == null || data.ConstValue == CodeAnalysis.ConstantValue.Unset) - { - AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDecimalConstantAttribute(value.DecimalValue)); - } - } - } - - public override Symbol AssociatedSymbol - { - get - { - return null; - } - } - protected sealed override ConstantValue MakeConstantValue(HashSet dependencies, bool earlyDecodingWellKnownAttributes, DiagnosticBag diagnostics) { if (!this.IsConst || VariableDeclaratorNode.Initializer == null) @@ -363,119 +553,6 @@ protected sealed override ConstantValue MakeConstantValue(HashSet CustomModifiers { get @@ -489,49 +566,6 @@ public sealed override ImmutableArray CustomModifiers } } - internal sealed override void ForceComplete(SourceLocation locationOpt, CancellationToken cancellationToken) - { - while (true) - { - cancellationToken.ThrowIfCancellationRequested(); - var incompletePart = state.NextIncompletePart; - switch (incompletePart) - { - case CompletionPart.Attributes: - GetAttributes(); - break; - - case CompletionPart.Type: - GetFieldType(ConsList.Empty); - break; - - case CompletionPart.ConstantValue: - GetConstantValue(ConstantFieldsInProgress.Empty, earlyDecodingWellKnownAttributes: false); - break; - - case CompletionPart.FixedSize: - int discarded = this.FixedSize; - break; - - case CompletionPart.None: - return; - - default: - // any other values are completion parts intended for other kinds of symbols - state.NotePartComplete(CompletionPart.All & ~CompletionPart.FieldSymbolAll); - break; - } - - state.SpinWaitComplete(incompletePart, cancellationToken); - } - } - - internal override NamedTypeSymbol FixedImplementationType(PEModuleBuilder emitModule) - { - Debug.Assert(!this.IsFixed, "Subclasses representing fixed fields must override"); - return null; - } - internal override bool IsDefinedInSourceTree(SyntaxTree tree, TextSpan? definedWithinSpan, CancellationToken cancellationToken = default(CancellationToken)) { if (this.SyntaxTree == tree) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbolFromDesignation.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbolFromDesignation.cs new file mode 100644 index 00000000000..92353efd3ec --- /dev/null +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbolFromDesignation.cs @@ -0,0 +1,219 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.CSharp.Symbols +{ + /// + /// Represents expression variables declared in a global statement. + /// + internal class SourceMemberFieldSymbolFromDesignation : SourceMemberFieldSymbol + { + private TypeSymbol _lazyType; + + internal SourceMemberFieldSymbolFromDesignation( + SourceMemberContainerTypeSymbol containingType, + SingleVariableDesignationSyntax designation, + DeclarationModifiers modifiers) + : base(containingType, modifiers, designation.Identifier.ValueText, designation.GetReference(), designation.Identifier.GetLocation()) + { + Debug.Assert(DeclaredAccessibility == Accessibility.Private); + } + + internal static SourceMemberFieldSymbolFromDesignation Create( + SourceMemberContainerTypeSymbol containingType, + SingleVariableDesignationSyntax designation, + DeclarationModifiers modifiers, + FieldSymbol containingFieldOpt, + SyntaxNode nodeToBind) + { + Debug.Assert(nodeToBind.Kind() == SyntaxKind.VariableDeclarator || nodeToBind is ExpressionSyntax); + var typeSyntax = ((TypedVariableComponentSyntax)designation.Parent).Type; + return typeSyntax.IsVar + ? new SourceMemberFieldSymbolFromDesignationWithEnclosingContext(containingType, designation, modifiers, containingFieldOpt, nodeToBind) + : new SourceMemberFieldSymbolFromDesignation(containingType, designation, modifiers); + } + + protected override SyntaxList AttributeDeclarationSyntaxList + { + get + { + return default(SyntaxList); + } + } + + public SingleVariableDesignationSyntax VariableDesignation + { + get + { + return (SingleVariableDesignationSyntax)this.SyntaxNode; + } + } + + protected override TypeSyntax TypeSyntax + { + get + { + return ((TypedVariableComponentSyntax)VariableDesignation.Parent).Type; + } + } + + protected override SyntaxTokenList ModifiersTokenList + { + get + { + return default(SyntaxTokenList); + } + } + + internal override TypeSymbol GetFieldType(ConsList fieldsBeingBound) + { + Debug.Assert(fieldsBeingBound != null); + + if ((object)_lazyType != null) + { + return _lazyType; + } + + var designation = VariableDesignation; + var typeSyntax = TypeSyntax; + + var compilation = this.DeclaringCompilation; + + var diagnostics = DiagnosticBag.GetInstance(); + TypeSymbol type; + + var binderFactory = compilation.GetBinderFactory(SyntaxTree); + var binder = binderFactory.GetBinder(typeSyntax); + + bool isVar; + type = binder.BindType(typeSyntax, diagnostics, out isVar); + + Debug.Assert((object)type != null || isVar); + + if (isVar && !fieldsBeingBound.ContainsReference(this)) + { + InferFieldType(fieldsBeingBound, binder); + Debug.Assert((object)_lazyType != null); + } + else + { + if (isVar) + { + diagnostics.Add(ErrorCode.ERR_RecursivelyTypedVariable, this.ErrorLocation, this); + type = binder.CreateErrorType("var"); + } + + SetType(compilation, diagnostics, type); + } + + diagnostics.Free(); + return _lazyType; + } + + /// + /// Can add some diagnostics into . + /// + private void SetType(CSharpCompilation compilation, DiagnosticBag diagnostics, TypeSymbol type) + { + TypeSymbol originalType = _lazyType; + + // In the event that we race to set the type of a field, we should + // always deduce the same type, unless the cached type is an error. + + Debug.Assert((object)originalType == null || + originalType.IsErrorType() || + originalType == type); + + if ((object)Interlocked.CompareExchange(ref _lazyType, type, null) == null) + { + TypeChecks(type, diagnostics); + + compilation.DeclarationDiagnostics.AddRange(diagnostics); + state.NotePartComplete(CompletionPart.Type); + } + } + + /// + /// Can add some diagnostics into . + /// + internal void SetType(TypeSymbol type, DiagnosticBag diagnostics) + { + SetType(DeclaringCompilation, diagnostics, type); + } + + protected virtual void InferFieldType(ConsList fieldsBeingBound, Binder binder) + { + throw ExceptionUtilities.Unreachable; + } + + protected override ConstantValue MakeConstantValue(HashSet dependencies, bool earlyDecodingWellKnownAttributes, DiagnosticBag diagnostics) + { + return null; + } + + public override bool HasInitializer + { + get + { + return false; + } + } + + private class SourceMemberFieldSymbolFromDesignationWithEnclosingContext : SourceMemberFieldSymbolFromDesignation + { + private readonly FieldSymbol _containingFieldOpt; + private readonly SyntaxReference _nodeToBind; + + + internal SourceMemberFieldSymbolFromDesignationWithEnclosingContext( + SourceMemberContainerTypeSymbol containingType, + SingleVariableDesignationSyntax designation, + DeclarationModifiers modifiers, + FieldSymbol containingFieldOpt, + SyntaxNode nodeToBind) + : base(containingType, designation, modifiers) + { + Debug.Assert(nodeToBind.Kind() == SyntaxKind.VariableDeclarator || nodeToBind is ExpressionSyntax); + _containingFieldOpt = containingFieldOpt; + _nodeToBind = nodeToBind.GetReference(); + } + + protected override void InferFieldType(ConsList fieldsBeingBound, Binder binder) + { + var nodeToBind = _nodeToBind.GetSyntax(); + + if ((object)_containingFieldOpt != null && nodeToBind.Kind() != SyntaxKind.VariableDeclarator) + { + binder = binder.WithContainingMemberOrLambda(_containingFieldOpt).WithAdditionalFlags(BinderFlags.FieldInitializer); + } + + fieldsBeingBound = new ConsList(this, fieldsBeingBound); + + binder = new ImplicitlyTypedFieldBinder(binder, fieldsBeingBound); + var diagnostics = DiagnosticBag.GetInstance(); + + switch (nodeToBind.Kind()) + { + case SyntaxKind.VariableDeclarator: + // This occurs, for example, in + // int x, y[out var Z, 1 is int I]; + // for (int x, y[out var Z, 1 is int I]; ;) {} + binder.BindDeclaratorArguments((VariableDeclaratorSyntax)nodeToBind, diagnostics); + break; + + default: + binder.BindExpression((ExpressionSyntax)nodeToBind, diagnostics); + break; + } + + diagnostics.Free(); + } + } + } +} \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs index 0eb8b6d0c00..e37de68724d 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs @@ -74,6 +74,15 @@ internal static TypeSyntax Type(this DeclarationExpressionSyntax self) return component.Type; } + /// + /// Return the variable designation of an out declaration argument expression. + /// + internal static SingleVariableDesignationSyntax VariableDesignation(this DeclarationExpressionSyntax self) + { + var component = (TypedVariableComponentSyntax)self.VariableComponent; + return (SingleVariableDesignationSyntax)component.Designation; + } + /// /// Return the identifier of an out declaration argument expression. /// diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs index 3cc8d789f1d..ce79dcfd470 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs @@ -393,7 +393,7 @@ internal static bool IsVarOrPredefinedType(this Syntax.InternalSyntax.SyntaxToke return node.IsVar() || IsPredefinedType(node.Kind); } - internal static bool IsDeconstructionType(SyntaxNode node, out SyntaxNode parent) + internal static bool IsVariableComponentType(SyntaxNode node, out SyntaxNode parent) { var component = node.Parent as TypedVariableComponentSyntax; parent = component; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/IteratorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/IteratorTests.cs index 4a65838e4ed..0a04358f20a 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/IteratorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/IteratorTests.cs @@ -407,5 +407,27 @@ protected override IEnumerable M() var comp = CompileAndVerify(source, expectedOutput: "0,1,2,3", options: TestOptions.DebugExe); comp.Compilation.VerifyDiagnostics(); } - } + + [Fact] + [WorkItem(261047, "https://devdiv.visualstudio.com/DevDiv/_workitems?id=261047&_a=edit")] + public void MissingExpression() + { + var text = +@"using System.Collections.Generic; + +class Test +{ + IEnumerable I() + { + yield return; + } +}"; + var comp = CreateCompilationWithMscorlib(text); + comp.VerifyDiagnostics( + // (7,15): error CS1627: Expression expected after yield return + // yield return; + Diagnostic(ErrorCode.ERR_EmptyYield, "return").WithLocation(7, 15) + ); + } + } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs index 4304ef36023..a61c85e5d58 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs @@ -851,6 +851,7 @@ private static void VerifyModelForOutVarInNotExecutableCode(SemanticModel model, var variableDeclaratorSyntax = GetVariableDesignation(decl); var symbol = model.GetDeclaredSymbol(variableDeclaratorSyntax); Assert.Equal(decl.Identifier().ValueText, symbol.Name); + Assert.Equal(variableDeclaratorSyntax, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); Assert.Equal(LocalDeclarationKind.RegularVariable, ((LocalSymbol)symbol).DeclarationKind); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)variableDeclaratorSyntax)); @@ -866,14 +867,18 @@ private static void VerifyModelForOutVarInNotExecutableCode(SemanticModel model, Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier().ValueText)); var local = (SourceLocalSymbol)symbol; + var typeSyntax = decl.Type(); - if (decl.Type().IsVar && local.IsVar && local.Type.IsErrorType()) + Assert.True(SyntaxFacts.IsInNamespaceOrTypeContext(typeSyntax)); + Assert.True(SyntaxFacts.IsInTypeOnlyContext(typeSyntax)); + + if (typeSyntax.IsVar && local.IsVar && local.Type.IsErrorType()) { - Assert.Null(model.GetSymbolInfo(decl.Type()).Symbol); + Assert.Null(model.GetSymbolInfo(typeSyntax).Symbol); } else { - Assert.Equal(local.Type, model.GetSymbolInfo(decl.Type()).Symbol); + Assert.Equal(local.Type, model.GetSymbolInfo(typeSyntax).Symbol); } Assert.Same(symbol, model.GetSymbolInfo(decl).Symbol); @@ -945,6 +950,7 @@ private static void VerifyModelForOutVarDuplicateInSameScope(SemanticModel model var variableDesignationSyntax = GetVariableDesignation(decl); var symbol = model.GetDeclaredSymbol(variableDesignationSyntax); Assert.Equal(decl.Identifier().ValueText, symbol.Name); + Assert.Equal(variableDesignationSyntax, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); Assert.Equal(LocalDeclarationKind.RegularVariable, ((LocalSymbol)symbol).DeclarationKind); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)variableDesignationSyntax)); Assert.NotEqual(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier().ValueText).Single()); @@ -16008,6 +16014,39 @@ static object Test1(out int x) Assert.Equal("a=System.Int32", model.GetAliasInfo(x1Decl.Type()).ToTestDisplayString()); } + + [Fact] + public void GetAliasInfo_02() + { + var text = @" +using var = System.Int32; + +public class Cls +{ + public static void Main() + { + Test1(out var x1); + } + + static object Test1(out int x) + { + x = 123; + return null; + } +}"; + var compilation = CreateCompilationWithMscorlib(text, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular); + + CompileAndVerify(compilation, expectedOutput: @"").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclaration(tree, "x1"); + VerifyModelForOutVar(model, x1Decl); + + Assert.Equal("var=System.Int32", model.GetAliasInfo(x1Decl.Type()).ToTestDisplayString()); + } + [Fact] public void VarIsNotVar_01() { @@ -19676,21 +19715,25 @@ static bool TakeOutParam(object y, out int x) var variableDeclaratorSyntax = GetVariableDesignation(decl); Assert.Null(model.GetDeclaredSymbol(variableDeclaratorSyntax)); Assert.Null(model.GetDeclaredSymbol((SyntaxNode)variableDeclaratorSyntax)); + var identifierText = decl.Identifier().ValueText; + Assert.False(model.LookupSymbols(decl.SpanStart, name: identifierText).Any()); - Assert.False(model.LookupSymbols(decl.SpanStart, name: decl.Identifier().ValueText).Any()); - - Assert.False(model.LookupNames(decl.SpanStart).Contains(decl.Identifier().ValueText)); + Assert.False(model.LookupNames(decl.SpanStart).Contains(identifierText)); Assert.Null(model.GetSymbolInfo(decl.Type()).Symbol); Assert.Null(model.GetSymbolInfo(decl).Symbol); Assert.Null(model.GetTypeInfo(decl).Type); Assert.Null(model.GetDeclaredSymbol(decl)); + VerifyModelNotSupported(model, references); + } + private static void VerifyModelNotSupported(SemanticModel model, params IdentifierNameSyntax[] references) + { foreach (var reference in references) { Assert.Null(model.GetSymbolInfo(reference).Symbol); - Assert.False(model.LookupSymbols(reference.SpanStart, name: decl.Identifier().ValueText).Any()); - Assert.False(model.LookupNames(reference.SpanStart).Contains(decl.Identifier().ValueText)); + Assert.False(model.LookupSymbols(reference.SpanStart, name: reference.Identifier.ValueText).Any()); + Assert.DoesNotContain(reference.Identifier.ValueText, model.LookupNames(reference.SpanStart)); Assert.True(((TypeSymbol)model.GetTypeInfo(reference).Type).IsErrorType()); } } @@ -20040,5 +20083,6944 @@ public static void Main() Assert.False(GetOutVarDeclarations(tree, "x3").Any()); } + + [Fact] + public void StaticType() + { + var text = @" +public class Cls +{ + public static void Main() + { + Test1(out StaticType x1); + } + + static object Test1(out StaticType x) + { + throw new System.NotSupportedException(); + } + + static class StaticType {} +}"; + var compilation = CreateCompilationWithMscorlib(text, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular); + + compilation.VerifyDiagnostics( + // (9,19): error CS0721: 'Cls.StaticType': static types cannot be used as parameters + // static object Test1(out StaticType x) + Diagnostic(ErrorCode.ERR_ParameterIsStaticClass, "Test1").WithArguments("Cls.StaticType").WithLocation(9, 19), + // (6,19): error CS0723: Cannot declare a variable of static type 'Cls.StaticType' + // Test1(out StaticType x1); + Diagnostic(ErrorCode.ERR_VarDeclIsStaticClass, "StaticType").WithArguments("Cls.StaticType").WithLocation(6, 19) + ); + } + + [Fact] + public void GlobalCode_ExpressionStatement_01() + { + string source = +@" +H.TakeOutParam(1, out int x1); +H.Dummy(x1); + +object x2; +H.TakeOutParam(2, out int x2); + +H.TakeOutParam(3, out int x3); +object x3; + +H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4)); + +void Test() +{ + H.Dummy(x1, x2, x3, x4); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,27): error CS0102: The type 'Script' already contains a definition for 'x2' + // H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 27), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,36): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)) + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 36), + // (16,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(16, 17), + // (16,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(16, 21), + // (16,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,27): error CS0102: The type '' already contains a definition for 'x2' + // H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 27), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,36): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 36), + // (16,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(16, 13), + // (16,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(16, 17), + // (16,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(16, 21), + // (16,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_ExpressionStatement_02() + { + string source = +@" +H.TakeOutParam(1, out var x1); +H.Dummy(x1); + +object x2; +H.TakeOutParam(2, out var x2); + +H.TakeOutParam(3, out var x3); +object x3; + +H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4)); + +void Test() +{ + H.Dummy(x1, x2, x3, x4); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,27): error CS0102: The type 'Script' already contains a definition for 'x2' + // H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 27), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,36): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 36), + // (16,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(16, 17), + // (16,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(16, 21), + // (16,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TypeVarNotFound, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,27): error CS0102: The type '' already contains a definition for 'x2' + // H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 27), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,36): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 36), + // (16,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(16, 13), + // (16,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(16, 17), + // (16,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(16, 21), + // (16,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_ExpressionStatement_03() + { + string source = +@" +System.Console.WriteLine(x1); +H.TakeOutParam(1, out var x1); +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_IfStatement_01() + { + string source = +@" +if (H.TakeOutParam(1, out int x1)) {} +H.Dummy(x1); + +object x2; +if (H.TakeOutParam(2, out int x2)) {} + +if (H.TakeOutParam(3, out int x3)) {} +object x3; + +if (H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4))) {} + +if (H.TakeOutParam(51, out int x5)) +{ + H.TakeOutParam(""52"", out string x5); + H.Dummy(x5); +} +H.Dummy(x5); + +int x6 = 6; +if (H.Dummy()) +{ + string x6 = ""6""; + H.Dummy(x6); +} + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,31): error CS0102: The type 'Script' already contains a definition for 'x2' + // if (H.TakeOutParam(2, out int x2)) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 31), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,40): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4))) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 40), + // (30,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(30, 17), + // (30,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(30, 21), + // (30,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(30, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").ToArray(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Decl.Length); + Assert.Equal(3, x5Ref.Length); + VerifyModelForOutField(model, x5Decl[0], x5Ref[1], x5Ref[2]); + VerifyModelForOutVar(model, x5Decl[1], x5Ref[0]); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,31): error CS0102: The type '' already contains a definition for 'x2' + // if (H.TakeOutParam(2, out int x2)) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 31), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,40): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4))) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 40), + // (16,37): error CS0102: The type '' already contains a definition for 'x5' + // H.TakeOutParam("52", out string x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("", "x5").WithLocation(16, 37), + // (24,12): error CS0102: The type '' already contains a definition for 'x6' + // string x6 = "6"; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x6").WithArguments("", "x6").WithLocation(24, 12), + // (30,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(30, 13), + // (30,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(30, 17), + // (30,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(30, 21), + // (30,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(30, 25), + // (30,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(30, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_IfStatement_02() + { + string source = +@" +if (H.TakeOutParam(1, out var x1)) {} +H.Dummy(x1); + +object x2; +if (H.TakeOutParam(2, out var x2)) {} + +if (H.TakeOutParam(3, out var x3)) {} +object x3; + +if (H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4))) {} + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +if (H.TakeOutParam(51, out var x5)) +{ + H.TakeOutParam(""52"", out var x5); + H.Dummy(x5); +} +H.Dummy(x5); + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,31): error CS0102: The type 'Script' already contains a definition for 'x2' + // if (H.TakeOutParam(2, out var x2)) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 31), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,40): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4))) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 40), + // (16,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(16, 17), + // (16,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(16, 21), + // (16,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").ToArray(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Decl.Length); + Assert.Equal(3, x5Ref.Length); + VerifyModelForOutField(model, x5Decl[0], x5Ref[0], x5Ref[2]); + VerifyModelForOutVar(model, x5Decl[1], x5Ref[1]); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TypeVarNotFound, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,31): error CS0102: The type '' already contains a definition for 'x2' + // if (H.TakeOutParam(2, out var x2)) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 31), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,40): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4))) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 40), + // (21,34): error CS0102: The type '' already contains a definition for 'x5' + // H.TakeOutParam("52", out var x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("", "x5").WithLocation(21, 34), + // (16,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(16, 13), + // (16,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(16, 17), + // (16,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(16, 21), + // (16,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(16, 25), + // (16,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(16, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_IfStatement_03() + { + string source = +@" +System.Console.WriteLine(x1); +if (H.TakeOutParam(1, out var x1)) +{ + H.TakeOutParam(""11"", out var x1); + System.Console.WriteLine(x1); +} +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +11 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").ToArray(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Decl.Length); + Assert.Equal(3, x1Ref.Length); + VerifyModelForOutField(model, x1Decl[0], x1Ref[0], x1Ref[2]); + VerifyModelForOutVar(model, x1Decl[1], x1Ref[1]); + } + + [Fact] + public void GlobalCode_IfStatement_04() + { + string source = +@" +System.Console.WriteLine(x1); +if (H.TakeOutParam(1, out var x1)) + H.Dummy(H.TakeOutParam(""11"", out var x1), x1); +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static void Dummy(object x, object y) + { + System.Console.WriteLine(y); + } + + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +11 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").ToArray(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Decl.Length); + Assert.Equal(3, x1Ref.Length); + VerifyModelForOutField(model, x1Decl[0], x1Ref[0], x1Ref[2]); + VerifyModelForOutVar(model, x1Decl[1], x1Ref[1]); + } + + [Fact] + public void GlobalCode_YieldReturnStatement_01() + { + string source = +@" +yield return H.TakeOutParam(1, out int x1); +H.Dummy(x1); + +object x2; +yield return H.TakeOutParam(2, out int x2); + +yield return H.TakeOutParam(3, out int x3); +object x3; + +yield return H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4)); + +void Test() +{ + H.Dummy(x1, x2, x3, x4); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,40): error CS0102: The type 'Script' already contains a definition for 'x2' + // yield return H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 40), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,49): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 49), + // (2,1): error CS7020: Cannot use 'yield' in top-level script code + // yield return H.TakeOutParam(1, out int x1); + Diagnostic(ErrorCode.ERR_YieldNotAllowedInScript, "yield").WithLocation(2, 1), + // (6,1): error CS7020: Cannot use 'yield' in top-level script code + // yield return H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_YieldNotAllowedInScript, "yield").WithLocation(6, 1), + // (8,1): error CS7020: Cannot use 'yield' in top-level script code + // yield return H.TakeOutParam(3, out int x3); + Diagnostic(ErrorCode.ERR_YieldNotAllowedInScript, "yield").WithLocation(8, 1), + // (11,1): error CS7020: Cannot use 'yield' in top-level script code + // yield return H.Dummy(H.TakeOutParam(41, out int x4), + Diagnostic(ErrorCode.ERR_YieldNotAllowedInScript, "yield").WithLocation(11, 1), + // (16,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(16, 17), + // (16,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(16, 21), + // (16,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,40): error CS0102: The type '' already contains a definition for 'x2' + // yield return H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 40), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,49): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 49), + // (16,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(16, 13), + // (16,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(16, 17), + // (16,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(16, 21), + // (16,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_YieldReturnStatement_02() + { + string source = +@" +yield return H.TakeOutParam(1, out var x1); +H.Dummy(x1); + +object x2; +yield return H.TakeOutParam(2, out var x2); + +yield return H.TakeOutParam(3, out var x3); +object x3; + +yield return H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4)); + +void Test() +{ + H.Dummy(x1, x2, x3, x4); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,40): error CS0102: The type 'Script' already contains a definition for 'x2' + // yield return H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 40), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,49): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 49), + // (2,1): error CS7020: Cannot use 'yield' in top-level script code + // yield return H.TakeOutParam(1, out var x1); + Diagnostic(ErrorCode.ERR_YieldNotAllowedInScript, "yield").WithLocation(2, 1), + // (6,1): error CS7020: Cannot use 'yield' in top-level script code + // yield return H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_YieldNotAllowedInScript, "yield").WithLocation(6, 1), + // (8,1): error CS7020: Cannot use 'yield' in top-level script code + // yield return H.TakeOutParam(3, out var x3); + Diagnostic(ErrorCode.ERR_YieldNotAllowedInScript, "yield").WithLocation(8, 1), + // (11,1): error CS7020: Cannot use 'yield' in top-level script code + // yield return H.Dummy(H.TakeOutParam(41, out var x4), + Diagnostic(ErrorCode.ERR_YieldNotAllowedInScript, "yield").WithLocation(11, 1), + // (16,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(16, 17), + // (16,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(16, 21), + // (16,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + Assert.Equal("System.Int32", ((FieldSymbol)compilation.GetSemanticModel(tree).GetDeclaredSymbol(x1Decl.VariableDesignation())).Type.ToTestDisplayString()); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TypeVarNotFound, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,40): error CS0102: The type '' already contains a definition for 'x2' + // yield return H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 40), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,49): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 49), + // (16,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(16, 13), + // (16,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(16, 17), + // (16,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(16, 21), + // (16,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_ReturnStatement_01() + { + string source = +@" +return H.TakeOutParam(1, out int x1); +H.Dummy(x1); + +object x2; +return H.TakeOutParam(2, out int x2); + +return H.TakeOutParam(3, out int x3); +object x3; + +return H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4)); + +void Test() +{ + H.Dummy(x1, x2, x3, x4); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,34): error CS0102: The type 'Script' already contains a definition for 'x2' + // return H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 34), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,43): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 43), + // (3,1): warning CS0162: Unreachable code detected + // H.Dummy(x1); + Diagnostic(ErrorCode.WRN_UnreachableCode, "H").WithLocation(3, 1), + // (16,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(16, 17), + // (16,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(16, 21), + // (16,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,34): error CS0102: The type '' already contains a definition for 'x2' + // return H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 34), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,43): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 43), + // (16,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(16, 13), + // (16,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(16, 17), + // (16,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(16, 21), + // (16,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_ReturnStatement_02() + { + string source = +@" +return H.TakeOutParam(1, out var x1); +H.Dummy(x1); + +object x2; +return H.TakeOutParam(2, out var x2); + +return H.TakeOutParam(3, out var x3); +object x3; + +return H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4)); + +void Test() +{ + H.Dummy(x1, x2, x3, x4); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,34): error CS0102: The type 'Script' already contains a definition for 'x2' + // return H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 34), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,43): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 43), + // (3,1): warning CS0162: Unreachable code detected + // H.Dummy(x1); + Diagnostic(ErrorCode.WRN_UnreachableCode, "H").WithLocation(3, 1), + // (16,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(16, 17), + // (16,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(16, 21), + // (16,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TypeVarNotFound, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,34): error CS0102: The type '' already contains a definition for 'x2' + // return H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 34), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,43): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 43), + // (16,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(16, 13), + // (16,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(16, 17), + // (16,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(16, 21), + // (16,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_ReturnStatement_03() + { + string source = +@" +System.Console.WriteLine(x1); +Test(); +return H.Dummy(H.TakeOutParam(1, out var x1), x1); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static bool Dummy(object x, object y) + { + System.Console.WriteLine(y); + return true; + } + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +0 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(3, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_ThrowStatement_01() + { + string source = +@" +throw H.TakeOutParam(1, out int x1); +H.Dummy(x1); + +object x2; +throw H.TakeOutParam(2, out int x2); + +throw H.TakeOutParam(3, out int x3); +object x3; + +throw H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4)); + +void Test() +{ + H.Dummy(x1, x2, x3, x4); +} + +class H +{ + public static System.Exception Dummy(params object[] x) {return null;} + public static System.Exception TakeOutParam(T y, out T x) + { + x = y; + return null; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,33): error CS0102: The type 'Script' already contains a definition for 'x2' + // throw H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 33), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,42): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 42), + // (3,1): warning CS0162: Unreachable code detected + // H.Dummy(x1); + Diagnostic(ErrorCode.WRN_UnreachableCode, "H").WithLocation(3, 1), + // (16,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(16, 17), + // (16,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(16, 21), + // (16,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,33): error CS0102: The type '' already contains a definition for 'x2' + // throw H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 33), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,42): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 42), + // (16,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(16, 13), + // (16,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(16, 17), + // (16,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(16, 21), + // (16,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_ThrowStatement_02() + { + string source = +@" +throw H.TakeOutParam(1, out var x1); +H.Dummy(x1); + +object x2; +throw H.TakeOutParam(2, out var x2); + +throw H.TakeOutParam(3, out var x3); +object x3; + +throw H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4)); + +void Test() +{ + H.Dummy(x1, x2, x3, x4); +} + +class H +{ + public static System.Exception Dummy(params object[] x) {return null;} + public static System.Exception TakeOutParam(T y, out T x) + { + x = y; + return null; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,33): error CS0102: The type 'Script' already contains a definition for 'x2' + // throw H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 33), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,42): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 42), + // (3,1): warning CS0162: Unreachable code detected + // H.Dummy(x1); + Diagnostic(ErrorCode.WRN_UnreachableCode, "H").WithLocation(3, 1), + // (16,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(16, 17), + // (16,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(16, 21), + // (16,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + Assert.Equal("System.Int32", ((FieldSymbol)compilation.GetSemanticModel(tree).GetDeclaredSymbol(x1Decl.VariableDesignation())).Type.ToTestDisplayString()); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TypeVarNotFound, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,33): error CS0102: The type '' already contains a definition for 'x2' + // throw H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 33), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,42): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 42), + // (16,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(16, 13), + // (16,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(16, 17), + // (16,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(16, 21), + // (16,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_SwitchStatement_01() + { + string source = +@" +switch (H.TakeOutParam(1, out int x1)) {default: break;} +H.Dummy(x1); + +object x2; +switch (H.TakeOutParam(2, out int x2)) {default: break;} + +switch (H.TakeOutParam(3, out int x3)) {default: break;} +object x3; + +switch (H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4))) {default: break;} + +switch (H.TakeOutParam(51, out int x5)) +{ +default: + H.TakeOutParam(""52"", out string x5); + H.Dummy(x5); + break; +} +H.Dummy(x5); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,35): error CS0102: The type 'Script' already contains a definition for 'x2' + // switch (H.TakeOutParam(2, out int x2)) {default: break;} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 35), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,44): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4))) {default: break;} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 44), + // (25,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(25, 17), + // (25,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(25, 21), + // (25,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(25, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").ToArray(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Decl.Length); + Assert.Equal(3, x5Ref.Length); + VerifyModelForOutField(model, x5Decl[0], x5Ref[1], x5Ref[2]); + VerifyModelForOutVar(model, x5Decl[1], x5Ref[0]); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,35): error CS0102: The type '' already contains a definition for 'x2' + // switch (H.TakeOutParam(2, out int x2)) {default: break;} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 35), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,44): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4))) {default: break;} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 44), + // (17,37): error CS0102: The type '' already contains a definition for 'x5' + // H.TakeOutParam("52", out string x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("", "x5").WithLocation(17, 37), + // (25,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(25, 13), + // (25,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(25, 17), + // (25,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(25, 21), + // (25,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(25, 25), + // (25,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(25, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_SwitchStatement_02() + { + string source = +@" +switch (H.TakeOutParam(1, out var x1)) {default: break;} +H.Dummy(x1); + +object x2; +switch (H.TakeOutParam(2, out var x2)) {default: break;} + +switch (H.TakeOutParam(3, out var x3)) {default: break;} +object x3; + +switch (H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4))) {default: break;} + +switch (H.TakeOutParam(51, out var x5)) +{ +default: + H.TakeOutParam(""52"", out var x5); + H.Dummy(x5); + break; +} +H.Dummy(x5); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,35): error CS0102: The type 'Script' already contains a definition for 'x2' + // switch (H.TakeOutParam(2, out var x2)) {default: break;} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 35), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,44): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4))) {default: break;} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 44), + // (25,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(25, 17), + // (25,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(25, 21), + // (25,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(25, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").ToArray(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Decl.Length); + Assert.Equal(3, x5Ref.Length); + VerifyModelForOutField(model, x5Decl[0], x5Ref[1], x5Ref[2]); + VerifyModelForOutVar(model, x5Decl[1], x5Ref[0]); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,35): error CS0102: The type '' already contains a definition for 'x2' + // switch (H.TakeOutParam(2, out var x2)) {default: break;} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 35), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,44): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4))) {default: break;} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 44), + // (17,34): error CS0102: The type '' already contains a definition for 'x5' + // H.TakeOutParam("52", out var x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("", "x5").WithLocation(17, 34), + // (6,31): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code + // switch (H.TakeOutParam(2, out var x2)) {default: break;} + Diagnostic(ErrorCode.ERR_TypeVarNotFound, "var").WithLocation(6, 31), + // (8,31): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code + // switch (H.TakeOutParam(3, out var x3)) {default: break;} + Diagnostic(ErrorCode.ERR_TypeVarNotFound, "var").WithLocation(8, 31), + // (11,40): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code + // switch (H.Dummy(H.TakeOutParam(41, out var x4), + Diagnostic(ErrorCode.ERR_TypeVarNotFound, "var").WithLocation(11, 40), + // (12,40): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code + // H.TakeOutParam(42, out var x4))) {default: break;} + Diagnostic(ErrorCode.ERR_TypeVarNotFound, "var").WithLocation(12, 40), + // (14,32): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code + // switch (H.TakeOutParam(51, out var x5)) + Diagnostic(ErrorCode.ERR_TypeVarNotFound, "var").WithLocation(14, 32), + // (17,30): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code + // H.TakeOutParam("52", out var x5); + Diagnostic(ErrorCode.ERR_TypeVarNotFound, "var").WithLocation(17, 30), + // (2,31): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code + // switch (H.TakeOutParam(1, out var x1)) {default: break;} + Diagnostic(ErrorCode.ERR_TypeVarNotFound, "var").WithLocation(2, 31), + // (25,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(25, 13), + // (25,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(25, 17), + // (25,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(25, 21), + // (25,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(25, 25), + // (25,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(25, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_SwitchStatement_03() + { + string source = +@" +System.Console.WriteLine(x1); +switch (H.TakeOutParam(1, out var x1)) +{ +default: + H.TakeOutParam(""11"", out var x1); + System.Console.WriteLine(x1); + break; +} +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +11 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").ToArray(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Decl.Length); + Assert.Equal(3, x1Ref.Length); + VerifyModelForOutField(model, x1Decl[0], x1Ref[0], x1Ref[2]); + VerifyModelForOutVar(model, x1Decl[1], x1Ref[1]); + } + + [Fact] + public void GlobalCode_WhileStatement_01() + { + string source = +@" +while (H.TakeOutParam(1, out int x1)) {} +H.Dummy(x1); + +object x2; +while (H.TakeOutParam(2, out int x2)) {} + +while (H.TakeOutParam(3, out int x3)) {} +object x3; + +while (H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4))) {} + +while (H.TakeOutParam(51, out int x5)) +{ + H.TakeOutParam(""52"", out string x5); + H.Dummy(x5); +} +H.Dummy(x5); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,34): error CS0102: The type 'Script' already contains a definition for 'x2' + // while (H.TakeOutParam(2, out int x2)) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 34), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,43): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4))) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 43), + // (23,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(23, 17), + // (23,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(23, 21), + // (23,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(23, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").ToArray(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Decl.Length); + Assert.Equal(3, x5Ref.Length); + VerifyModelForOutField(model, x5Decl[0], x5Ref[1], x5Ref[2]); + VerifyModelForOutVar(model, x5Decl[1], x5Ref[0]); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,34): error CS0102: The type '' already contains a definition for 'x2' + // while (H.TakeOutParam(2, out int x2)) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 34), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,43): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4))) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 43), + // (16,37): error CS0102: The type '' already contains a definition for 'x5' + // H.TakeOutParam("52", out string x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("", "x5").WithLocation(16, 37), + // (23,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(23, 13), + // (23,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(23, 17), + // (23,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(23, 21), + // (23,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(23, 25), + // (23,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(23, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_WhileStatement_02() + { + string source = +@" +while (H.TakeOutParam(1, out var x1)) {} +H.Dummy(x1); + +object x2; +while (H.TakeOutParam(2, out var x2)) {} + +while (H.TakeOutParam(3, out var x3)) {} +object x3; + +while (H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4))) {} + +while (H.TakeOutParam(51, out var x5)) +{ + H.TakeOutParam(""52"", out var x5); + H.Dummy(x5); +} +H.Dummy(x5); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,34): error CS0102: The type 'Script' already contains a definition for 'x2' + // while (H.TakeOutParam(2, out var x2)) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 34), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,43): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4))) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 43), + // (23,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(23, 17), + // (23,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(23, 21), + // (23,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(23, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").ToArray(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Decl.Length); + Assert.Equal(3, x5Ref.Length); + VerifyModelForOutField(model, x5Decl[0], x5Ref[1], x5Ref[2]); + VerifyModelForOutVar(model, x5Decl[1], x5Ref[0]); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TypeVarNotFound, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,34): error CS0102: The type '' already contains a definition for 'x2' + // while (H.TakeOutParam(2, out var x2)) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 34), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,43): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4))) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 43), + // (16,34): error CS0102: The type '' already contains a definition for 'x5' + // H.TakeOutParam("52", out var x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("", "x5").WithLocation(16, 34), + // (23,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(23, 13), + // (23,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(23, 17), + // (23,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(23, 21), + // (23,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(23, 25), + // (23,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(23, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_WhileStatement_03() + { + string source = +@" +System.Console.WriteLine(x1); +while (H.TakeOutParam(1, out var x1)) +{ + H.TakeOutParam(""11"", out var x1); + System.Console.WriteLine(x1); + break; +} +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +11 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").ToArray(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Decl.Length); + Assert.Equal(3, x1Ref.Length); + VerifyModelForOutField(model, x1Decl[0], x1Ref[0], x1Ref[2]); + VerifyModelForOutVar(model, x1Decl[1], x1Ref[1]); + } + + [Fact] + public void GlobalCode_WhileStatement_04() + { + string source = +@" +bool x0 = true; +System.Console.WriteLine(x1); +while (x0 && H.TakeOutParam(1, out var x1)) + H.Dummy(H.TakeOutParam(""11"", out var x1) && (x0 = false), x1); +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static void Dummy(object x, object y) + { + System.Console.WriteLine(y); + } + + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +11 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").ToArray(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Decl.Length); + Assert.Equal(3, x1Ref.Length); + VerifyModelForOutField(model, x1Decl[0], x1Ref[0], x1Ref[2]); + VerifyModelForOutVar(model, x1Decl[1], x1Ref[1]); + } + + [Fact] + public void GlobalCode_DoStatement_01() + { + string source = +@" +do {} while (H.TakeOutParam(1, out int x1)); +H.Dummy(x1); + +object x2; +do {} while (H.TakeOutParam(2, out int x2)); + +do {} while (H.TakeOutParam(3, out int x3)); +object x3; + +do {} while (H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4))); + +do +{ + H.TakeOutParam(""52"", out string x5); + H.Dummy(x5); +} +while (H.TakeOutParam(51, out int x5)); +H.Dummy(x5); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,40): error CS0102: The type 'Script' already contains a definition for 'x2' + // do {} while (H.TakeOutParam(2, out int x2)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 40), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,49): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4))); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 49), + // (24,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(24, 17), + // (24,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(24, 21), + // (24,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(24, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").ToArray(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Decl.Length); + Assert.Equal(3, x5Ref.Length); + VerifyModelForOutVar(model, x5Decl[0], x5Ref[0]); + VerifyModelForOutField(model, x5Decl[1], x5Ref[1], x5Ref[2]); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,40): error CS0102: The type '' already contains a definition for 'x2' + // do {} while (H.TakeOutParam(2, out int x2)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 40), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,49): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4))); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 49), + // (19,35): error CS0102: The type '' already contains a definition for 'x5' + // while (H.TakeOutParam(51, out int x5)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("", "x5").WithLocation(19, 35), + // (24,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(24, 13), + // (24,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(24, 17), + // (24,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(24, 21), + // (24,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(24, 25), + // (24,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(24, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_DoStatement_02() + { + string source = +@" +do {} while (H.TakeOutParam(1, out var x1)); +H.Dummy(x1); + +object x2; +do {} while (H.TakeOutParam(2, out var x2)); + +do {} while (H.TakeOutParam(3, out var x3)); +object x3; + +do {} while (H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4))); + +do +{ + H.TakeOutParam(""52"", out var x5); + H.Dummy(x5); +} +while (H.TakeOutParam(51, out var x5)); +H.Dummy(x5); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,40): error CS0102: The type 'Script' already contains a definition for 'x2' + // do {} while (H.TakeOutParam(2, out var x2)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 40), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,49): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4))); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 49), + // (24,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(24, 17), + // (24,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(24, 21), + // (24,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(24, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").ToArray(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Decl.Length); + Assert.Equal(3, x5Ref.Length); + VerifyModelForOutVar(model, x5Decl[0], x5Ref[0]); + VerifyModelForOutField(model, x5Decl[1], x5Ref[1], x5Ref[2]); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TypeVarNotFound, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,40): error CS0102: The type '' already contains a definition for 'x2' + // do {} while (H.TakeOutParam(2, out var x2)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 40), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,49): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4))); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 49), + // (19,35): error CS0102: The type '' already contains a definition for 'x5' + // while (H.TakeOutParam(51, out var x5)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("", "x5").WithLocation(19, 35), + // (24,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(24, 13), + // (24,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(24, 17), + // (24,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(24, 21), + // (24,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(24, 25), + // (24,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(24, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_DoStatement_03() + { + string source = +@" +System.Console.WriteLine(x1); +do +{ + H.TakeOutParam(""11"", out var x1); + System.Console.WriteLine(x1); +} +while (H.TakeOutParam(1, out var x1) && false); +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +11 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").ToArray(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Decl.Length); + Assert.Equal(3, x1Ref.Length); + VerifyModelForOutVar(model, x1Decl[0], x1Ref[1]); + VerifyModelForOutField(model, x1Decl[1], x1Ref[0], x1Ref[2]); + } + + [Fact] + public void GlobalCode_DoStatement_04() + { + string source = +@" +System.Console.WriteLine(x1); +do + H.Dummy(H.TakeOutParam(""11"", out var x1), x1); +while (H.TakeOutParam(1, out var x1) && false); +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static void Dummy(object x, object y) + { + System.Console.WriteLine(y); + } + + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +11 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").ToArray(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Decl.Length); + Assert.Equal(3, x1Ref.Length); + VerifyModelForOutVar(model, x1Decl[0], x1Ref[1]); + VerifyModelForOutField(model, x1Decl[1], x1Ref[0], x1Ref[2]); + } + + [Fact] + public void GlobalCode_LockStatement_01() + { + string source = +@" +lock (H.TakeOutParam(1, out int x1)) {} +H.Dummy(x1); + +object x2; +lock (H.TakeOutParam(2, out int x2)) {} + +lock (H.TakeOutParam(3, out int x3)) {} +object x3; + +lock (H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4))) {} + +lock (H.TakeOutParam(51, out int x5)) +{ + H.TakeOutParam(""52"", out string x5); + H.Dummy(x5); +} +H.Dummy(x5); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +class H +{ + public static object Dummy(params object[] x) {return true;} + public static object TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,33): error CS0102: The type 'Script' already contains a definition for 'x2' + // lock (H.TakeOutParam(2, out int x2)) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 33), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,42): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4))) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 42), + // (23,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(23, 17), + // (23,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(23, 21), + // (23,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(23, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").ToArray(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Decl.Length); + Assert.Equal(3, x5Ref.Length); + VerifyModelForOutField(model, x5Decl[0], x5Ref[1], x5Ref[2]); + VerifyModelForOutVar(model, x5Decl[1], x5Ref[0]); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,33): error CS0102: The type '' already contains a definition for 'x2' + // lock (H.TakeOutParam(2, out int x2)) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 33), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,42): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4))) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 42), + // (16,37): error CS0102: The type '' already contains a definition for 'x5' + // H.TakeOutParam("52", out string x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("", "x5").WithLocation(16, 37), + // (23,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(23, 13), + // (23,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(23, 17), + // (23,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(23, 21), + // (23,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(23, 25), + // (23,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(23, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_LockStatement_02() + { + string source = +@" +lock (H.TakeOutParam(1, out var x1)) {} +H.Dummy(x1); + +object x2; +lock (H.TakeOutParam(2, out var x2)) {} + +lock (H.TakeOutParam(3, out var x3)) {} +object x3; + +lock (H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4))) {} + +lock (H.TakeOutParam(51, out var x5)) +{ + H.TakeOutParam(""52"", out var x5); + H.Dummy(x5); +} +H.Dummy(x5); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +class H +{ + public static object Dummy(params object[] x) {return true;} + public static object TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,33): error CS0102: The type 'Script' already contains a definition for 'x2' + // lock (H.TakeOutParam(2, out var x2)) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 33), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,42): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4))) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 42), + // (23,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(23, 17), + // (23,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(23, 21), + // (23,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(23, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").ToArray(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Decl.Length); + Assert.Equal(3, x5Ref.Length); + VerifyModelForOutField(model, x5Decl[0], x5Ref[1], x5Ref[2]); + VerifyModelForOutVar(model, x5Decl[1], x5Ref[0]); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TypeVarNotFound, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,33): error CS0102: The type '' already contains a definition for 'x2' + // lock (H.TakeOutParam(2, out var x2)) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 33), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,42): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4))) {} + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 42), + // (16,34): error CS0102: The type '' already contains a definition for 'x5' + // H.TakeOutParam("52", out var x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("", "x5").WithLocation(16, 34), + // (23,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(23, 13), + // (23,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(23, 17), + // (23,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(23, 21), + // (23,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(23, 25), + // (23,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(23, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_LockStatement_03() + { + string source = +@" +System.Console.WriteLine(x1); +lock (H.TakeOutParam(1, out var x1)) +{ + H.TakeOutParam(""11"", out var x1); + System.Console.WriteLine(x1); +} +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static object TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +11 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").ToArray(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Decl.Length); + Assert.Equal(3, x1Ref.Length); + VerifyModelForOutField(model, x1Decl[0], x1Ref[0], x1Ref[2]); + VerifyModelForOutVar(model, x1Decl[1], x1Ref[1]); + } + + [Fact] + public void GlobalCode_LockStatement_04() + { + string source = +@" +System.Console.WriteLine(x1); +lock (H.TakeOutParam(1, out var x1)) + H.Dummy(H.TakeOutParam(""11"", out var x1), x1); +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static void Dummy(object x, object y) + { + System.Console.WriteLine(y); + } + + public static object TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +11 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").ToArray(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Decl.Length); + Assert.Equal(3, x1Ref.Length); + VerifyModelForOutField(model, x1Decl[0], x1Ref[0], x1Ref[2]); + VerifyModelForOutVar(model, x1Decl[1], x1Ref[1]); + } + + [Fact] + [CompilerTrait(CompilerFeature.Tuples)] + public void GlobalCode_DeconstructionDeclarationStatement_01() + { + string source = +@" +(bool a, int b) = (H.TakeOutParam(1, out int x1), 1); +H.Dummy(x1); + +object x2; +(bool c, int d) = (H.TakeOutParam(2, out int x2), 2); + +(bool e, int f) = (H.TakeOutParam(3, out int x3), 3); +object x3; + +(bool g, bool h) = (H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4)); + +(bool x5, bool x6) = (H.TakeOutParam(5, out int x5), + H.TakeOutParam(6, out int x6)); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5, x6); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, + options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (2,17): error CS1519: Invalid token '=' in class, struct, or interface member declaration + // (bool a, int b) = (H.TakeOutParam(1, out int x1), 1); + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(2, 17), + // (2,17): error CS1525: Invalid expression term '=' + // (bool a, int b) = (H.TakeOutParam(1, out int x1), 1); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "=").WithArguments("=").WithLocation(2, 17), + // (6,17): error CS1519: Invalid token '=' in class, struct, or interface member declaration + // (bool c, int d) = (H.TakeOutParam(2, out int x2), 2); + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(6, 17), + // (6,17): error CS1525: Invalid expression term '=' + // (bool c, int d) = (H.TakeOutParam(2, out int x2), 2); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "=").WithArguments("=").WithLocation(6, 17), + // (8,17): error CS1519: Invalid token '=' in class, struct, or interface member declaration + // (bool e, int f) = (H.TakeOutParam(3, out int x3), 3); + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(8, 17), + // (8,17): error CS1525: Invalid expression term '=' + // (bool e, int f) = (H.TakeOutParam(3, out int x3), 3); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "=").WithArguments("=").WithLocation(8, 17), + // (11,18): error CS1519: Invalid token '=' in class, struct, or interface member declaration + // (bool g, bool h) = (H.TakeOutParam(41, out int x4), + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(11, 18), + // (11,18): error CS1525: Invalid expression term '=' + // (bool g, bool h) = (H.TakeOutParam(41, out int x4), + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "=").WithArguments("=").WithLocation(11, 18), + // (14,20): error CS1519: Invalid token '=' in class, struct, or interface member declaration + // (bool x5, bool x6) = (H.TakeOutParam(5, out int x5), + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(14, 20), + // (14,20): error CS1525: Invalid expression term '=' + // (bool x5, bool x6) = (H.TakeOutParam(5, out int x5), + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "=").WithArguments("=").WithLocation(14, 20), + // (6,46): error CS0102: The type 'Script' already contains a definition for 'x2' + // (bool c, int d) = (H.TakeOutParam(2, out int x2), 2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 46), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,48): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 48), + // (19,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(19, 17), + // (19,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(19, 21), + // (19,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(19, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Ref.Length); + VerifyModelForOutField(model, x5Decl, x5Ref[1]); + + var x6Decl = GetOutVarDeclarations(tree, "x6").Single(); + var x6Ref = GetReferences(tree, "x6").ToArray(); + Assert.Equal(2, x6Ref.Length); + VerifyModelForOutField(model, x6Decl, x6Ref[1]); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,46): error CS0102: The type '' already contains a definition for 'x2' + // (bool c, int d) = (H.TakeOutParam(2, out int x2), 2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 46), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,48): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 48), + // (19,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(19, 13), + // (19,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(19, 17), + // (19,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(19, 21), + // (19,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(19, 25), + // (19,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(19, 29), + // (19,33): error CS0103: The name 'x6' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x6").WithArguments("x6").WithLocation(19, 33) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_LabeledStatement_01() + { + string source = +@" +a: H.TakeOutParam(1, out int x1); +H.Dummy(x1); + +object x2; +b: H.TakeOutParam(2, out int x2); + +c: H.TakeOutParam(3, out int x3); +object x3; + +d: H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4)); + +void Test() +{ + H.Dummy(x1, x2, x3, x4); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,30): error CS0102: The type 'Script' already contains a definition for 'x2' + // b: H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 30), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,39): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 39), + // (2,1): warning CS0164: This label has not been referenced + // a: H.TakeOutParam(1, out int x1); + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "a").WithLocation(2, 1), + // (6,1): warning CS0164: This label has not been referenced + // b: H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "b").WithLocation(6, 1), + // (8,1): warning CS0164: This label has not been referenced + // c: H.TakeOutParam(3, out int x3); + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "c").WithLocation(8, 1), + // (11,1): warning CS0164: This label has not been referenced + // d: H.Dummy(H.TakeOutParam(41, out int x4), + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "d").WithLocation(11, 1), + // (16,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(16, 17), + // (16,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(16, 21), + // (16,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,30): error CS0102: The type '' already contains a definition for 'x2' + // b: H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 30), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,39): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 39), + // (16,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(16, 13), + // (16,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(16, 17), + // (16,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(16, 21), + // (16,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_LabeledStatement_02() + { + string source = +@" +a: H.TakeOutParam(1, out var x1); +H.Dummy(x1); + +object x2; +b: H.TakeOutParam(2, out var x2); + +c: H.TakeOutParam(3, out var x3); +object x3; + +d: H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4)); + +void Test() +{ + H.Dummy(x1, x2, x3, x4); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,30): error CS0102: The type 'Script' already contains a definition for 'x2' + // b: H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 30), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,39): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 39), + // (2,1): warning CS0164: This label has not been referenced + // a: H.TakeOutParam(1, out var x1); + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "a").WithLocation(2, 1), + // (6,1): warning CS0164: This label has not been referenced + // b: H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "b").WithLocation(6, 1), + // (8,1): warning CS0164: This label has not been referenced + // c: H.TakeOutParam(3, out var x3); + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "c").WithLocation(8, 1), + // (11,1): warning CS0164: This label has not been referenced + // d: H.Dummy(H.TakeOutParam(41, out var x4), + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "d").WithLocation(11, 1), + // (16,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(16, 17), + // (16,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(16, 21), + // (16,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TypeVarNotFound, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,30): error CS0102: The type '' already contains a definition for 'x2' + // b: H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 30), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,39): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 39), + // (16,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(16, 13), + // (16,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(16, 17), + // (16,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(16, 21), + // (16,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(16, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + public void GlobalCode_LabeledStatement_03() + { + string source = +@" +System.Console.WriteLine(x1); +a:b:c:H.TakeOutParam(1, out var x1); +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +1").VerifyDiagnostics( + // (3,1): warning CS0164: This label has not been referenced + // a:b:c:H.TakeOutParam(1, out var x1); + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "a").WithLocation(3, 1), + // (3,3): warning CS0164: This label has not been referenced + // a:b:c:H.TakeOutParam(1, out var x1); + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "b").WithLocation(3, 3), + // (3,5): warning CS0164: This label has not been referenced + // a:b:c:H.TakeOutParam(1, out var x1); + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "c").WithLocation(3, 5) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_LabeledStatement_04() + { + string source = +@" +a: +bool b = H.TakeOutParam(1, out int x1); +H.Dummy(x1); +object x2; +c: +bool d = H.TakeOutParam(2, out int x2); +e: +bool f = H.TakeOutParam(3, out int x3); +object x3; +g: +bool h = H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4)); +i: +bool x5 = H.TakeOutParam(5, out int x5); +H.Dummy(x5); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (7,36): error CS0102: The type 'Script' already contains a definition for 'x2' + // bool d = H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(7, 36), + // (10,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(10, 8), + // (13,45): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(13, 45), + // (2,1): warning CS0164: This label has not been referenced + // a: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "a").WithLocation(2, 1), + // (6,1): warning CS0164: This label has not been referenced + // c: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "c").WithLocation(6, 1), + // (8,1): warning CS0164: This label has not been referenced + // e: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "e").WithLocation(8, 1), + // (11,1): warning CS0164: This label has not been referenced + // g: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "g").WithLocation(11, 1), + // (14,1): warning CS0164: This label has not been referenced + // i: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "i").WithLocation(14, 1), + // (20,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(20, 17), + // (20,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(20, 21), + // (20,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(20, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Ref.Length); + VerifyModelForOutField(model, x5Decl, x5Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (3,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool b = H.TakeOutParam(1, out int x1); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x1").WithLocation(3, 32), + // (7,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool d = H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x2").WithLocation(7, 32), + // (9,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool f = H.TakeOutParam(3, out int x3); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x3").WithLocation(9, 32), + // (12,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool h = H.Dummy(H.TakeOutParam(41, out int x4), + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x4").WithLocation(12, 41), + // (13,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x4").WithLocation(13, 41), + // (13,45): error CS0128: A local variable named 'x4' is already defined in this scope + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_LocalDuplicate, "x4").WithArguments("x4").WithLocation(13, 45), + // (15,33): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool x5 = H.TakeOutParam(5, out int x5); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x5").WithLocation(15, 33), + // (20,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(20, 13), + // (20,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(20, 17), + // (20,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(20, 21), + // (20,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(20, 25), + // (20,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(20, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutVar(model, x1Decl); + VerifyModelNotSupported(model, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutVar(model, x2Decl); + VerifyModelNotSupported(model, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutVar(model, x3Decl); + VerifyModelNotSupported(model, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutVar(model, x4Decl[0]); + VerifyModelForOutVarDuplicateInSameScope(model, x4Decl[1]); + VerifyModelNotSupported(model, x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Ref.Length); + VerifyModelForOutVar(model, x5Decl); + VerifyModelNotSupported(model, x5Ref); + } + } + + [Fact] + public void GlobalCode_LabeledStatement_05() + { + string source = +@" +a: +bool b = H.TakeOutParam(1, out var x1); +H.Dummy(x1); +object x2; +c: +bool d = H.TakeOutParam(2, out var x2); +e: +bool f = H.TakeOutParam(3, out var x3); +object x3; +g: +bool h = H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4)); +i: +bool x5 = H.TakeOutParam(5, out var x5); +H.Dummy(x5); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (7,36): error CS0102: The type 'Script' already contains a definition for 'x2' + // bool d = H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(7, 36), + // (10,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(10, 8), + // (13,45): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(13, 45), + // (2,1): warning CS0164: This label has not been referenced + // a: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "a").WithLocation(2, 1), + // (6,1): warning CS0164: This label has not been referenced + // c: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "c").WithLocation(6, 1), + // (8,1): warning CS0164: This label has not been referenced + // e: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "e").WithLocation(8, 1), + // (11,1): warning CS0164: This label has not been referenced + // g: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "g").WithLocation(11, 1), + // (14,1): warning CS0164: This label has not been referenced + // i: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "i").WithLocation(14, 1), + // (20,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(20, 17), + // (20,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(20, 21), + // (20,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(20, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Ref.Length); + VerifyModelForOutField(model, x5Decl, x5Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (3,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool b = H.TakeOutParam(1, out var x1); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x1").WithLocation(3, 32), + // (7,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool d = H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x2").WithLocation(7, 32), + // (9,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool f = H.TakeOutParam(3, out var x3); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x3").WithLocation(9, 32), + // (12,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool h = H.Dummy(H.TakeOutParam(41, out var x4), + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x4").WithLocation(12, 41), + // (13,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x4").WithLocation(13, 41), + // (13,45): error CS0128: A local variable named 'x4' is already defined in this scope + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_LocalDuplicate, "x4").WithArguments("x4").WithLocation(13, 45), + // (15,33): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool x5 = H.TakeOutParam(5, out var x5); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x5").WithLocation(15, 33), + // (20,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(20, 13), + // (20,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(20, 17), + // (20,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(20, 21), + // (20,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(20, 25), + // (20,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(20, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutVar(model, x1Decl); + VerifyModelNotSupported(model, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutVar(model, x2Decl); + VerifyModelNotSupported(model, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutVar(model, x3Decl); + VerifyModelNotSupported(model, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutVar(model, x4Decl[0]); + VerifyModelForOutVarDuplicateInSameScope(model, x4Decl[1]); + VerifyModelNotSupported(model, x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(2, x5Ref.Length); + VerifyModelForOutVar(model, x5Decl); + VerifyModelNotSupported(model, x5Ref); + } + } + + [Fact] + public void GlobalCode_LabeledStatement_06() + { + string source = +@" +System.Console.WriteLine(x1); +a:b:c: +var d = H.TakeOutParam(1, out var x1); +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +1").VerifyDiagnostics( + // (3,1): warning CS0164: This label has not been referenced + // a:b:c: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "a").WithLocation(3, 1), + // (3,3): warning CS0164: This label has not been referenced + // a:b:c: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "b").WithLocation(3, 3), + // (3,5): warning CS0164: This label has not been referenced + // a:b:c: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "c").WithLocation(3, 5) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + [CompilerTrait(CompilerFeature.Tuples)] + public void GlobalCode_LabeledStatement_07() + { + string source = +@"l1: +(bool a, int b) = (H.TakeOutParam(1, out int x1), 1); +H.Dummy(x1); +object x2; +l2: +(bool c, int d) = (H.TakeOutParam(2, out int x2), 2); +l3: +(bool e, int f) = (H.TakeOutParam(3, out int x3), 3); +object x3; +l4: +(bool g, bool h) = (H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4)); +l5: +(bool x5, bool x6) = (H.TakeOutParam(5, out int x5), + H.TakeOutParam(6, out int x6)); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5, x6); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, + options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,46): error CS0102: The type 'Script' already contains a definition for 'x2' + // (bool c, int d) = (H.TakeOutParam(2, out int x2), 2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 46), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,48): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 48), + // (1,1): warning CS0164: This label has not been referenced + // l1: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "l1").WithLocation(1, 1), + // (5,1): warning CS0164: This label has not been referenced + // l2: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "l2").WithLocation(5, 1), + // (7,1): warning CS0164: This label has not been referenced + // l3: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "l3").WithLocation(7, 1), + // (10,1): warning CS0164: This label has not been referenced + // l4: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "l4").WithLocation(10, 1), + // (13,1): warning CS0164: This label has not been referenced + // l5: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "l5").WithLocation(13, 1), + // (19,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(19, 17), + // (19,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(19, 21), + // (19,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(19, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(1, x5Ref.Length); + VerifyModelForOutField(model, x5Decl, x5Ref); + + var x6Decl = GetOutVarDeclarations(tree, "x6").Single(); + var x6Ref = GetReferences(tree, "x6").ToArray(); + Assert.Equal(1, x6Ref.Length); + VerifyModelForOutField(model, x6Decl, x6Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,46): error CS0102: The type '' already contains a definition for 'x2' + // (bool c, int d) = (H.TakeOutParam(2, out int x2), 2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 46), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,48): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 48), + // (19,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(19, 13), + // (19,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(19, 17), + // (19,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(19, 21), + // (19,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(19, 25), + // (19,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(19, 29), + // (19,33): error CS0103: The name 'x6' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x6").WithArguments("x6").WithLocation(19, 33) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + [CompilerTrait(CompilerFeature.Tuples)] + public void GlobalCode_LabeledStatement_08() + { + string source = +@"l1: +(bool a, int b) = (H.TakeOutParam(1, out var x1), 1); +H.Dummy(x1); +object x2; +l2: +(bool c, int d) = (H.TakeOutParam(2, out var x2), 2); +l3: +(bool e, int f) = (H.TakeOutParam(3, out var x3), 3); +object x3; +l4: +(bool g, bool h) = (H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4)); +l5: +(bool x5, bool x6) = (H.TakeOutParam(5, out var x5), + H.TakeOutParam(6, out var x6)); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5, x6); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, + options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (6,46): error CS0102: The type 'Script' already contains a definition for 'x2' + // (bool c, int d) = (H.TakeOutParam(2, out var x2), 2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(6, 46), + // (9,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(9, 8), + // (12,48): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(12, 48), + // (1,1): warning CS0164: This label has not been referenced + // l1: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "l1").WithLocation(1, 1), + // (5,1): warning CS0164: This label has not been referenced + // l2: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "l2").WithLocation(5, 1), + // (7,1): warning CS0164: This label has not been referenced + // l3: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "l3").WithLocation(7, 1), + // (10,1): warning CS0164: This label has not been referenced + // l4: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "l4").WithLocation(10, 1), + // (13,1): warning CS0164: This label has not been referenced + // l5: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "l5").WithLocation(13, 1), + // (19,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(19, 17), + // (19,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(19, 21), + // (19,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(19, 25) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").ToArray(); + Assert.Equal(1, x5Ref.Length); + VerifyModelForOutField(model, x5Decl, x5Ref); + + var x6Decl = GetOutVarDeclarations(tree, "x6").Single(); + var x6Ref = GetReferences(tree, "x6").ToArray(); + Assert.Equal(1, x6Ref.Length); + VerifyModelForOutField(model, x6Decl, x6Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TypeVarNotFound, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (6,46): error CS0102: The type '' already contains a definition for 'x2' + // (bool c, int d) = (H.TakeOutParam(2, out var x2), 2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("", "x2").WithLocation(6, 46), + // (9,8): error CS0102: The type '' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("", "x3").WithLocation(9, 8), + // (12,48): error CS0102: The type '' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("", "x4").WithLocation(12, 48), + // (19,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(19, 13), + // (19,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(19, 17), + // (19,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(19, 21), + // (19,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(19, 25), + // (19,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(19, 29), + // (19,33): error CS0103: The name 'x6' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x6").WithArguments("x6").WithLocation(19, 33) + ); + + var tree = compilation.SyntaxTrees.Single(); + Assert.Empty(GetOutVarDeclarations(tree)); + } + } + + [Fact] + [CompilerTrait(CompilerFeature.Tuples)] + public void GlobalCode_LabeledStatement_09() + { + string source = +@" +System.Console.WriteLine(x1); +a:b:c: +var (d, e) = (H.TakeOutParam(1, out var x1), 1); +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, + options: TestOptions.DebugExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +1").VerifyDiagnostics( + // (3,1): warning CS0164: This label has not been referenced + // a:b:c: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "a").WithLocation(3, 1), + // (3,3): warning CS0164: This label has not been referenced + // a:b:c: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "b").WithLocation(3, 3), + // (3,5): warning CS0164: This label has not been referenced + // a:b:c: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "c").WithLocation(3, 5) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_FieldDeclaration_01() + { + string source = +@" + +bool b = H.TakeOutParam(1, out int x1); +H.Dummy(x1); + +object x2; +bool d = H.TakeOutParam(2, out int x2); + +bool f = H.TakeOutParam(3, out int x3); +object x3; + +bool h = H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4)); + +bool x5 = + H.TakeOutParam(5, out int x5); + +bool i = H.TakeOutParam(5, out int x6), + x6; + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5, x6); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (7,36): error CS0102: The type 'Script' already contains a definition for 'x2' + // bool d = H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(7, 36), + // (10,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(10, 8), + // (13,45): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(13, 45), + // (16,37): error CS0102: The type 'Script' already contains a definition for 'x5' + // H.TakeOutParam(5, out int x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("Script", "x5").WithLocation(16, 37), + // (19,10): error CS0102: The type 'Script' already contains a definition for 'x6' + // x6; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x6").WithArguments("Script", "x6").WithLocation(19, 10), + // (23,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(23, 17), + // (23,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(23, 21), + // (23,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(23, 25), + // (23,29): error CS0229: Ambiguity between 'x5' and 'x5' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x5").WithArguments("x5", "x5").WithLocation(23, 29), + // (23,33): error CS0229: Ambiguity between 'x6' and 'x6' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x6").WithArguments("x6", "x6").WithLocation(23, 33) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").Single(); + VerifyModelForOutFieldDuplicate(model, x5Decl, x5Ref); + + var x6Decl = GetOutVarDeclarations(tree, "x6").Single(); + var x6Ref = GetReferences(tree, "x6").Single(); + VerifyModelForOutFieldDuplicate(model, x6Decl, x6Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (3,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool b = H.TakeOutParam(1, out int x1); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x1").WithLocation(3, 32), + // (7,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool d = H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x2").WithLocation(7, 32), + // (9,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool f = H.TakeOutParam(3, out int x3); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x3").WithLocation(9, 32), + // (12,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool h = H.Dummy(H.TakeOutParam(41, out int x4), + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x4").WithLocation(12, 41), + // (13,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x4").WithLocation(13, 41), + // (13,45): error CS0128: A local variable named 'x4' is already defined in this scope + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_LocalDuplicate, "x4").WithArguments("x4").WithLocation(13, 45), + // (16,33): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(5, out int x5); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x5").WithLocation(16, 33), + // (18,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool i = H.TakeOutParam(5, out int x6), + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x6").WithLocation(18, 32), + // (23,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(23, 13), + // (23,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(23, 17), + // (23,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(23, 21), + // (23,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(23, 25), + // (23,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(23, 29), + // (23,33): error CS0103: The name 'x6' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x6").WithArguments("x6").WithLocation(23, 33) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutVar(model, x1Decl); + VerifyModelNotSupported(model, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutVar(model, x2Decl); + VerifyModelNotSupported(model, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutVar(model, x3Decl); + VerifyModelNotSupported(model, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutVar(model, x4Decl[0]); + VerifyModelForOutVarDuplicateInSameScope(model, x4Decl[1]); + VerifyModelNotSupported(model, x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").Single(); + VerifyModelForOutVar(model, x5Decl); + VerifyModelNotSupported(model, x5Ref); + + var x6Decl = GetOutVarDeclarations(tree, "x6").Single(); + var x6Ref = GetReferences(tree, "x6").Single(); + VerifyModelForOutVar(model, x6Decl); + VerifyModelNotSupported(model, x6Ref); + } + } + + [Fact] + public void GlobalCode_FieldDeclaration_02() + { + string source = +@" + +bool b = H.TakeOutParam(1, out var x1); +H.Dummy(x1); + +object x2; +bool d = H.TakeOutParam(2, out var x2); + +bool f = H.TakeOutParam(3, out var x3); +object x3; + +bool h = H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4)); + +bool x5 = + H.TakeOutParam(5, out var x5); + +bool i = H.TakeOutParam(5, out var x6), + x6; + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5, x6); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (7,36): error CS0102: The type 'Script' already contains a definition for 'x2' + // bool d = H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(7, 36), + // (10,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(10, 8), + // (13,45): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(13, 45), + // (16,37): error CS0102: The type 'Script' already contains a definition for 'x5' + // H.TakeOutParam(5, out var x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("Script", "x5").WithLocation(16, 37), + // (19,10): error CS0102: The type 'Script' already contains a definition for 'x6' + // x6; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x6").WithArguments("Script", "x6").WithLocation(19, 10), + // (23,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(23, 17), + // (23,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(23, 21), + // (23,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(23, 25), + // (23,29): error CS0229: Ambiguity between 'x5' and 'x5' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x5").WithArguments("x5", "x5").WithLocation(23, 29), + // (23,33): error CS0229: Ambiguity between 'x6' and 'x6' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x6").WithArguments("x6", "x6").WithLocation(23, 33) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").Single(); + VerifyModelForOutFieldDuplicate(model, x5Decl, x5Ref); + + var x6Decl = GetOutVarDeclarations(tree, "x6").Single(); + var x6Ref = GetReferences(tree, "x6").Single(); + VerifyModelForOutFieldDuplicate(model, x6Decl, x6Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (3,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool b = H.TakeOutParam(1, out var x1); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x1").WithLocation(3, 32), + // (7,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool d = H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x2").WithLocation(7, 32), + // (9,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool f = H.TakeOutParam(3, out var x3); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x3").WithLocation(9, 32), + // (12,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool h = H.Dummy(H.TakeOutParam(41, out var x4), + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x4").WithLocation(12, 41), + // (13,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x4").WithLocation(13, 41), + // (13,45): error CS0128: A local variable named 'x4' is already defined in this scope + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_LocalDuplicate, "x4").WithArguments("x4").WithLocation(13, 45), + // (16,33): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(5, out var x5); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x5").WithLocation(16, 33), + // (18,32): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool i = H.TakeOutParam(5, out var x6), + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x6").WithLocation(18, 32), + // (23,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(23, 13), + // (23,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(23, 17), + // (23,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(23, 21), + // (23,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(23, 25), + // (23,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(23, 29), + // (23,33): error CS0103: The name 'x6' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x6").WithArguments("x6").WithLocation(23, 33) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutVar(model, x1Decl); + VerifyModelNotSupported(model, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutVar(model, x2Decl); + VerifyModelNotSupported(model, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutVar(model, x3Decl); + VerifyModelNotSupported(model, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutVar(model, x4Decl[0]); + VerifyModelForOutVarDuplicateInSameScope(model, x4Decl[1]); + VerifyModelNotSupported(model, x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").Single(); + VerifyModelForOutVar(model, x5Decl); + VerifyModelNotSupported(model, x5Ref); + + var x6Decl = GetOutVarDeclarations(tree, "x6").Single(); + var x6Ref = GetReferences(tree, "x6").Single(); + VerifyModelForOutVar(model, x6Decl); + VerifyModelNotSupported(model, x6Ref); + } + } + + [Fact] + public void GlobalCode_FieldDeclaration_03() + { + string source = +@" +System.Console.WriteLine(x1); +var d = H.TakeOutParam(1, out var x1); +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_FieldDeclaration_04() + { + string source = +@" +static var a = InitA(); +System.Console.WriteLine(x1); +static var b = H.TakeOutParam(1, out var x1); +Test(); +static var c = InitB(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +static object InitA() +{ + System.Console.WriteLine(""InitA {0}"", x1); + return null; +} + +static object InitB() +{ + System.Console.WriteLine(""InitB {0}"", x1); + return null; +} + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"InitA 0 +InitB 1 +1 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(4, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_FieldDeclaration_05() + { + string source = +@" + +bool b = H.TakeOutParam(1, out var x1); +static var d = x1; + +static void Test() +{ + H.Dummy(x1); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (4,16): error CS0120: An object reference is required for the non-static field, method, or property 'x1' + // static var d = x1; + Diagnostic(ErrorCode.ERR_ObjectRequired, "x1").WithArguments("x1").WithLocation(4, 16), + // (8,13): error CS0120: An object reference is required for the non-static field, method, or property 'x1' + // H.Dummy(x1); + Diagnostic(ErrorCode.ERR_ObjectRequired, "x1").WithArguments("x1").WithLocation(8, 13) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_FieldDeclaration_06() + { + string source = +@" + +bool b = H.TakeOutParam(1, out int x1); +static var d = x1; + +static void Test() +{ + H.Dummy(x1); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (4,16): error CS0120: An object reference is required for the non-static field, method, or property 'x1' + // static var d = x1; + Diagnostic(ErrorCode.ERR_ObjectRequired, "x1").WithArguments("x1").WithLocation(4, 16), + // (8,13): error CS0120: An object reference is required for the non-static field, method, or property 'x1' + // H.Dummy(x1); + Diagnostic(ErrorCode.ERR_ObjectRequired, "x1").WithArguments("x1").WithLocation(8, 13) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_FieldDeclaration_07() + { + string source = +@" +Test(); +bool a = H.TakeOutParam(1, out var x1), b = Test(), c = H.TakeOutParam(2, out var x2); +Test(); + +bool Test() +{ + System.Console.WriteLine(""{0} {1}"", x1, x2); + return false; +} + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 0 +1 0 +1 2").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").Single(); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutField(model, x2Decl, x2Ref); + } + + [Fact] + public void GlobalCode_PropertyDeclaration_01() + { + string source = +@" + +bool b { get; } = H.TakeOutParam(1, out int x1); +H.Dummy(x1); + +object x2; +bool d { get; } = H.TakeOutParam(2, out int x2); + +bool f { get; } = H.TakeOutParam(3, out int x3); +object x3; + +bool h { get; } = H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4)); + +bool x5 { get; } = + H.TakeOutParam(5, out int x5); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (7,45): error CS0102: The type 'Script' already contains a definition for 'x2' + // bool d { get; } = H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(7, 45), + // (10,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(10, 8), + // (13,54): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(13, 54), + // (16,37): error CS0102: The type 'Script' already contains a definition for 'x5' + // H.TakeOutParam(5, out int x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("Script", "x5").WithLocation(16, 37), + // (20,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(20, 17), + // (20,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(20, 21), + // (20,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(20, 25), + // (20,29): error CS0229: Ambiguity between 'x5' and 'x5' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x5").WithArguments("x5", "x5").WithLocation(20, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").Single(); + VerifyModelForOutFieldDuplicate(model, x5Decl, x5Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (3,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool b { get; } = H.TakeOutParam(1, out int x1); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x1").WithLocation(3, 41), + // (7,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool d { get; } = H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x2").WithLocation(7, 41), + // (9,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool f { get; } = H.TakeOutParam(3, out int x3); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x3").WithLocation(9, 41), + // (12,50): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool h { get; } = H.Dummy(H.TakeOutParam(41, out int x4), + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x4").WithLocation(12, 50), + // (13,50): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x4").WithLocation(13, 50), + // (13,54): error CS0128: A local variable named 'x4' is already defined in this scope + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_LocalDuplicate, "x4").WithArguments("x4").WithLocation(13, 54), + // (16,33): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(5, out int x5); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x5").WithLocation(16, 33), + // (20,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(20, 13), + // (20,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(20, 17), + // (20,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(20, 21), + // (20,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(20, 25), + // (20,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(20, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutVar(model, x1Decl); + VerifyModelNotSupported(model, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutVar(model, x2Decl); + VerifyModelNotSupported(model, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutVar(model, x3Decl); + VerifyModelNotSupported(model, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutVar(model, x4Decl[0]); + VerifyModelForOutVarDuplicateInSameScope(model, x4Decl[1]); + VerifyModelNotSupported(model, x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").Single(); + VerifyModelForOutVar(model, x5Decl); + VerifyModelNotSupported(model, x5Ref); + } + } + + [Fact] + public void GlobalCode_PropertyDeclaration_02() + { + string source = +@" + +bool b { get; } = H.TakeOutParam(1, out var x1); +H.Dummy(x1); + +object x2; +bool d { get; } = H.TakeOutParam(2, out var x2); + +bool f { get; } = H.TakeOutParam(3, out var x3); +object x3; + +bool h { get; } = H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4)); + +bool x5 { get; } = + H.TakeOutParam(5, out var x5); + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (7,45): error CS0102: The type 'Script' already contains a definition for 'x2' + // bool d { get; } = H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(7, 45), + // (10,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(10, 8), + // (13,54): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(13, 54), + // (16,37): error CS0102: The type 'Script' already contains a definition for 'x5' + // H.TakeOutParam(5, out var x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("Script", "x5").WithLocation(16, 37), + // (20,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(20, 17), + // (20,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(20, 21), + // (20,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(20, 25), + // (20,29): error CS0229: Ambiguity between 'x5' and 'x5' + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_AmbigMember, "x5").WithArguments("x5", "x5").WithLocation(20, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").Single(); + VerifyModelForOutFieldDuplicate(model, x5Decl, x5Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (3,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool b { get; } = H.TakeOutParam(1, out var x1); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x1").WithLocation(3, 41), + // (7,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool d { get; } = H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x2").WithLocation(7, 41), + // (9,41): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool f { get; } = H.TakeOutParam(3, out var x3); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x3").WithLocation(9, 41), + // (12,50): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // bool h { get; } = H.Dummy(H.TakeOutParam(41, out var x4), + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x4").WithLocation(12, 50), + // (13,50): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x4").WithLocation(13, 50), + // (13,54): error CS0128: A local variable named 'x4' is already defined in this scope + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_LocalDuplicate, "x4").WithArguments("x4").WithLocation(13, 54), + // (16,33): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(5, out var x5); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x5").WithLocation(16, 33), + // (20,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(20, 13), + // (20,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(20, 17), + // (20,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(20, 21), + // (20,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(20, 25), + // (20,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(20, 29) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutVar(model, x1Decl); + VerifyModelNotSupported(model, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutVar(model, x2Decl); + VerifyModelNotSupported(model, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutVar(model, x3Decl); + VerifyModelNotSupported(model, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutVar(model, x4Decl[0]); + VerifyModelForOutVarDuplicateInSameScope(model, x4Decl[1]); + VerifyModelNotSupported(model, x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").Single(); + VerifyModelForOutVar(model, x5Decl); + VerifyModelNotSupported(model, x5Ref); + } + } + + [Fact] + public void GlobalCode_PropertyDeclaration_03() + { + string source = +@" +System.Console.WriteLine(x1); +bool d { get; set; } = H.TakeOutParam(1, out var x1); +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_PropertyDeclaration_04() + { + string source = +@" +static var a = InitA(); +System.Console.WriteLine(x1); +static bool b { get; } = H.TakeOutParam(1, out var x1); +Test(); +static var c = InitB(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +static object InitA() +{ + System.Console.WriteLine(""InitA {0}"", x1); + return null; +} + +static object InitB() +{ + System.Console.WriteLine(""InitB {0}"", x1); + return null; +} + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"InitA 0 +InitB 1 +1 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(4, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_PropertyDeclaration_05() + { + string source = +@" + +bool b { get; } = H.TakeOutParam(1, out var x1); +static var d = x1; + +static void Test() +{ + H.Dummy(x1); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (4,16): error CS0120: An object reference is required for the non-static field, method, or property 'x1' + // static var d = x1; + Diagnostic(ErrorCode.ERR_ObjectRequired, "x1").WithArguments("x1").WithLocation(4, 16), + // (8,13): error CS0120: An object reference is required for the non-static field, method, or property 'x1' + // H.Dummy(x1); + Diagnostic(ErrorCode.ERR_ObjectRequired, "x1").WithArguments("x1").WithLocation(8, 13) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_PropertyDeclaration_06() + { + string source = +@" + +bool b { get; } = H.TakeOutParam(1, out int x1); +static var d = x1; + +static void Test() +{ + H.Dummy(x1); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (4,16): error CS0120: An object reference is required for the non-static field, method, or property 'x1' + // static var d = x1; + Diagnostic(ErrorCode.ERR_ObjectRequired, "x1").WithArguments("x1").WithLocation(4, 16), + // (8,13): error CS0120: An object reference is required for the non-static field, method, or property 'x1' + // H.Dummy(x1); + Diagnostic(ErrorCode.ERR_ObjectRequired, "x1").WithArguments("x1").WithLocation(8, 13) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_EventDeclaration_01() + { + string source = +@" + +event System.Action b = H.TakeOutParam(1, out int x1); +H.Dummy(x1); + +object x2; +event System.Action d = H.TakeOutParam(2, out int x2); + +event System.Action f = H.TakeOutParam(3, out int x3); +object x3; + +event System.Action h = H.Dummy(H.TakeOutParam(41, out int x4), + H.TakeOutParam(42, out int x4)); + +event System.Action x5 = + H.TakeOutParam(5, out int x5); + +event System.Action i = H.TakeOutParam(5, out int x6), + x6; + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5, x6); +} + +class H +{ + public static System.Action Dummy(params object[] x) {return null;} + public static System.Action TakeOutParam(T y, out T x) + { + x = y; + return null; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (7,51): error CS0102: The type 'Script' already contains a definition for 'x2' + // event System.Action d = H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(7, 51), + // (10,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(10, 8), + // (13,52): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(13, 52), + // (16,37): error CS0102: The type 'Script' already contains a definition for 'x5' + // H.TakeOutParam(5, out int x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("Script", "x5").WithLocation(16, 37), + // (19,10): error CS0102: The type 'Script' already contains a definition for 'x6' + // x6; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x6").WithArguments("Script", "x6").WithLocation(19, 10), + // (23,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(23, 17), + // (23,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(23, 21), + // (23,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(23, 25), + // (23,29): error CS0229: Ambiguity between 'x5' and 'x5' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x5").WithArguments("x5", "x5").WithLocation(23, 29), + // (23,33): error CS0229: Ambiguity between 'x6' and 'x6' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x6").WithArguments("x6", "x6").WithLocation(23, 33) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").Single(); + VerifyModelForOutFieldDuplicate(model, x5Decl, x5Ref); + + var x6Decl = GetOutVarDeclarations(tree, "x6").Single(); + var x6Ref = GetReferences(tree, "x6").Single(); + VerifyModelForOutFieldDuplicate(model, x6Decl, x6Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (3,47): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // event System.Action b = H.TakeOutParam(1, out int x1); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x1").WithLocation(3, 47), + // (7,47): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // event System.Action d = H.TakeOutParam(2, out int x2); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x2").WithLocation(7, 47), + // (9,47): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // event System.Action f = H.TakeOutParam(3, out int x3); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x3").WithLocation(9, 47), + // (12,56): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // event System.Action h = H.Dummy(H.TakeOutParam(41, out int x4), + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x4").WithLocation(12, 56), + // (13,48): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x4").WithLocation(13, 48), + // (13,52): error CS0128: A local variable named 'x4' is already defined in this scope + // H.TakeOutParam(42, out int x4)); + Diagnostic(ErrorCode.ERR_LocalDuplicate, "x4").WithArguments("x4").WithLocation(13, 52), + // (16,33): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(5, out int x5); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x5").WithLocation(16, 33), + // (18,47): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // event System.Action i = H.TakeOutParam(5, out int x6), + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "int x6").WithLocation(18, 47), + // (23,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(23, 13), + // (23,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(23, 17), + // (23,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(23, 21), + // (23,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(23, 25), + // (23,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(23, 29), + // (23,33): error CS0103: The name 'x6' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x6").WithArguments("x6").WithLocation(23, 33) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutVar(model, x1Decl); + VerifyModelNotSupported(model, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutVar(model, x2Decl); + VerifyModelNotSupported(model, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutVar(model, x3Decl); + VerifyModelNotSupported(model, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutVar(model, x4Decl[0]); + VerifyModelForOutVarDuplicateInSameScope(model, x4Decl[1]); + VerifyModelNotSupported(model, x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").Single(); + VerifyModelForOutVar(model, x5Decl); + VerifyModelNotSupported(model, x5Ref); + + var x6Decl = GetOutVarDeclarations(tree, "x6").Single(); + var x6Ref = GetReferences(tree, "x6").Single(); + VerifyModelForOutVar(model, x6Decl); + VerifyModelNotSupported(model, x6Ref); + } + } + + [Fact] + public void GlobalCode_EventDeclaration_02() + { + string source = +@" + +event System.Action b = H.TakeOutParam(1, out var x1); +H.Dummy(x1); + +object x2; +event System.Action d = H.TakeOutParam(2, out var x2); + +event System.Action f = H.TakeOutParam(3, out var x3); +object x3; + +event System.Action h = H.Dummy(H.TakeOutParam(41, out var x4), + H.TakeOutParam(42, out var x4)); + +event System.Action x5 = + H.TakeOutParam(5, out var x5); + +event System.Action i = H.TakeOutParam(5, out var x6), + x6; + +void Test() +{ + H.Dummy(x1, x2, x3, x4, x5, x6); +} + +class H +{ + public static System.Action Dummy(params object[] x) {return null;} + public static System.Action TakeOutParam(T y, out T x) + { + x = y; + return null; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (7,51): error CS0102: The type 'Script' already contains a definition for 'x2' + // event System.Action d = H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x2").WithArguments("Script", "x2").WithLocation(7, 51), + // (10,8): error CS0102: The type 'Script' already contains a definition for 'x3' + // object x3; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x3").WithArguments("Script", "x3").WithLocation(10, 8), + // (13,52): error CS0102: The type 'Script' already contains a definition for 'x4' + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x4").WithArguments("Script", "x4").WithLocation(13, 52), + // (16,37): error CS0102: The type 'Script' already contains a definition for 'x5' + // H.TakeOutParam(5, out var x5); + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x5").WithArguments("Script", "x5").WithLocation(16, 37), + // (19,10): error CS0102: The type 'Script' already contains a definition for 'x6' + // x6; + Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "x6").WithArguments("Script", "x6").WithLocation(19, 10), + // (23,17): error CS0229: Ambiguity between 'x2' and 'x2' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x2").WithArguments("x2", "x2").WithLocation(23, 17), + // (23,21): error CS0229: Ambiguity between 'x3' and 'x3' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x3").WithArguments("x3", "x3").WithLocation(23, 21), + // (23,25): error CS0229: Ambiguity between 'x4' and 'x4' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x4").WithArguments("x4", "x4").WithLocation(23, 25), + // (23,29): error CS0229: Ambiguity between 'x5' and 'x5' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x5").WithArguments("x5", "x5").WithLocation(23, 29), + // (23,33): error CS0229: Ambiguity between 'x6' and 'x6' + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_AmbigMember, "x6").WithArguments("x6", "x6").WithLocation(23, 33) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutFieldDuplicate(model, x2Decl, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutFieldDuplicate(model, x3Decl, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutFieldDuplicate(model, x4Decl[0], x4Ref); + VerifyModelForOutFieldDuplicate(model, x4Decl[1], x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").Single(); + VerifyModelForOutFieldDuplicate(model, x5Decl, x5Ref); + + var x6Decl = GetOutVarDeclarations(tree, "x6").Single(); + var x6Ref = GetReferences(tree, "x6").Single(); + VerifyModelForOutFieldDuplicate(model, x6Decl, x6Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (3,47): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // event System.Action b = H.TakeOutParam(1, out var x1); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x1").WithLocation(3, 47), + // (7,47): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // event System.Action d = H.TakeOutParam(2, out var x2); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x2").WithLocation(7, 47), + // (9,47): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // event System.Action f = H.TakeOutParam(3, out var x3); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x3").WithLocation(9, 47), + // (12,56): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // event System.Action h = H.Dummy(H.TakeOutParam(41, out var x4), + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x4").WithLocation(12, 56), + // (13,48): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x4").WithLocation(13, 48), + // (13,52): error CS0128: A local variable named 'x4' is already defined in this scope + // H.TakeOutParam(42, out var x4)); + Diagnostic(ErrorCode.ERR_LocalDuplicate, "x4").WithArguments("x4").WithLocation(13, 52), + // (16,33): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // H.TakeOutParam(5, out var x5); + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x5").WithLocation(16, 33), + // (18,47): error CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers. + // event System.Action i = H.TakeOutParam(5, out var x6), + Diagnostic(ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, "var x6").WithLocation(18, 47), + // (23,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(23, 13), + // (23,17): error CS0103: The name 'x2' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x2").WithArguments("x2").WithLocation(23, 17), + // (23,21): error CS0103: The name 'x3' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x3").WithArguments("x3").WithLocation(23, 21), + // (23,25): error CS0103: The name 'x4' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x4").WithArguments("x4").WithLocation(23, 25), + // (23,29): error CS0103: The name 'x5' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x5").WithArguments("x5").WithLocation(23, 29), + // (23,33): error CS0103: The name 'x6' does not exist in the current context + // H.Dummy(x1, x2, x3, x4, x5, x6); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x6").WithArguments("x6").WithLocation(23, 33) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutVar(model, x1Decl); + VerifyModelNotSupported(model, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutVar(model, x2Decl); + VerifyModelNotSupported(model, x2Ref); + + var x3Decl = GetOutVarDeclarations(tree, "x3").Single(); + var x3Ref = GetReferences(tree, "x3").Single(); + VerifyModelForOutVar(model, x3Decl); + VerifyModelNotSupported(model, x3Ref); + + var x4Decl = GetOutVarDeclarations(tree, "x4").ToArray(); + var x4Ref = GetReferences(tree, "x4").Single(); + Assert.Equal(2, x4Decl.Length); + VerifyModelForOutVar(model, x4Decl[0]); + VerifyModelForOutVarDuplicateInSameScope(model, x4Decl[1]); + VerifyModelNotSupported(model, x4Ref); + + var x5Decl = GetOutVarDeclarations(tree, "x5").Single(); + var x5Ref = GetReferences(tree, "x5").Single(); + VerifyModelForOutVar(model, x5Decl); + VerifyModelNotSupported(model, x5Ref); + + var x6Decl = GetOutVarDeclarations(tree, "x6").Single(); + var x6Ref = GetReferences(tree, "x6").Single(); + VerifyModelForOutVar(model, x6Decl); + VerifyModelNotSupported(model, x6Ref); + } + } + + [Fact] + public void GlobalCode_EventDeclaration_03() + { + string source = +@" +System.Console.WriteLine(x1); +event System.Action d = H.TakeOutParam(1, out var x1); +Test(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +class H +{ + public static System.Action TakeOutParam(T y, out T x) + { + x = y; + return null; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_EventDeclaration_04() + { + string source = +@" +static var a = InitA(); +System.Console.WriteLine(x1); +static event System.Action b = H.TakeOutParam(1, out var x1); +Test(); +static var c = InitB(); + +void Test() +{ + System.Console.WriteLine(x1); +} + +static object InitA() +{ + System.Console.WriteLine(""InitA {0}"", x1); + return null; +} + +static object InitB() +{ + System.Console.WriteLine(""InitB {0}"", x1); + return null; +} + +class H +{ + public static System.Action TakeOutParam(T y, out T x) + { + x = y; + return null; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"InitA 0 +InitB 1 +1 +1").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(4, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_EventDeclaration_05() + { + string source = +@" + +event System.Action b = H.TakeOutParam(1, out var x1); +static var d = x1; + +static void Test() +{ + H.Dummy(x1); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static System.Action TakeOutParam(T y, out T x) + { + x = y; + return null; + } +} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (4,16): error CS0120: An object reference is required for the non-static field, method, or property 'x1' + // static var d = x1; + Diagnostic(ErrorCode.ERR_ObjectRequired, "x1").WithArguments("x1").WithLocation(4, 16), + // (8,13): error CS0120: An object reference is required for the non-static field, method, or property 'x1' + // H.Dummy(x1); + Diagnostic(ErrorCode.ERR_ObjectRequired, "x1").WithArguments("x1").WithLocation(8, 13) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_EventDeclaration_06() + { + string source = +@" + +event System.Action b = H.TakeOutParam(1, out int x1); +static var d = x1; + +static void Test() +{ + H.Dummy(x1); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static System.Action TakeOutParam(T y, out T x) + { + x = y; + return null; + } +} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (4,16): error CS0120: An object reference is required for the non-static field, method, or property 'x1' + // static var d = x1; + Diagnostic(ErrorCode.ERR_ObjectRequired, "x1").WithArguments("x1").WithLocation(4, 16), + // (8,13): error CS0120: An object reference is required for the non-static field, method, or property 'x1' + // H.Dummy(x1); + Diagnostic(ErrorCode.ERR_ObjectRequired, "x1").WithArguments("x1").WithLocation(8, 13) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + [Fact] + public void GlobalCode_EventDeclaration_07() + { + string source = +@" +Test(); +event System.Action a = H.TakeOutParam(1, out var x1), b = Test(), c = H.TakeOutParam(2, out var x2); +Test(); + +System.Action Test() +{ + System.Console.WriteLine(""{0} {1}"", x1, x2); + return null; +} + +class H +{ + public static System.Action TakeOutParam(T y, out T x) + { + x = y; + return null; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + CompileAndVerify(compilation, expectedOutput: +@"0 0 +1 0 +1 2").VerifyDiagnostics(); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").Single(); + VerifyModelForOutField(model, x1Decl, x1Ref); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + var x2Ref = GetReferences(tree, "x2").Single(); + VerifyModelForOutField(model, x2Decl, x2Ref); + } + + [Fact] + public void GlobalCode_DeclaratorArguments_01() + { + string source = +@" + +bool a, b(out var x1); +H.Dummy(x1); + +void Test() +{ + H.Dummy(x1); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (3,10): error CS1528: Expected ; or = (cannot specify constructor arguments in declaration) + // bool a, b(out var x1); + Diagnostic(ErrorCode.ERR_BadVarDecl, "(out var x1").WithLocation(3, 10), + // (3,10): error CS1003: Syntax error, '[' expected + // bool a, b(out var x1); + Diagnostic(ErrorCode.ERR_SyntaxError, "(").WithArguments("[", "(").WithLocation(3, 10), + // (3,11): error CS1525: Invalid expression term 'out' + // bool a, b(out var x1); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "out").WithArguments("out").WithLocation(3, 11), + // (3,11): error CS1026: ) expected + // bool a, b(out var x1); + Diagnostic(ErrorCode.ERR_CloseParenExpected, "out").WithLocation(3, 11), + // (3,11): error CS1003: Syntax error, ',' expected + // bool a, b(out var x1); + Diagnostic(ErrorCode.ERR_SyntaxError, "out").WithArguments(",", "out").WithLocation(3, 11), + // (3,21): error CS1003: Syntax error, ']' expected + // bool a, b(out var x1); + Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments("]", ")").WithLocation(3, 21), + // (3,21): error CS1003: Syntax error, ',' expected + // bool a, b(out var x1); + Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments(",", ")").WithLocation(3, 21), + // (3,19): error CS8197: Cannot infer the type of implicitly-typed out variable 'x1'. + // bool a, b(out var x1); + Diagnostic(ErrorCode.ERR_TypeInferenceFailedForImplicitlyTypedOutVariable, "x1").WithArguments("x1").WithLocation(3, 19) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + AssertContainedInDeclaratorArguments(x1Decl); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (3,10): error CS1528: Expected ; or = (cannot specify constructor arguments in declaration) + // bool a, b(out var x1); + Diagnostic(ErrorCode.ERR_BadVarDecl, "(out var x1").WithLocation(3, 10), + // (3,10): error CS1003: Syntax error, '[' expected + // bool a, b(out var x1); + Diagnostic(ErrorCode.ERR_SyntaxError, "(").WithArguments("[", "(").WithLocation(3, 10), + // (3,11): error CS1525: Invalid expression term 'out' + // bool a, b(out var x1); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "out").WithArguments("out").WithLocation(3, 11), + // (3,11): error CS1003: Syntax error, ',' expected + // bool a, b(out var x1); + Diagnostic(ErrorCode.ERR_SyntaxError, "out").WithArguments(",", "out").WithLocation(3, 11), + // (3,21): error CS1003: Syntax error, ']' expected + // bool a, b(out var x1); + Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments("]", ")").WithLocation(3, 21), + // (8,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(8, 13) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + AssertContainedInDeclaratorArguments(x1Decl); + VerifyModelNotSupported(model, x1Decl, x1Ref); + } + } + + [Fact] + public void GlobalCode_DeclaratorArguments_02() + { + string source = +@" +label: +bool a, b(H.TakeOutParam(1, out var x1)); +H.Dummy(x1); + +void Test() +{ + H.Dummy(x1); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (3,10): error CS1528: Expected ; or = (cannot specify constructor arguments in declaration) + // bool a, b(H.TakeOutParam(1, out var x1)); + Diagnostic(ErrorCode.ERR_BadVarDecl, "(H.TakeOutParam(1, out var x1))").WithLocation(3, 10), + // (3,10): error CS1003: Syntax error, '[' expected + // bool a, b(H.TakeOutParam(1, out var x1)); + Diagnostic(ErrorCode.ERR_SyntaxError, "(").WithArguments("[", "(").WithLocation(3, 10), + // (3,41): error CS1003: Syntax error, ']' expected + // bool a, b(H.TakeOutParam(1, out var x1)); + Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments("]", ";").WithLocation(3, 41), + // (2,1): warning CS0164: This label has not been referenced + // label: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "label").WithLocation(2, 1) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + AssertContainedInDeclaratorArguments(x1Decl); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (3,10): error CS1528: Expected ; or = (cannot specify constructor arguments in declaration) + // bool a, b(H.TakeOutParam(1, out var x1)); + Diagnostic(ErrorCode.ERR_BadVarDecl, "(H.TakeOutParam(1, out var x1))").WithLocation(3, 10), + // (3,10): error CS1003: Syntax error, '[' expected + // bool a, b(H.TakeOutParam(1, out var x1)); + Diagnostic(ErrorCode.ERR_SyntaxError, "(").WithArguments("[", "(").WithLocation(3, 10), + // (3,41): error CS1003: Syntax error, ']' expected + // bool a, b(H.TakeOutParam(1, out var x1)); + Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments("]", ";").WithLocation(3, 41), + // (8,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(8, 13) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + AssertContainedInDeclaratorArguments(x1Decl); + VerifyModelNotSupported(model, x1Decl, x1Ref); + } + } + + [Fact] + public void GlobalCode_DeclaratorArguments_03() + { + string source = +@" + +event System.Action a, b(H.TakeOutParam(1, out var x1)); +H.Dummy(x1); + +void Test() +{ + H.Dummy(x1); +} + +class H +{ + public static System.Action Dummy(params object[] x) {return null;} + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (3,25): error CS1528: Expected ; or = (cannot specify constructor arguments in declaration) + // event System.Action a, b(H.TakeOutParam(1, out var x1)); + Diagnostic(ErrorCode.ERR_BadVarDecl, "(H.TakeOutParam(1, out var x1))").WithLocation(3, 25), + // (3,25): error CS1003: Syntax error, '[' expected + // event System.Action a, b(H.TakeOutParam(1, out var x1)); + Diagnostic(ErrorCode.ERR_SyntaxError, "(").WithArguments("[", "(").WithLocation(3, 25), + // (3,56): error CS1003: Syntax error, ']' expected + // event System.Action a, b(H.TakeOutParam(1, out var x1)); + Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments("]", ";").WithLocation(3, 56) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + AssertContainedInDeclaratorArguments(x1Decl); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (3,25): error CS1528: Expected ; or = (cannot specify constructor arguments in declaration) + // event System.Action a, b(H.TakeOutParam(1, out var x1)); + Diagnostic(ErrorCode.ERR_BadVarDecl, "(H.TakeOutParam(1, out var x1))").WithLocation(3, 25), + // (3,25): error CS1003: Syntax error, '[' expected + // event System.Action a, b(H.TakeOutParam(1, out var x1)); + Diagnostic(ErrorCode.ERR_SyntaxError, "(").WithArguments("[", "(").WithLocation(3, 25), + // (3,56): error CS1003: Syntax error, ']' expected + // event System.Action a, b(H.TakeOutParam(1, out var x1)); + Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments("]", ";").WithLocation(3, 56), + // (8,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(8, 13) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + AssertContainedInDeclaratorArguments(x1Decl); + VerifyModelNotSupported(model, x1Decl, x1Ref); + } + } + + [Fact] + public void GlobalCode_DeclaratorArguments_04() + { + string source = +@" + +fixed bool a[2], b[H.TakeOutParam(1, out var x1)]; +H.Dummy(x1); + +void Test() +{ + H.Dummy(x1); +} + +class H +{ + public static bool Dummy(params object[] x) {return true;} + public static int TakeOutParam(T y, out T x) + { + x = y; + return 3; + } +} +"; + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), + parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (3,18): error CS1642: Fixed size buffer fields may only be members of structs + // fixed bool a[2], b[H.TakeOutParam(1, out var x1)]; + Diagnostic(ErrorCode.ERR_FixedNotInStruct, "b").WithLocation(3, 18), + // (3,20): error CS0133: The expression being assigned to 'b' must be constant + // fixed bool a[2], b[H.TakeOutParam(1, out var x1)]; + Diagnostic(ErrorCode.ERR_NotConstantExpression, "H.TakeOutParam(1, out var x1)").WithArguments("b").WithLocation(3, 20), + // (3,12): error CS1642: Fixed size buffer fields may only be members of structs + // fixed bool a[2], b[H.TakeOutParam(1, out var x1)]; + Diagnostic(ErrorCode.ERR_FixedNotInStruct, "a").WithLocation(3, 12), + // (3,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // fixed bool a[2], b[H.TakeOutParam(1, out var x1)]; + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "a[2]").WithLocation(3, 12) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + AssertContainedInDeclaratorArguments(x1Decl); + VerifyModelForOutField(model, x1Decl, x1Ref); + } + + { + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular); + int[] exclude = new int[] { (int)ErrorCode.ERR_EOFExpected, + (int)ErrorCode.ERR_CloseParenExpected, + (int)ErrorCode.ERR_SemicolonExpected, + (int)ErrorCode.ERR_TypeExpected, + (int)ErrorCode.ERR_NamespaceUnexpected, + (int)ErrorCode.ERR_TupleTooFewElements + }; + + compilation.GetDiagnostics().Where(d => !exclude.Contains(d.Code)).Verify( + // (3,18): error CS1642: Fixed size buffer fields may only be members of structs + // fixed bool a[2], b[H.TakeOutParam(1, out var x1)]; + Diagnostic(ErrorCode.ERR_FixedNotInStruct, "b").WithLocation(3, 18), + // (3,20): error CS0133: The expression being assigned to '.b' must be constant + // fixed bool a[2], b[H.TakeOutParam(1, out var x1)]; + Diagnostic(ErrorCode.ERR_NotConstantExpression, "H.TakeOutParam(1, out var x1)").WithArguments(".b").WithLocation(3, 20), + // (3,12): error CS1642: Fixed size buffer fields may only be members of structs + // fixed bool a[2], b[H.TakeOutParam(1, out var x1)]; + Diagnostic(ErrorCode.ERR_FixedNotInStruct, "a").WithLocation(3, 12), + // (3,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // fixed bool a[2], b[H.TakeOutParam(1, out var x1)]; + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "a[2]").WithLocation(3, 12), + // (8,13): error CS0103: The name 'x1' does not exist in the current context + // H.Dummy(x1); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(8, 13) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(2, x1Ref.Length); + AssertContainedInDeclaratorArguments(x1Decl); + VerifyModelNotSupported(model, x1Decl, x1Ref); + } + } + + [Fact] + public void GlobalCode_RestrictedType_01() + { + string source = +@" + +H.TakeOutParam(out var x1); + +H.TakeOutParam(out System.ArgIterator x2); + +class H +{ + public static void TakeOutParam(out System.ArgIterator x) + { + x = default(System.ArgIterator); + } +} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.GetDeclarationDiagnostics().Verify( + // (9,37): error CS1601: Cannot make reference to variable of type 'ArgIterator' + // public static void TakeOutParam(out System.ArgIterator x) + Diagnostic(ErrorCode.ERR_MethodArgCantBeRefAny, "out System.ArgIterator x").WithArguments("System.ArgIterator").WithLocation(9, 37), + // (5,20): error CS0610: Field or property cannot be of type 'ArgIterator' + // H.TakeOutParam(out System.ArgIterator x2); + Diagnostic(ErrorCode.ERR_FieldCantBeRefAny, "System.ArgIterator").WithArguments("System.ArgIterator").WithLocation(5, 20), + // (3,20): error CS0610: Field or property cannot be of type 'ArgIterator' + // H.TakeOutParam(out var x1); + Diagnostic(ErrorCode.ERR_FieldCantBeRefAny, "var").WithArguments("System.ArgIterator").WithLocation(3, 20) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + VerifyModelForOutField(model, x1Decl); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + VerifyModelForOutField(model, x2Decl); + } + + [Fact] + public void GlobalCode_StaticType_01() + { + string source = +@" + +H.TakeOutParam(out var x1); + +H.TakeOutParam(out StaticType x2); + +class H +{ + public static void TakeOutParam(out StaticType x) + { + x = default(System.ArgIterator); + } +} + +static class StaticType{} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.GetDeclarationDiagnostics().Verify( + // (5,31): error CS0723: Cannot declare a variable of static type 'StaticType' + // H.TakeOutParam(out StaticType x2); + Diagnostic(ErrorCode.ERR_VarDeclIsStaticClass, "x2").WithArguments("StaticType").WithLocation(5, 31), + // (9,24): error CS0721: 'StaticType': static types cannot be used as parameters + // public static void TakeOutParam(out StaticType x) + Diagnostic(ErrorCode.ERR_ParameterIsStaticClass, "TakeOutParam").WithArguments("StaticType").WithLocation(9, 24), + // (3,24): error CS0723: Cannot declare a variable of static type 'StaticType' + // H.TakeOutParam(out var x1); + Diagnostic(ErrorCode.ERR_VarDeclIsStaticClass, "x1").WithArguments("StaticType").WithLocation(3, 24) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + VerifyModelForOutField(model, x1Decl); + + var x2Decl = GetOutVarDeclarations(tree, "x2").Single(); + VerifyModelForOutField(model, x2Decl); + } + + [Fact] + public void GlobalCode_InferenceFailure_01() + { + string source = +@" + +H.TakeOutParam(out var x1, x1); + +class H +{ + public static void TakeOutParam(out int x, long y) + { + x = 1; + } +} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (3,24): error CS7019: Type of 'x1' cannot be inferred since its initializer directly or indirectly refers to the definition. + // H.TakeOutParam(out var x1, x1); + Diagnostic(ErrorCode.ERR_RecursivelyTypedVariable, "x1").WithArguments("x1").WithLocation(3, 24) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + var x1Ref = GetReferences(tree, "x1").ToArray(); + Assert.Equal(1, x1Ref.Length); + VerifyModelForOutField(model, x1Decl, x1Ref); + var x1 = (FieldSymbol)model.GetDeclaredSymbol(x1Decl.VariableDesignation()); + Assert.Equal("var", x1.Type.ToTestDisplayString()); + Assert.True(x1.Type.IsErrorType()); + } + + [Fact] + public void GlobalCode_InferenceFailure_02() + { + string source = +@" + +var a = b; +var b = H.TakeOutParam(out var x1, a); + +class H +{ + public static int TakeOutParam(out int x, long y) + { + x = 1; + return 123; + } +} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (4,5): error CS7019: Type of 'b' cannot be inferred since its initializer directly or indirectly refers to the definition. + // var b = H.TakeOutParam(out var x1, a); + Diagnostic(ErrorCode.ERR_RecursivelyTypedVariable, "b").WithArguments("b").WithLocation(4, 5) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + VerifyModelForOutField(model, x1Decl); + var x1 = (FieldSymbol)model.GetDeclaredSymbol(x1Decl.VariableDesignation()); + Assert.Equal("System.Int32", x1.Type.ToTestDisplayString()); + } + + [Fact] + public void GlobalCode_InferenceFailure_03() + { + string source = +@" + +var a = H.TakeOutParam(out var x1, b); +var b = a; + +class H +{ + public static int TakeOutParam(out int x, long y) + { + x = 1; + return 123; + } +} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (4,5): error CS7019: Type of 'b' cannot be inferred since its initializer directly or indirectly refers to the definition. + // var b = a; + Diagnostic(ErrorCode.ERR_RecursivelyTypedVariable, "b").WithArguments("b").WithLocation(4, 5) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + VerifyModelForOutField(model, x1Decl); + var x1 = (FieldSymbol)model.GetDeclaredSymbol(x1Decl.VariableDesignation()); + Assert.Equal("System.Int32", x1.Type.ToTestDisplayString()); + } + + [Fact] + public void GlobalCode_InferenceFailure_04() + { + string source = +@" + +var a = x1; +var b = H.TakeOutParam(out var x1, a); + +class H +{ + public static int TakeOutParam(out int x, long y) + { + x = 1; + return 123; + } +} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (3,5): error CS7019: Type of 'a' cannot be inferred since its initializer directly or indirectly refers to the definition. + // var a = x1; + Diagnostic(ErrorCode.ERR_RecursivelyTypedVariable, "a").WithArguments("a").WithLocation(3, 5) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + VerifyModelForOutField(model, x1Decl); + var x1 = (FieldSymbol)model.GetDeclaredSymbol(x1Decl.VariableDesignation()); + Assert.Equal("System.Int32", x1.Type.ToTestDisplayString()); + + compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + tree = compilation.SyntaxTrees.Single(); + model = compilation.GetSemanticModel(tree); + x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + + x1 = (FieldSymbol)model.GetDeclaredSymbol(x1Decl.VariableDesignation()); + Assert.Equal("var", x1.Type.ToTestDisplayString()); + Assert.True(x1.Type.IsErrorType()); + + compilation.VerifyDiagnostics( + // (4,32): error CS7019: Type of 'x1' cannot be inferred since its initializer directly or indirectly refers to the definition. + // var b = H.TakeOutParam(out var x1, a); + Diagnostic(ErrorCode.ERR_RecursivelyTypedVariable, "x1").WithArguments("x1").WithLocation(4, 32) + ); + } + + [Fact] + public void GlobalCode_InferenceFailure_05() + { + string source = +@" + +var a = H.TakeOutParam(out var x1, b); +var b = x1; + +class H +{ + public static int TakeOutParam(out int x, long y) + { + x = 1; + return 123; + } +} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (3,32): error CS7019: Type of 'x1' cannot be inferred since its initializer directly or indirectly refers to the definition. + // var a = H.TakeOutParam(out var x1, b); + Diagnostic(ErrorCode.ERR_RecursivelyTypedVariable, "x1").WithArguments("x1").WithLocation(3, 32) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + VerifyModelForOutField(model, x1Decl); + var x1 = (FieldSymbol)model.GetDeclaredSymbol(x1Decl.VariableDesignation()); + Assert.Equal("var", x1.Type.ToTestDisplayString()); + Assert.True(x1.Type.IsErrorType()); + + compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + tree = compilation.SyntaxTrees.Single(); + model = compilation.GetSemanticModel(tree); + + x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + + var bDecl = tree.GetRoot().DescendantNodes().OfType().Where(d => d.Identifier.ValueText == "b").Single(); + var b = (FieldSymbol)model.GetDeclaredSymbol(bDecl); + Assert.True(b.Type.IsErrorType()); + + x1 = (FieldSymbol)model.GetDeclaredSymbol(x1Decl.VariableDesignation()); + Assert.Equal("System.Int32", x1.Type.ToTestDisplayString()); + Assert.False(x1.Type.IsErrorType()); + + compilation.VerifyDiagnostics( + // (4,5): error CS7019: Type of 'b' cannot be inferred since its initializer directly or indirectly refers to the definition. + // var b = x1; + Diagnostic(ErrorCode.ERR_RecursivelyTypedVariable, "b").WithArguments("b").WithLocation(4, 5) + ); + } + + [Fact] + public void GlobalCode_InferenceFailure_06() + { + string source = +@" +H.TakeOutParam(out var x1); + +class H +{ + public static int TakeOutParam(out T x) + { + x = default(T); + return 123; + } +} +"; + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + compilation.VerifyDiagnostics( + // (2,24): error CS8197: Cannot infer the type of implicitly-typed out variable 'x1'. + // H.TakeOutParam(out var x1); + Diagnostic(ErrorCode.ERR_TypeInferenceFailedForImplicitlyTypedOutVariable, "x1").WithArguments("x1").WithLocation(2, 24), + // (2,3): error CS0411: The type arguments for method 'H.TakeOutParam(out T)' cannot be inferred from the usage. Try specifying the type arguments explicitly. + // H.TakeOutParam(out var x1); + Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "TakeOutParam").WithArguments("H.TakeOutParam(out T)").WithLocation(2, 3) + ); + + compilation.GetDeclarationDiagnostics().Verify( + // (2,24): error CS8197: Cannot infer the type of implicitly-typed out variable 'x1'. + // H.TakeOutParam(out var x1); + Diagnostic(ErrorCode.ERR_TypeInferenceFailedForImplicitlyTypedOutVariable, "x1").WithArguments("x1").WithLocation(2, 24) + ); + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + VerifyModelForOutField(model, x1Decl); + var x1 = (FieldSymbol)model.GetDeclaredSymbol(x1Decl.VariableDesignation()); + Assert.Equal("var", x1.Type.ToTestDisplayString()); + Assert.True(x1.Type.IsErrorType()); + } + + [Fact] + public void GlobalCode_AliasInfo_01() + { + string source = +@" +H.TakeOutParam(1, out var x1); + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + Assert.Null(model.GetAliasInfo(x1Decl.Type())); + } + + [Fact] + public void GlobalCode_AliasInfo_02() + { + string source = +@" +using var = System.Int32; + +H.TakeOutParam(1, out var x1); + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + Assert.Equal("var=System.Int32", model.GetAliasInfo(x1Decl.Type()).ToTestDisplayString()); + } + + [Fact] + public void GlobalCode_AliasInfo_03() + { + string source = +@" +using a = System.Int32; + +H.TakeOutParam(1, out a x1); + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + Assert.Equal("a=System.Int32", model.GetAliasInfo(x1Decl.Type()).ToTestDisplayString()); + } + + [Fact] + public void GlobalCode_AliasInfo_04() + { + string source = +@" +H.TakeOutParam(1, out int x1); + +class H +{ + public static bool TakeOutParam(T y, out T x) + { + x = y; + return true; + } +} +"; + + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); + + + var tree = compilation.SyntaxTrees.Single(); + var model = compilation.GetSemanticModel(tree); + + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); + Assert.Null(model.GetAliasInfo(x1Decl.Type())); + } + + private static void VerifyModelForOutField( + SemanticModel model, + DeclarationExpressionSyntax decl, + params IdentifierNameSyntax[] references) + { + VerifyModelForOutField(model, decl, false, references); + } + + private static void VerifyModelForOutFieldDuplicate( + SemanticModel model, + DeclarationExpressionSyntax decl, + params IdentifierNameSyntax[] references) + { + VerifyModelForOutField(model, decl, true, references); + } + + private static void VerifyModelForOutField( + SemanticModel model, + DeclarationExpressionSyntax decl, + bool duplicate, + params IdentifierNameSyntax[] references) + { + var variableDesignationSyntax = GetVariableDesignation(decl); + var symbol = model.GetDeclaredSymbol(variableDesignationSyntax); + Assert.Equal(decl.Identifier().ValueText, symbol.Name); + Assert.Equal(SymbolKind.Field, symbol.Kind); + Assert.Equal(variableDesignationSyntax, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); + Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)variableDesignationSyntax)); + + var symbols = model.LookupSymbols(decl.SpanStart, name: decl.Identifier().ValueText); + var names = model.LookupNames(decl.SpanStart); + + if (duplicate) + { + Assert.True(symbols.Count() > 1); + Assert.Contains(symbol, symbols); + } + else + { + Assert.Same(symbol, symbols.Single()); + } + + Assert.Contains(decl.Identifier().ValueText, names); + + var local = (FieldSymbol)symbol; + var typeSyntax = decl.Type(); + + Assert.True(SyntaxFacts.IsInNamespaceOrTypeContext(typeSyntax)); + Assert.True(SyntaxFacts.IsInTypeOnlyContext(typeSyntax)); + + if (typeSyntax.IsVar && local.Type.IsErrorType()) + { + Assert.Null(model.GetSymbolInfo(typeSyntax).Symbol); + } + else + { + Assert.Equal(local.Type, model.GetSymbolInfo(typeSyntax).Symbol); + } + + var declarator = decl.Ancestors().OfType().FirstOrDefault(); + var inFieldDeclaratorArgumentlist = declarator != null && declarator.Parent.Parent.Kind() != SyntaxKind.LocalDeclarationStatement && + (declarator.ArgumentList?.Contains(decl)).GetValueOrDefault(); + if (inFieldDeclaratorArgumentlist) + { + Assert.Null(model.GetSymbolInfo(decl).Symbol); + Assert.Null(model.GetSymbolInfo(decl).Symbol); + } + else + { + Assert.Same(symbol, model.GetSymbolInfo(decl).Symbol); + Assert.Same(symbol, model.GetSymbolInfo(decl).Symbol); + } + + Assert.Null(model.GetDeclaredSymbol(decl)); + + foreach (var reference in references) + { + var referenceInfo = model.GetSymbolInfo(reference); + symbols = model.LookupSymbols(reference.SpanStart, name: decl.Identifier().ValueText); + + if (duplicate) + { + Assert.Null(referenceInfo.Symbol); + Assert.Contains(symbol, referenceInfo.CandidateSymbols); + Assert.True(symbols.Count() > 1); + Assert.Contains(symbol, symbols); + } + else + { + Assert.Same(symbol, referenceInfo.Symbol); + Assert.Same(symbol, symbols.Single()); + Assert.Equal(local.Type, model.GetTypeInfo(reference).Type); + } + + Assert.True(model.LookupNames(reference.SpanStart).Contains(decl.Identifier().ValueText)); + } + + if (!inFieldDeclaratorArgumentlist) + { + var dataFlowParent = (ExpressionSyntax)decl.Parent.Parent.Parent; + + if (model.IsSpeculativeSemanticModel) + { + Assert.Throws(() => model.AnalyzeDataFlow(dataFlowParent)); + } + else + { + var dataFlow = model.AnalyzeDataFlow(dataFlowParent); + + if (dataFlow.Succeeded) + { + Assert.False(dataFlow.VariablesDeclared.Contains(symbol, ReferenceEqualityComparer.Instance)); + Assert.False(dataFlow.AlwaysAssigned.Contains(symbol, ReferenceEqualityComparer.Instance)); + Assert.False(dataFlow.WrittenInside.Contains(symbol, ReferenceEqualityComparer.Instance)); + Assert.False(dataFlow.DataFlowsIn.Contains(symbol, ReferenceEqualityComparer.Instance)); + Assert.False(dataFlow.ReadInside.Contains(symbol, ReferenceEqualityComparer.Instance)); + Assert.False(dataFlow.DataFlowsOut.Contains(symbol, ReferenceEqualityComparer.Instance)); + Assert.False(dataFlow.ReadOutside.Contains(symbol, ReferenceEqualityComparer.Instance)); + Assert.False(dataFlow.WrittenOutside.Contains(symbol, ReferenceEqualityComparer.Instance)); + } + } + } + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs index ca9c4a19289..21c55055b1e 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs @@ -1049,6 +1049,7 @@ private static void VerifyModelForDeclarationPattern(SemanticModel model, Declar { var symbol = model.GetDeclaredSymbol(decl); Assert.Equal(decl.Identifier.ValueText, symbol.Name); + Assert.Equal(decl, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl)); @@ -1063,6 +1064,9 @@ private static void VerifyModelForDeclarationPattern(SemanticModel model, Declar Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText)); + Assert.True(SyntaxFacts.IsInNamespaceOrTypeContext(decl.Type)); + Assert.True(SyntaxFacts.IsInTypeOnlyContext(decl.Type)); + var type = ((LocalSymbol)symbol).Type; if (!decl.Type.IsVar || !type.IsErrorType()) { @@ -1081,6 +1085,7 @@ private static void VerifyModelForDeclarationPatternDuplicateInSameScope(Semanti { var symbol = model.GetDeclaredSymbol(decl); Assert.Equal(decl.Identifier.ValueText, symbol.Name); + Assert.Equal(decl, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl)); Assert.NotEqual(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single()); @@ -14487,16 +14492,17 @@ private static void VerifyModelNotSupported(SemanticModel model, DeclarationPatt Assert.Null(model.GetDeclaredSymbol(decl)); Assert.Null(model.GetDeclaredSymbol((SyntaxNode)decl)); - Assert.False(model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Any()); - Assert.False(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText)); + var identifierText = decl.Identifier.ValueText; + Assert.False(model.LookupSymbols(decl.SpanStart, name: identifierText).Any()); + Assert.False(model.LookupNames(decl.SpanStart).Contains(identifierText)); Assert.Null(model.GetSymbolInfo(decl.Type).Symbol); foreach (var reference in references) { Assert.Null(model.GetSymbolInfo(reference).Symbol); - Assert.False(model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText).Any()); - Assert.False(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText)); + Assert.False(model.LookupSymbols(reference.SpanStart, name: identifierText).Any()); + Assert.False(model.LookupNames(reference.SpanStart).Contains(identifierText)); } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ScriptSemanticsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ScriptSemanticsTests.cs index b73e06e296c..504c59eb2dd 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/ScriptSemanticsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ScriptSemanticsTests.cs @@ -911,5 +911,51 @@ public void DefineExtensionMethods() // error CS1103: The first parameter of an extension method cannot be of type 'dynamic' Diagnostic(ErrorCode.ERR_BadTypeforThis, "dynamic").WithArguments("dynamic")); } + + [Fact] + [WorkItem(13590, "https://github.com/dotnet/roslyn/issues/13590")] + public void FixedBuffer_01() + { + string source = +@"fixed int x[3]; +"; + var tree = Parse(source, options: TestOptions.Script); + var compilation = CreateCompilationWithMscorlib45(new[] { tree }); + + compilation.VerifyDiagnostics( + // (1,11): error CS1642: Fixed size buffer fields may only be members of structs + // fixed int x[3]; + Diagnostic(ErrorCode.ERR_FixedNotInStruct, "x").WithLocation(1, 11), + // (1,11): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // fixed int x[3]; + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x[3]").WithLocation(1, 11) + ); + } + + [Fact] + [WorkItem(13590, "https://github.com/dotnet/roslyn/issues/13590")] + public void FixedBuffer_02() + { + string source = +@"fixed var x[3] = 1; +"; + var tree = Parse(source, options: TestOptions.Script); + var compilation = CreateCompilationWithMscorlib45(new[] { tree }); + + compilation.VerifyDiagnostics( + // (1,16): error CS1003: Syntax error, ',' expected + // fixed var x[3] = 1; + Diagnostic(ErrorCode.ERR_SyntaxError, "=").WithArguments(",", "=").WithLocation(1, 16), + // (1,11): error CS1642: Fixed size buffer fields may only be members of structs + // fixed var x[3] = 1; + Diagnostic(ErrorCode.ERR_FixedNotInStruct, "x").WithLocation(1, 11), + // (1,7): error CS1663: Fixed size buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double + // fixed var x[3] = 1; + Diagnostic(ErrorCode.ERR_IllegalFixedType, "var").WithLocation(1, 7), + // (1,11): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // fixed var x[3] = 1; + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "x[3]").WithLocation(1, 11) + ); + } } } -- GitLab