Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into diagnosticProjectId
Browse files Browse the repository at this point in the history
  • Loading branch information
CyrusNajmabadi committed Feb 4, 2025
2 parents 21798f3 + f4c1b45 commit 26a9974
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 258 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,7 @@ protected override SyntaxNode ConvertPropertyToExpressionBodyIfDesired(

var preference = info.Options.PreferExpressionBodiedProperties.Value;
if (preference == ExpressionBodyPreference.Never)
{
return propertyDeclaration.WithSemicolonToken(default);
}
return propertyDeclaration;

// if there is a get accessors only, we can move the expression body to the property
if (propertyDeclaration.AccessorList?.Accessors.Count == 1 &&
Expand All @@ -146,7 +144,7 @@ protected override SyntaxNode ConvertPropertyToExpressionBodyIfDesired(
}
}

return propertyDeclaration.WithSemicolonToken(default);
return propertyDeclaration;
}

protected override SyntaxNode GetTypeBlock(SyntaxNode syntaxNode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1444,4 +1444,34 @@ public int Goo
""";
await TestInRegularAndScriptAsync(text, expected, options: DoNotPreferExpressionBodiedAccessors, index: 1, parseOptions: CSharp14);
}

[Theory]
[InlineData("set"), InlineData("init")]
[WorkItem("https://github.com/dotnet/roslyn/issues/76992")]
public async Task ProduceFieldBackedProperty2(string setter)
{
var text = $$"""
class TestClass
{
public int G[||]oo { get; {{setter}}; } = 0;
}
""";
var expected = $$"""
class TestClass
{
public int Goo
{
get
{
return field;
}
{{setter}}
{
field = value;
}
} = 0;
}
""";
await TestInRegularAndScriptAsync(text, expected, options: DoNotPreferExpressionBodiedAccessors, index: 1, parseOptions: CSharp14);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ private async Task<Document> ExpandToFullPropertyAsync(
var fieldName = await GetFieldNameAsync(document, propertySymbol, cancellationToken).ConfigureAwait(false);
var (newGetAccessor, newSetAccessor) = GetNewAccessors(info, property, fieldName, cancellationToken);

editor.ReplaceNode(
property,
CreateFinalProperty(document, property, info, newGetAccessor, newSetAccessor));
var finalProperty = CreateFinalProperty(
document, GetPropertyWithoutInitializer(property), info, newGetAccessor, newSetAccessor);
editor.ReplaceNode(property, finalProperty);

// add backing field, plus initializer if it exists
var newField = CodeGenerationSymbolFactory.CreateFieldSymbol(
Expand Down Expand Up @@ -137,7 +137,7 @@ protected SyntaxNode CreateFinalProperty(

var fullProperty = generator
.WithAccessorDeclarations(
GetPropertyWithoutInitializer(property),
property,
newSetAccessor == null
? [newGetAccessor]
: [newGetAccessor, newSetAccessor])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,139 +10,121 @@
using Microsoft.CodeAnalysis.Workspaces.Diagnostics;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2
namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2;

internal partial class DiagnosticIncrementalAnalyzer
{
internal partial class DiagnosticIncrementalAnalyzer
/// <summary>
/// Simple data holder for local diagnostics for an analyzer
/// </summary>
private readonly struct DocumentAnalysisData
{
public static readonly DocumentAnalysisData Empty = new(VersionStamp.Default, lineCount: 0, []);

/// <summary>
/// Simple data holder for local diagnostics for an analyzer
/// Version of the diagnostic data.
/// </summary>
private readonly struct DocumentAnalysisData
{
public static readonly DocumentAnalysisData Empty = new(VersionStamp.Default, lineCount: 0, []);
public readonly VersionStamp Version;

/// <summary>
/// Version of the diagnostic data.
/// </summary>
public readonly VersionStamp Version;

/// <summary>
/// Number of lines in the document.
/// </summary>
public readonly int LineCount;
/// <summary>
/// Number of lines in the document.
/// </summary>
public readonly int LineCount;

/// <summary>
/// Current data that matches the version.
/// </summary>
public readonly ImmutableArray<DiagnosticData> Items;
/// <summary>
/// Current data that matches the version.
/// </summary>
public readonly ImmutableArray<DiagnosticData> Items;

/// <summary>
/// Last set of data we broadcasted to outer world, or <see langword="default"/>.
/// </summary>
public readonly ImmutableArray<DiagnosticData> OldItems;
/// <summary>
/// Last set of data we broadcasted to outer world, or <see langword="default"/>.
/// </summary>
public readonly ImmutableArray<DiagnosticData> OldItems;

public DocumentAnalysisData(VersionStamp version, int lineCount, ImmutableArray<DiagnosticData> items)
{
Debug.Assert(!items.IsDefault);
public DocumentAnalysisData(VersionStamp version, int lineCount, ImmutableArray<DiagnosticData> items)
{
Debug.Assert(!items.IsDefault);

Version = version;
LineCount = lineCount;
Items = items;
OldItems = default;
}
Version = version;
LineCount = lineCount;
Items = items;
OldItems = default;
}

public DocumentAnalysisData(VersionStamp version, int lineCount, ImmutableArray<DiagnosticData> oldItems, ImmutableArray<DiagnosticData> newItems)
: this(version, lineCount, newItems)
{
Debug.Assert(!oldItems.IsDefault);
OldItems = oldItems;
}
public DocumentAnalysisData(VersionStamp version, int lineCount, ImmutableArray<DiagnosticData> oldItems, ImmutableArray<DiagnosticData> newItems)
: this(version, lineCount, newItems)
{
Debug.Assert(!oldItems.IsDefault);
OldItems = oldItems;
}
}

/// <summary>
/// Data holder for all diagnostics for a project for an analyzer
/// </summary>
private readonly struct ProjectAnalysisData
{
/// <summary>
/// Data holder for all diagnostics for a project for an analyzer
/// ProjectId of this data
/// </summary>
private readonly struct ProjectAnalysisData
{
/// <summary>
/// ProjectId of this data
/// </summary>
public readonly ProjectId ProjectId;

/// <summary>
/// Version of the Items
/// </summary>
public readonly VersionStamp Version;

/// <summary>
/// Current data that matches the version
/// </summary>
public readonly ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResult> Result;

/// <summary>
/// When present, holds onto last data we broadcasted to outer world.
/// </summary>
public readonly ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResult>? OldResult;

public ProjectAnalysisData(ProjectId projectId, VersionStamp version, ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResult> result)
{
ProjectId = projectId;
Version = version;
Result = result;
public readonly ProjectId ProjectId;

OldResult = null;
}
/// <summary>
/// Version of the Items
/// </summary>
public readonly VersionStamp Version;

public ProjectAnalysisData(
ProjectId projectId,
VersionStamp version,
ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResult> oldResult,
ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResult> newResult)
: this(projectId, version, newResult)
{
OldResult = oldResult;
}
/// <summary>
/// Current data that matches the version
/// </summary>
public readonly ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResult> Result;

public ProjectAnalysisData(ProjectId projectId, VersionStamp version, ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResult> result)
{
ProjectId = projectId;
Version = version;
Result = result;
}

public DiagnosticAnalysisResult GetResult(DiagnosticAnalyzer analyzer)
=> GetResultOrEmpty(Result, analyzer, ProjectId, Version);

public DiagnosticAnalysisResult GetResult(DiagnosticAnalyzer analyzer)
=> GetResultOrEmpty(Result, analyzer, ProjectId, Version);
public bool TryGetResult(DiagnosticAnalyzer analyzer, out DiagnosticAnalysisResult result)
=> Result.TryGetValue(analyzer, out result);

public bool TryGetResult(DiagnosticAnalyzer analyzer, out DiagnosticAnalysisResult result)
=> Result.TryGetValue(analyzer, out result);
public static async Task<ProjectAnalysisData> CreateAsync(Project project, IEnumerable<StateSet> stateSets, bool avoidLoadingData, CancellationToken cancellationToken)
{
VersionStamp? version = null;

public static async Task<ProjectAnalysisData> CreateAsync(Project project, IEnumerable<StateSet> stateSets, bool avoidLoadingData, CancellationToken cancellationToken)
var builder = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, DiagnosticAnalysisResult>();
foreach (var stateSet in stateSets)
{
VersionStamp? version = null;
var state = stateSet.GetOrCreateProjectState(project.Id);
var result = await state.GetAnalysisDataAsync(project, avoidLoadingData, cancellationToken).ConfigureAwait(false);
Contract.ThrowIfFalse(project.Id == result.ProjectId);

var builder = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, DiagnosticAnalysisResult>();
foreach (var stateSet in stateSets)
if (!version.HasValue)
{
var state = stateSet.GetOrCreateProjectState(project.Id);
var result = await state.GetAnalysisDataAsync(project, avoidLoadingData, cancellationToken).ConfigureAwait(false);
Contract.ThrowIfFalse(project.Id == result.ProjectId);

if (!version.HasValue)
{
version = result.Version;
}
else if (version.Value != VersionStamp.Default && version.Value != result.Version)
{
// if not all version is same, set version as default.
// this can happen at the initial data loading or
// when document is closed and we put active file state to project state
version = VersionStamp.Default;
}

builder.Add(stateSet.Analyzer, result);
version = result.Version;
}

if (!version.HasValue)
else if (version.Value != VersionStamp.Default && version.Value != result.Version)
{
// there is no saved data to return.
return new ProjectAnalysisData(project.Id, VersionStamp.Default, ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResult>.Empty);
// if not all version is same, set version as default.
// this can happen at the initial data loading or
// when document is closed and we put active file state to project state
version = VersionStamp.Default;
}

return new ProjectAnalysisData(project.Id, version.Value, builder.ToImmutable());
builder.Add(stateSet.Analyzer, result);
}

if (!version.HasValue)
{
// there is no saved data to return.
return new ProjectAnalysisData(project.Id, VersionStamp.Default, ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResult>.Empty);
}

return new ProjectAnalysisData(project.Id, version.Value, builder.ToImmutable());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ private async Task<ProjectAnalysisData> GetProjectAnalysisDataAsync(
// Now we run analyzers but filter out some information. So on such projects, there will be some perf degradation.
result = await RemoveCompilerSemanticErrorsIfProjectNotLoadedAsync(result, project, cancellationToken).ConfigureAwait(false);

return new ProjectAnalysisData(project.Id, version, existingData.Result, result);
return new ProjectAnalysisData(project.Id, version, result);
}
catch (Exception e) when (FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Simplification;
using Microsoft.CodeAnalysis.SolutionCrawler;
using Microsoft.CodeAnalysis.Workspaces.Diagnostics;
using Roslyn.Utilities;
Expand Down Expand Up @@ -239,12 +238,6 @@ public async ValueTask SaveToInMemoryStorageAsync(Project project, DiagnosticAna
AddToInMemoryStorage(serializerVersion, project, document: null, result.ProjectId, NonLocalStateName, result.GetOtherDiagnostics());
}

public void ResetVersion()
{
// reset version of cached data so that we can recalculate new data (ex, OnDocumentReset)
_lastResult = _lastResult.Reset();
}

public async ValueTask MergeAsync(ActiveFileState state, TextDocument document, IGlobalOptionService globalOptions)
{
Contract.ThrowIfFalse(state.DocumentId == document.Id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,22 +111,6 @@ public async Task<ImmutableArray<StateSet>> GetOrCreateStateSetsAsync(Project pr
return null;
}

public bool OnProjectRemoved(IEnumerable<StateSet> stateSets, ProjectId projectId)
{
var removed = false;
foreach (var stateSet in stateSets)
{
removed |= stateSet.OnProjectRemoved(projectId);
}

lock (_projectAnalyzerStateMap)
{
_projectAnalyzerStateMap = _projectAnalyzerStateMap.Remove(projectId);
}

return removed;
}

private void RaiseProjectAnalyzerReferenceChanged(ProjectAnalyzerReferenceChangedEventArgs args)
=> ProjectAnalyzerReferenceChanged?.Invoke(this, args);

Expand Down
Loading

0 comments on commit 26a9974

Please sign in to comment.