Skip to content

Commit

Permalink
Merge remote-tracking branch 'dotnet/main' into SessionData
Browse files Browse the repository at this point in the history
  • Loading branch information
genlu committed Feb 15, 2022
2 parents 281cafd + 10a9d97 commit 57be575
Show file tree
Hide file tree
Showing 137 changed files with 1,738 additions and 1,084 deletions.
2 changes: 1 addition & 1 deletion docs/Language Feature Status.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ efforts behind them.
| [nameof accessing instance members](https://github.com/dotnet/roslyn/issues/40229) | main | [In Progress](https://github.com/dotnet/roslyn/pull/48754) | [YairHalberstadt ](https://github.com/YairHalberstadt) | [333fred](https://github.com/333fred), [AlekseyTs](https://github.com/AlekseyTs) | [333fred](https://github.com/333fred) |
| [Utf8 String Literals](https://github.com/dotnet/csharplang/issues/184) | [Utf8StringLiterals](https://github.com/dotnet/roslyn/tree/features/Utf8StringLiterals) | [In Progress](https://github.com/dotnet/roslyn/issues/58848) | [AlekseyTs](https://github.com/AlekseyTs) | [cston](https://github.com/cston), [RikkiGibson](https://github.com/RikkiGibson) | [MadsTorgersen](https://github.com/MadsTorgersen) |
| [ref fields](https://github.com/dotnet/csharplang/blob/main/proposals/low-level-struct-improvements.md) | TBD | [In Progress](https://github.com/dotnet/roslyn/issues/59194) | TBD | TBD | [jaredpar](https://github.com/jaredpar) |
| [checked operators](https://github.com/dotnet/csharplang/issues/4665) | [CheckedUserDefinedOperators](https://github.com/dotnet/roslyn/tree/features/CheckedUserDefinedOperators) | [In Progress](https://github.com/dotnet/roslyn/issues/59458) | [AlekseyTs](https://github.com/AlekseyTs) | TBD | [AlekseyTs](https://github.com/AlekseyTs) |
| [checked operators](https://github.com/dotnet/csharplang/issues/4665) | [CheckedUserDefinedOperators](https://github.com/dotnet/roslyn/tree/features/CheckedUserDefinedOperators) | [In Progress](https://github.com/dotnet/roslyn/issues/59458) | [AlekseyTs](https://github.com/AlekseyTs) | [333fred](https://github.com/333fred), [chsienki](https://github.com/chsienki) | [AlekseyTs](https://github.com/AlekseyTs) |

# C# 10.0

Expand Down
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
<MicrosoftDevDivOptimizationDataPowerShellVersion>1.0.339</MicrosoftDevDivOptimizationDataPowerShellVersion>
<MicrosoftDiagnosticsRuntimeVersion>0.8.31-beta</MicrosoftDiagnosticsRuntimeVersion>
<MicrosoftDiagnosticsTracingTraceEventVersion>1.0.35</MicrosoftDiagnosticsTracingTraceEventVersion>
<MicrosoftDiaSymReaderVersion>1.4.0-beta2-21528-02</MicrosoftDiaSymReaderVersion>
<MicrosoftDiaSymReaderVersion>1.4.0</MicrosoftDiaSymReaderVersion>
<MicrosoftDiaSymReaderConverterVersion>1.1.0-beta2-21528-01</MicrosoftDiaSymReaderConverterVersion>
<MicrosoftDiaSymReaderConverterXmlVersion>1.1.0-beta2-21528-01</MicrosoftDiaSymReaderConverterXmlVersion>
<MicrosoftDiaSymReaderNativeVersion>17.0.0-beta1.21524.1</MicrosoftDiaSymReaderNativeVersion>
Expand Down
107 changes: 107 additions & 0 deletions src/Analyzers/CSharp/Tests/MakeFieldReadonly/MakeFieldReadonlyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1797,6 +1797,113 @@ public int Value
}
</Document>
</Project>
</Workspace>");
}

[WorkItem(40644, "https://github.com/dotnet/roslyn/issues/40644")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)]
public async Task ShouldNotWarnForDataMemberFieldsInDataContractClasses()
{
await TestMissingAsync(
@"
<Workspace>
<Project Language=""C#"" AssemblyName=""Assembly1"" CommonReferencesNet45=""true"">
<Document>
[System.Runtime.Serialization.DataContractAttribute]
public class MyClass
{
[System.Runtime.Serialization.DataMember]
private bool [|isReadOnly|];
}
</Document>
</Project>
</Workspace>");
}

[WorkItem(40644, "https://github.com/dotnet/roslyn/issues/40644")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)]
public async Task ShouldWarnForDataMemberFieldsInNonDataContractClasses()
{
await TestInRegularAndScript1Async(
@"
<Workspace>
<Project Language=""C#"" AssemblyName=""Assembly1"" CommonReferencesNet45=""true"">
<Document>
public class MyClass
{
[System.Runtime.Serialization.DataMember]
private bool [|isReadOnly|];
}
</Document>
</Project>
</Workspace>",
@"
<Workspace>
<Project Language=""C#"" AssemblyName=""Assembly1"" CommonReferencesNet45=""true"">
<Document>
public class MyClass
{
[System.Runtime.Serialization.DataMember]
private readonly bool isReadOnly;
}
</Document>
</Project>
</Workspace>");
}

[WorkItem(40644, "https://github.com/dotnet/roslyn/issues/40644")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)]
public async Task ShouldWarnForPrivateNonDataMemberFieldsInDataContractClasses()
{
await TestInRegularAndScript1Async(
@"
<Workspace>
<Project Language=""C#"" AssemblyName=""Assembly1"" CommonReferencesNet45=""true"">
<Document>
[System.Runtime.Serialization.DataContractAttribute]
public class MyClass
{
[System.Runtime.Serialization.DataMember]
private bool isReadOnly;
private bool [|isReadOnly2|];
}
</Document>
</Project>
</Workspace>",
@"
<Workspace>
<Project Language=""C#"" AssemblyName=""Assembly1"" CommonReferencesNet45=""true"">
<Document>
[System.Runtime.Serialization.DataContractAttribute]
public class MyClass
{
[System.Runtime.Serialization.DataMember]
private bool isReadOnly;
private readonly bool isReadOnly2;
}
</Document>
</Project>
</Workspace>");
}

[WorkItem(40644, "https://github.com/dotnet/roslyn/issues/40644")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)]
public async Task ShouldNotWarnForPublicImplicitDataMemberFieldsInDataContractClasses()
{
await TestMissingAsync(
@"
<Workspace>
<Project Language=""C#"" AssemblyName=""Assembly1"" CommonReferencesNet45=""true"">
<Document>
[System.Runtime.Serialization.DataContractAttribute]
public class MyClass
{
public bool [|isReadOnly|];
}
</Document>
</Project>
</Workspace>");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ protected override void InitializeWorker(AnalysisContext context)
var fieldStateMap = new ConcurrentDictionary<IFieldSymbol, (bool isCandidate, bool written)>();
var threadStaticAttribute = compilationStartContext.Compilation.ThreadStaticAttributeType();
var dataContractAttribute = compilationStartContext.Compilation.DataContractAttribute();
var dataMemberAttribute = compilationStartContext.Compilation.DataMemberAttribute();
// We register following actions in the compilation:
// 1. A symbol action for field symbols to ensure the field state is initialized for every field in
Expand Down Expand Up @@ -111,7 +113,7 @@ void OnSymbolEnd(SymbolAnalysisContext symbolEndContext)
}
}
static bool IsCandidateField(IFieldSymbol symbol, INamedTypeSymbol threadStaticAttribute) =>
static bool IsCandidateField(IFieldSymbol symbol, INamedTypeSymbol threadStaticAttribute, INamedTypeSymbol dataContractAttribute, INamedTypeSymbol dataMemberAttribute) =>
symbol.DeclaredAccessibility == Accessibility.Private &&
!symbol.IsReadOnly &&
!symbol.IsConst &&
Expand All @@ -121,12 +123,22 @@ static bool IsCandidateField(IFieldSymbol symbol, INamedTypeSymbol threadStaticA
!symbol.IsFixedSizeBuffer &&
!symbol.GetAttributes().Any(
static (a, threadStaticAttribute) => SymbolEqualityComparer.Default.Equals(a.AttributeClass, threadStaticAttribute),
threadStaticAttribute);
threadStaticAttribute) &&
!IsDataContractSerializable(symbol, dataContractAttribute, dataMemberAttribute);
static bool IsDataContractSerializable(IFieldSymbol symbol, INamedTypeSymbol dataContractAttribute, INamedTypeSymbol dataMemberAttribute)
{
if (dataContractAttribute is null || dataMemberAttribute is null)
return false;
return symbol.GetAttributes().Any(static (x, dataMemberAttribute) => SymbolEqualityComparer.Default.Equals(x.AttributeClass, dataMemberAttribute), dataMemberAttribute)
&& symbol.ContainingType.GetAttributes().Any(static (x, dataContractAttribute) => SymbolEqualityComparer.Default.Equals(x.AttributeClass, dataContractAttribute), dataContractAttribute);
}
// Method to update the field state for a candidate field written outside constructor and field initializer.
void UpdateFieldStateOnWrite(IFieldSymbol field)
{
Debug.Assert(IsCandidateField(field, threadStaticAttribute));
Debug.Assert(IsCandidateField(field, threadStaticAttribute, dataContractAttribute, dataMemberAttribute));
Debug.Assert(fieldStateMap.ContainsKey(field));
fieldStateMap[field] = (isCandidate: true, written: true);
Expand All @@ -135,7 +147,7 @@ void UpdateFieldStateOnWrite(IFieldSymbol field)
// Method to get or initialize the field state.
(bool isCandidate, bool written) TryGetOrInitializeFieldState(IFieldSymbol fieldSymbol, AnalyzerOptions options, CancellationToken cancellationToken)
{
if (!IsCandidateField(fieldSymbol, threadStaticAttribute))
if (!IsCandidateField(fieldSymbol, threadStaticAttribute, dataContractAttribute, dataMemberAttribute))
{
return default;
}
Expand All @@ -145,14 +157,14 @@ void UpdateFieldStateOnWrite(IFieldSymbol field)
return result;
}
result = ComputeInitialFieldState(fieldSymbol, options, threadStaticAttribute, cancellationToken);
result = ComputeInitialFieldState(fieldSymbol, options, threadStaticAttribute, dataContractAttribute, dataMemberAttribute, cancellationToken);
return fieldStateMap.GetOrAdd(fieldSymbol, result);
}
// Method to compute the initial field state.
static (bool isCandidate, bool written) ComputeInitialFieldState(IFieldSymbol field, AnalyzerOptions options, INamedTypeSymbol threadStaticAttribute, CancellationToken cancellationToken)
static (bool isCandidate, bool written) ComputeInitialFieldState(IFieldSymbol field, AnalyzerOptions options, INamedTypeSymbol threadStaticAttribute, INamedTypeSymbol dataContractAttribute, INamedTypeSymbol dataMemberAttribute, CancellationToken cancellationToken)
{
Debug.Assert(IsCandidateField(field, threadStaticAttribute));
Debug.Assert(IsCandidateField(field, threadStaticAttribute, dataContractAttribute, dataMemberAttribute));
var option = GetCodeStyleOption(field, options, cancellationToken);
if (option == null || !option.Value)
Expand Down
15 changes: 8 additions & 7 deletions src/Analyzers/Core/Analyzers/UseSystemHashCode/Analyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
Expand Down Expand Up @@ -35,18 +36,18 @@ private Analyzer(

public static bool TryGetAnalyzer(Compilation compilation, [NotNullWhen(true)] out Analyzer analyzer)
{
analyzer = default;
var objectType = compilation.GetSpecialType(SpecialType.System_Object);
// This may not find anything. However, CanAnalyze checks for this. So
// we represent the value as non-nullable for all future code.
var objectGetHashCodeMethod = objectType?.GetMembers(nameof(GetHashCode)).FirstOrDefault() as IMethodSymbol;
var equalityComparerType = compilation.GetTypeByMetadataName(typeof(EqualityComparer<>).FullName!);
var systemHashCodeType = compilation.GetTypeByMetadataName("System.HashCode");
var equalityComparerType = compilation.GetBestTypeByMetadataName(typeof(EqualityComparer<>).FullName!);

if (systemHashCodeType == null || objectGetHashCodeMethod == null)
{
analyzer = default;
if (objectType?.GetMembers(nameof(GetHashCode)).FirstOrDefault() is not IMethodSymbol objectGetHashCodeMethod)
return false;

var systemHashCodeType = compilation.GetBestTypeByMetadataName("System.HashCode");
if (systemHashCodeType == null)
return false;
}

analyzer = new Analyzer(compilation, objectGetHashCodeMethod, equalityComparerType, systemHashCodeType);
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ protected override async Task FixAllAsync(

var methodDecl = diagnostic.AdditionalLocations[1].FindNode(cancellationToken);
var method = semanticModel.GetDeclaredSymbol(methodDecl, cancellationToken);
if (method == null)
continue;

var methodBlock = declarationService.GetDeclarations(method)[0].GetSyntax(cancellationToken);

var (accessesBase, members, _) = analyzer.GetHashedMembers(method, operation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -979,5 +979,106 @@ Class C
Private Shared [|t_obj|] As Object
End Class")
End Function

<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
<WorkItem(40644, "https://github.com/dotnet/roslyn/issues/40644")>
Public Async Function ShouldNotWarnForDataMemberFieldsInDataContractClasses() As Task
Dim initialMarkup =
<Workspace>
<Project Language="Visual Basic" CommonReferencesNet45="true">
<Document>
&lt;System.Runtime.Serialization.DataContract&gt;
Class Test
&lt;System.Runtime.Serialization.DataMember&gt;
Private [|id|] As String
End Class
</Document>
</Project>
</Workspace>.ToString()

Await TestMissingAsync(initialMarkup)
End Function

<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
<WorkItem(40644, "https://github.com/dotnet/roslyn/issues/40644")>
Public Async Function ShouldWarnForDataMemberFieldsInNonDataContractClasses() As Task
Dim initialMarkup =
<Workspace>
<Project Language="Visual Basic" CommonReferencesNet45="true">
<Document>
Class Test
&lt;System.Runtime.Serialization.DataMember&gt;
Private [|id|] As String
End Class
</Document>
</Project>
</Workspace>.ToString()
Dim expectedMarkup =
<Workspace>
<Project Language="Visual Basic" CommonReferencesNet45="true">
<Document>
Class Test
&lt;System.Runtime.Serialization.DataMember&gt;
Private ReadOnly id As String
End Class
</Document>
</Project>
</Workspace>.ToString()

Await TestInRegularAndScript1Async(initialMarkup, expectedMarkup)
End Function

<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
<WorkItem(40644, "https://github.com/dotnet/roslyn/issues/40644")>
Public Async Function ShouldWarnForPrivateNonDataMemberFieldsInDataContractClasses() As Task
Dim initialMarkup =
<Workspace>
<Project Language="Visual Basic" CommonReferencesNet45="true">
<Document>
&lt;System.Runtime.Serialization.DataContract&gt;
Class Test
&lt;System.Runtime.Serialization.DataMember&gt;
Private id As String

Private [|id2|] As String
End Class
</Document>
</Project>
</Workspace>.ToString()
Dim expectedMarkup =
<Workspace>
<Project Language="Visual Basic" CommonReferencesNet45="true">
<Document>
&lt;System.Runtime.Serialization.DataContract&gt;
Class Test
&lt;System.Runtime.Serialization.DataMember&gt;
Private id As String

Private ReadOnly id2 As String
End Class
</Document>
</Project>
</Workspace>.ToString()

Await TestInRegularAndScript1Async(initialMarkup, expectedMarkup)
End Function

<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
<WorkItem(40644, "https://github.com/dotnet/roslyn/issues/40644")>
Public Async Function ShouldNotWarnForPublicImplicitDataMemberFieldsInDataContractClasses() As Task
Dim initialMarkup =
<Workspace>
<Project Language="Visual Basic" CommonReferencesNet45="true">
<Document>
&lt;System.Runtime.Serialization.DataContract&gt;
Class Test
Public [|id|] As String
End Class
</Document>
</Project>
</Workspace>.ToString()

Await TestMissingAsync(initialMarkup)
End Function
End Class
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public QueryUnboundLambdaState(Binder binder, RangeVariableMap rangeVariableMap,
public override bool ParameterIsDiscard(int index) { return false; }
public override bool ParameterIsNullChecked(int index) { return false; }
public override SyntaxList<AttributeListSyntax> ParameterAttributes(int index) => default;
public override bool HasNames { get { return true; } }
public override bool HasSignature { get { return true; } }

public override bool HasExplicitReturnType(out RefKind refKind, out TypeWithAnnotations returnType)
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ private UnboundLambda BindAnonymousFunction(AnonymousFunctionExpressionSyntax sy
// are reported now.
ModifierUtils.ToDeclarationModifiers(syntax.Modifiers, diagnostics.DiagnosticBag ?? new DiagnosticBag());

if (data.HasNames)
if (data.HasSignature)
{
var binder = new LocalScopeBinder(this);
bool allowShadowingNames = binder.Compilation.IsFeatureEnabled(MessageID.IDS_FeatureNameShadowingInNestedFunctions);
Expand Down
2 changes: 0 additions & 2 deletions src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,6 @@ internal UnboundLambdaState WithCaching(bool includeCache)
public abstract bool HasExplicitlyTypedParameterList { get; }
public abstract int ParameterCount { get; }
public abstract bool IsAsync { get; }
public abstract bool HasNames { get; }
public abstract bool IsStatic { get; }
public abstract Location ParameterLocation(int index);
public abstract TypeWithAnnotations ParameterTypeWithAnnotations(int index);
Expand Down Expand Up @@ -1357,7 +1356,6 @@ internal PlainUnboundLambdaState(
_isStatic = isStatic;
}

public override bool HasNames { get { return !_parameterNames.IsDefault; } }

public override bool HasSignature { get { return !_parameterNames.IsDefault; } }

Expand Down
Loading

0 comments on commit 57be575

Please sign in to comment.