diff --git a/BuildAndTest.proj b/BuildAndTest.proj
index 362ce85a3aae0..e6b27797e3c7e 100644
--- a/BuildAndTest.proj
+++ b/BuildAndTest.proj
@@ -96,7 +96,7 @@
-
+
diff --git a/README.md b/README.md
index 48c70c19d5e3b..6b210ee7a61f0 100644
--- a/README.md
+++ b/README.md
@@ -5,16 +5,18 @@
|:--:|:--:|:--:|:--:|:--:|:--:|
|**stabilization**|[](http://dotnet-ci.cloudapp.net/job/roslyn_stabil_win_dbg_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_stabil_win_dbg_unit64/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_stabil_win_rel_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_stabil_win_rel_unit64/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_stabil_determinism/)|
|**master**|[](http://dotnet-ci.cloudapp.net/job/roslyn_master_win_dbg_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_master_win_dbg_unit64/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_master_win_rel_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_master_win_rel_unit64/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_master_determinism/)|
+|**future-stabilization**|[](http://dotnet-ci.cloudapp.net/job/roslyn_future-stabilization_win_dbg_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_future-stabilization_win_dbg_unit64/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_future-stabilization_win_rel_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_future-stabilization_win_rel_unit64/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_future-stabilization_determinism/)|
|**future**|[](http://dotnet-ci.cloudapp.net/job/roslyn_future_win_dbg_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_future_win_dbg_unit64/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_future_win_rel_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_future_win_rel_unit64/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_future_determinism/)|
-
+|**hotfix**|[](http://dotnet-ci.cloudapp.net/job/roslyn_hotfix_win_dbg_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_hotfix_win_dbg_unit64/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_hotfix_win_rel_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_hotfix_win_rel_unit64/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_hotfix_determinism/)|
### Linux/Mac - Unit Tests
||Linux|Mac OSX|
|:--:|:--:|:--:|
|**stabilization**|[](http://dotnet-ci.cloudapp.net/job/roslyn_stabil_lin_dbg_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_stabil_mac_dbg_unit32/)|
|**master**|[](http://dotnet-ci.cloudapp.net/job/roslyn_master_lin_dbg_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_master_mac_dbg_unit32/)|
+|**future-stabilization**|[](http://dotnet-ci.cloudapp.net/job/roslyn_future-stabilization_lin_dbg_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_future-stabilization_mac_dbg_unit32/)|
|**future**|[](http://dotnet-ci.cloudapp.net/job/roslyn_future_lin_dbg_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_future_mac_dbg_unit32/)|
-
+|**hotfix**|[](http://dotnet-ci.cloudapp.net/job/roslyn_hotfix_lin_dbg_unit32/)|[](http://dotnet-ci.cloudapp.net/job/roslyn_hotfix_mac_dbg_unit32/)|
[](https://gitter.im/dotnet/roslyn?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
diff --git a/build/Targets/VSL.Versions.targets b/build/Targets/VSL.Versions.targets
index 355ccaf50db16..55e4c897189d8 100644
--- a/build/Targets/VSL.Versions.targets
+++ b/build/Targets/VSL.Versions.targets
@@ -5,7 +5,7 @@
1.1.37
2.8.5
1.0.27
- $(SystemReflectionMetadataAssemblyVersion)-rc3-23811
+ $(SystemReflectionMetadataAssemblyVersion)-rc2-23826
$(SystemCollectionsImmutableAssemblyVersion)
1.3.3
$(NuGetCommandLineAssemblyVersion)
diff --git a/docs/contributing/Building, Debugging, and Testing on Windows.md b/docs/contributing/Building, Debugging, and Testing on Windows.md
index 653f4e97dedab..e08970c5da84f 100644
--- a/docs/contributing/Building, Debugging, and Testing on Windows.md
+++ b/docs/contributing/Building, Debugging, and Testing on Windows.md
@@ -1,7 +1,20 @@
# Required Software
1. [Visual Studio 2015 with Update 1](http://go.microsoft.com/fwlink/?LinkId=691129). _You need Update 1_.
-2. Visual Studio 2015 Extensibility Tools. If you already installed Visual Studio, choose "Modify" from the Programs and Features control panel, and check "Visual Studio Extensibility".
+2. Visual Studio 2015 Extensibility Tools.
+
+ If you already installed Visual Studio, the Extensibility Tools can be added as follows:
+ - Open Control Panel -> Programs and Features
+ - Select the entry for your installation of Microsoft Visual Studio. Depending on your version, it may appear as follows:
+ - Microsoft Visual Studio Community 2015 with Update 1
+ - Microsoft Visual Studio Professional 2015
+ - Microsoft Visual Studio Enterprise 2015
+ - Press the 'Change' button
+ - In the resulting window, press the 'Modify' button
+ - Check the "Visual Studio Extensibility Tools Update 1" item and press the 'Next' button
+ - Press the 'Update' button
+
+
# Getting the Code
diff --git a/netci.groovy b/netci.groovy
index da9ab477ff927..b1710e37f1fb6 100644
--- a/netci.groovy
+++ b/netci.groovy
@@ -174,16 +174,21 @@ static void addStandardJob(def myJob, String jobName, String branchName, String
}
}
+def branchNames = []
['master', 'future', 'stabilization', 'future-stabilization', 'hotfixes', 'prtest'].each { branchName ->
- // folder("${branchName.substring(0, 6)}")
+ def shortBranchName = branchName.substring(0, 6)
+ def jobBranchName = shortBranchName in branchNames ? branchName : shortBranchName
+ branchNames << jobBranchName
+
+ // folder("${jobBranchName}")
['win', 'linux', 'mac'].each { opsys ->
- // folder("${branchName.substring(0, 6)}/${opsys.substring(0, 3)}")
+ // folder("${jobBranchName}/${opsys.substring(0, 3)}")
['dbg', 'rel'].each { configuration ->
if ((configuration == 'dbg') || ((branchName != 'prtest') && (opsys == 'win'))) {
- // folder("${branchName.substring(0, 6)}/${opsys.substring(0, 3)}/${configuration}")
+ // folder("${jobBranchName}/${opsys.substring(0, 3)}/${configuration}")
['unit32', 'unit64'].each { buildTarget ->
if ((opsys == 'win') || (buildTarget == 'unit32')) {
- def jobName = "roslyn_${branchName.substring(0, 6)}_${opsys.substring(0, 3)}_${configuration}_${buildTarget}"
+ def jobName = "roslyn_${jobBranchName}_${opsys.substring(0, 3)}_${configuration}_${buildTarget}"
def myJob = job(jobName) {
description('')
}
@@ -231,7 +236,7 @@ set TMP=%TEMP%
}
if (branchName != 'prtest') {
- def determinismJobName = "roslyn_${branchName.substring(0, 6)}_determinism"
+ def determinismJobName = "roslyn_${jobBranchName}_determinism"
def determinismJob = job(determinismJobName) {
description('')
}
diff --git a/src/Compilers/CSharp/CscCore/project.lock.json b/src/Compilers/CSharp/CscCore/project.lock.json
index ee58614bc3365..80184c55b42d1 100644
--- a/src/Compilers/CSharp/CscCore/project.lock.json
+++ b/src/Compilers/CSharp/CscCore/project.lock.json
@@ -511,7 +511,7 @@
"lib/DNXCore50/System.Reflection.Extensions.dll": {}
}
},
- "System.Reflection.Metadata/1.2.0-rc3-23811": {
+ "System.Reflection.Metadata/1.2.0-rc2-23826": {
"dependencies": {
"System.Collections": "4.0.0",
"System.Collections.Immutable": "1.1.37",
@@ -1795,7 +1795,7 @@
"lib/DNXCore50/System.Reflection.Extensions.dll": {}
}
},
- "System.Reflection.Metadata/1.2.0-rc3-23811": {
+ "System.Reflection.Metadata/1.2.0-rc2-23826": {
"dependencies": {
"System.Collections": "4.0.0",
"System.Collections.Immutable": "1.1.37",
@@ -3149,7 +3149,7 @@
"lib/DNXCore50/System.Reflection.Extensions.dll": {}
}
},
- "System.Reflection.Metadata/1.2.0-rc3-23811": {
+ "System.Reflection.Metadata/1.2.0-rc2-23826": {
"dependencies": {
"System.Collections": "4.0.0",
"System.Collections.Immutable": "1.1.37",
@@ -4654,7 +4654,7 @@
"lib/DNXCore50/System.Reflection.Extensions.dll": {}
}
},
- "System.Reflection.Metadata/1.2.0-rc3-23811": {
+ "System.Reflection.Metadata/1.2.0-rc2-23826": {
"dependencies": {
"System.Collections": "4.0.0",
"System.Collections.Immutable": "1.1.37",
@@ -7735,11 +7735,11 @@
"runtimes/win8-aot/lib/netcore50/System.Reflection.Extensions.dll"
]
},
- "System.Reflection.Metadata/1.2.0-rc3-23811": {
- "sha512": "gAOQV1dsGyQfQUuzsCYFLMlI6BhfK1/2aA7JGf6gJphaLgjU4dV4hzjbE0iZXgo61VUuda2LtCBrWWZBw5897Q==",
+ "System.Reflection.Metadata/1.2.0-rc2-23826": {
+ "sha512": "iaq5zpluF7mUMd5hFyhmZGyCSzF6glZjvNI2VAhLFQEp8sGA/tROj6NoZL42q6HhoHxi1XyGeoIXPi5hyw0+5w==",
"type": "package",
"files": [
- "System.Reflection.Metadata.1.2.0-rc3-23811.nupkg.sha512",
+ "System.Reflection.Metadata.1.2.0-rc2-23826.nupkg.sha512",
"System.Reflection.Metadata.nuspec",
"ThirdPartyNotices.txt",
"dotnet_library_license.txt",
diff --git a/src/Compilers/CSharp/Portable/Binder/Binder.cs b/src/Compilers/CSharp/Portable/Binder/Binder.cs
index 46a11c8661533..954d6f3cf026a 100644
--- a/src/Compilers/CSharp/Portable/Binder/Binder.cs
+++ b/src/Compilers/CSharp/Portable/Binder/Binder.cs
@@ -760,5 +760,24 @@ internal Binder WithPatternVariablesIfAny(ExpressionSyntax scopeOpt)
Debug.Assert(Locals.Length == 0);
return new PatternVariableBinder(scopeOpt, scopeOpt, this);
}
+
+ internal Binder WithPatternVariablesIfAny(ArgumentListSyntax initializerArgumentListOpt)
+ {
+ Debug.Assert(Locals.Length == 0);
+
+ if (initializerArgumentListOpt == null || initializerArgumentListOpt.Arguments.Count == 0)
+ {
+ return this;
+ }
+
+ return new PatternVariableBinder(initializerArgumentListOpt, initializerArgumentListOpt.Arguments, this);
+ }
+
+ internal BoundExpression WrapWithVariablesIfAny(BoundExpression expression)
+ {
+ return (Locals.Length == 0)
+ ? expression
+ : new BoundSequence(expression.Syntax, Locals, ImmutableArray.Empty, expression, expression.Type) { WasCompilerGenerated = true };
+ }
}
}
diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs
index a3650ee581e5f..89c7a2d524b05 100644
--- a/src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs
+++ b/src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs
@@ -94,7 +94,7 @@ internal static void GetAttributes(
internal CSharpAttributeData GetAttribute(AttributeSyntax node, NamedTypeSymbol boundAttributeType, DiagnosticBag diagnostics)
{
- var boundAttribute = BindAttribute(node, boundAttributeType, diagnostics);
+ var boundAttribute = new PatternVariableBinder(node, this).BindAttribute(node, boundAttributeType, diagnostics);
return GetAttribute(boundAttribute, diagnostics);
}
diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
index af7fb0fd38f3f..ba5bf41681606 100644
--- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
+++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
@@ -339,7 +339,8 @@ internal Binder CreateBinderForParameterDefaultValue(
ParameterSymbol parameter,
EqualsValueClauseSyntax defaultValueSyntax)
{
- return new LocalScopeBinder(this.WithContainingMemberOrLambda(parameter.ContainingSymbol).WithAdditionalFlags(BinderFlags.ParameterDefaultValue));
+ return new LocalScopeBinder(this.WithContainingMemberOrLambda(parameter.ContainingSymbol).WithAdditionalFlags(BinderFlags.ParameterDefaultValue)).
+ WithPatternVariablesIfAny(defaultValueSyntax.Value);
}
internal BoundExpression BindParameterDefaultValue(
@@ -357,7 +358,7 @@ internal BoundExpression BindParameterDefaultValue(
// Always generate the conversion, even if the expression is not convertible to the given type.
// We want the erroneous conversion in the tree.
- return GenerateConversionForAssignment(parameterType, valueBeforeConversion, diagnostics, isDefaultParameter: true);
+ return WrapWithVariablesIfAny(GenerateConversionForAssignment(parameterType, valueBeforeConversion, diagnostics, isDefaultParameter: true));
}
internal BoundExpression BindEnumConstantInitializer(
@@ -2644,12 +2645,8 @@ internal BoundExpression BindConstructorInitializer(
MethodSymbol constructor,
DiagnosticBag diagnostics)
{
- // Handle scoping for possible pattern variables declared in the initializer
- PatternVariableBinder patBinder = (initializerArgumentListOpt != null)
- ? new PatternVariableBinder(initializerArgumentListOpt, initializerArgumentListOpt.Arguments, this)
- : null;
- var result = (patBinder ?? this).BindConstructorInitializerCore(initializerArgumentListOpt, constructor, diagnostics);
- return patBinder?.WrapWithPatternVariables(result) ?? result;
+ var result = BindConstructorInitializerCore(initializerArgumentListOpt, constructor, diagnostics);
+ return WrapWithVariablesIfAny(result);
}
private BoundExpression BindConstructorInitializerCore(
diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs
index 198e84ea9560d..15a0d4bad3ec4 100644
--- a/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs
+++ b/src/Compilers/CSharp/Portable/Binder/Binder_Initializers.cs
@@ -270,7 +270,7 @@ private static BoundFieldInitializer BindFieldInitializer(Binder binder, FieldSy
var collisionDetector = new LocalScopeBinder(binder);
var patternBinder = new PatternVariableBinder(equalsValueClauseNode, equalsValueClauseNode.Value, collisionDetector);
var boundInitValue = patternBinder.BindVariableOrAutoPropInitializer(equalsValueClauseNode, RefKind.None, fieldSymbol.GetFieldType(fieldsBeingBound), initializerDiagnostics);
- boundInitValue = patternBinder.WrapWithPatternVariables(boundInitValue);
+ boundInitValue = patternBinder.WrapWithVariablesIfAny(boundInitValue);
if (isImplicitlyTypedField)
{
diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
index 9e1430cd6b813..492e1b7bda823 100644
--- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
+++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
@@ -3450,7 +3450,7 @@ private BoundExpression BindCatchFilter(CatchFilterClauseSyntax filter, Diagnost
Error(diagnostics, ErrorCode.WRN_FilterIsConstant, filter.FilterExpression);
}
- boundFilter = patternBinder.WrapWithPatternVariables(boundFilter);
+ boundFilter = patternBinder.WrapWithVariablesIfAny(boundFilter);
boundFilter = new BoundSequencePointExpression(filter, boundFilter, boundFilter.Type);
return boundFilter;
}
diff --git a/src/Compilers/CSharp/Portable/Binder/LocalScopeBinder.cs b/src/Compilers/CSharp/Portable/Binder/LocalScopeBinder.cs
index afd9d7b185e72..2c759b176e4fe 100644
--- a/src/Compilers/CSharp/Portable/Binder/LocalScopeBinder.cs
+++ b/src/Compilers/CSharp/Portable/Binder/LocalScopeBinder.cs
@@ -183,7 +183,7 @@ protected ImmutableArray BuildLocals(SyntaxList st
if (decl.Pattern != null)
{
// Patterns from the let statement introduce bindings into the enclosing scope.
- var patterns = PatternVariableFinder.FindPatternVariables(patterns: ImmutableArray.Create(decl.Pattern));
+ var patterns = PatternVariableFinder.FindPatternVariables(decl.Pattern);
foreach (var pattern in patterns)
{
var localSymbol = SourceLocalSymbol.MakeLocal(this.ContainingMemberOrLambda, this, RefKind.None, pattern.Type, pattern.Identifier, LocalDeclarationKind.PatternVariable);
diff --git a/src/Compilers/CSharp/Portable/Binder/PatternVariableBinder.cs b/src/Compilers/CSharp/Portable/Binder/PatternVariableBinder.cs
index 3c78775638904..2021468f72e7a 100644
--- a/src/Compilers/CSharp/Portable/Binder/PatternVariableBinder.cs
+++ b/src/Compilers/CSharp/Portable/Binder/PatternVariableBinder.cs
@@ -11,77 +11,73 @@ namespace Microsoft.CodeAnalysis.CSharp
{
internal sealed class PatternVariableBinder : LocalScopeBinder
{
- private readonly ExpressionSyntax Expression;
- private readonly ImmutableArray Expressions;
- private readonly ImmutableArray Patterns;
+ private readonly CSharpSyntaxNode _node;
+ private readonly ImmutableArray _nodes;
public readonly SyntaxNode Syntax;
internal PatternVariableBinder(SyntaxNode syntax, ImmutableArray expressions, Binder next) : base(next)
{
this.Syntax = syntax;
- this.Expressions = expressions;
+ this._nodes = StaticCast.From(expressions);
}
internal PatternVariableBinder(SyntaxNode syntax, IEnumerable declarations, Binder next) : base(next)
{
this.Syntax = syntax;
- var expressions = ArrayBuilder.GetInstance();
+ var nodes = ArrayBuilder.GetInstance();
foreach (var decl in declarations)
{
var value = decl.Initializer?.Value;
- if (value != null) expressions.Add(value);
+ if (value != null) nodes.Add(value);
}
- this.Expressions = expressions.ToImmutableAndFree();
+ this._nodes = nodes.ToImmutableAndFree();
}
internal PatternVariableBinder(SyntaxNode syntax, IEnumerable arguments, Binder next) : base(next)
{
this.Syntax = syntax;
- var expressions = ArrayBuilder.GetInstance();
+ var nodes = ArrayBuilder.GetInstance();
foreach (var arg in arguments)
{
var value = arg.Expression;
- if (value != null) expressions.Add(value);
+ if (value != null) nodes.Add(value);
}
- this.Expressions = expressions.ToImmutableAndFree();
+ this._nodes = nodes.ToImmutableAndFree();
}
internal PatternVariableBinder(SwitchSectionSyntax syntax, Binder next) : base(next)
{
this.Syntax = syntax;
- var expressions = ArrayBuilder.GetInstance();
- var patterns = ArrayBuilder.GetInstance();
+ var nodes = ArrayBuilder.GetInstance();
foreach (var label in syntax.Labels)
{
var match = label as CasePatternSwitchLabelSyntax;
if (match != null)
{
- patterns.Add(match.Pattern);
+ nodes.Add(match.Pattern);
if (match.WhenClause != null)
{
- expressions.Add(match.WhenClause.Condition);
+ nodes.Add(match.WhenClause.Condition);
}
}
}
- this.Expressions = expressions.ToImmutableAndFree();
- this.Patterns = patterns.ToImmutableAndFree();
+ this._nodes = nodes.ToImmutableAndFree();
}
internal PatternVariableBinder(MatchSectionSyntax syntax, Binder next) : base(next)
{
this.Syntax = syntax;
- this.Patterns = ImmutableArray.Create(syntax.Pattern);
- this.Expressions = syntax.WhenClause != null
- ? ImmutableArray.Create(syntax.Expression, syntax.WhenClause.Condition)
- : ImmutableArray.Create(syntax.Expression)
+ this._nodes = syntax.WhenClause != null
+ ? ImmutableArray.Create(syntax.Pattern, syntax.WhenClause.Condition, syntax.Expression)
+ : ImmutableArray.Create(syntax.Pattern, syntax.Expression)
;
}
internal PatternVariableBinder(ForStatementSyntax syntax, Binder next) : base(next)
{
this.Syntax = syntax;
- var expressions = ArrayBuilder.GetInstance();
+ var expressions = ArrayBuilder.GetInstance();
if (syntax.Declaration != null) foreach(var decl in syntax.Declaration.Variables)
{
var value = decl.Initializer?.Value;
@@ -91,18 +87,35 @@ internal PatternVariableBinder(ForStatementSyntax syntax, Binder next) : base(ne
if (syntax.Initializers != null) expressions.AddRange(syntax.Initializers);
if (syntax.Condition != null) expressions.Add(syntax.Condition);
if (syntax.Incrementors != null) expressions.AddRange(syntax.Incrementors);
- this.Expressions = expressions.ToImmutableAndFree();
+ this._nodes = expressions.ToImmutableAndFree();
}
internal PatternVariableBinder(SyntaxNode syntax, ExpressionSyntax expression, Binder next) : base(next)
{
- this.Expression = expression;
+ this._node = expression;
+ this.Syntax = syntax;
+ }
+
+ internal PatternVariableBinder(AttributeSyntax syntax, Binder next) : base(next)
+ {
this.Syntax = syntax;
+
+ if (syntax.ArgumentList?.Arguments.Count > 0)
+ {
+ var expressions = ArrayBuilder.GetInstance(syntax.ArgumentList.Arguments.Count);
+
+ foreach (var argument in syntax.ArgumentList.Arguments)
+ {
+ expressions.Add(argument.Expression);
+ }
+
+ this._nodes = expressions.ToImmutableAndFree();
+ }
}
protected override ImmutableArray BuildLocals()
{
- var patterns = PatternVariableFinder.FindPatternVariables(Expression, Expressions, this.Patterns);
+ var patterns = PatternVariableFinder.FindPatternVariables(_node, _nodes);
var builder = ArrayBuilder.GetInstance();
foreach (var pattern in patterns)
{
@@ -111,12 +124,5 @@ protected override ImmutableArray BuildLocals()
patterns.Free();
return builder.ToImmutableAndFree();
}
-
- internal BoundExpression WrapWithPatternVariables(BoundExpression expression)
- {
- return (Locals.Length == 0)
- ? expression
- : new BoundSequence(expression.Syntax, Locals, ImmutableArray.Empty, expression, expression.Type);
- }
}
}
diff --git a/src/Compilers/CSharp/Portable/Binder/PatternVariableFinder.cs b/src/Compilers/CSharp/Portable/Binder/PatternVariableFinder.cs
index 5ff7c377feed5..f08102d642678 100644
--- a/src/Compilers/CSharp/Portable/Binder/PatternVariableFinder.cs
+++ b/src/Compilers/CSharp/Portable/Binder/PatternVariableFinder.cs
@@ -13,48 +13,42 @@ namespace Microsoft.CodeAnalysis.CSharp
class PatternVariableFinder : CSharpSyntaxWalker
{
ArrayBuilder declarationPatterns;
- ArrayBuilder expressionsToVisit = ArrayBuilder.GetInstance();
+ ArrayBuilder nodesToVisit = ArrayBuilder.GetInstance();
internal static ArrayBuilder FindPatternVariables(
- ExpressionSyntax expression = null,
- ImmutableArray expressions = default(ImmutableArray),
- ImmutableArray patterns = default(ImmutableArray))
+ CSharpSyntaxNode node = null,
+ ImmutableArray nodes = default(ImmutableArray))
{
var finder = s_poolInstance.Allocate();
finder.declarationPatterns = ArrayBuilder.GetInstance();
- // push expressions to be visited onto a stack
- var expressionsToVisit = finder.expressionsToVisit;
- if (expression != null) expressionsToVisit.Add(expression);
- if (!expressions.IsDefaultOrEmpty)
+ // push nodes to be visited onto a stack
+ var nodesToVisit = finder.nodesToVisit;
+ if (node != null) nodesToVisit.Add(node);
+ if (!nodes.IsDefaultOrEmpty)
{
- foreach (var subExpression in expressions)
+ foreach (var subExpression in nodes)
{
- if (subExpression != null) expressionsToVisit.Add(subExpression);
+ if (subExpression != null) nodesToVisit.Add(subExpression);
}
}
- finder.VisitExpressions();
- if (!patterns.IsDefaultOrEmpty)
- {
- foreach (var pattern in patterns)
- {
- finder.Visit(pattern);
- }
- }
+ nodesToVisit.ReverseContents();
+
+ finder.VisitNodes();
var result = finder.declarationPatterns;
finder.declarationPatterns = null;
- Debug.Assert(finder.expressionsToVisit.Count == 0);
+ Debug.Assert(finder.nodesToVisit.Count == 0);
s_poolInstance.Free(finder);
return result;
}
- private void VisitExpressions()
+ private void VisitNodes()
{
- while (expressionsToVisit.Count != 0)
+ while (nodesToVisit.Count != 0)
{
- var e = expressionsToVisit[expressionsToVisit.Count - 1];
- expressionsToVisit.RemoveLast();
+ var e = nodesToVisit[nodesToVisit.Count - 1];
+ nodesToVisit.RemoveLast();
Visit(e);
}
}
@@ -85,16 +79,16 @@ public override void VisitQueryExpression(QueryExpressionSyntax node)
public override void VisitBinaryExpression(BinaryExpressionSyntax node)
{
- expressionsToVisit.Add(node.Right);
- expressionsToVisit.Add(node.Left);
+ nodesToVisit.Add(node.Right);
+ nodesToVisit.Add(node.Left);
}
public override void VisitPostfixUnaryExpression(PostfixUnaryExpressionSyntax node)
{
- expressionsToVisit.Add(node.Operand);
+ nodesToVisit.Add(node.Operand);
}
public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
{
- expressionsToVisit.Add(node.Operand);
+ nodesToVisit.Add(node.Operand);
}
public override void VisitMatchExpression(MatchExpressionSyntax node)
{
diff --git a/src/Compilers/CSharp/Portable/Binder/SwitchBinder_BindPatternSwitch.cs b/src/Compilers/CSharp/Portable/Binder/SwitchBinder_BindPatternSwitch.cs
index b405b62ff51b0..cac936332bf0d 100644
--- a/src/Compilers/CSharp/Portable/Binder/SwitchBinder_BindPatternSwitch.cs
+++ b/src/Compilers/CSharp/Portable/Binder/SwitchBinder_BindPatternSwitch.cs
@@ -16,7 +16,8 @@ internal partial class SwitchBinder
{
private BoundPatternSwitchStatement BindPatternSwitch(SwitchStatementSyntax node, DiagnosticBag diagnostics)
{
- var boundSwitchExpression = BindValue(node.Expression, diagnostics, BindValueKind.RValue);
+ // See BindSwitchExpression for an explanation why we should use Next binder here.
+ var boundSwitchExpression = this.Next.BindValue(node.Expression, diagnostics, BindValueKind.RValue);
// TODO: any constraints on a switch expression must be enforced here. For example,
// it must have a type (not be target-typed, lambda, null, etc)
diff --git a/src/Compilers/CSharp/Portable/BoundTree/Expression.cs b/src/Compilers/CSharp/Portable/BoundTree/Expression.cs
index 5c015833b52b2..91ee254823ca8 100644
--- a/src/Compilers/CSharp/Portable/BoundTree/Expression.cs
+++ b/src/Compilers/CSharp/Portable/BoundTree/Expression.cs
@@ -706,7 +706,7 @@ Semantics.ConversionKind IConversionExpression.ConversionKind
return Semantics.ConversionKind.CSharp;
default:
- throw ExceptionUtilities.UnexpectedValue(this.ConversionKind);
+ return Semantics.ConversionKind.Invalid;
}
}
}
diff --git a/src/Compilers/CSharp/Portable/CSharpCompilationOptions.cs b/src/Compilers/CSharp/Portable/CSharpCompilationOptions.cs
index e12be547b1a8b..383df9726d301 100644
--- a/src/Compilers/CSharp/Portable/CSharpCompilationOptions.cs
+++ b/src/Compilers/CSharp/Portable/CSharpCompilationOptions.cs
@@ -520,6 +520,8 @@ protected override CompilationOptions CommonWithFeatures(ImmutableArray
internal override void ValidateOptions(ArrayBuilder builder)
{
+ ValidateOptions(builder, MessageProvider.Instance);
+
// /main & /target:{library|netmodule|winmdobj}
if (this.MainTypeName != null)
{
@@ -581,24 +583,6 @@ internal override void ValidateOptions(ArrayBuilder builder)
// TODO: add check for
// (kind == 'arm' || kind == 'appcontainer' || kind == 'winmdobj') &&
// (version >= "6.2")
-
- if (!CryptoPublicKey.IsEmpty)
- {
- if (CryptoKeyFile != null)
- {
- builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_MutuallyExclusiveOptions, nameof(CryptoPublicKey), nameof(CryptoKeyFile)));
- }
-
- if (CryptoKeyContainer != null)
- {
- builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_MutuallyExclusiveOptions, nameof(CryptoPublicKey), nameof(CryptoKeyContainer)));
- }
- }
-
- if (PublicSign && DelaySign == true)
- {
- builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_MutuallyExclusiveOptions, nameof(PublicSign), nameof(DelaySign)));
- }
}
public bool Equals(CSharpCompilationOptions other)
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
index b5bde2a1091b1..0b47c5cbf5533 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
+++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
@@ -7261,6 +7261,15 @@ internal static string ERR_PermissionSetAttributeInvalidFile {
}
}
+ ///
+ /// Looks up a localized string similar to An error occurred while writing the output file: {0}.
+ ///
+ internal static string ERR_PeWritingFailure {
+ get {
+ return ResourceManager.GetString("ERR_PeWritingFailure", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Neither 'is' nor 'as' is valid on pointer types.
///
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index bfe3c87f26992..5226a66ef158c 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -4849,6 +4849,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
An 'else' clause is required when a 'when' clause is present.
+
+ An error occurred while writing the output file: {0}
+
{ or ; or => expected
diff --git a/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs b/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs
index d81a620d99607..2d1d01e7f9c79 100644
--- a/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs
+++ b/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs
@@ -1118,6 +1118,12 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable ar
keyFileSearchPaths.Add(outputDirectory);
}
+ // Public sign doesn't use the legacy search path settings
+ if (publicSign && !string.IsNullOrWhiteSpace(keyFileSetting))
+ {
+ keyFileSetting = ParseGenericPathToFile(keyFileSetting, diagnostics, baseDirectory);
+ }
+
var parsedFeatures = CompilerOptionParseUtilities.ParseFeatures(features);
string compilationName;
diff --git a/src/Compilers/CSharp/Portable/Compilation/AttributeSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/AttributeSemanticModel.cs
index cf4e0605e046c..ec53f621fdd93 100644
--- a/src/Compilers/CSharp/Portable/Compilation/AttributeSemanticModel.cs
+++ b/src/Compilers/CSharp/Portable/Compilation/AttributeSemanticModel.cs
@@ -28,7 +28,7 @@ private AttributeSemanticModel(CSharpCompilation compilation, AttributeSyntax sy
public static AttributeSemanticModel Create(CSharpCompilation compilation, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder)
{
var executableBinder = new ExecutableCodeBinder(syntax, attributeType, rootBinder);
- return new AttributeSemanticModel(compilation, syntax, attributeType, aliasOpt, new LocalScopeBinder(executableBinder));
+ return new AttributeSemanticModel(compilation, syntax, attributeType, aliasOpt, new PatternVariableBinder(syntax, executableBinder));
}
///
diff --git a/src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs
index 71c27c6e62c9c..3327c376884ed 100644
--- a/src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs
+++ b/src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs
@@ -194,6 +194,7 @@ private BoundEqualsValue BindEqualsValue(Binder binder, EqualsValueClauseSyntax
}
if (result != null)
{
+ result = binder.WrapWithVariablesIfAny(result);
return new BoundFieldEqualsValue(equalsValue, field, result);
}
break;
@@ -205,6 +206,7 @@ private BoundEqualsValue BindEqualsValue(Binder binder, EqualsValueClauseSyntax
BoundExpression result = binder.BindVariableOrAutoPropInitializer(equalsValue, RefKind.None, property.Type, diagnostics);
if (result != null)
{
+ result = binder.WrapWithVariablesIfAny(result);
return new BoundPropertyEqualsValue(equalsValue, property, result);
}
break;
diff --git a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs
index 1120d46e783c2..dbbfcc928a1e2 100644
--- a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs
+++ b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs
@@ -141,10 +141,14 @@ internal sealed override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSeman
private Binder GetEnclosingBinder(CSharpSyntaxNode node, int position)
{
AssertPositionAdjusted(position);
+ return GetEnclosingBinder(node, position, RootBinder, _root).WithAdditionalFlags(GetSemanticModelBinderFlags());
+ }
- if (node == _root)
+ private static Binder GetEnclosingBinder(CSharpSyntaxNode node, int position, Binder rootBinder, CSharpSyntaxNode root)
+ {
+ if (node == root)
{
- return RootBinder;
+ return rootBinder;
}
ExpressionSyntax typeOfArgument = null;
@@ -166,7 +170,7 @@ private Binder GetEnclosingBinder(CSharpSyntaxNode node, int position)
{
if (LookupPosition.IsInStatementScope(position, stmt))
{
- binder = RootBinder.GetBinder(current);
+ binder = rootBinder.GetBinder(current);
if (binder != null)
{
@@ -178,27 +182,27 @@ private Binder GetEnclosingBinder(CSharpSyntaxNode node, int position)
{
if (LookupPosition.IsInCatchBlockScope(position, (CatchClauseSyntax)current))
{
- binder = RootBinder.GetBinder(current);
+ binder = rootBinder.GetBinder(current);
}
}
else if (current.Kind() == SyntaxKind.CatchFilterClause)
{
if (LookupPosition.IsInCatchFilterScope(position, (CatchFilterClauseSyntax)current))
{
- binder = RootBinder.GetBinder(current);
+ binder = rootBinder.GetBinder(current);
}
}
else if (current.IsAnonymousFunction())
{
if (LookupPosition.IsInAnonymousFunctionOrQuery(position, current))
{
- binder = RootBinder.GetBinder(current);
+ binder = rootBinder.GetBinder(current);
// This should only happen in error scenarios. For example, C# does not allow array rank
// specifiers in types, (e.g. int[1] x;), but the syntax model does. In order to construct
// an appropriate binder chain for the anonymous method body, we need to construct an
// ExecutableCodeBinder.
- if (binder == null && unexpectedAnonymousFunction == null)
+ if (binder == null && unexpectedAnonymousFunction == null && current != root)
{
unexpectedAnonymousFunction = current;
}
@@ -218,28 +222,28 @@ private Binder GetEnclosingBinder(CSharpSyntaxNode node, int position)
{
if (LookupPosition.IsInSwitchSectionScope(position, (SwitchSectionSyntax)current))
{
- binder = RootBinder.GetBinder(current);
+ binder = rootBinder.GetBinder(current);
}
}
else if (current.Kind() == SyntaxKind.ArrowExpressionClause && current.Parent?.Kind() == SyntaxKind.LocalFunctionStatement)
{
- binder = RootBinder.GetBinder(current);
+ binder = rootBinder.GetBinder(current);
}
else
{
// If this ever breaks, make sure that all callers of
// CanHaveAssociatedLocalBinder are in sync.
Debug.Assert(!current.CanHaveAssociatedLocalBinder() ||
- (current == _root && current.Kind() == SyntaxKind.ArrowExpressionClause));
+ (current == root && current.Kind() == SyntaxKind.ArrowExpressionClause));
}
- if (current == _root)
+ if (current == root)
{
break;
}
}
- binder = binder ?? RootBinder;
+ binder = binder ?? rootBinder;
Debug.Assert(binder != null);
if (typeOfArgument != null && !typeOfEncounteredBeforeUnexpectedAnonymousFunction)
@@ -266,11 +270,23 @@ private Binder GetEnclosingBinder(CSharpSyntaxNode node, int position)
binder = new TypeofBinder(typeOfArgument, binder);
}
- return binder.WithAdditionalFlags(GetSemanticModelBinderFlags());
+ return binder;
}
private static Binder AdjustBinderForPositionWithinStatement(int position, Binder binder, StatementSyntax stmt)
{
+ switch (stmt.Kind())
+ {
+ case SyntaxKind.SwitchStatement:
+ var switchStmt = (SwitchStatementSyntax)stmt;
+ if (LookupPosition.IsBetweenTokens(position, switchStmt.OpenParenToken, switchStmt.OpenBraceToken))
+ {
+ binder = binder.Next;
+ Debug.Assert(binder is PatternVariableBinder);
+ }
+ break;
+ }
+
return binder;
}
@@ -1392,78 +1408,7 @@ private static Binder GetLambdaEnclosingBinder(int position, CSharpSyntaxNode st
Debug.Assert(containingLambda.IsAnonymousFunction());
Debug.Assert(LookupPosition.IsInAnonymousFunctionOrQuery(position, containingLambda));
- var current = startingNode;
- while (current != containingLambda)
- {
- Debug.Assert(current != null);
-
- StatementSyntax stmt = current as StatementSyntax;
- if (stmt != null)
- {
- if (LookupPosition.IsInStatementScope(position, stmt))
- {
- Binder binder = lambdaBinder.GetBinder(current);
- if (binder != null)
- {
- return AdjustBinderForPositionWithinStatement(position, binder, stmt);
- }
- }
- }
- else if (current.Kind() == SyntaxKind.CatchClause)
- {
- if (LookupPosition.IsInCatchBlockScope(position, (CatchClauseSyntax)current))
- {
- Binder binder = lambdaBinder.GetBinder(current);
- if (binder != null)
- {
- return binder;
- }
- }
- }
- else if (current.Kind() == SyntaxKind.CatchFilterClause)
- {
- if (LookupPosition.IsInCatchFilterScope(position, (CatchFilterClauseSyntax)current))
- {
- Binder binder = lambdaBinder.GetBinder(current);
- if (binder != null)
- {
- return binder;
- }
- }
- }
- else if (current.IsAnonymousFunction())
- {
- if (LookupPosition.IsInAnonymousFunctionOrQuery(position, current))
- {
- Binder binder = lambdaBinder.GetBinder(current);
- if (binder != null)
- {
- return binder;
- }
- }
- }
- else if (current.Kind() == SyntaxKind.SwitchSection)
- {
- if (LookupPosition.IsInSwitchSectionScope(position, (SwitchSectionSyntax)current))
- {
- Binder binder = lambdaBinder.GetBinder(current);
- if (binder != null)
- {
- return binder;
- }
- }
- }
- else
- {
- // If this ever breaks, make sure that all callers of
- // CanHaveAssociatedLocalBinder are in sync.
- Debug.Assert(!current.CanHaveAssociatedLocalBinder());
- }
-
- current = current.ParentOrStructuredTriviaParent;
- }
-
- return lambdaBinder;
+ return GetEnclosingBinder(startingNode, position, lambdaBinder, containingLambda);
}
///
diff --git a/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs
index a250584c8654d..9b6ca91c43d1f 100644
--- a/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs
+++ b/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs
@@ -927,7 +927,7 @@ private MemberSemanticModel CreateMemberModel(CSharpSyntaxNode node)
variableDecl, //pass in the entire field initializer to permit region analysis.
fieldSymbol,
//if we're in regular C#, then insert an extra binder to perform field initialization checks
- GetFieldOrPropertyInitializerBinder(fieldSymbol, outer));
+ GetFieldOrPropertyInitializerBinder(fieldSymbol, outer, variableDecl.Initializer?.Value));
}
case SyntaxKind.PropertyDeclaration:
@@ -938,7 +938,7 @@ private MemberSemanticModel CreateMemberModel(CSharpSyntaxNode node)
this.Compilation,
propertyDecl,
propertySymbol,
- GetFieldOrPropertyInitializerBinder(propertySymbol.BackingField, outer));
+ GetFieldOrPropertyInitializerBinder(propertySymbol.BackingField, outer, propertyDecl.Initializer?.Value));
}
case SyntaxKind.Parameter:
@@ -969,7 +969,7 @@ private MemberSemanticModel CreateMemberModel(CSharpSyntaxNode node)
this.Compilation,
enumDecl,
enumSymbol,
- GetFieldOrPropertyInitializerBinder(enumSymbol, outer));
+ GetFieldOrPropertyInitializerBinder(enumSymbol, outer, enumDecl.EqualsValue?.Value));
}
default:
throw ExceptionUtilities.UnexpectedValue(node.Parent.Kind());
@@ -1043,7 +1043,9 @@ private MemberSemanticModel CreateMemberModel(CSharpSyntaxNode node)
(ConstructorInitializerSyntax)node,
constructorSymbol,
//insert an extra binder to perform constructor initialization checks
- outer.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.ConstructorInitializer, constructorSymbol));
+ // Handle scoping for possible pattern variables declared in the initializer
+ outer.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.ConstructorInitializer, constructorSymbol).
+ WithPatternVariablesIfAny(((ConstructorInitializerSyntax)node).ArgumentList));
}
case SyntaxKind.Attribute:
@@ -1085,7 +1087,7 @@ private SourceMemberFieldSymbol GetDeclaredFieldSymbol(VariableDeclaratorSyntax
return null;
}
- private Binder GetFieldOrPropertyInitializerBinder(FieldSymbol symbol, Binder outer)
+ private Binder GetFieldOrPropertyInitializerBinder(FieldSymbol symbol, Binder outer, ExpressionSyntax valueSyntaxOpt)
{
BinderFlags flags = BinderFlags.None;
@@ -1095,7 +1097,13 @@ private Binder GetFieldOrPropertyInitializerBinder(FieldSymbol symbol, Binder ou
flags |= BinderFlags.FieldInitializer;
}
- return new LocalScopeBinder(outer).WithAdditionalFlagsAndContainingMemberOrLambda(flags, symbol);
+ Binder result = new LocalScopeBinder(outer).WithAdditionalFlagsAndContainingMemberOrLambda(flags, symbol);
+ if (valueSyntaxOpt != null)
+ {
+ result = result.WithPatternVariablesIfAny(valueSyntaxOpt);
+ }
+
+ return result;
}
private static bool IsMemberDeclaration(CSharpSyntaxNode node)
diff --git a/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs b/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
index 73a594caa8f0a..91b7f73ab1414 100644
--- a/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
+++ b/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
@@ -1726,7 +1726,9 @@ internal static BoundExpression BindConstructorInitializer(MethodSymbol construc
}
// wrap in ConstructorInitializerBinder for appropriate errors
- Binder initializerBinder = outerBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.ConstructorInitializer, constructor);
+ // Handle scoping for possible pattern variables declared in the initializer
+ Binder initializerBinder = outerBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.ConstructorInitializer, constructor).
+ WithPatternVariablesIfAny(initializerArgumentListOpt);
return initializerBinder.BindConstructorInitializer(initializerArgumentListOpt, constructor, diagnostics);
}
diff --git a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpDefinitionMap.cs b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpDefinitionMap.cs
index 702a5a061755b..897fa039fe7a0 100644
--- a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpDefinitionMap.cs
+++ b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpDefinitionMap.cs
@@ -1,17 +1,14 @@
// 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.Linq;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Reflection.Metadata;
-using System.Reflection.Metadata.Ecma335;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.Emit;
-using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Emit
{
@@ -36,6 +33,8 @@ public CSharpDefinitionMap(
_metadataDecoder = metadataDecoder;
}
+ internal override CommonMessageProvider MessageProvider => CSharp.MessageProvider.Instance;
+
internal bool TryGetAnonymousTypeName(NamedTypeSymbol template, out string name, out int index)
{
return this.mapToPrevious.TryGetAnonymousTypeName(template, out name, out index);
diff --git a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpSymbolMatcher.cs b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpSymbolMatcher.cs
index 931ad582ea633..4da73640c543d 100644
--- a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpSymbolMatcher.cs
+++ b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpSymbolMatcher.cs
@@ -402,15 +402,10 @@ public override Symbol VisitAssembly(AssemblySymbol symbol)
return _otherAssembly;
}
- // find a referenced assembly with the exactly same source identity:
+ // find a referenced assembly with the exactly same identity:
foreach (var otherReferencedAssembly in _otherAssembly.Modules[0].ReferencedAssemblySymbols)
{
- var identity = symbol.Identity;
- var otherIdentity = otherReferencedAssembly.Identity;
-
- if (AssemblyIdentityComparer.SimpleNameComparer.Equals(identity.Name, otherIdentity.Name) &&
- (symbol.AssemblyVersionPattern ?? symbol.Identity.Version).Equals(otherReferencedAssembly.AssemblyVersionPattern ?? otherReferencedAssembly.Identity.Version) &&
- AssemblyIdentity.EqualIgnoringNameAndVersion(identity, otherIdentity))
+ if (symbol.Identity.Equals(otherReferencedAssembly.Identity))
{
return otherReferencedAssembly;
}
diff --git a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/EmitHelpers.cs b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/EmitHelpers.cs
index f0487a888ce05..6b30d222e93c0 100644
--- a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/EmitHelpers.cs
+++ b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/EmitHelpers.cs
@@ -35,7 +35,7 @@ internal static EmitDifferenceResult EmitDifference(
}
catch (BadImageFormatException)
{
- // TODO (https://github.com/dotnet/roslyn/issues/8910):
+ // TODO:
// return MakeEmitResult(success: false, diagnostics: ..., baseline: null);
throw;
}
@@ -47,25 +47,15 @@ internal static EmitDifferenceResult EmitDifference(
var serializationProperties = compilation.ConstructModuleSerializationProperties(emitOptions, runtimeMDVersion, moduleVersionId);
var manifestResources = SpecializedCollections.EmptyEnumerable();
- PEDeltaAssemblyBuilder moduleBeingBuilt;
- try
- {
- moduleBeingBuilt = new PEDeltaAssemblyBuilder(
- compilation.SourceAssembly,
- emitOptions: emitOptions,
- outputKind: compilation.Options.OutputKind,
- serializationProperties: serializationProperties,
- manifestResources: manifestResources,
- previousGeneration: baseline,
- edits: edits,
- isAddedSymbol: isAddedSymbol);
- }
- catch (NotSupportedException)
- {
- // TODO: better error code (https://github.com/dotnet/roslyn/issues/8910)
- diagnostics.Add(ErrorCode.ERR_ModuleEmitFailure, NoLocation.Singleton, compilation.AssemblyName);
- return new EmitDifferenceResult(success: false, diagnostics: diagnostics.ToReadOnlyAndFree(), baseline: null);
- }
+ var moduleBeingBuilt = new PEDeltaAssemblyBuilder(
+ compilation.SourceAssembly,
+ emitOptions: emitOptions,
+ outputKind: compilation.Options.OutputKind,
+ serializationProperties: serializationProperties,
+ manifestResources: manifestResources,
+ previousGeneration: baseline,
+ edits: edits,
+ isAddedSymbol: isAddedSymbol);
if (testData != null)
{
diff --git a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/PEDeltaAssemblyBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/PEDeltaAssemblyBuilder.cs
index dae2c36ad454a..cb392ea6eca4d 100644
--- a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/PEDeltaAssemblyBuilder.cs
+++ b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/PEDeltaAssemblyBuilder.cs
@@ -102,11 +102,10 @@ private EmitBaseline.MetadataSymbols GetOrCreateMetadataSymbols(EmitBaseline ini
// We need to transfer the references from the current source compilation but don't need its syntax trees.
var metadataCompilation = compilation.RemoveAllSyntaxTrees();
- ImmutableDictionary assemblyReferenceIdentityMap;
- var metadataAssembly = metadataCompilation.GetBoundReferenceManager().CreatePEAssemblyForAssemblyMetadata(AssemblyMetadata.Create(originalMetadata), MetadataImportOptions.All, out assemblyReferenceIdentityMap);
+ var metadataAssembly = metadataCompilation.GetBoundReferenceManager().CreatePEAssemblyForAssemblyMetadata(AssemblyMetadata.Create(originalMetadata), MetadataImportOptions.All);
var metadataDecoder = new MetadataDecoder(metadataAssembly.PrimaryModule);
var metadataAnonymousTypes = GetAnonymousTypeMapFromMetadata(originalMetadata.MetadataReader, metadataDecoder);
- var metadataSymbols = new EmitBaseline.MetadataSymbols(metadataAnonymousTypes, metadataDecoder, assemblyReferenceIdentityMap);
+ var metadataSymbols = new EmitBaseline.MetadataSymbols(metadataAnonymousTypes, metadataDecoder);
return InterlockedOperations.Initialize(ref initialBaseline.LazyMetadataSymbols, metadataSymbols);
}
diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/AssemblyReference.cs b/src/Compilers/CSharp/Portable/Emitter/Model/AssemblyReference.cs
index a2696330f4ac4..ffc07b2bebb50 100644
--- a/src/Compilers/CSharp/Portable/Emitter/Model/AssemblyReference.cs
+++ b/src/Compilers/CSharp/Portable/Emitter/Model/AssemblyReference.cs
@@ -22,7 +22,6 @@ internal AssemblyReference(AssemblySymbol assemblySymbol)
}
public AssemblyIdentity Identity => _targetAssembly.Identity;
- public Version AssemblyVersionPattern => _targetAssembly.AssemblyVersionPattern;
public override string ToString()
{
diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs
index 5cd19c3983b0c..abf660116f32a 100644
--- a/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs
+++ b/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs
@@ -162,7 +162,6 @@ protected override void AddEmbeddedResourcesFromAddedModules(ArrayBuilder _sourceAssembly.Identity;
- Version Cci.IAssemblyReference.AssemblyVersionPattern => _sourceAssembly.AssemblyVersionPattern;
internal override string Name
{
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index 13bf1593588e0..8448e5fc8ae05 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -1322,7 +1322,7 @@ internal enum ErrorCode
ERR_InvalidPathMap = 8101,
ERR_PublicSignButNoKey = 8102,
ERR_TooManyUserStrings = 8103,
- ERR_ExpressionTreeContainsLocalFunction = 8104,
+ ERR_PeWritingFailure = 8104,
ERR_ReturnTypesDontMatch = 8105,
ERR_DynamicLocalFunctionParameter = 8106,
ERR_CantInferVoid = 8107,
@@ -1332,6 +1332,7 @@ internal enum ErrorCode
ERR_AmbigMatch1 = 8111,
ERR_ThrowMisplaced = 8112,
ERR_ElseClauseRequiredWithWhenClause = 8113,
+ ERR_ExpressionTreeContainsLocalFunction = 8114,
// huge gap here???
diff --git a/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs b/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs
index 4a4d0ff96aac2..68f9753fea429 100644
--- a/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs
+++ b/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs
@@ -143,6 +143,7 @@ public override ReportDiagnostic GetDiagnosticReport(DiagnosticInfo diagnosticIn
// compilation options:
public override int ERR_BadCompilationOptionValue { get { return (int)ErrorCode.ERR_BadCompilationOptionValue; } }
+ public override int ERR_MutuallyExclusiveOptions => (int)ErrorCode.ERR_MutuallyExclusiveOptions;
// emit options:
public override int ERR_InvalidDebugInformationFormat { get { return (int)ErrorCode.ERR_InvalidDebugInformationFormat; } }
@@ -202,6 +203,8 @@ public override void ReportDuplicateMetadataReferenceWeak(DiagnosticBag diagnost
public override int ERR_MetadataNameTooLong { get { return (int)ErrorCode.ERR_MetadataNameTooLong; } }
public override int ERR_EncReferenceToAddedMember { get { return (int)ErrorCode.ERR_EncReferenceToAddedMember; } }
public override int ERR_TooManyUserStrings { get { return (int)ErrorCode.ERR_TooManyUserStrings; } }
+ public override int ERR_PeWritingFailure { get { return (int)ErrorCode.ERR_PeWritingFailure; } }
+ public override int ERR_ModuleEmitFailure { get { return (int)ErrorCode.ERR_ModuleEmitFailure; } }
public override void ReportInvalidAttributeArgument(DiagnosticBag diagnostics, SyntaxNode attributeSyntax, int parameterIndex, AttributeData attribute)
{
diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs
index dfe0f77fffddf..93831b611e71d 100644
--- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs
@@ -96,7 +96,7 @@ private FieldSymbol GetAwaiterField(TypeSymbol awaiterType)
if (!_awaiterFields.TryGetValue(awaiterType, out result))
{
int slotIndex;
- if (slotAllocatorOpt == null || !slotAllocatorOpt.TryGetPreviousAwaiterSlotIndex(F.ModuleBuilderOpt.Translate(awaiterType, F.Syntax, F.Diagnostics), out slotIndex))
+ if (slotAllocatorOpt == null || !slotAllocatorOpt.TryGetPreviousAwaiterSlotIndex(F.ModuleBuilderOpt.Translate(awaiterType, F.Syntax, F.Diagnostics), F.Diagnostics, out slotIndex))
{
slotIndex = _nextAwaiterId++;
}
diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_MatchStatement.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_MatchStatement.cs
index 7d58757ad9e0e..68671cf32275a 100644
--- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_MatchStatement.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_MatchStatement.cs
@@ -18,7 +18,7 @@ public override BoundNode VisitPatternSwitchStatement(BoundPatternSwitchStatemen
// copy the original switch expression into a temp
BoundAssignmentOperator initialStore;
- var switchExpressionTemp = _factory.StoreToTemp(node.Expression, out initialStore, syntaxOpt: node.Expression.Syntax);
+ var switchExpressionTemp = _factory.StoreToTemp(VisitExpression(node.Expression), out initialStore, syntaxOpt: node.Expression.Syntax);
statements.Add(_factory.ExpressionStatement(initialStore));
// save the default label, if and when we find it.
diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs
index 31f06fbd294e0..1c4f600358117 100644
--- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs
@@ -550,7 +550,14 @@ private BoundExpression HoistExpression(
// Editing await expression is not allowed. Thus all spilled fields will be present in the previous state machine.
// However, it may happen that the type changes, in which case we need to allocate a new slot.
int slotIndex;
- if (slotAllocatorOpt == null || !slotAllocatorOpt.TryGetPreviousHoistedLocalSlotIndex(awaitSyntaxOpt, F.ModuleBuilderOpt.Translate(fieldType, awaitSyntaxOpt, Diagnostics), kind, id, out slotIndex))
+ if (slotAllocatorOpt == null ||
+ !slotAllocatorOpt.TryGetPreviousHoistedLocalSlotIndex(
+ awaitSyntaxOpt,
+ F.ModuleBuilderOpt.Translate(fieldType, awaitSyntaxOpt, Diagnostics),
+ kind,
+ id,
+ Diagnostics,
+ out slotIndex))
{
slotIndex = _nextFreeHoistedLocalSlot++;
}
diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs
index 9f759785579e1..ff524a9800219 100644
--- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs
@@ -172,7 +172,13 @@ private void CreateNonReusableLocalProxies(
// map local id to the previous id, if available:
int previousSlotIndex;
- if (mapToPreviousFields && slotAllocatorOpt.TryGetPreviousHoistedLocalSlotIndex(declaratorSyntax, F.ModuleBuilderOpt.Translate(fieldType, declaratorSyntax, diagnostics), synthesizedKind, id, out previousSlotIndex))
+ if (mapToPreviousFields && slotAllocatorOpt.TryGetPreviousHoistedLocalSlotIndex(
+ declaratorSyntax,
+ F.ModuleBuilderOpt.Translate(fieldType, declaratorSyntax, diagnostics),
+ synthesizedKind,
+ id,
+ diagnostics,
+ out previousSlotIndex))
{
slotIndex = previousSlotIndex;
}
diff --git a/src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs
index bd29e48ab7eb0..7c01a7432e0f9 100644
--- a/src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs
@@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols
///
/// Represents a .NET assembly, consisting of one or more modules.
///
- internal abstract class AssemblySymbol : Symbol, IAssemblySymbolInternal
+ internal abstract class AssemblySymbol : Symbol, IAssemblySymbol
{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Changes to the public interface of this class should remain synchronized with the VB version.
@@ -78,16 +78,6 @@ public override string Name
///
public abstract AssemblyIdentity Identity { get; }
- ///
- /// Assembly version pattern with wildcards represented by ,
- /// or null if the version string specified in the doesn't contain a wildcard.
- ///
- /// For example,
- /// AssemblyVersion("1.2.*") is represented as 1.2.65535.65535,
- /// AssemblyVersion("1.2.3.*") is represented as 1.2.3.65535.
- ///
- public abstract Version AssemblyVersionPattern { get; }
-
///
/// Target architecture of the machine.
///
diff --git a/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs b/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs
index c16ccf8151c27..f7414593a6be6 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Compilation_WellKnownMembers.cs
@@ -300,7 +300,9 @@ internal SynthesizedAttributeData TrySynthesizeAttribute(
ImmutableArray arguments = default(ImmutableArray),
ImmutableArray> namedArguments = default(ImmutableArray>))
{
- var ctorSymbol = (MethodSymbol)GetWellKnownTypeMember(constructor);
+ DiagnosticInfo diagnosticInfo;
+ var ctorSymbol = (MethodSymbol)Binder.GetWellKnownTypeMember(this, constructor, out diagnosticInfo, isOptional: true);
+
if ((object)ctorSymbol == null)
{
// if this assert fails, UseSiteErrors for "member" have not been checked before emitting ...
@@ -323,7 +325,7 @@ internal SynthesizedAttributeData TrySynthesizeAttribute(
var builder = new ArrayBuilder>(namedArguments.Length);
foreach (var arg in namedArguments)
{
- var wellKnownMember = GetWellKnownTypeMember(arg.Key);
+ var wellKnownMember = Binder.GetWellKnownTypeMember(this, arg.Key, out diagnosticInfo, isOptional: true);
if (wellKnownMember == null || wellKnownMember is ErrorTypeSymbol)
{
// if this assert fails, UseSiteErrors for "member" have not been checked before emitting ...
diff --git a/src/Compilers/CSharp/Portable/Symbols/ConstantValueUtils.cs b/src/Compilers/CSharp/Portable/Symbols/ConstantValueUtils.cs
index e3497a7e2c572..a3af63e58499e 100644
--- a/src/Compilers/CSharp/Portable/Symbols/ConstantValueUtils.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/ConstantValueUtils.cs
@@ -52,15 +52,21 @@ private static BoundExpression BindFieldOrEnumInitializer(
DiagnosticBag diagnostics)
{
var enumConstant = fieldSymbol as SourceEnumConstantSymbol;
- var collisionDetector = new LocalScopeBinder(binder);
+ Binder collisionDetector = new LocalScopeBinder(binder);
+ collisionDetector = collisionDetector.WithPatternVariablesIfAny(initializer.Value);
+ BoundExpression result;
+
if ((object)enumConstant != null)
{
- return collisionDetector.BindEnumConstantInitializer(enumConstant, initializer.Value, diagnostics);
+ result = collisionDetector.BindEnumConstantInitializer(enumConstant, initializer.Value, diagnostics);
}
else
{
- return collisionDetector.BindVariableOrAutoPropInitializer(initializer, RefKind.None, fieldSymbol.Type, diagnostics);
+ result = collisionDetector.BindVariableOrAutoPropInitializer(initializer, RefKind.None, fieldSymbol.Type, diagnostics);
}
+
+ result = collisionDetector.WrapWithVariablesIfAny(result);
+ return result;
}
internal static ConstantValue GetAndValidateConstantValue(
diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEAssemblySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEAssemblySymbol.cs
index 044061e6f58db..6749f3423c73c 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEAssemblySymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEAssemblySymbol.cs
@@ -1,12 +1,10 @@
// 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.Collections.Immutable;
+using Roslyn.Utilities;
using System.Diagnostics;
-
using System.Linq;
-using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE
{
@@ -92,9 +90,6 @@ public override AssemblyIdentity Identity
}
}
- // TODO: https://github.com/dotnet/roslyn/issues/9000
- public override Version AssemblyVersionPattern => null;
-
public override ImmutableArray Modules
{
get
diff --git a/src/Compilers/CSharp/Portable/Symbols/MissingAssemblySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/MissingAssemblySymbol.cs
index a50cb3cc4f334..9ed0fc40642c4 100644
--- a/src/Compilers/CSharp/Portable/Symbols/MissingAssemblySymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/MissingAssemblySymbol.cs
@@ -60,8 +60,6 @@ public override AssemblyIdentity Identity
}
}
- public override Version AssemblyVersionPattern => null;
-
internal override ImmutableArray PublicKey
{
get { return Identity.PublicKey; }
diff --git a/src/Compilers/CSharp/Portable/Symbols/ReferenceManager.cs b/src/Compilers/CSharp/Portable/Symbols/ReferenceManager.cs
index b0d9604bbb015..282948d69ad04 100644
--- a/src/Compilers/CSharp/Portable/Symbols/ReferenceManager.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/ReferenceManager.cs
@@ -219,52 +219,27 @@ public void CreateSourceAssemblyForCompilation(CSharpCompilation compilation)
/// Used by EnC to create symbols for emit baseline. The PE symbols are used by .
///
/// The assembly references listed in the metadata AssemblyRef table are matched to the resolved references
- /// stored on this . We assume that the dependencies of the baseline metadata are
- /// the same as the dependencies of the current compilation. This is not exactly true when the dependencies use
- /// time-based versioning pattern, e.g. AssemblyVersion("1.0.*"). In that case we assume only the version
- /// changed and nothing else.
- ///
- /// Each AssemblyRef is matched against the assembly identities using an exact equality comparison modulo version.
- /// AssemblyRef with lower version in metadata is matched to a PE assembly symbol with the higher version
- /// (provided that the assembly name, culture, PKT and flags are the same) if there is no symbol with the exactly matching version.
- /// If there are multiple symbols with higher versions selects the one with the minimal version among them.
- ///
- /// Matching to a higher version is necessary to support EnC for projects whose P2P dependencies use time-based versioning pattern.
- /// The versions of the dependent projects seen from the IDE will be higher than
- /// the one written in the metadata at the time their respective baselines are built.
- ///
- /// No other unification or further resolution is performed.
+ /// stored on this . Each AssemblyRef is matched against the assembly identities
+ /// using an exact equality comparison. No unification or further resolution is performed.
///
- ///
- ///
- ///
- /// A map of the PE assembly symbol identities to the identities of the original metadata AssemblyRefs.
- /// This map will be used in emit when serializing AssemblyRef table of the delta. For the delta to be compatible with
- /// the original metadata we need to map the identities of the PE assembly symbols back to the original AssemblyRefs (if different).
- /// In other words, we pretend that the versions of the dependencies haven't changed.
- ///
- public PEAssemblySymbol CreatePEAssemblyForAssemblyMetadata(AssemblyMetadata metadata, MetadataImportOptions importOptions, out ImmutableDictionary assemblyReferenceIdentityMap)
+ public PEAssemblySymbol CreatePEAssemblyForAssemblyMetadata(AssemblyMetadata metadata, MetadataImportOptions importOptions)
{
AssertBound();
// If the compilation has a reference from metadata to source assembly we can't share the referenced PE symbols.
Debug.Assert(!HasCircularReference);
- var referencedAssembliesByIdentity = new AssemblyIdentityMap();
+ var referencedAssembliesByIdentity = new Dictionary();
foreach (var symbol in this.ReferencedAssemblies)
{
referencedAssembliesByIdentity.Add(symbol.Identity, symbol);
}
var assembly = metadata.GetAssembly();
-
var peReferences = assembly.AssemblyReferences.SelectAsArray(MapAssemblyIdentityToResolvedSymbol, referencedAssembliesByIdentity);
-
- assemblyReferenceIdentityMap = GetAssemblyReferenceIdentityBaselineMap(peReferences, assembly.AssemblyReferences);
-
var assemblySymbol = new PEAssemblySymbol(assembly, DocumentationProvider.Default, isLinked: false, importOptions: importOptions);
- var unifiedAssemblies = this.UnifiedAssemblies.WhereAsArray(unified => referencedAssembliesByIdentity.Contains(unified.OriginalReference, allowHigherVersion: false));
+ var unifiedAssemblies = this.UnifiedAssemblies.WhereAsArray(unified => referencedAssembliesByIdentity.ContainsKey(unified.OriginalReference));
InitializeAssemblyReuseData(assemblySymbol, peReferences, unifiedAssemblies);
if (assembly.ContainsNoPiaLocalTypes())
@@ -275,20 +250,13 @@ public PEAssemblySymbol CreatePEAssemblyForAssemblyMetadata(AssemblyMetadata met
return assemblySymbol;
}
- private static AssemblySymbol MapAssemblyIdentityToResolvedSymbol(AssemblyIdentity identity, AssemblyIdentityMap map)
+ private static AssemblySymbol MapAssemblyIdentityToResolvedSymbol(AssemblyIdentity identity, Dictionary map)
{
AssemblySymbol symbol;
- if (map.TryGetValue(identity, out symbol, CompareVersionPartsSpecifiedInSource))
+ if (map.TryGetValue(identity, out symbol))
{
return symbol;
}
-
- if (map.TryGetValue(identity, out symbol, (v1, v2, s) => true))
- {
- // TODO: https://github.com/dotnet/roslyn/issues/9004
- throw new NotSupportedException($"Changing the version of an assembly reference is not allowed during debugging: '{identity}' changed version to {symbol.Identity.Version}");
- }
-
return new MissingAssemblySymbol(identity);
}
diff --git a/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingAssemblySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingAssemblySymbol.cs
index e63c55e6fa4d3..5667c30c78b32 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingAssemblySymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingAssemblySymbol.cs
@@ -148,8 +148,6 @@ public override AssemblyIdentity Identity
}
}
- public override Version AssemblyVersionPattern => _underlyingAssembly.AssemblyVersionPattern;
-
internal override ImmutableArray PublicKey
{
get { return _underlyingAssembly.PublicKey; }
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs
index e516036f5ae50..93b1db8b66a8c 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs
@@ -352,10 +352,6 @@ internal string SignatureKey
}
}
- ///
- /// Raw assembly version as specified in the AssemblyVersionAttribute, or null if none specified.
- /// If the string passed to AssemblyVersionAttribute contains * the version build and/or revision numbers are set to .
- ///
private Version AssemblyVersionAttributeSetting
{
get
@@ -382,15 +378,6 @@ private Version AssemblyVersionAttributeSetting
}
}
- public override Version AssemblyVersionPattern
- {
- get
- {
- var attributeValue = AssemblyVersionAttributeSetting;
- return (object)attributeValue == null || (attributeValue.Build != ushort.MaxValue && attributeValue.Revision != ushort.MaxValue) ? null : attributeValue;
- }
- }
-
internal AssemblyHashAlgorithm AssemblyHashAlgorithm
{
get
@@ -462,6 +449,26 @@ private StrongNameKeys ComputeStrongNameKeys()
// when both attributes and command-line options specified, cmd line wins.
string keyFile = _compilation.Options.CryptoKeyFile;
+ // Public sign requires a keyfile
+ if (DeclaringCompilation.Options.PublicSign)
+ {
+ // TODO(https://github.com/dotnet/roslyn/issues/9150):
+ // Provide better error message if keys are provided by
+ // the attributes. Right now we'll just fall through to the
+ // "no key available" error.
+
+ if (!string.IsNullOrEmpty(keyFile) && !PathUtilities.IsAbsolute(keyFile))
+ {
+ // If keyFile has a relative path then there should be a diagnostic
+ // about it
+ Debug.Assert(!DeclaringCompilation.Options.Errors.IsEmpty);
+ return StrongNameKeys.None;
+ }
+
+ // If we're public signing, we don't need a strong name provider
+ return StrongNameKeys.Create(keyFile, MessageProvider.Instance);
+ }
+
if (string.IsNullOrEmpty(keyFile))
{
keyFile = this.AssemblyKeyFileAttributeSetting;
@@ -484,16 +491,7 @@ private StrongNameKeys ComputeStrongNameKeys()
}
}
- // If we're public signing, we don't need a strong name provider, just
- // the file containing the public key
- if (DeclaringCompilation.Options.PublicSign && keyFile != null)
- {
- return StrongNameKeys.Create(keyFile, MessageProvider.Instance);
- }
- else
- {
- return StrongNameKeys.Create(DeclaringCompilation.Options.StrongNameProvider, keyFile, keyContainer, MessageProvider.Instance);
- }
+ return StrongNameKeys.Create(DeclaringCompilation.Options.StrongNameProvider, keyFile, keyContainer, MessageProvider.Instance);
}
// A collection of assemblies to which we were granted internals access by only checking matches for assembly name
@@ -1898,7 +1896,7 @@ private AssemblyIdentity ComputeIdentity()
{
return new AssemblyIdentity(
_assemblySimpleName,
- VersionHelper.GenerateVersionFromPatternAndCurrentTime(this.AssemblyVersionAttributeSetting),
+ this.AssemblyVersionAttributeSetting,
this.AssemblyCultureAttributeSetting,
StrongNameKeys.PublicKey,
hasPublicKey: !StrongNameKeys.PublicKey.IsDefault);
@@ -2126,7 +2124,7 @@ private void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArguments GetIntAsync()
AssertEx.SetEqual(new[] { "CompilerGeneratedAttribute", "DebuggerHiddenAttribute" }, GetAttributeNames(baseMethodWrapper.GetAttributes()));
}
}
+
+ [Fact, WorkItem(7809, "https://github.com/dotnet/roslyn/issues/7809")]
+ public void SynthesizeAttributeWithUseSiteErrorFails()
+ {
+ #region "mslib"
+ var mslibNoString = @"
+namespace System
+{
+ public class Object { }
+ public struct Int32 { }
+ public class ValueType { }
+ public class Attribute { }
+ public struct Void { }
+}";
+ var mslib = mslibNoString + @"
+namespace System
+{
+ public class String { }
+}";
+ #endregion
+
+ // Build an mscorlib including String
+ var mslibComp = CreateCompilation(new string[] { mslib }).VerifyDiagnostics();
+ var mslibRef = mslibComp.EmitToImageReference();
+
+ // Build an mscorlib without String
+ var mslibNoStringComp = CreateCompilation(new string[] { mslibNoString }).VerifyDiagnostics();
+ var mslibNoStringRef = mslibNoStringComp.EmitToImageReference();
+
+ var diagLibSource = @"
+namespace System.Diagnostics
+{
+ public class DebuggerDisplayAttribute : System.Attribute
+ {
+ public DebuggerDisplayAttribute(System.String s) { }
+ public System.String Type { get { return null; } set { } }
+ }
+}
+namespace System.Runtime.CompilerServices
+{
+ public class CompilerGeneratedAttribute { }
+}";
+ // Build Diagnostics referencing mscorlib with String
+ var diagLibComp = CreateCompilation(new string[] { diagLibSource }, references: new[] { mslibRef }).VerifyDiagnostics();
+ var diagLibRef = diagLibComp.EmitToImageReference();
+
+ // Create compilation using Diagnostics but referencing mscorlib without String
+ var comp = CreateCompilation(new SyntaxTree[] { Parse("") }, references: new[] { diagLibRef, mslibNoStringRef });
+
+ // Attribute cannot be synthesized because ctor has a use-site error (String type missing)
+ var attribute = comp.TrySynthesizeAttribute(WellKnownMember.System_Diagnostics_DebuggerDisplayAttribute__ctor);
+ Assert.Equal(null, attribute);
+
+ // Attribute cannot be synthesized because type in named argument has use-site error (String type missing)
+ var attribute2 = comp.TrySynthesizeAttribute(
+ WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor,
+ namedArguments: ImmutableArray.Create(new KeyValuePair(
+ WellKnownMember.System_Diagnostics_DebuggerDisplayAttribute__Type,
+ new TypedConstant(comp.GetSpecialType(SpecialType.System_String), TypedConstantKind.Primitive, "unused"))));
+ Assert.Equal(null, attribute2);
+ }
}
}
diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/EmitTestStrongNameProvider.cs b/src/Compilers/CSharp/Test/Emit/Attributes/EmitTestStrongNameProvider.cs
index 6f67bc26092b7..64c2df914c614 100644
--- a/src/Compilers/CSharp/Test/Emit/Attributes/EmitTestStrongNameProvider.cs
+++ b/src/Compilers/CSharp/Test/Emit/Attributes/EmitTestStrongNameProvider.cs
@@ -16,6 +16,9 @@ public partial class InternalsVisibleToAndStrongNameTests : CSharpTestBase
private class StrongNameProviderWithBadInputStream : StrongNameProvider
{
private StrongNameProvider _underlyingProvider;
+
+ public Exception ThrownException;
+
public StrongNameProviderWithBadInputStream(StrongNameProvider underlyingProvider)
{
_underlyingProvider = underlyingProvider;
@@ -27,7 +30,8 @@ public StrongNameProviderWithBadInputStream(StrongNameProvider underlyingProvide
internal override Stream CreateInputStream()
{
- throw new IOException("This is a test IOException");
+ ThrownException = new IOException("This is a test IOException");
+ throw ThrownException;
}
internal override StrongNameKeys CreateKeys(string keyFilePath, string keyContainerName, CommonMessageProvider messageProvider) =>
@@ -53,9 +57,9 @@ public static void Main(string[] args) { }
var comp = CreateCompilationWithMscorlib(src,
options: options);
- comp.VerifyEmitDiagnostics(
- // error CS7028: Error signing output with public key from container 'RoslynTestContainer' -- This is a test IOException
- Diagnostic(ErrorCode.ERR_PublicKeyContainerFailure).WithArguments("RoslynTestContainer", "This is a test IOException").WithLocation(1, 1));
+ comp.Emit(new MemoryStream()).Diagnostics.Verify(
+ // error CS8104: An error occurred while writing the Portable Executable file.
+ Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments(testProvider.ThrownException.ToString()).WithLocation(1, 1));
}
}
}
diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/InternalsVisibleToAndStrongNameTests.cs b/src/Compilers/CSharp/Test/Emit/Attributes/InternalsVisibleToAndStrongNameTests.cs
index 8f1bffddee139..0a2b3f2b411aa 100644
--- a/src/Compilers/CSharp/Test/Emit/Attributes/InternalsVisibleToAndStrongNameTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/Attributes/InternalsVisibleToAndStrongNameTests.cs
@@ -420,6 +420,36 @@ public class C {}
Assert.Equal(CorFlags.ILOnly | CorFlags.StrongNameSigned, metadata.Module.PEReaderOpt.PEHeaders.CorHeader.Flags);
}
+ [Fact]
+ public void KeyFileFromAttributes_PublicSign()
+ {
+ string source = @"
+[assembly: System.Reflection.AssemblyKeyFile(""test.snk"")]
+public class C {}
+";
+ var c = CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseDll.WithPublicSign(true));
+ c.VerifyDiagnostics(
+ // error CS8102: Public signing was specified and requires a public key, but no public key was specified.
+ Diagnostic(ErrorCode.ERR_PublicSignButNoKey).WithLocation(1, 1));
+
+ Assert.True(c.Options.PublicSign);
+ }
+
+ [Fact]
+ public void KeyContainerFromAttributes_PublicSign()
+ {
+ string source = @"
+[assembly: System.Reflection.AssemblyKeyName(""roslynTestContainer"")]
+public class C {}
+";
+ var c = CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseDll.WithPublicSign(true));
+ c.VerifyDiagnostics(
+ // error CS8102: Public signing was specified and requires a public key, but no public key was specified.
+ Diagnostic(ErrorCode.ERR_PublicSignButNoKey).WithLocation(1, 1));
+
+ Assert.True(c.Options.PublicSign);
+ }
+
private void VerifySignedBitSetAfterEmit(Compilation comp)
{
var outStrm = new MemoryStream();
@@ -511,8 +541,8 @@ public void KeyContainerNoSNProvider_PublicSign()
.WithPublicSign(true));
comp.VerifyDiagnostics(
- // error CS7028: Error signing output with public key from container 'roslynTestContainer' -- Assembly signing not supported.
- Diagnostic(ErrorCode.ERR_PublicKeyContainerFailure).WithArguments("roslynTestContainer", "Assembly signing not supported.").WithLocation(1, 1),
+ // error CS7102: Compilation options 'PublicSign' and 'CryptoKeyContainer' can't both be specified at the same time.
+ Diagnostic(ErrorCode.ERR_MutuallyExclusiveOptions).WithArguments("PublicSign", "CryptoKeyContainer").WithLocation(1, 1),
// error CS8102: Public signing was specified and requires a public key, but no public key was specified.
Diagnostic(ErrorCode.ERR_PublicSignButNoKey).WithLocation(1, 1));
}
@@ -526,14 +556,16 @@ public void KeyContainerDesktopProvider_PublicSign()
.WithStrongNameProvider(s_defaultProvider)
.WithPublicSign(true));
- comp.VerifyDiagnostics();
+ comp.VerifyDiagnostics(
+ // error CS7102: Compilation options 'PublicSign' and 'CryptoKeyContainer' can't both be specified at the same time.
+ Diagnostic(ErrorCode.ERR_MutuallyExclusiveOptions).WithArguments("PublicSign", "CryptoKeyContainer").WithLocation(1, 1),
+ // error CS8102: Public signing was specified and requires a public key, but no public key was specified.
+ Diagnostic(ErrorCode.ERR_PublicSignButNoKey).WithLocation(1, 1));
Assert.True(comp.Options.PublicSign);
Assert.Null(comp.Options.DelaySign);
Assert.False(comp.IsRealSigned);
Assert.NotNull(comp.Options.CryptoKeyContainer);
-
- VerifySignedBitSetAfterEmit(comp);
}
[Fact]
diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs
index 45606201a51fd..33b7635ca8d6b 100644
--- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs
+++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs
@@ -2326,5 +2326,73 @@ .locals init (bool V_0,
}");
Assert.True(expectedIL.IndexOf("<>_", StringComparison.Ordinal) < 0);
}
+
+ [Fact, WorkItem(9167, "https://github.com/dotnet/roslyn/issues/9167")]
+ public void IteratorShouldCompileWithoutOptionalAttributes()
+ {
+ #region IL for corlib without CompilerGeneratedAttribute or DebuggerNonUserCodeAttribute
+ var corlib = @"
+namespace System
+{
+ public class Object { }
+ public struct Int32 { }
+ public struct Boolean { }
+ public class String { }
+ public class Exception { }
+ public class NotSupportedException : Exception { }
+ public class ValueType { }
+ public class Enum { }
+ public struct Void { }
+
+ public interface IDisposable
+ {
+ void Dispose();
+ }
+}
+
+namespace System.Collections
+{
+ public interface IEnumerable
+ {
+ IEnumerator GetEnumerator();
+ }
+
+ public interface IEnumerator
+ {
+ bool MoveNext();
+ object Current { get; }
+ void Reset();
+ }
+
+ namespace Generic
+ {
+ public interface IEnumerable : IEnumerable
+ {
+ new IEnumerator GetEnumerator();
+ }
+
+ public interface IEnumerator : IEnumerator
+ {
+ new T Current { get; }
+ }
+ }
+}";
+ #endregion
+
+ var source = @"
+public class C
+{
+ public System.Collections.IEnumerable SomeNumbers()
+ {
+ yield return 42;
+ }
+}";
+ // The compilation succeeds even though CompilerGeneratedAttribute and DebuggerNonUserCodeAttribute are not available.
+ var compilation = CreateCompilation(new[] { Parse(source), Parse(corlib) });
+ var verifier = CompileAndVerify(compilation, verify: false);
+ verifier.VerifyDiagnostics(
+ // warning CS8021: No value for RuntimeMetadataVersion found. No assembly containing System.Object was found nor was a value for RuntimeMetadataVersion specified through options.
+ Diagnostic(ErrorCode.WRN_NoRuntimeMetadataVersion).WithLocation(1, 1));
+ }
}
}
diff --git a/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs
index d32cf1cd11a64..4b6d6ca83bde5 100644
--- a/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs
@@ -1,7 +1,6 @@
// 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.Immutable;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -2699,10 +2698,16 @@ public void BrokenOutStream()
var compilation = CreateCompilationWithMscorlib(source);
var output = new BrokenStream();
- Assert.Throws(() => compilation.Emit(output));
+ var result = compilation.Emit(output);
+ result.Diagnostics.Verify(
+ // error CS8104: An error occurred while writing the Portable Executable file.
+ Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments(output.ThrownException.ToString()).WithLocation(1, 1));
- output.BreakHow = 1;
- Assert.Throws(() => compilation.Emit(output));
+ output.BreakHow = BrokenStream.BreakHowType.ThrowOnSetPosition;
+ result = compilation.Emit(output);
+ result.Diagnostics.Verify(
+ // error CS8104: An error occurred while writing the Portable Executable file.
+ Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments(output.ThrownException.ToString()).WithLocation(1, 1));
// disposed stream is not writable
var outReal = new MemoryStream();
@@ -2718,7 +2723,7 @@ public void BrokenPDBStream()
var output = new MemoryStream();
var pdb = new BrokenStream();
- pdb.BreakHow = 2;
+ pdb.BreakHow = BrokenStream.BreakHowType.ThrowOnSetLength;
var result = compilation.Emit(output, pdb);
// error CS0041: Unexpected error writing debug information -- 'Exception from HRESULT: 0x806D0004'
@@ -2949,5 +2954,27 @@ static int M(dynamic d, object o)
AssertEx.Equal(expectedNames, actualNames);
}
}
+
+ [Fact]
+ [WorkItem(3240, "https://github.com/dotnet/roslyn/pull/8227")]
+ public void FailingEmitter()
+ {
+ string source = @"
+public class X
+{
+ public static void Main()
+ {
+
+ }
+}";
+ var compilation = CreateCompilationWithMscorlib(source);
+ var broken = new BrokenStream();
+ broken.BreakHow = BrokenStream.BreakHowType.ThrowOnWrite;
+ var result = compilation.Emit(broken);
+ Assert.False(result.Success);
+ result.Diagnostics.Verify(
+ // error CS8104: An error occurred while writing the Portable Executable file.
+ Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments(broken.ThrownException.ToString()).WithLocation(1, 1));
+ }
}
}
diff --git a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/AssemblyReferencesTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/AssemblyReferencesTests.cs
index 192ba4c37d308..a6478e760639f 100644
--- a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/AssemblyReferencesTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/AssemblyReferencesTests.cs
@@ -1,14 +1,10 @@
// 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.Collections.Immutable;
-using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection.Metadata;
-using System.Reflection.Metadata.Ecma335;
-using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.CSharp.UnitTests;
@@ -22,9 +18,6 @@ namespace Microsoft.CodeAnalysis.CSharp.EditAndContinue.UnitTests
{
public class AssemblyReferencesTests : EditAndContinueTestBase
{
- private static readonly CSharpCompilationOptions s_signedDll =
- TestOptions.ReleaseDll.WithCryptoPublicKey(TestResources.TestKeys.PublicKey_ce65828c82a341f2);
-
///
/// The baseline metadata might have less (or even different) references than
/// the current compilation. We shouldn't assume that the reference sets are the same.
@@ -231,269 +224,5 @@ class C
diff2.EmitResult.Diagnostics.Verify();
}
-
- [Fact]
- public void DependencyVersionWildcards_Compilation()
- {
- TestDependencyVersionWildcards(
- "1.0.0.*",
- new Version(1, 0, 2000, 1001),
- new Version(1, 0, 2000, 1001),
- new Version(1, 0, 2000, 1002));
-
- TestDependencyVersionWildcards(
- "1.0.0.*",
- new Version(1, 0, 2000, 1001),
- new Version(1, 0, 2000, 1002),
- new Version(1, 0, 2000, 1002));
-
- TestDependencyVersionWildcards(
- "1.0.0.*",
- new Version(1, 0, 2000, 1003),
- new Version(1, 0, 2000, 1002),
- new Version(1, 0, 2000, 1001));
-
- TestDependencyVersionWildcards(
- "1.0.*",
- new Version(1, 0, 2000, 1001),
- new Version(1, 0, 2000, 1002),
- new Version(1, 0, 2000, 1003));
-
- TestDependencyVersionWildcards(
- "1.0.*",
- new Version(1, 0, 2000, 1001),
- new Version(1, 0, 2000, 1005),
- new Version(1, 0, 2000, 1002));
- }
-
- private void TestDependencyVersionWildcards(string sourceVersion, Version version0, Version version1, Version version2)
- {
- string srcLib = $@"
-[assembly: System.Reflection.AssemblyVersion(""{sourceVersion}"")]
-
-public class D {{ }}
-";
-
- string src0 = @"
-class C
-{
- public static int F(D a) { return 1; }
-}
-";
- string src1 = @"
-class C
-{
- public static int F(D a) { return 2; }
-}
-";
- string src2 = @"
-class C
-{
- public static int F(D a) { return 3; }
- public static int G(D a) { return 4; }
-}
-";
- var lib0 = CreateCompilationWithMscorlib(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll);
-
- ((SourceAssemblySymbol)lib0.Assembly).lazyAssemblyIdentity = new AssemblyIdentity("Lib", version0);
- lib0.VerifyDiagnostics();
-
- var lib1 = CreateCompilationWithMscorlib(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll);
- ((SourceAssemblySymbol)lib1.Assembly).lazyAssemblyIdentity = new AssemblyIdentity("Lib", version1);
- lib1.VerifyDiagnostics();
-
- var lib2 = CreateCompilationWithMscorlib(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll);
- ((SourceAssemblySymbol)lib2.Assembly).lazyAssemblyIdentity = new AssemblyIdentity("Lib", version2);
-
- lib2.VerifyDiagnostics();
-
- var compilation0 = CreateCompilation(src0, new[] { MscorlibRef, lib0.ToMetadataReference() }, assemblyName: "C", options: TestOptions.DebugDll);
- var compilation1 = compilation0.WithSource(src1).WithReferences(new[] { MscorlibRef, lib1.ToMetadataReference() });
- var compilation2 = compilation1.WithSource(src2).WithReferences(new[] { MscorlibRef, lib2.ToMetadataReference() });
-
- var v0 = CompileAndVerify(compilation0);
- var v1 = CompileAndVerify(compilation1);
- var v2 = CompileAndVerify(compilation2);
-
- var f0 = compilation0.GetMember("C.F");
- var f1 = compilation1.GetMember("C.F");
- var f2 = compilation2.GetMember("C.F");
- var g2 = compilation2.GetMember("C.G");
-
- var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData);
- var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider);
-
- var diff1 = compilation1.EmitDifference(
- generation0,
- ImmutableArray.Create(new SemanticEdit(SemanticEditKind.Update, f0, f1)));
-
- var diff2 = compilation2.EmitDifference(
- diff1.NextGeneration,
- ImmutableArray.Create(
- new SemanticEdit(SemanticEditKind.Update, f1, f2),
- new SemanticEdit(SemanticEditKind.Insert, null, g2)));
-
- var md1 = diff1.GetMetadata();
- var md2 = diff2.GetMetadata();
-
- var aggReader = new AggregatedMetadataReader(md0.MetadataReader, md1.Reader, md2.Reader);
-
- // all references to Lib should be to the baseline version:
- VerifyAssemblyReferences(aggReader, new[]
- {
- "mscorlib, 4.0.0.0",
- "Lib, " + lib0.Assembly.Identity.Version,
- "mscorlib, 4.0.0.0",
- "Lib, " + lib0.Assembly.Identity.Version,
- "mscorlib, 4.0.0.0",
- "Lib, " + lib0.Assembly.Identity.Version,
- });
- }
-
- [Fact]
- public void DependencyVersionWildcards_Metadata()
- {
- string srcLib = @"
-[assembly: System.Reflection.AssemblyVersion(""1.0.*"")]
-
-public class D { }
-";
-
- string src0 = @"
-class C
-{
- public static int F(D a) { return 1; }
-}
-";
- string src1 = @"
-class C
-{
- public static int F(D a) { return 2; }
-}
-";
- string src2 = @"
-class C
-{
- public static int F(D a) { return 3; }
- public static int G(D a) { return 4; }
-}
-";
- var lib0 = CreateCompilationWithMscorlib(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll);
- ((SourceAssemblySymbol)lib0.Assembly).lazyAssemblyIdentity = new AssemblyIdentity("Lib", new Version(1, 0, 2000, 1001));
- lib0.VerifyDiagnostics();
-
- var lib1 = CreateCompilationWithMscorlib(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll);
- ((SourceAssemblySymbol)lib1.Assembly).lazyAssemblyIdentity = new AssemblyIdentity("Lib", new Version(1, 0, 2000, 1002));
- lib1.VerifyDiagnostics();
-
- var lib2 = CreateCompilationWithMscorlib(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll);
- ((SourceAssemblySymbol)lib2.Assembly).lazyAssemblyIdentity = new AssemblyIdentity("Lib", new Version(1, 0, 2000, 1003));
- lib2.VerifyDiagnostics();
-
- var compilation0 = CreateCompilation(src0, new[] { MscorlibRef, lib0.EmitToImageReference() }, assemblyName: "C", options: TestOptions.DebugDll);
- var compilation1 = compilation0.WithSource(src1).WithReferences(new[] { MscorlibRef, lib1.EmitToImageReference() });
- var compilation2 = compilation1.WithSource(src2).WithReferences(new[] { MscorlibRef, lib2.EmitToImageReference() });
-
- var v0 = CompileAndVerify(compilation0);
- var v1 = CompileAndVerify(compilation1);
- var v2 = CompileAndVerify(compilation2);
-
- var f0 = compilation0.GetMember("C.F");
- var f1 = compilation1.GetMember("C.F");
- var f2 = compilation2.GetMember("C.F");
- var g2 = compilation2.GetMember("C.G");
-
- var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData);
- var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider);
-
- var diff1 = compilation1.EmitDifference(
- generation0,
- ImmutableArray.Create(new SemanticEdit(SemanticEditKind.Update, f0, f1)));
-
- diff1.EmitResult.Diagnostics.Verify(
- // error CS7038: Failed to emit module 'C'.
- Diagnostic(ErrorCode.ERR_ModuleEmitFailure).WithArguments("C"));
- }
-
- [Fact, WorkItem(9004, "https://github.com/dotnet/roslyn/issues/9004")]
- public void DependencyVersionWildcardsCollisions()
- {
- string srcLib01 = @"
-[assembly: System.Reflection.AssemblyVersion(""1.0.0.1"")]
-
-public class D { }
-";
- string srcLib02 = @"
-[assembly: System.Reflection.AssemblyVersion(""1.0.0.2"")]
-
-public class D { }
-";
-
- string srcLib11 = @"
-[assembly: System.Reflection.AssemblyVersion(""1.0.1.1"")]
-
-public class D { }
-";
- string srcLib12 = @"
-[assembly: System.Reflection.AssemblyVersion(""1.0.1.2"")]
-
-public class D { }
-";
-
- string src0 = @"
-extern alias L0;
-extern alias L1;
-
-class C
-{
- public static int F(L0::D a, L1::D b) => 1;
-}
-";
- string src1 = @"
-extern alias L0;
-extern alias L1;
-
-class C
-{
- public static int F(L0::D a, L1::D b) => 2;
-}
-";
- var lib01 = CreateCompilationWithMscorlib(srcLib01, assemblyName: "Lib", options: s_signedDll).VerifyDiagnostics();
- var ref01 = lib01.ToMetadataReference(ImmutableArray.Create("L0"));
-
- var lib02 = CreateCompilationWithMscorlib(srcLib02, assemblyName: "Lib", options: s_signedDll).VerifyDiagnostics();
- var ref02 = lib02.ToMetadataReference(ImmutableArray.Create("L0"));
-
- var lib11 = CreateCompilationWithMscorlib(srcLib11, assemblyName: "Lib", options: s_signedDll).VerifyDiagnostics();
- var ref11 = lib11.ToMetadataReference(ImmutableArray.Create("L1"));
-
- var lib12 = CreateCompilationWithMscorlib(srcLib12, assemblyName: "Lib", options: s_signedDll).VerifyDiagnostics();
- var ref12 = lib12.ToMetadataReference(ImmutableArray.Create("L1"));
-
- var compilation0 = CreateCompilation(src0, new[] { MscorlibRef, ref01, ref11 }, assemblyName: "C", options: TestOptions.DebugDll);
- var compilation1 = compilation0.WithSource(src1).WithReferences(new[] { MscorlibRef, ref02, ref12 });
-
- var v0 = CompileAndVerify(compilation0);
-
- var f0 = compilation0.GetMember("C.F");
- var f1 = compilation1.GetMember("C.F");
-
- var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData);
- var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider);
-
- var diff1 = compilation1.EmitDifference(
- generation0,
- ImmutableArray.Create(new SemanticEdit(SemanticEditKind.Update, f0, f1)));
-
- // TODO: message should be: Changing the version of an assembly reference is not allowed during debugging
- diff1.EmitResult.Diagnostics.Verify(
- // error CS7038: Failed to emit module 'C'.
- Diagnostic(ErrorCode.ERR_ModuleEmitFailure).WithArguments("C"));
- }
-
- public void VerifyAssemblyReferences(AggregatedMetadataReader reader, string[] expected)
- {
- AssertEx.Equal(expected, reader.GetAssemblyReferences().Select(aref => $"{reader.GetString(aref.Name)}, {aref.Version}"));
- }
}
}
diff --git a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs
index 118319e6dbf2c..206c4255744ff 100644
--- a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs
@@ -4702,5 +4702,119 @@ .locals init (int V_0,
"<>f__AnonymousType5<<<>h__TransparentIdentifier0>j__TPar, j__TPar>: {Equals, GetHashCode, ToString}",
"<>f__AnonymousType2<<<>h__TransparentIdentifier0>j__TPar, j__TPar>: {Equals, GetHashCode, ToString}");
}
+
+ [Fact, WorkItem(9119, "https://github.com/dotnet/roslyn/issues/9119")]
+ public void MissingIteratorStateMachineAttribute()
+ {
+ var source0 = MarkedSource(@"
+using System;
+using System.Collections.Generic;
+
+class C
+{
+ public IEnumerable F()
+ {
+ int a = 0;
+ yield return 0;
+ Console.WriteLine(a);
+ }
+}
+");
+ var source1 = MarkedSource(@"
+using System;
+using System.Collections.Generic;
+
+class C
+{
+ public IEnumerable F()
+ {
+ int a = 1;
+ yield return 1;
+ Console.WriteLine(a);
+ }
+}
+");
+
+ var compilation0 = CreateCompilationWithMscorlib(new[] { source0.Tree }, options: ComSafeDebugDll);
+ var compilation1 = compilation0.WithSource(source1.Tree);
+
+ // older versions of mscorlib don't contain IteratorStateMachineAttribute
+ Assert.Null(compilation0.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_IteratorStateMachineAttribute__ctor));
+
+ var v0 = CompileAndVerify(compilation0);
+ v0.VerifyDiagnostics();
+ var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData);
+
+ var f0 = compilation0.GetMember("C.F");
+ var f1 = compilation1.GetMember("C.F");
+
+ var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo);
+
+ var diff1 = compilation1.EmitDifference(
+ generation0,
+ ImmutableArray.Create(
+ new SemanticEdit(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true)));
+
+ diff1.EmitResult.Diagnostics.Verify(
+ // error CS7038: Failed to emit module '{0}'.
+ Diagnostic(ErrorCode.ERR_ModuleEmitFailure).WithArguments(compilation0.SourceModule.Name));
+ }
+
+ [Fact, WorkItem(9119, "https://github.com/dotnet/roslyn/issues/9119")]
+ public void MissingAsyncStateMachineAttribute()
+ {
+ var source0 = MarkedSource(@"
+using System.Threading.Tasks;
+
+class C
+{
+ public async Task F()
+ {
+ int a = 0;
+ await new Task();
+ return a;
+ }
+}
+");
+ var source1 = MarkedSource(@"
+using System.Threading.Tasks;
+
+class C
+{
+ public async Task F()
+ {
+ int a = 1;
+ await new Task();
+ return a;
+ }
+}
+");
+
+ var compilation0 = CreateCompilation(new[] { source0.Tree }, new[] { TestReferences.NetFx.Minimal.mincorlib, TestReferences.NetFx.Minimal.minasync }, options: ComSafeDebugDll);
+ var compilation1 = compilation0.WithSource(source1.Tree);
+
+ // older versions of mscorlib don't contain AsyncStateMachineAttribute, IteratorStateMachineAttribute
+ Assert.Null(compilation0.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_AsyncStateMachineAttribute__ctor));
+ Assert.Null(compilation0.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_IteratorStateMachineAttribute__ctor));
+
+ var v0 = CompileAndVerify(compilation0, verify: false);
+ var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData);
+
+ var f0 = compilation0.GetMember("C.F");
+ var f1 = compilation1.GetMember("C.F");
+
+ var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo);
+
+ var diff1 = compilation1.EmitDifference(
+ generation0,
+ ImmutableArray.Create(
+ new SemanticEdit(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true)));
+
+ diff1.EmitResult.Diagnostics.Verify(
+ // error CS7038: Failed to emit module '{0}'.
+ Diagnostic(ErrorCode.ERR_ModuleEmitFailure).WithArguments(compilation0.SourceModule.Name),
+ // error CS7038: Failed to emit module '{0}'.
+ Diagnostic(ErrorCode.ERR_ModuleEmitFailure).WithArguments(compilation0.SourceModule.Name));
+ }
}
}
diff --git a/src/Compilers/CSharp/Test/Emit/Emit/OutputStreams.cs b/src/Compilers/CSharp/Test/Emit/Emit/OutputStreams.cs
index 26880dfaa98e7..674fd11abe81b 100644
--- a/src/Compilers/CSharp/Test/Emit/Emit/OutputStreams.cs
+++ b/src/Compilers/CSharp/Test/Emit/Emit/OutputStreams.cs
@@ -20,71 +20,4 @@ public Stream GetXmlInclude(SyntaxTree syntaxTree, string xmlIncludeFile)
throw new NotImplementedException();
}
}
-
- internal class BrokenStream : Stream
- {
- public int BreakHow;
-
- public override bool CanRead
- {
- get { return true; }
- }
-
- public override bool CanSeek
- {
- get { return true; }
- }
-
- public override bool CanWrite
- {
- get { return true; }
- }
-
- public override void Flush()
- {
- }
-
- public override long Length
- {
- get
- {
- return 0;
- }
- }
-
- public override long Position
- {
- get
- {
- return 0;
- }
- set
- {
- if (BreakHow == 1)
- throw new NotSupportedException();
- }
- }
-
- public override int Read(byte[] buffer, int offset, int count)
- {
- return 0;
- }
-
- public override long Seek(long offset, SeekOrigin origin)
- {
- return 0;
- }
-
- public override void SetLength(long value)
- {
- if (BreakHow == 2)
- throw new IOException();
- }
-
- public override void Write(byte[] buffer, int offset, int count)
- {
- if (BreakHow == 0)
- throw new IOException();
- }
- }
}
diff --git a/src/Compilers/CSharp/Test/Emit/project.lock.json b/src/Compilers/CSharp/Test/Emit/project.lock.json
index 8e273a551710d..0be6e5524107a 100644
--- a/src/Compilers/CSharp/Test/Emit/project.lock.json
+++ b/src/Compilers/CSharp/Test/Emit/project.lock.json
@@ -70,7 +70,7 @@
"lib/net45/_._": {}
}
},
- "System.Reflection.Metadata/1.2.0-rc3-23811": {
+ "System.Reflection.Metadata/1.2.0-rc2-23826": {
"dependencies": {
"System.Collections.Immutable": "1.1.37"
},
@@ -233,7 +233,7 @@
"lib/net45/_._": {}
}
},
- "System.Reflection.Metadata/1.2.0-rc3-23811": {
+ "System.Reflection.Metadata/1.2.0-rc2-23826": {
"dependencies": {
"System.Collections.Immutable": "1.1.37"
},
@@ -550,11 +550,11 @@
"ref/wpa81/_._"
]
},
- "System.Reflection.Metadata/1.2.0-rc3-23811": {
- "sha512": "gAOQV1dsGyQfQUuzsCYFLMlI6BhfK1/2aA7JGf6gJphaLgjU4dV4hzjbE0iZXgo61VUuda2LtCBrWWZBw5897Q==",
+ "System.Reflection.Metadata/1.2.0-rc2-23826": {
+ "sha512": "iaq5zpluF7mUMd5hFyhmZGyCSzF6glZjvNI2VAhLFQEp8sGA/tROj6NoZL42q6HhoHxi1XyGeoIXPi5hyw0+5w==",
"type": "package",
"files": [
- "System.Reflection.Metadata.1.2.0-rc3-23811.nupkg.sha512",
+ "System.Reflection.Metadata.1.2.0-rc2-23826.nupkg.sha512",
"System.Reflection.Metadata.nuspec",
"ThirdPartyNotices.txt",
"dotnet_library_license.txt",
diff --git a/src/Compilers/CSharp/Test/Performance/project.lock.json b/src/Compilers/CSharp/Test/Performance/project.lock.json
index 222661284f954..24c270eaf73fb 100644
--- a/src/Compilers/CSharp/Test/Performance/project.lock.json
+++ b/src/Compilers/CSharp/Test/Performance/project.lock.json
@@ -156,7 +156,7 @@
"lib/net46/_._": {}
}
},
- "System.Reflection.Metadata/1.2.0-rc3-23811": {
+ "System.Reflection.Metadata/1.2.0-rc2-23826": {
"dependencies": {
"System.Collections.Immutable": "1.1.37"
},
@@ -428,7 +428,7 @@
"lib/net46/_._": {}
}
},
- "System.Reflection.Metadata/1.2.0-rc3-23811": {
+ "System.Reflection.Metadata/1.2.0-rc2-23826": {
"dependencies": {
"System.Collections.Immutable": "1.1.37"
},
@@ -700,7 +700,7 @@
"lib/net46/_._": {}
}
},
- "System.Reflection.Metadata/1.2.0-rc3-23811": {
+ "System.Reflection.Metadata/1.2.0-rc2-23826": {
"dependencies": {
"System.Collections.Immutable": "1.1.37"
},
@@ -1170,11 +1170,11 @@
"runtimes/win8-aot/lib/netcore50/System.Reflection.dll"
]
},
- "System.Reflection.Metadata/1.2.0-rc3-23811": {
- "sha512": "gAOQV1dsGyQfQUuzsCYFLMlI6BhfK1/2aA7JGf6gJphaLgjU4dV4hzjbE0iZXgo61VUuda2LtCBrWWZBw5897Q==",
+ "System.Reflection.Metadata/1.2.0-rc2-23826": {
+ "sha512": "iaq5zpluF7mUMd5hFyhmZGyCSzF6glZjvNI2VAhLFQEp8sGA/tROj6NoZL42q6HhoHxi1XyGeoIXPi5hyw0+5w==",
"type": "package",
"files": [
- "System.Reflection.Metadata.1.2.0-rc3-23811.nupkg.sha512",
+ "System.Reflection.Metadata.1.2.0-rc2-23826.nupkg.sha512",
"System.Reflection.Metadata.nuspec",
"ThirdPartyNotices.txt",
"dotnet_library_license.txt",
diff --git a/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs b/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs
index de5b3a1c0badf..bd6aecf03aa05 100644
--- a/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs
@@ -1529,6 +1529,41 @@ public void M1()
Diagnostic(NullOperationSyntaxTestAnalyzer.ParamsArrayOperationDescriptor.Id, "1").WithLocation(12, 12));
}
+ [WorkItem(9113, "https://github.com/dotnet/roslyn/issues/9113")]
+ [Fact]
+ public void ConversionExpressionCSharp()
+ {
+ const string source = @"
+class X
+{
+ static void Main()
+ {
+ string three = 3.ToString();
+
+ int x = null.Length;
+
+ int y = string.Empty;
+
+ int i = global::MyType();
+ }
+}";
+ CreateCompilationWithMscorlib45(source)
+ .VerifyDiagnostics(
+ // (8,17): error CS0023: Operator '.' cannot be applied to operand of type ''
+ // int x = null.Length;
+ Diagnostic(ErrorCode.ERR_BadUnaryOp, "null.Length").WithArguments(".", "").WithLocation(8, 17),
+ // (10,17): error CS0029: Cannot implicitly convert type 'string' to 'int'
+ // int y = string.Empty;
+ Diagnostic(ErrorCode.ERR_NoImplicitConv, "string.Empty").WithArguments("string", "int").WithLocation(10, 17),
+ // (12,25): error CS0400: The type or namespace name 'MyType' could not be found in the global namespace (are you missing an assembly reference?)
+ // int i = global::MyType();
+ Diagnostic(ErrorCode.ERR_GlobalSingleTypeNameNotFound, "MyType").WithArguments("MyType", "").WithLocation(12, 25))
+ .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new ConversionExpressionCSharpTestAnalyzer() }, null, null, false,
+ Diagnostic(ConversionExpressionCSharpTestAnalyzer.InvalidConversionExpressionDescriptor.Id, "null.Length").WithLocation(8, 17),
+ Diagnostic(ConversionExpressionCSharpTestAnalyzer.InvalidConversionExpressionDescriptor.Id, "string.Empty").WithLocation(10, 17),
+ Diagnostic(ConversionExpressionCSharpTestAnalyzer.InvalidConversionExpressionDescriptor.Id, "global::MyType()").WithLocation(12, 17));
+ }
+
[WorkItem(8114, "https://github.com/dotnet/roslyn/issues/8114")]
[Fact]
public void InvalidOperatorCSharp()
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ExpressionBodiedMemberTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ExpressionBodiedMemberTests.cs
index d87f37e3c93d6..12d767cf5656d 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/ExpressionBodiedMemberTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ExpressionBodiedMemberTests.cs
@@ -774,5 +774,88 @@ public class C
Assert.Equal($"System.Int32 y{i}", model.LookupSymbols(nodes[i].SpanStart, name: $"y{i}").Single().ToTestDisplayString());
}
}
+
+ [Fact, WorkItem(8594, "https://github.com/dotnet/roslyn/pull/8594")]
+ public void ExpressionBodyDeclaredSymbols_01()
+ {
+ var comp = CreateCompilationWithMscorlib(@"
+class C
+{
+ int _p1 = 0;
+ int P1 {
+ get => _p1;
+ set => _p1 = value;
+ }
+ C(int x) => P1 = x;
+ C(int y) : this(y) => _p1 = y;
+ ~C() => _p1 = 0;
+}
+");
+ var tree = comp.SyntaxTrees[0];
+ var model = comp.GetSemanticModel(tree);
+ var dn = tree.GetRoot().DescendantNodes();
+
+ var node = tree.GetRoot()
+ .DescendantNodes()
+ .OfType()
+ .ElementAt(0);
+
+ var fooDef = model.GetDeclaredSymbol(node) as SourcePropertyAccessorSymbol;
+ Assert.NotNull(fooDef);
+ Assert.Equal(SymbolKind.Method, fooDef.Kind);
+ Assert.Equal("get_P1", fooDef.Name);
+
+
+ node = tree.GetRoot()
+ .DescendantNodes()
+ .OfType()
+ .ElementAt(1);
+
+ fooDef = model.GetDeclaredSymbol(node) as SourcePropertyAccessorSymbol;
+ Assert.NotNull(fooDef);
+ Assert.Equal(SymbolKind.Method, fooDef.Kind);
+ Assert.Equal("set_P1", fooDef.Name);
+
+
+ }
+ [Fact, WorkItem(8594, "https://github.com/dotnet/roslyn/pull/8594")]
+ public void ExpressionBodyDeclaredSymbols_02()
+ {
+ var comp = CreateCompilationWithMscorlib(@"
+class C
+{
+ int _p1 = 0;
+ int P1 {
+ get => _p1;
+ set => _p1 = value;
+ }
+}
+");
+ var tree = comp.SyntaxTrees[0];
+ var model = comp.GetSemanticModel(tree);
+
+ var node = tree.GetRoot()
+ .DescendantNodes()
+ .OfType()
+ .ElementAt(0);
+
+ var fooDef = model.GetDeclaredSymbol(node) as SourcePropertyAccessorSymbol;
+ Assert.NotNull(fooDef);
+ Assert.Equal(SymbolKind.Method, fooDef.Kind);
+ Assert.Equal("get_P1", fooDef.Name);
+
+
+ node = tree.GetRoot()
+ .DescendantNodes()
+ .OfType()
+ .ElementAt(1);
+
+ fooDef = model.GetDeclaredSymbol(node) as SourcePropertyAccessorSymbol;
+ Assert.NotNull(fooDef);
+ Assert.Equal(SymbolKind.Method, fooDef.Kind);
+ Assert.Equal("set_P1", fooDef.Name);
+
+ }
+
}
}
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs
index 4702e939acb70..7078d2cd90bf8 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs
@@ -481,15 +481,12 @@ private static void M(string p = """" is object o ? o.ToString() : """")
";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
compilation.VerifyDiagnostics(
- // (2,28): error CS0103: The name 's' does not exist in the current context
+ // (2,11): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
// [Obsolete("" is string s ? s : "")]
- Diagnostic(ErrorCode.ERR_NameNotInContext, "s").WithArguments("s").WithLocation(2, 28),
- // (8,55): error CS0103: The name 'o' does not exist in the current context
+ Diagnostic(ErrorCode.ERR_BadAttributeArgument, @""""" is string s ? s : """"").WithLocation(2, 11),
+ // (8,38): error CS1736: Default parameter value for 'p' must be a compile-time constant
// private static void M(string p = "" is object o ? o.ToString() : "")
- Diagnostic(ErrorCode.ERR_NameNotInContext, "o").WithArguments("o").WithLocation(8, 55),
- // (8,34): error CS1750: A value of type '?' cannot be used as a default parameter because there are no standard conversions to type 'string'
- // private static void M(string p = "" is object o ? o.ToString() : "")
- Diagnostic(ErrorCode.ERR_NoConversionForDefaultParam, "p").WithArguments("?", "string").WithLocation(8, 34)
+ Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, @""""" is object o ? o.ToString() : """"").WithArguments("p").WithLocation(8, 38)
);
}
@@ -1543,7 +1540,18 @@ private static void VerifyModelForDeclarationPattern(SemanticModel model, LetSta
foreach (var reference in references)
{
- Assert.Same(symbol, model.GetSymbolInfo(reference).Symbol);
+ var symbolInfo = model.GetSymbolInfo(reference);
+
+ if ((object)symbolInfo.Symbol != null)
+ {
+ Assert.Same(symbol, symbolInfo.Symbol);
+ }
+ else
+ {
+ Assert.Same(symbol, symbolInfo.CandidateSymbols.Single());
+ Assert.Equal(CandidateReason.NotAVariable, symbolInfo.CandidateReason);
+ }
+
Assert.Same(symbol, model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText).Single());
Assert.True(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText));
}
@@ -3561,6 +3569,15 @@ bool f (object o) => o is int x12 &&
Dummy(x12);
f(null);
}
+
+ System.Action Test13()
+ {
+ return () =>
+ {
+ bool f (object o) => o is int x13 && x13 > 0;
+ f(null);
+ };
+ }
}
";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions.WithLocalFunctionsFeature());
@@ -3657,6 +3674,10 @@ bool f (object o) => o is int x12 &&
Assert.Equal(2, x12Ref.Length);
VerifyModelForDeclarationPattern(model, x12Decl, x12Ref[0]);
VerifyNotAPatternLocal(model, x12Ref[1]);
+
+ var x13Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x13").Single();
+ var x13Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x13").Single();
+ VerifyModelForDeclarationPattern(model, x13Decl, x13Ref);
}
[Fact]
@@ -3695,7 +3716,7 @@ bool Test11(object x11) => 1 is int x11 &&
bool Dummy(params object[] x) {return true;}
}
";
- var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions.WithLocalFunctionsFeature());
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
compilation.VerifyDiagnostics(
// (9,33): error CS1002: ; expected
// void Test1(object o) => let x1 = o;
@@ -3825,7 +3846,7 @@ 52 is int x5 &&
bool Dummy(params object[] x) {return true;}
}
";
- var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions.WithLocalFunctionsFeature());
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
compilation.VerifyDiagnostics(
// (9,33): error CS1002: ; expected
// bool Test1(object o) => let x1 = o;
@@ -3909,5 +3930,2071 @@ 52 is int x5 &&
var x11Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x11").Single();
VerifyModelForDeclarationPattern(model, x11Decl, x11Ref);
}
+
+ [Fact]
+ public void ScopeOfPatternVariables_FieldInitializers_01()
+ {
+ var source =
+@"
+public class X
+{
+ public static void Main()
+ {
+ System.Console.WriteLine(Test1);
+ }
+
+ static bool Test1 = 1 is int x1 && Dummy(x1);
+
+ static bool Dummy(int x)
+ {
+ System.Console.WriteLine(x);
+ return true;
+ }
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+ CompileAndVerify(compilation, expectedOutput: @"1
+True");
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_FieldInitializers_02()
+ {
+ var source =
+@"
+public class X
+{
+ public static void Main()
+ {
+ }
+
+ bool Test3 = 3 is int x3 && x3 > 0;
+
+ bool Test4 = x4 && 4 is int x4;
+
+ bool Test5 = 51 is int x5 &&
+ 52 is int x5 &&
+ x5 > 0;
+
+ bool Test61 = 6 is int x6 && x6 > 0, Test62 = 6 is int x6 && x6 > 0;
+
+ bool Test71 = 7 is int x7 && x7 > 0;
+ bool Test72 = Dummy(x7, 2);
+ void Test73() { Dummy(x7, 3); }
+
+ bool Dummy(params object[] x) {return true;}
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+ compilation.VerifyDiagnostics(
+ // (10,18): error CS0841: Cannot use local variable 'x4' before it is declared
+ // bool Test4 = x4 && 4 is int x4;
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x4").WithArguments("x4").WithLocation(10, 18),
+ // (13,28): error CS0128: A local variable named 'x5' is already defined in this scope
+ // 52 is int x5 &&
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x5").WithArguments("x5").WithLocation(13, 28),
+ // (19,25): error CS0103: The name 'x7' does not exist in the current context
+ // bool Test72 = Dummy(x7, 2);
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(19, 25),
+ // (20,27): error CS0103: The name 'x7' does not exist in the current context
+ // void Test73() { Dummy(x7, 3); }
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(20, 27)
+ );
+
+ var tree = compilation.SyntaxTrees.Single();
+ var model = compilation.GetSemanticModel(tree);
+
+ var x3Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x3").Single();
+ var x3Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x3").Single();
+ VerifyModelForDeclarationPattern(model, x3Decl, x3Ref);
+
+ var x4Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x4").Single();
+ var x4Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x4").Single();
+ VerifyModelForDeclarationPattern(model, x4Decl, x4Ref);
+
+ var x5Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x5").ToArray();
+ var x5Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x5").Single();
+ Assert.Equal(2, x5Decl.Length);
+ VerifyModelForDeclarationPattern(model, x5Decl[0], x5Ref);
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x5Decl[1]);
+
+ var x6Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x6").ToArray();
+ var x6Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x6").ToArray();
+ Assert.Equal(2, x6Decl.Length);
+ Assert.Equal(2, x6Ref.Length);
+ VerifyModelForDeclarationPattern(model, x6Decl[0], x6Ref[0]);
+ VerifyModelForDeclarationPattern(model, x6Decl[1], x6Ref[1]);
+
+ var x7Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x7").Single();
+ var x7Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x7").ToArray();
+ Assert.Equal(3, x7Ref.Length);
+ VerifyModelForDeclarationPattern(model, x7Decl, x7Ref[0]);
+ VerifyNotInScope(model, x7Ref[1]);
+ VerifyNotInScope(model, x7Ref[2]);
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_FieldInitializers_03()
+ {
+ var source =
+@"
+public enum X
+{
+ Test3 = 3 is int x3 ? x3 : 0,
+
+ Test4 = x4 && 4 is int x4 ? 1 : 0,
+
+ Test5 = 51 is int x5 &&
+ 52 is int x5 &&
+ x5 > 0 ? 1 : 0,
+
+ Test61 = 6 is int x6 && x6 > 0 ? 1 : 0, Test62 = 6 is int x6 && x6 > 0 ? 1 : 0,
+
+ Test71 = 7 is int x7 && x7 > 0 ? 1 : 0,
+ Test72 = x7,
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll, parseOptions: patternParseOptions);
+ compilation.VerifyDiagnostics(
+ // (6,13): error CS0841: Cannot use local variable 'x4' before it is declared
+ // Test4 = x4 && 4 is int x4 ? 1 : 0,
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x4").WithArguments("x4").WithLocation(6, 13),
+ // (9,23): error CS0128: A local variable named 'x5' is already defined in this scope
+ // 52 is int x5 &&
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x5").WithArguments("x5").WithLocation(9, 23),
+ // (12,14): error CS0133: The expression being assigned to 'X.Test61' must be constant
+ // Test61 = 6 is int x6 && x6 > 0 ? 1 : 0, Test62 = 6 is int x6 && x6 > 0 ? 1 : 0,
+ Diagnostic(ErrorCode.ERR_NotConstantExpression, "6 is int x6 && x6 > 0 ? 1 : 0").WithArguments("X.Test61").WithLocation(12, 14),
+ // (12,54): error CS0133: The expression being assigned to 'X.Test62' must be constant
+ // Test61 = 6 is int x6 && x6 > 0 ? 1 : 0, Test62 = 6 is int x6 && x6 > 0 ? 1 : 0,
+ Diagnostic(ErrorCode.ERR_NotConstantExpression, "6 is int x6 && x6 > 0 ? 1 : 0").WithArguments("X.Test62").WithLocation(12, 54),
+ // (14,14): error CS0133: The expression being assigned to 'X.Test71' must be constant
+ // Test71 = 7 is int x7 && x7 > 0 ? 1 : 0,
+ Diagnostic(ErrorCode.ERR_NotConstantExpression, "7 is int x7 && x7 > 0 ? 1 : 0").WithArguments("X.Test71").WithLocation(14, 14),
+ // (15,14): error CS0103: The name 'x7' does not exist in the current context
+ // Test72 = x7,
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(15, 14),
+ // (4,13): error CS0133: The expression being assigned to 'X.Test3' must be constant
+ // Test3 = 3 is int x3 ? x3 : 0,
+ Diagnostic(ErrorCode.ERR_NotConstantExpression, "3 is int x3 ? x3 : 0").WithArguments("X.Test3").WithLocation(4, 13)
+ );
+
+ var tree = compilation.SyntaxTrees.Single();
+ var model = compilation.GetSemanticModel(tree);
+
+ var x3Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x3").Single();
+ var x3Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x3").Single();
+ VerifyModelForDeclarationPattern(model, x3Decl, x3Ref);
+
+ var x4Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x4").Single();
+ var x4Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x4").Single();
+ VerifyModelForDeclarationPattern(model, x4Decl, x4Ref);
+
+ var x5Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x5").ToArray();
+ var x5Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x5").Single();
+ Assert.Equal(2, x5Decl.Length);
+ VerifyModelForDeclarationPattern(model, x5Decl[0], x5Ref);
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x5Decl[1]);
+
+ var x6Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x6").ToArray();
+ var x6Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x6").ToArray();
+ Assert.Equal(2, x6Decl.Length);
+ Assert.Equal(2, x6Ref.Length);
+ VerifyModelForDeclarationPattern(model, x6Decl[0], x6Ref[0]);
+ VerifyModelForDeclarationPattern(model, x6Decl[1], x6Ref[1]);
+
+ var x7Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x7").Single();
+ var x7Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x7").ToArray();
+ Assert.Equal(2, x7Ref.Length);
+ VerifyModelForDeclarationPattern(model, x7Decl, x7Ref[0]);
+ VerifyNotInScope(model, x7Ref[1]);
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_FieldInitializers_04()
+ {
+ var source =
+@"
+public class X
+{
+ public static void Main()
+ {
+ }
+
+ const bool Test3 = 3 is int x3 && x3 > 0;
+
+ const bool Test4 = x4 && 4 is int x4;
+
+ const bool Test5 = 51 is int x5 &&
+ 52 is int x5 &&
+ x5 > 0;
+
+ const bool Test61 = 6 is int x6 && x6 > 0, Test62 = 6 is int x6 && x6 > 0;
+
+ const bool Test71 = 7 is int x7 && x7 > 0;
+ const bool Test72 = x7 > 2;
+ void Test73() { Dummy(x7, 3); }
+
+ bool Dummy(params object[] x) {return true;}
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+ compilation.VerifyDiagnostics(
+ // (8,24): error CS0133: The expression being assigned to 'X.Test3' must be constant
+ // const bool Test3 = 3 is int x3 && x3 > 0;
+ Diagnostic(ErrorCode.ERR_NotConstantExpression, "3 is int x3 && x3 > 0").WithArguments("X.Test3").WithLocation(8, 24),
+ // (10,24): error CS0841: Cannot use local variable 'x4' before it is declared
+ // const bool Test4 = x4 && 4 is int x4;
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x4").WithArguments("x4").WithLocation(10, 24),
+ // (13,34): error CS0128: A local variable named 'x5' is already defined in this scope
+ // 52 is int x5 &&
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x5").WithArguments("x5").WithLocation(13, 34),
+ // (16,25): error CS0133: The expression being assigned to 'X.Test61' must be constant
+ // const bool Test61 = 6 is int x6 && x6 > 0, Test62 = 6 is int x6 && x6 > 0;
+ Diagnostic(ErrorCode.ERR_NotConstantExpression, "6 is int x6 && x6 > 0").WithArguments("X.Test61").WithLocation(16, 25),
+ // (16,57): error CS0133: The expression being assigned to 'X.Test62' must be constant
+ // const bool Test61 = 6 is int x6 && x6 > 0, Test62 = 6 is int x6 && x6 > 0;
+ Diagnostic(ErrorCode.ERR_NotConstantExpression, "6 is int x6 && x6 > 0").WithArguments("X.Test62").WithLocation(16, 57),
+ // (18,25): error CS0133: The expression being assigned to 'X.Test71' must be constant
+ // const bool Test71 = 7 is int x7 && x7 > 0;
+ Diagnostic(ErrorCode.ERR_NotConstantExpression, "7 is int x7 && x7 > 0").WithArguments("X.Test71").WithLocation(18, 25),
+ // (19,25): error CS0103: The name 'x7' does not exist in the current context
+ // const bool Test72 = x7 > 2;
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(19, 25),
+ // (20,27): error CS0103: The name 'x7' does not exist in the current context
+ // void Test73() { Dummy(x7, 3); }
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(20, 27)
+ );
+
+ var tree = compilation.SyntaxTrees.Single();
+ var model = compilation.GetSemanticModel(tree);
+
+ var x3Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x3").Single();
+ var x3Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x3").Single();
+ VerifyModelForDeclarationPattern(model, x3Decl, x3Ref);
+
+ var x4Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x4").Single();
+ var x4Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x4").Single();
+ VerifyModelForDeclarationPattern(model, x4Decl, x4Ref);
+
+ var x5Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x5").ToArray();
+ var x5Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x5").Single();
+ Assert.Equal(2, x5Decl.Length);
+ VerifyModelForDeclarationPattern(model, x5Decl[0], x5Ref);
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x5Decl[1]);
+
+ var x6Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x6").ToArray();
+ var x6Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x6").ToArray();
+ Assert.Equal(2, x6Decl.Length);
+ Assert.Equal(2, x6Ref.Length);
+ VerifyModelForDeclarationPattern(model, x6Decl[0], x6Ref[0]);
+ VerifyModelForDeclarationPattern(model, x6Decl[1], x6Ref[1]);
+
+ var x7Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x7").Single();
+ var x7Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x7").ToArray();
+ Assert.Equal(3, x7Ref.Length);
+ VerifyModelForDeclarationPattern(model, x7Decl, x7Ref[0]);
+ VerifyNotInScope(model, x7Ref[1]);
+ VerifyNotInScope(model, x7Ref[2]);
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_PropertyInitializers_01()
+ {
+ var source =
+@"
+public class X
+{
+ public static void Main()
+ {
+ System.Console.WriteLine(Test1);
+ }
+
+ static bool Test1 {get;} = 1 is int x1 && Dummy(x1);
+
+ static bool Dummy(int x)
+ {
+ System.Console.WriteLine(x);
+ return true;
+ }
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+ CompileAndVerify(compilation, expectedOutput: @"1
+True");
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_PropertyInitializers_02()
+ {
+ var source =
+@"
+public class X
+{
+ public static void Main()
+ {
+ }
+
+ bool Test3 {get;} = 3 is int x3 && x3 > 0;
+
+ bool Test4 {get;} = x4 && 4 is int x4;
+
+ bool Test5 {get;} = 51 is int x5 &&
+ 52 is int x5 &&
+ x5 > 0;
+
+ bool Test61 {get;} = 6 is int x6 && x6 > 0; bool Test62 {get;} = 6 is int x6 && x6 > 0;
+
+ bool Test71 {get;} = 7 is int x7 && x7 > 0;
+ bool Test72 {get;} = Dummy(x7, 2);
+ void Test73() { Dummy(x7, 3); }
+
+ bool Dummy(params object[] x) {return true;}
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+ compilation.VerifyDiagnostics(
+ // (10,25): error CS0841: Cannot use local variable 'x4' before it is declared
+ // bool Test4 {get;} = x4 && 4 is int x4;
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x4").WithArguments("x4").WithLocation(10, 25),
+ // (13,28): error CS0128: A local variable named 'x5' is already defined in this scope
+ // 52 is int x5 &&
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x5").WithArguments("x5").WithLocation(13, 28),
+ // (19,32): error CS0103: The name 'x7' does not exist in the current context
+ // bool Test72 {get;} = Dummy(x7, 2);
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(19, 32),
+ // (20,27): error CS0103: The name 'x7' does not exist in the current context
+ // void Test73() { Dummy(x7, 3); }
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(20, 27)
+ );
+
+ var tree = compilation.SyntaxTrees.Single();
+ var model = compilation.GetSemanticModel(tree);
+
+ var x3Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x3").Single();
+ var x3Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x3").Single();
+ VerifyModelForDeclarationPattern(model, x3Decl, x3Ref);
+
+ var x4Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x4").Single();
+ var x4Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x4").Single();
+ VerifyModelForDeclarationPattern(model, x4Decl, x4Ref);
+
+ var x5Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x5").ToArray();
+ var x5Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x5").Single();
+ Assert.Equal(2, x5Decl.Length);
+ VerifyModelForDeclarationPattern(model, x5Decl[0], x5Ref);
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x5Decl[1]);
+
+ var x6Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x6").ToArray();
+ var x6Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x6").ToArray();
+ Assert.Equal(2, x6Decl.Length);
+ Assert.Equal(2, x6Ref.Length);
+ VerifyModelForDeclarationPattern(model, x6Decl[0], x6Ref[0]);
+ VerifyModelForDeclarationPattern(model, x6Decl[1], x6Ref[1]);
+
+ var x7Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x7").Single();
+ var x7Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x7").ToArray();
+ Assert.Equal(3, x7Ref.Length);
+ VerifyModelForDeclarationPattern(model, x7Decl, x7Ref[0]);
+ VerifyNotInScope(model, x7Ref[1]);
+ VerifyNotInScope(model, x7Ref[2]);
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_ParameterDefault_01()
+ {
+ var source =
+@"
+public class X
+{
+ public static void Main()
+ {
+ }
+
+ void Test3(bool p = 3 is int x3 && x3 > 0)
+ {}
+
+ void Test4(bool p = x4 && 4 is int x4)
+ {}
+
+ void Test5(bool p = 51 is int x5 &&
+ 52 is int x5 &&
+ x5 > 0)
+ {}
+
+ void Test61(bool p1 = 6 is int x6 && x6 > 0, bool p2 = 6 is int x6 && x6 > 0)
+ {}
+
+ void Test71(bool p = 7 is int x7 && x7 > 0)
+ {
+ }
+
+ void Test72(bool p = x7 > 2)
+ {}
+
+ void Test73() { Dummy(x7, 3); }
+
+ bool Dummy(params object[] x) {return true;}
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+ compilation.VerifyDiagnostics(
+ // (8,25): error CS1736: Default parameter value for 'p' must be a compile-time constant
+ // void Test3(bool p = 3 is int x3 && x3 > 0)
+ Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "3 is int x3 && x3 > 0").WithArguments("p").WithLocation(8, 25),
+ // (11,25): error CS0841: Cannot use local variable 'x4' before it is declared
+ // void Test4(bool p = x4 && 4 is int x4)
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x4").WithArguments("x4").WithLocation(11, 25),
+ // (11,21): error CS1750: A value of type '?' cannot be used as a default parameter because there are no standard conversions to type 'bool'
+ // void Test4(bool p = x4 && 4 is int x4)
+ Diagnostic(ErrorCode.ERR_NoConversionForDefaultParam, "p").WithArguments("?", "bool").WithLocation(11, 21),
+ // (15,35): error CS0128: A local variable named 'x5' is already defined in this scope
+ // 52 is int x5 &&
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x5").WithArguments("x5").WithLocation(15, 35),
+ // (14,21): error CS1750: A value of type '?' cannot be used as a default parameter because there are no standard conversions to type 'bool'
+ // void Test5(bool p = 51 is int x5 &&
+ Diagnostic(ErrorCode.ERR_NoConversionForDefaultParam, "p").WithArguments("?", "bool").WithLocation(14, 21),
+ // (19,27): error CS1736: Default parameter value for 'p1' must be a compile-time constant
+ // void Test61(bool p1 = 6 is int x6 && x6 > 0, bool p2 = 6 is int x6 && x6 > 0)
+ Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "6 is int x6 && x6 > 0").WithArguments("p1").WithLocation(19, 27),
+ // (19,60): error CS1736: Default parameter value for 'p2' must be a compile-time constant
+ // void Test61(bool p1 = 6 is int x6 && x6 > 0, bool p2 = 6 is int x6 && x6 > 0)
+ Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "6 is int x6 && x6 > 0").WithArguments("p2").WithLocation(19, 60),
+ // (22,26): error CS1736: Default parameter value for 'p' must be a compile-time constant
+ // void Test71(bool p = 7 is int x7 && x7 > 0)
+ Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "7 is int x7 && x7 > 0").WithArguments("p").WithLocation(22, 26),
+ // (26,26): error CS0103: The name 'x7' does not exist in the current context
+ // void Test72(bool p = x7 > 2)
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(26, 26),
+ // (29,27): error CS0103: The name 'x7' does not exist in the current context
+ // void Test73() { Dummy(x7, 3); }
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(29, 27)
+ );
+
+ var tree = compilation.SyntaxTrees.Single();
+ var model = compilation.GetSemanticModel(tree);
+
+ var x3Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x3").Single();
+ var x3Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x3").Single();
+ VerifyModelForDeclarationPattern(model, x3Decl, x3Ref);
+
+ var x4Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x4").Single();
+ var x4Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x4").Single();
+ VerifyModelForDeclarationPattern(model, x4Decl, x4Ref);
+
+ var x5Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x5").ToArray();
+ var x5Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x5").Single();
+ Assert.Equal(2, x5Decl.Length);
+ VerifyModelForDeclarationPattern(model, x5Decl[0], x5Ref);
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x5Decl[1]);
+
+ var x6Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x6").ToArray();
+ var x6Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x6").ToArray();
+ Assert.Equal(2, x6Decl.Length);
+ Assert.Equal(2, x6Ref.Length);
+ VerifyModelForDeclarationPattern(model, x6Decl[0], x6Ref[0]);
+ VerifyModelForDeclarationPattern(model, x6Decl[1], x6Ref[1]);
+
+ var x7Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x7").Single();
+ var x7Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x7").ToArray();
+ Assert.Equal(3, x7Ref.Length);
+ VerifyModelForDeclarationPattern(model, x7Decl, x7Ref[0]);
+ VerifyNotInScope(model, x7Ref[1]);
+ VerifyNotInScope(model, x7Ref[2]);
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_Attribute_01()
+ {
+ var source =
+@"
+public class X
+{
+ public static void Main()
+ {
+ }
+
+ [Test(p = 3 is int x3 && x3 > 0)]
+ [Test(p = x4 && 4 is int x4)]
+ [Test(p = 51 is int x5 &&
+ 52 is int x5 &&
+ x5 > 0)]
+ [Test(p1 = 6 is int x6 && x6 > 0, p2 = 6 is int x6 && x6 > 0)]
+ [Test(p = 7 is int x7 && x7 > 0)]
+ [Test(p = x7 > 2)]
+ void Test73() { Dummy(x7, 3); }
+
+ bool Dummy(params object[] x) {return true;}
+}
+
+class Test : System.Attribute
+{
+ public bool p {get; set;}
+ public bool p1 {get; set;}
+ public bool p2 {get; set;}
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+ compilation.VerifyDiagnostics(
+ // (8,15): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
+ // [Test(p = 3 is int x3 && x3 > 0)]
+ Diagnostic(ErrorCode.ERR_BadAttributeArgument, "3 is int x3 && x3 > 0").WithLocation(8, 15),
+ // (9,15): error CS0841: Cannot use local variable 'x4' before it is declared
+ // [Test(p = x4 && 4 is int x4)]
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x4").WithArguments("x4").WithLocation(9, 15),
+ // (11,25): error CS0128: A local variable named 'x5' is already defined in this scope
+ // 52 is int x5 &&
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x5").WithArguments("x5").WithLocation(11, 25),
+ // (13,53): error CS0128: A local variable named 'x6' is already defined in this scope
+ // [Test(p1 = 6 is int x6 && x6 > 0, p2 = 6 is int x6 && x6 > 0)]
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x6").WithArguments("x6").WithLocation(13, 53),
+ // (13,16): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
+ // [Test(p1 = 6 is int x6 && x6 > 0, p2 = 6 is int x6 && x6 > 0)]
+ Diagnostic(ErrorCode.ERR_BadAttributeArgument, "6 is int x6 && x6 > 0").WithLocation(13, 16),
+ // (14,15): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
+ // [Test(p = 7 is int x7 && x7 > 0)]
+ Diagnostic(ErrorCode.ERR_BadAttributeArgument, "7 is int x7 && x7 > 0").WithLocation(14, 15),
+ // (15,15): error CS0103: The name 'x7' does not exist in the current context
+ // [Test(p = x7 > 2)]
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(15, 15),
+ // (16,27): error CS0103: The name 'x7' does not exist in the current context
+ // void Test73() { Dummy(x7, 3); }
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(16, 27)
+ );
+
+ var tree = compilation.SyntaxTrees.Single();
+ var model = compilation.GetSemanticModel(tree);
+
+ var x3Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x3").Single();
+ var x3Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x3").Single();
+ VerifyModelForDeclarationPattern(model, x3Decl, x3Ref);
+
+ var x4Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x4").Single();
+ var x4Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x4").Single();
+ VerifyModelForDeclarationPattern(model, x4Decl, x4Ref);
+
+ var x5Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x5").ToArray();
+ var x5Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x5").Single();
+ Assert.Equal(2, x5Decl.Length);
+ VerifyModelForDeclarationPattern(model, x5Decl[0], x5Ref);
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x5Decl[1]);
+
+ var x6Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x6").ToArray();
+ var x6Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x6").ToArray();
+ Assert.Equal(2, x6Decl.Length);
+ Assert.Equal(2, x6Ref.Length);
+ VerifyModelForDeclarationPattern(model, x6Decl[0], x6Ref);
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x6Decl[1]);
+
+ var x7Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x7").Single();
+ var x7Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x7").ToArray();
+ Assert.Equal(3, x7Ref.Length);
+ VerifyModelForDeclarationPattern(model, x7Decl, x7Ref[0]);
+ VerifyNotInScope(model, x7Ref[1]);
+ VerifyNotInScope(model, x7Ref[2]);
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_Attribute_02()
+ {
+ var source =
+@"
+public class X
+{
+ public static void Main()
+ {
+ }
+
+ [Test(3 is int x3 && x3 > 0)]
+ [Test(x4 && 4 is int x4)]
+ [Test(51 is int x5 &&
+ 52 is int x5 &&
+ x5 > 0)]
+ [Test(6 is int x6 && x6 > 0, 6 is int x6 && x6 > 0)]
+ [Test(7 is int x7 && x7 > 0)]
+ [Test(x7 > 2)]
+ void Test73() { Dummy(x7, 3); }
+
+ bool Dummy(params object[] x) {return true;}
+}
+
+class Test : System.Attribute
+{
+ public Test(bool p) {}
+ public Test(bool p1, bool p2) {}
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+ compilation.VerifyDiagnostics(
+ // (8,11): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
+ // [Test(3 is int x3 && x3 > 0)]
+ Diagnostic(ErrorCode.ERR_BadAttributeArgument, "3 is int x3 && x3 > 0").WithLocation(8, 11),
+ // (9,11): error CS0841: Cannot use local variable 'x4' before it is declared
+ // [Test(x4 && 4 is int x4)]
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x4").WithArguments("x4").WithLocation(9, 11),
+ // (11,21): error CS0128: A local variable named 'x5' is already defined in this scope
+ // 52 is int x5 &&
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x5").WithArguments("x5").WithLocation(11, 21),
+ // (13,43): error CS0128: A local variable named 'x6' is already defined in this scope
+ // [Test(6 is int x6 && x6 > 0, 6 is int x6 && x6 > 0)]
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x6").WithArguments("x6").WithLocation(13, 43),
+ // (14,11): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
+ // [Test(7 is int x7 && x7 > 0)]
+ Diagnostic(ErrorCode.ERR_BadAttributeArgument, "7 is int x7 && x7 > 0").WithLocation(14, 11),
+ // (15,11): error CS0103: The name 'x7' does not exist in the current context
+ // [Test(x7 > 2)]
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(15, 11),
+ // (16,27): error CS0103: The name 'x7' does not exist in the current context
+ // void Test73() { Dummy(x7, 3); }
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(16, 27)
+ );
+
+ var tree = compilation.SyntaxTrees.Single();
+ var model = compilation.GetSemanticModel(tree);
+
+ var x3Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x3").Single();
+ var x3Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x3").Single();
+ VerifyModelForDeclarationPattern(model, x3Decl, x3Ref);
+
+ var x4Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x4").Single();
+ var x4Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x4").Single();
+ VerifyModelForDeclarationPattern(model, x4Decl, x4Ref);
+
+ var x5Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x5").ToArray();
+ var x5Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x5").Single();
+ Assert.Equal(2, x5Decl.Length);
+ VerifyModelForDeclarationPattern(model, x5Decl[0], x5Ref);
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x5Decl[1]);
+
+ var x6Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x6").ToArray();
+ var x6Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x6").ToArray();
+ Assert.Equal(2, x6Decl.Length);
+ Assert.Equal(2, x6Ref.Length);
+ VerifyModelForDeclarationPattern(model, x6Decl[0], x6Ref);
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x6Decl[1]);
+
+ var x7Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x7").Single();
+ var x7Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x7").ToArray();
+ Assert.Equal(3, x7Ref.Length);
+ VerifyModelForDeclarationPattern(model, x7Decl, x7Ref[0]);
+ VerifyNotInScope(model, x7Ref[1]);
+ VerifyNotInScope(model, x7Ref[2]);
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_ConstructorInitializers_01()
+ {
+ var source =
+@"
+public class X
+{
+ public static void Main()
+ {
+ }
+
+ X(byte x)
+ : this(3 is int x3 && x3 > 0)
+ {}
+
+ X(sbyte x)
+ : this(x4 && 4 is int x4)
+ {}
+
+ X(short x)
+ : this(51 is int x5 &&
+ 52 is int x5 &&
+ x5 > 0)
+ {}
+
+ X(ushort x)
+ : this(6 is int x6 && x6 > 0, 6 is int x6 && x6 > 0)
+ {}
+
+ X(int x)
+ : this(7 is int x7 && x7 > 0)
+ {}
+ X(uint x)
+ : this(x7, 2)
+ {}
+ void Test73() { Dummy(x7, 3); }
+
+ X(params object[] x) {}
+ bool Dummy(params object[] x) {return true;}
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+ compilation.VerifyDiagnostics(
+ // (13,16): error CS0841: Cannot use local variable 'x4' before it is declared
+ // : this(x4 && 4 is int x4)
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x4").WithArguments("x4").WithLocation(13, 16),
+ // (18,26): error CS0128: A local variable named 'x5' is already defined in this scope
+ // 52 is int x5 &&
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x5").WithArguments("x5").WithLocation(18, 26),
+ // (23,48): error CS0128: A local variable named 'x6' is already defined in this scope
+ // : this(6 is int x6 && x6 > 0, 6 is int x6 && x6 > 0)
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x6").WithArguments("x6").WithLocation(23, 48),
+ // (30,16): error CS0103: The name 'x7' does not exist in the current context
+ // : this(x7, 2)
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(30, 16),
+ // (32,27): error CS0103: The name 'x7' does not exist in the current context
+ // void Test73() { Dummy(x7, 3); }
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(32, 27)
+ );
+
+ var tree = compilation.SyntaxTrees.Single();
+ var model = compilation.GetSemanticModel(tree);
+
+ var x3Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x3").Single();
+ var x3Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x3").Single();
+ VerifyModelForDeclarationPattern(model, x3Decl, x3Ref);
+
+ var x4Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x4").Single();
+ var x4Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x4").Single();
+ VerifyModelForDeclarationPattern(model, x4Decl, x4Ref);
+
+ var x5Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x5").ToArray();
+ var x5Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x5").Single();
+ Assert.Equal(2, x5Decl.Length);
+ VerifyModelForDeclarationPattern(model, x5Decl[0], x5Ref);
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x5Decl[1]);
+
+ var x6Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x6").ToArray();
+ var x6Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x6").ToArray();
+ Assert.Equal(2, x6Decl.Length);
+ Assert.Equal(2, x6Ref.Length);
+ VerifyModelForDeclarationPattern(model, x6Decl[0], x6Ref);
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x6Decl[1]);
+
+ var x7Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x7").Single();
+ var x7Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x7").ToArray();
+ Assert.Equal(3, x7Ref.Length);
+ VerifyModelForDeclarationPattern(model, x7Decl, x7Ref[0]);
+ VerifyNotInScope(model, x7Ref[1]);
+ VerifyNotInScope(model, x7Ref[2]);
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_ConstructorInitializers_02()
+ {
+ var source =
+@"
+public class X : Y
+{
+ public static void Main()
+ {
+ }
+
+ X(byte x)
+ : base(3 is int x3 && x3 > 0)
+ {}
+
+ X(sbyte x)
+ : base(x4 && 4 is int x4)
+ {}
+
+ X(short x)
+ : base(51 is int x5 &&
+ 52 is int x5 &&
+ x5 > 0)
+ {}
+
+ X(ushort x)
+ : base(6 is int x6 && x6 > 0, 6 is int x6 && x6 > 0)
+ {}
+
+ X(int x)
+ : base(7 is int x7 && x7 > 0)
+ {}
+ X(uint x)
+ : base(x7, 2)
+ {}
+ void Test73() { Dummy(x7, 3); }
+
+ bool Dummy(params object[] x) {return true;}
+}
+
+public class Y
+{
+ public Y(params object[] x) {}
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+ compilation.VerifyDiagnostics(
+ // (13,16): error CS0841: Cannot use local variable 'x4' before it is declared
+ // : base(x4 && 4 is int x4)
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x4").WithArguments("x4").WithLocation(13, 16),
+ // (18,26): error CS0128: A local variable named 'x5' is already defined in this scope
+ // 52 is int x5 &&
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x5").WithArguments("x5").WithLocation(18, 26),
+ // (23,48): error CS0128: A local variable named 'x6' is already defined in this scope
+ // : base(6 is int x6 && x6 > 0, 6 is int x6 && x6 > 0)
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x6").WithArguments("x6").WithLocation(23, 48),
+ // (30,16): error CS0103: The name 'x7' does not exist in the current context
+ // : base(x7, 2)
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(30, 16),
+ // (32,27): error CS0103: The name 'x7' does not exist in the current context
+ // void Test73() { Dummy(x7, 3); }
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x7").WithArguments("x7").WithLocation(32, 27)
+ );
+
+ var tree = compilation.SyntaxTrees.Single();
+ var model = compilation.GetSemanticModel(tree);
+
+ var x3Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x3").Single();
+ var x3Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x3").Single();
+ VerifyModelForDeclarationPattern(model, x3Decl, x3Ref);
+
+ var x4Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x4").Single();
+ var x4Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x4").Single();
+ VerifyModelForDeclarationPattern(model, x4Decl, x4Ref);
+
+ var x5Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x5").ToArray();
+ var x5Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x5").Single();
+ Assert.Equal(2, x5Decl.Length);
+ VerifyModelForDeclarationPattern(model, x5Decl[0], x5Ref);
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x5Decl[1]);
+
+ var x6Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x6").ToArray();
+ var x6Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x6").ToArray();
+ Assert.Equal(2, x6Decl.Length);
+ Assert.Equal(2, x6Ref.Length);
+ VerifyModelForDeclarationPattern(model, x6Decl[0], x6Ref);
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x6Decl[1]);
+
+ var x7Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x7").Single();
+ var x7Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x7").ToArray();
+ Assert.Equal(3, x7Ref.Length);
+ VerifyModelForDeclarationPattern(model, x7Decl, x7Ref[0]);
+ VerifyNotInScope(model, x7Ref[1]);
+ VerifyNotInScope(model, x7Ref[2]);
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_ConstructorInitializers_03()
+ {
+ var source =
+@"using System;
+public class X
+{
+ public static void Main()
+ {
+ new D(1);
+ new D(10);
+ new D(1.2);
+ }
+}
+class D
+{
+ public D(object o) : this(o is int x && x >= 5)
+ {
+ Console.WriteLine(x);
+ }
+
+ public D(bool b) { Console.WriteLine(b); }
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+ compilation.VerifyDiagnostics(
+ // (15,27): error CS0103: The name 'x' does not exist in the current context
+ // Console.WriteLine(x);
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(15, 27)
+ );
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_ConstructorInitializers_04()
+ {
+ var source =
+@"using System;
+public class X
+{
+ public static void Main()
+ {
+ new D(1);
+ new D(10);
+ new D(1.2);
+ }
+}
+class D : C
+{
+ public D(object o) : base(o is int x && x >= 5)
+ {
+ Console.WriteLine(x);
+ }
+}
+
+class C
+{
+ public C(bool b) { Console.WriteLine(b); }
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+ compilation.VerifyDiagnostics(
+ // (15,27): error CS0103: The name 'x' does not exist in the current context
+ // Console.WriteLine(x);
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(15, 27)
+ );
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_SwitchLabelGuard_01()
+ {
+ var source =
+@"
+public class X
+{
+ public static void Main()
+ {
+ }
+
+ bool Dummy(params object[] x) { return true; }
+
+ void Test1(int val)
+ {
+ switch (val)
+ {
+ case 0 when Dummy(true is var x1, x1):
+ Dummy(x1);
+ break;
+ case 1 when Dummy(true is var x1, x1):
+ Dummy(x1);
+ break;
+ case 2 when Dummy(true is var x1, x1):
+ Dummy(x1);
+ break;
+ }
+ }
+
+ void Test2(int val)
+ {
+ switch (val)
+ {
+ case 0 when Dummy(x2, true is var x2):
+ Dummy(x2);
+ break;
+ }
+ }
+
+ void Test3(int x3, int val)
+ {
+ switch (val)
+ {
+ case 0 when Dummy(true is var x3, x3):
+ Dummy(x3);
+ break;
+ }
+ }
+
+ void Test4(int val)
+ {
+ var x4 = 11;
+ switch (val)
+ {
+ case 0 when Dummy(true is var x4, x4):
+ Dummy(x4);
+ break;
+ case 1 when Dummy(x4): Dummy(x4); break;
+ }
+ }
+
+ void Test5(int val)
+ {
+ switch (val)
+ {
+ case 0 when Dummy(true is var x5, x5):
+ Dummy(x5);
+ break;
+ }
+
+ var x5 = 11;
+ Dummy(x5);
+ }
+
+ void Test6(int val)
+ {
+ let x6 = 11;
+ switch (val)
+ {
+ case 0 when Dummy(x6):
+ Dummy(x6);
+ break;
+ case 1 when Dummy(true is var x6, x6):
+ Dummy(x6);
+ break;
+ }
+ }
+
+ void Test7(int val)
+ {
+ switch (val)
+ {
+ case 0 when Dummy(true is var x7, x7):
+ Dummy(x7);
+ break;
+ }
+
+ let x7 = 11;
+ Dummy(x7);
+ }
+
+ void Test8(int val)
+ {
+ switch (val)
+ {
+ case 0 when Dummy(true is var x8, x8, false is var x8, x8):
+ Dummy(x8);
+ break;
+ }
+ }
+
+ void Test9(int val)
+ {
+ switch (val)
+ {
+ case 0 when Dummy(x9):
+ int x9 = 9;
+ Dummy(x9);
+ break;
+ case 2 when Dummy(x9 = 9):
+ Dummy(x9);
+ break;
+ case 1 when Dummy(true is var x9, x9):
+ Dummy(x9);
+ break;
+ }
+ }
+
+ void Test10(int val)
+ {
+ switch (val)
+ {
+ case 1 when Dummy(true is var x10, x10):
+ Dummy(x10);
+ break;
+ case 0 when Dummy(x10):
+ let x10 = 10;
+ Dummy(x10);
+ break;
+ case 2 when Dummy(x10 = 10, x10):
+ Dummy(x10);
+ break;
+ }
+ }
+
+ void Test11(int val)
+ {
+ switch (x11 ? val : 0)
+ {
+ case 0 when Dummy(x11):
+ Dummy(x11, 0);
+ break;
+ case 1 when Dummy(true is var x11, x11):
+ Dummy(x11, 1);
+ break;
+ }
+ }
+
+ void Test12(int val)
+ {
+ switch (x12 ? val : 0)
+ {
+ case 0 when Dummy(true is var x12, x12):
+ Dummy(x12, 0);
+ break;
+ case 1 when Dummy(x12):
+ Dummy(x12, 1);
+ break;
+ }
+ }
+
+ void Test13()
+ {
+ switch (1 is var x13 ? x13 : 0)
+ {
+ case 0 when Dummy(x13):
+ Dummy(x13);
+ break;
+ case 1 when Dummy(true is var x13, x13):
+ Dummy(x13);
+ break;
+ }
+ }
+
+ void Test14(int val)
+ {
+ switch (val)
+ {
+ case 1 when Dummy(true is var x14, x14):
+ Dummy(x14);
+ Dummy(true is var x14, x14);
+ Dummy(x14);
+ break;
+ }
+ }
+
+ void Test15(int val)
+ {
+ switch (val)
+ {
+ case 0 when Dummy(true is var x15, x15):
+ case 1 when Dummy(true is var x15, x15):
+ Dummy(x15);
+ break;
+ }
+ }
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+
+ compilation.VerifyDiagnostics(
+ // (30,31): error CS0841: Cannot use local variable 'x2' before it is declared
+ // case 0 when Dummy(x2, true is var x2):
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x2").WithArguments("x2").WithLocation(30, 31),
+ // (40,43): error CS0136: A local or parameter named 'x3' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case 0 when Dummy(true is var x3, x3):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x3").WithArguments("x3").WithLocation(40, 43),
+ // (51,43): error CS0136: A local or parameter named 'x4' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case 0 when Dummy(true is var x4, x4):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x4").WithArguments("x4").WithLocation(51, 43),
+ // (62,43): error CS0136: A local or parameter named 'x5' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case 0 when Dummy(true is var x5, x5):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x5").WithArguments("x5").WithLocation(62, 43),
+ // (79,43): error CS0136: A local or parameter named 'x6' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case 1 when Dummy(true is var x6, x6):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x6").WithArguments("x6").WithLocation(79, 43),
+ // (89,43): error CS0136: A local or parameter named 'x7' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case 0 when Dummy(true is var x7, x7):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x7").WithArguments("x7").WithLocation(89, 43),
+ // (102,64): error CS0128: A local variable named 'x8' is already defined in this scope
+ // case 0 when Dummy(true is var x8, x8, false is var x8, x8):
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x8").WithArguments("x8").WithLocation(102, 64),
+ // (112,31): error CS0841: Cannot use local variable 'x9' before it is declared
+ // case 0 when Dummy(x9):
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x9").WithArguments("x9").WithLocation(112, 31),
+ // (119,43): error CS0136: A local or parameter named 'x9' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case 1 when Dummy(true is var x9, x9):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x9").WithArguments("x9").WithLocation(119, 43),
+ // (129,43): error CS0136: A local or parameter named 'x10' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case 1 when Dummy(true is var x10, x10):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x10").WithArguments("x10").WithLocation(129, 43),
+ // (132,31): error CS0841: Cannot use local variable 'x10' before it is declared
+ // case 0 when Dummy(x10):
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x10").WithArguments("x10").WithLocation(132, 31),
+ // (136,31): error CS0131: The left-hand side of an assignment must be a variable, property or indexer
+ // case 2 when Dummy(x10 = 10):
+ Diagnostic(ErrorCode.ERR_AssgLvalueExpected, "x10").WithLocation(136, 31),
+ // (144,17): error CS0103: The name 'x11' does not exist in the current context
+ // switch (x11 ? val : 0)
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x11").WithArguments("x11").WithLocation(144, 17),
+ // (146,31): error CS0103: The name 'x11' does not exist in the current context
+ // case 0 when Dummy(x11):
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x11").WithArguments("x11").WithLocation(146, 31),
+ // (147,23): error CS0103: The name 'x11' does not exist in the current context
+ // Dummy(x11, 0);
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x11").WithArguments("x11").WithLocation(147, 23),
+ // (157,17): error CS0103: The name 'x12' does not exist in the current context
+ // switch (x12 ? val : 0)
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x12").WithArguments("x12").WithLocation(157, 17),
+ // (162,31): error CS0103: The name 'x12' does not exist in the current context
+ // case 1 when Dummy(x12):
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x12").WithArguments("x12").WithLocation(162, 31),
+ // (163,23): error CS0103: The name 'x12' does not exist in the current context
+ // Dummy(x12, 1);
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x12").WithArguments("x12").WithLocation(163, 23),
+ // (175,43): error CS0136: A local or parameter named 'x13' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case 1 when Dummy(true is var x13, x13):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x13").WithArguments("x13").WithLocation(175, 43),
+ // (187,35): error CS0136: A local or parameter named 'x14' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // Dummy(true is var x14, x14);
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x14").WithArguments("x14").WithLocation(187, 35),
+ // (198,43): error CS0128: A local variable named 'x15' is already defined in this scope
+ // case 1 when Dummy(true is var x15, x15):
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x15").WithArguments("x15").WithLocation(198, 43),
+ // (198,48): error CS0165: Use of unassigned local variable 'x15'
+ // case 1 when Dummy(true is var x15, x15):
+ Diagnostic(ErrorCode.ERR_UseDefViolation, "x15").WithArguments("x15").WithLocation(198, 48)
+ );
+
+ var tree = compilation.SyntaxTrees.Single();
+ var model = compilation.GetSemanticModel(tree);
+
+ var x1Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x1").ToArray();
+ var x1Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x1").ToArray();
+ Assert.Equal(3, x1Decl.Length);
+ Assert.Equal(6, x1Ref.Length);
+ for (int i = 0; i < x1Decl.Length; i++)
+ {
+ VerifyModelForDeclarationPattern(model, x1Decl[i], x1Ref[i*2], x1Ref[i * 2 + 1]);
+ }
+
+ var x2Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x2").Single();
+ var x2Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x2").ToArray();
+ Assert.Equal(2, x2Ref.Length);
+ VerifyModelForDeclarationPattern(model, x2Decl, x2Ref);
+
+ var x3Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x3").Single();
+ var x3Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x3").ToArray();
+ Assert.Equal(2, x3Ref.Length);
+ VerifyModelForDeclarationPattern(model, x3Decl, x3Ref);
+
+ var x4Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x4").Single();
+ var x4Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x4").ToArray();
+ Assert.Equal(4, x4Ref.Length);
+ VerifyModelForDeclarationPattern(model, x4Decl, x4Ref[0], x4Ref[1]);
+ VerifyNotAPatternLocal(model, x4Ref[2]);
+ VerifyNotAPatternLocal(model, x4Ref[3]);
+
+ var x5Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x5").Single();
+ var x5Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x5").ToArray();
+ Assert.Equal(3, x5Ref.Length);
+ VerifyModelForDeclarationPattern(model, x5Decl, x5Ref[0], x5Ref[1]);
+ VerifyNotAPatternLocal(model, x5Ref[2]);
+
+ var x6Decl_1 = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x6").Single();
+ var x6Decl_2 = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x6").Single();
+ var x6Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x6").ToArray();
+ Assert.Equal(4, x6Ref.Length);
+ VerifyModelForDeclarationPattern(model, x6Decl_1, x6Ref[0], x6Ref[1]);
+ VerifyModelForDeclarationPattern(model, x6Decl_2, x6Ref[2], x6Ref[3]);
+
+ var x7Decl_1 = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x7").Single();
+ var x7Decl_2 = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x7").Single();
+ var x7Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x7").ToArray();
+ Assert.Equal(3, x7Ref.Length);
+ VerifyModelForDeclarationPattern(model, x7Decl_1, x7Ref[0], x7Ref[1]);
+ VerifyModelForDeclarationPattern(model, x7Decl_2, x7Ref[2]);
+
+ var x8Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x8").ToArray();
+ var x8Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x8").ToArray();
+ Assert.Equal(2, x8Decl.Length);
+ Assert.Equal(3, x8Ref.Length);
+ for (int i = 0; i < x8Ref.Length; i++)
+ {
+ VerifyModelForDeclarationPattern(model, x8Decl[0], x8Ref[i]);
+ }
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x8Decl[1]);
+
+ var x9Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x9").Single();
+ var x9Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x9").ToArray();
+ Assert.Equal(6, x9Ref.Length);
+ VerifyNotAPatternLocal(model, x9Ref[0]);
+ VerifyNotAPatternLocal(model, x9Ref[1]);
+ VerifyNotAPatternLocal(model, x9Ref[2]);
+ VerifyNotAPatternLocal(model, x9Ref[3]);
+ VerifyModelForDeclarationPattern(model, x9Decl, x9Ref[4], x9Ref[5]);
+
+ var x10Decl_1 = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x10").Single();
+ var x10Decl_2 = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x10").Single();
+ var x10Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x10").ToArray();
+ Assert.Equal(7, x10Ref.Length);
+ VerifyModelForDeclarationPattern(model, x10Decl_1, x10Ref[0], x10Ref[1]);
+ VerifyModelForDeclarationPattern(model, x10Decl_2, x10Ref[2], x10Ref[3], x10Ref[4], x10Ref[5], x10Ref[6]);
+
+ var x11Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x11").Single();
+ var x11Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x11").ToArray();
+ Assert.Equal(5, x11Ref.Length);
+ VerifyNotInScope(model, x11Ref[0]);
+ VerifyNotInScope(model, x11Ref[1]);
+ VerifyNotInScope(model, x11Ref[2]);
+ VerifyModelForDeclarationPattern(model, x11Decl, x11Ref[3], x11Ref[4]);
+
+ var x12Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x12").Single();
+ var x12Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x12").ToArray();
+ Assert.Equal(5, x12Ref.Length);
+ VerifyNotInScope(model, x12Ref[0]);
+ VerifyModelForDeclarationPattern(model, x12Decl, x12Ref[1], x12Ref[2]);
+ VerifyNotInScope(model, x12Ref[3]);
+ VerifyNotInScope(model, x12Ref[4]);
+
+ var x13Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x13").ToArray();
+ var x13Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x13").ToArray();
+ Assert.Equal(2, x13Decl.Length);
+ Assert.Equal(5, x13Ref.Length);
+ VerifyModelForDeclarationPattern(model, x13Decl[0], x13Ref[0], x13Ref[1], x13Ref[2]);
+ VerifyModelForDeclarationPattern(model, x13Decl[1], x13Ref[3], x13Ref[4]);
+
+ var x14Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x14").ToArray();
+ var x14Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x14").ToArray();
+ Assert.Equal(2, x14Decl.Length);
+ Assert.Equal(4, x14Ref.Length);
+ VerifyModelForDeclarationPattern(model, x14Decl[0], x14Ref[0], x14Ref[1], x14Ref[3]);
+ VerifyModelForDeclarationPattern(model, x14Decl[1], x14Ref[2]);
+
+ var x15Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x15").ToArray();
+ var x15Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x15").ToArray();
+ Assert.Equal(2, x15Decl.Length);
+ Assert.Equal(3, x15Ref.Length);
+ for (int i = 0; i < x15Ref.Length; i++)
+ {
+ VerifyModelForDeclarationPattern(model, x15Decl[0], x15Ref[i]);
+ }
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x15Decl[1]);
+ }
+
+ [Fact]
+ public void ScopeOfPatternVariables_SwitchLabelPattern_01()
+ {
+ var source =
+@"
+public class X
+{
+ public static void Main()
+ {
+ }
+
+ bool Dummy(params object[] x) { return true; }
+
+ void Test1(object val)
+ {
+ switch (val)
+ {
+ case byte x1 when Dummy(x1):
+ Dummy(x1);
+ break;
+ case int x1 when Dummy(x1):
+ Dummy(x1);
+ break;
+ case long x1 when Dummy(x1):
+ Dummy(x1);
+ break;
+ }
+ }
+
+ void Test2(object val)
+ {
+ switch (val)
+ {
+ case 0 when Dummy(x2):
+ case int x2:
+ Dummy(x2);
+ break;
+ }
+ }
+
+ void Test3(int x3, object val)
+ {
+ switch (val)
+ {
+ case int x3 when Dummy(x3):
+ Dummy(x3);
+ break;
+ }
+ }
+
+ void Test4(object val)
+ {
+ var x4 = 11;
+ switch (val)
+ {
+ case int x4 when Dummy(x4):
+ Dummy(x4);
+ break;
+ case 1 when Dummy(x4):
+ Dummy(x4);
+ break;
+ }
+ }
+
+ void Test5(object val)
+ {
+ switch (val)
+ {
+ case int x5 when Dummy(x5):
+ Dummy(x5);
+ break;
+ }
+
+ var x5 = 11;
+ Dummy(x5);
+ }
+
+ void Test6(object val)
+ {
+ let x6 = 11;
+ switch (val)
+ {
+ case 0 when Dummy(x6):
+ Dummy(x6);
+ break;
+ case int x6 when Dummy(x6):
+ Dummy(x6);
+ break;
+ }
+ }
+
+ void Test7(object val)
+ {
+ switch (val)
+ {
+ case int x7 when Dummy(x7):
+ Dummy(x7);
+ break;
+ }
+
+ let x7 = 11;
+ Dummy(x7);
+ }
+
+ void Test8(object val)
+ {
+ switch (val)
+ {
+ case int x8
+ when Dummy(x8, false is var x8, x8):
+ Dummy(x8);
+ break;
+ }
+ }
+
+ void Test9(object val)
+ {
+ switch (val)
+ {
+ case 0 when Dummy(x9):
+ int x9 = 9;
+ Dummy(x9);
+ break;
+ case 2 when Dummy(x9 = 9):
+ Dummy(x9);
+ break;
+ case int x9 when Dummy(x9):
+ Dummy(x9);
+ break;
+ }
+ }
+
+ void Test10(object val)
+ {
+ switch (val)
+ {
+ case int x10 when Dummy(x10):
+ Dummy(x10);
+ break;
+ case 0 when Dummy(x10):
+ let x10 = 10;
+ Dummy(x10);
+ break;
+ case 2 when Dummy(x10 = 10, x10):
+ Dummy(x10);
+ break;
+ }
+ }
+
+ void Test11(object val)
+ {
+ switch (x11 ? val : 0)
+ {
+ case 0 when Dummy(x11):
+ Dummy(x11, 0);
+ break;
+ case int x11 when Dummy(x11):
+ Dummy(x11, 1);
+ break;
+ }
+ }
+
+ void Test12(object val)
+ {
+ switch (x12 ? val : 0)
+ {
+ case int x12 when Dummy(x12):
+ Dummy(x12, 0);
+ break;
+ case 1 when Dummy(x12):
+ Dummy(x12, 1);
+ break;
+ }
+ }
+
+ void Test13()
+ {
+ switch (1 is var x13 ? x13 : 0)
+ {
+ case 0 when Dummy(x13):
+ Dummy(x13);
+ break;
+ case int x13 when Dummy(x13):
+ Dummy(x13);
+ break;
+ }
+ }
+
+ void Test14(object val)
+ {
+ switch (val)
+ {
+ case int x14 when Dummy(x14):
+ Dummy(x14);
+ Dummy(true is var x14, x14);
+ Dummy(x14);
+ break;
+ }
+ }
+
+ void Test15(object val)
+ {
+ switch (val)
+ {
+ case int x15 when Dummy(x15):
+ case long x15 when Dummy(x15):
+ Dummy(x15);
+ break;
+ }
+ }
+
+ void Test16(object val)
+ {
+ switch (val)
+ {
+ case int x16 when Dummy(x16):
+ case 1 when Dummy(true is var x16, x16):
+ Dummy(x16);
+ break;
+ }
+ }
+
+ void Test17(object val)
+ {
+ switch (val)
+ {
+ case 0 when Dummy(true is var x17, x17):
+ case int x17 when Dummy(x17):
+ Dummy(x17);
+ break;
+ }
+ }
+}
+";
+ var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
+
+ compilation.VerifyDiagnostics(
+ // (30,31): error CS0841: Cannot use local variable 'x2' before it is declared
+ // case 0 when Dummy(x2):
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x2").WithArguments("x2").WithLocation(30, 31),
+ // (41,22): error CS0136: A local or parameter named 'x3' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case int x3 when Dummy(x3):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x3").WithArguments("x3").WithLocation(41, 22),
+ // (52,22): error CS0136: A local or parameter named 'x4' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case int x4 when Dummy(x4):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x4").WithArguments("x4").WithLocation(52, 22),
+ // (65,22): error CS0136: A local or parameter named 'x5' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case int x5 when Dummy(x5):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x5").WithArguments("x5").WithLocation(65, 22),
+ // (82,22): error CS0136: A local or parameter named 'x6' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case int x6 when Dummy(x6):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x6").WithArguments("x6").WithLocation(82, 22),
+ // (92,22): error CS0136: A local or parameter named 'x7' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case int x7 when Dummy(x7):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x7").WithArguments("x7").WithLocation(92, 22),
+ // (106,49): error CS0128: A local variable named 'x8' is already defined in this scope
+ // when Dummy(x8, false is var x8, x8):
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x8").WithArguments("x8").WithLocation(106, 49),
+ // (116,31): error CS0841: Cannot use local variable 'x9' before it is declared
+ // case 0 when Dummy(x9):
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x9").WithArguments("x9").WithLocation(116, 31),
+ // (123,22): error CS0136: A local or parameter named 'x9' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case int x9 when Dummy(x9):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x9").WithArguments("x9").WithLocation(123, 22),
+ // (133,22): error CS0136: A local or parameter named 'x10' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case int x10 when Dummy(x10):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x10").WithArguments("x10").WithLocation(133, 22),
+ // (136,31): error CS0841: Cannot use local variable 'x10' before it is declared
+ // case 0 when Dummy(x10):
+ Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "x10").WithArguments("x10").WithLocation(136, 31),
+ // (140,31): error CS0131: The left-hand side of an assignment must be a variable, property or indexer
+ // case 2 when Dummy(x10 = 10, x10):
+ Diagnostic(ErrorCode.ERR_AssgLvalueExpected, "x10").WithLocation(140, 31),
+ // (148,17): error CS0103: The name 'x11' does not exist in the current context
+ // switch (x11 ? val : 0)
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x11").WithArguments("x11").WithLocation(148, 17),
+ // (150,31): error CS0103: The name 'x11' does not exist in the current context
+ // case 0 when Dummy(x11):
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x11").WithArguments("x11").WithLocation(150, 31),
+ // (151,23): error CS0103: The name 'x11' does not exist in the current context
+ // Dummy(x11, 0);
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x11").WithArguments("x11").WithLocation(151, 23),
+ // (161,17): error CS0103: The name 'x12' does not exist in the current context
+ // switch (x12 ? val : 0)
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x12").WithArguments("x12").WithLocation(161, 17),
+ // (166,31): error CS0103: The name 'x12' does not exist in the current context
+ // case 1 when Dummy(x12):
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x12").WithArguments("x12").WithLocation(166, 31),
+ // (167,23): error CS0103: The name 'x12' does not exist in the current context
+ // Dummy(x12, 1);
+ Diagnostic(ErrorCode.ERR_NameNotInContext, "x12").WithArguments("x12").WithLocation(167, 23),
+ // (179,22): error CS0136: A local or parameter named 'x13' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // case int x13 when Dummy(x13):
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x13").WithArguments("x13").WithLocation(179, 22),
+ // (191,35): error CS0136: A local or parameter named 'x14' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
+ // Dummy(true is var x14, x14);
+ Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x14").WithArguments("x14").WithLocation(191, 35),
+ // (202,23): error CS0128: A local variable named 'x15' is already defined in this scope
+ // case long x15 when Dummy(x15):
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x15").WithArguments("x15").WithLocation(202, 23),
+ // (202,38): error CS0165: Use of unassigned local variable 'x15'
+ // case long x15 when Dummy(x15):
+ Diagnostic(ErrorCode.ERR_UseDefViolation, "x15").WithArguments("x15").WithLocation(202, 38),
+ // (213,43): error CS0128: A local variable named 'x16' is already defined in this scope
+ // case 1 when Dummy(true is var x16, x16):
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x16").WithArguments("x16").WithLocation(213, 43),
+ // (213,48): error CS0165: Use of unassigned local variable 'x16'
+ // case 1 when Dummy(true is var x16, x16):
+ Diagnostic(ErrorCode.ERR_UseDefViolation, "x16").WithArguments("x16").WithLocation(213, 48),
+ // (224,22): error CS0128: A local variable named 'x17' is already defined in this scope
+ // case int x17 when Dummy(x17):
+ Diagnostic(ErrorCode.ERR_LocalDuplicate, "x17").WithArguments("x17").WithLocation(224, 22),
+ // (224,37): error CS0165: Use of unassigned local variable 'x17'
+ // case int x17 when Dummy(x17):
+ Diagnostic(ErrorCode.ERR_UseDefViolation, "x17").WithArguments("x17").WithLocation(224, 37)
+ );
+
+ var tree = compilation.SyntaxTrees.Single();
+ var model = compilation.GetSemanticModel(tree);
+
+ var x1Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x1").ToArray();
+ var x1Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x1").ToArray();
+ Assert.Equal(3, x1Decl.Length);
+ Assert.Equal(6, x1Ref.Length);
+ for (int i = 0; i < x1Decl.Length; i++)
+ {
+ VerifyModelForDeclarationPattern(model, x1Decl[i], x1Ref[i * 2], x1Ref[i * 2 + 1]);
+ }
+
+ var x2Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x2").Single();
+ var x2Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x2").ToArray();
+ Assert.Equal(2, x2Ref.Length);
+ VerifyModelForDeclarationPattern(model, x2Decl, x2Ref);
+
+ var x3Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x3").Single();
+ var x3Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x3").ToArray();
+ Assert.Equal(2, x3Ref.Length);
+ VerifyModelForDeclarationPattern(model, x3Decl, x3Ref);
+
+ var x4Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x4").Single();
+ var x4Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x4").ToArray();
+ Assert.Equal(4, x4Ref.Length);
+ VerifyModelForDeclarationPattern(model, x4Decl, x4Ref[0], x4Ref[1]);
+ VerifyNotAPatternLocal(model, x4Ref[2]);
+ VerifyNotAPatternLocal(model, x4Ref[3]);
+
+ var x5Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x5").Single();
+ var x5Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x5").ToArray();
+ Assert.Equal(3, x5Ref.Length);
+ VerifyModelForDeclarationPattern(model, x5Decl, x5Ref[0], x5Ref[1]);
+ VerifyNotAPatternLocal(model, x5Ref[2]);
+
+ var x6Decl_1 = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x6").Single();
+ var x6Decl_2 = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x6").Single();
+ var x6Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x6").ToArray();
+ Assert.Equal(4, x6Ref.Length);
+ VerifyModelForDeclarationPattern(model, x6Decl_1, x6Ref[0], x6Ref[1]);
+ VerifyModelForDeclarationPattern(model, x6Decl_2, x6Ref[2], x6Ref[3]);
+
+ var x7Decl_1 = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x7").Single();
+ var x7Decl_2 = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x7").Single();
+ var x7Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x7").ToArray();
+ Assert.Equal(3, x7Ref.Length);
+ VerifyModelForDeclarationPattern(model, x7Decl_1, x7Ref[0], x7Ref[1]);
+ VerifyModelForDeclarationPattern(model, x7Decl_2, x7Ref[2]);
+
+ var x8Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x8").ToArray();
+ var x8Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x8").ToArray();
+ Assert.Equal(2, x8Decl.Length);
+ Assert.Equal(3, x8Ref.Length);
+ for (int i = 0; i < x8Ref.Length; i++)
+ {
+ VerifyModelForDeclarationPattern(model, x8Decl[0], x8Ref[i]);
+ }
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x8Decl[1]);
+
+ var x9Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x9").Single();
+ var x9Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x9").ToArray();
+ Assert.Equal(6, x9Ref.Length);
+ VerifyNotAPatternLocal(model, x9Ref[0]);
+ VerifyNotAPatternLocal(model, x9Ref[1]);
+ VerifyNotAPatternLocal(model, x9Ref[2]);
+ VerifyNotAPatternLocal(model, x9Ref[3]);
+ VerifyModelForDeclarationPattern(model, x9Decl, x9Ref[4], x9Ref[5]);
+
+ var x10Decl_1 = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x10").Single();
+ var x10Decl_2 = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x10").Single();
+ var x10Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x10").ToArray();
+ Assert.Equal(7, x10Ref.Length);
+ VerifyModelForDeclarationPattern(model, x10Decl_1, x10Ref[0], x10Ref[1]);
+ VerifyModelForDeclarationPattern(model, x10Decl_2, x10Ref[2], x10Ref[3], x10Ref[4], x10Ref[5], x10Ref[6]);
+
+ var x11Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x11").Single();
+ var x11Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x11").ToArray();
+ Assert.Equal(5, x11Ref.Length);
+ VerifyNotInScope(model, x11Ref[0]);
+ VerifyNotInScope(model, x11Ref[1]);
+ VerifyNotInScope(model, x11Ref[2]);
+ VerifyModelForDeclarationPattern(model, x11Decl, x11Ref[3], x11Ref[4]);
+
+ var x12Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x12").Single();
+ var x12Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x12").ToArray();
+ Assert.Equal(5, x12Ref.Length);
+ VerifyNotInScope(model, x12Ref[0]);
+ VerifyModelForDeclarationPattern(model, x12Decl, x12Ref[1], x12Ref[2]);
+ VerifyNotInScope(model, x12Ref[3]);
+ VerifyNotInScope(model, x12Ref[4]);
+
+ var x13Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x13").ToArray();
+ var x13Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x13").ToArray();
+ Assert.Equal(2, x13Decl.Length);
+ Assert.Equal(5, x13Ref.Length);
+ VerifyModelForDeclarationPattern(model, x13Decl[0], x13Ref[0], x13Ref[1], x13Ref[2]);
+ VerifyModelForDeclarationPattern(model, x13Decl[1], x13Ref[3], x13Ref[4]);
+
+ var x14Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x14").ToArray();
+ var x14Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x14").ToArray();
+ Assert.Equal(2, x14Decl.Length);
+ Assert.Equal(4, x14Ref.Length);
+ VerifyModelForDeclarationPattern(model, x14Decl[0], x14Ref[0], x14Ref[1], x14Ref[3]);
+ VerifyModelForDeclarationPattern(model, x14Decl[1], x14Ref[2]);
+
+ var x15Decl = tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier.ValueText == "x15").ToArray();
+ var x15Ref = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "x15").ToArray();
+ Assert.Equal(2, x15Decl.Length);
+ Assert.Equal(3, x15Ref.Length);
+ for (int i = 0; i < x15Ref.Length; i++)
+ {
+ VerifyModelForDeclarationPattern(model, x15Decl[0], x15Ref[i]);
+ }
+ VerifyModelForDeclarationPatternDuplicateInSameScope(model, x15Decl[1]);
+
+ var x16Decl = tree.GetRoot().DescendantNodes().OfType