提交 d9749bdc 编写于 作者: C Cyrus Najmabadi

NRT much of the rename core.

上级 d893350b
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
#nullable enable
using System.Collections.Immutable; using System.Collections.Immutable;
using Microsoft.CodeAnalysis.Rename.ConflictEngine; using Microsoft.CodeAnalysis.Rename.ConflictEngine;
using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Extensions;
...@@ -12,7 +14,7 @@ namespace Microsoft.CodeAnalysis.Rename ...@@ -12,7 +14,7 @@ namespace Microsoft.CodeAnalysis.Rename
{ {
internal readonly partial struct ConflictResolution internal readonly partial struct ConflictResolution
{ {
public readonly string ErrorMessage; public readonly string? ErrorMessage;
private readonly Solution _newSolutionWithoutRenamedDocument; private readonly Solution _newSolutionWithoutRenamedDocument;
private readonly (DocumentId documentId, string newName) _renamedDocument; private readonly (DocumentId documentId, string newName) _renamedDocument;
......
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
#nullable enable
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
...@@ -10,6 +13,7 @@ ...@@ -10,6 +13,7 @@
using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Remote; using Microsoft.CodeAnalysis.Remote;
using Microsoft.CodeAnalysis.Rename.ConflictEngine; using Microsoft.CodeAnalysis.Rename.ConflictEngine;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities; using Roslyn.Utilities;
...@@ -68,36 +72,35 @@ internal class SerializableSearchResult ...@@ -68,36 +72,35 @@ internal class SerializableSearchResult
{ {
// We use arrays so we can represent default immutable arrays. // We use arrays so we can represent default immutable arrays.
public SerializableRenameLocation[] Locations; public SerializableRenameLocation[]? Locations;
public SerializableReferenceLocation[] ImplicitLocations; public SerializableReferenceLocation[]? ImplicitLocations;
public SerializableSymbolAndProjectId[] ReferencedSymbols; public SerializableSymbolAndProjectId[]? ReferencedSymbols;
public static SerializableSearchResult Dehydrate(Solution solution, RenameLocations.SearchResult result, CancellationToken cancellationToken) [return: NotNullIfNotNull("result")]
public static SerializableSearchResult? Dehydrate(Solution solution, RenameLocations.SearchResult? result, CancellationToken cancellationToken)
=> result == null ? null : new SerializableSearchResult => result == null ? null : new SerializableSearchResult
{ {
Locations = result.Locations?.Select(loc => SerializableRenameLocation.Dehydrate(loc)).ToArray(), Locations = result.Locations.Select(loc => SerializableRenameLocation.Dehydrate(loc)).ToArray(),
ImplicitLocations = result.ImplicitLocations.IsDefault ? null : result.ImplicitLocations.Select(loc => SerializableReferenceLocation.Dehydrate(loc, cancellationToken)).ToArray(), ImplicitLocations = result.ImplicitLocations.IsDefault ? null : result.ImplicitLocations.Select(loc => SerializableReferenceLocation.Dehydrate(loc, cancellationToken)).ToArray(),
ReferencedSymbols = result.ReferencedSymbols.IsDefault ? null : result.ReferencedSymbols.Select(s => SerializableSymbolAndProjectId.Dehydrate(solution, s, cancellationToken)).ToArray(), ReferencedSymbols = result.ReferencedSymbols.IsDefault ? null : result.ReferencedSymbols.Select(s => SerializableSymbolAndProjectId.Dehydrate(solution, s, cancellationToken)).ToArray(),
}; };
public async Task<RenameLocations.SearchResult> RehydrateAsync(Solution solution, CancellationToken cancellationToken) public async Task<RenameLocations.SearchResult> RehydrateAsync(Solution solution, CancellationToken cancellationToken)
{ {
ImmutableHashSet<RenameLocation> locations = null;
ImmutableArray<ReferenceLocation> implicitLocations = default; ImmutableArray<ReferenceLocation> implicitLocations = default;
ImmutableArray<ISymbol> referencedSymbols = default; ImmutableArray<ISymbol> referencedSymbols = default;
if (Locations != null) Contract.ThrowIfNull(Locations);
{
using var _ = ArrayBuilder<RenameLocation>.GetInstance(Locations.Length, out var builder);
foreach (var loc in Locations)
builder.Add(await loc.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false));
locations = builder.ToImmutableHashSet(); using var _1 = ArrayBuilder<RenameLocation>.GetInstance(Locations.Length, out var locBuilder);
} foreach (var loc in Locations)
locBuilder.Add(await loc.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false));
var locations = locBuilder.ToImmutableHashSet();
if (ImplicitLocations != null) if (ImplicitLocations != null)
{ {
using var _ = ArrayBuilder<ReferenceLocation>.GetInstance(ImplicitLocations.Length, out var builder); using var _2 = ArrayBuilder<ReferenceLocation>.GetInstance(ImplicitLocations.Length, out var builder);
foreach (var loc in ImplicitLocations) foreach (var loc in ImplicitLocations)
builder.Add(await loc.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false)); builder.Add(await loc.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false));
...@@ -106,7 +109,7 @@ public async Task<RenameLocations.SearchResult> RehydrateAsync(Solution solution ...@@ -106,7 +109,7 @@ public async Task<RenameLocations.SearchResult> RehydrateAsync(Solution solution
if (ReferencedSymbols != null) if (ReferencedSymbols != null)
{ {
using var _ = ArrayBuilder<ISymbol>.GetInstance(ReferencedSymbols.Length, out var builder); using var _3 = ArrayBuilder<ISymbol>.GetInstance(ReferencedSymbols.Length, out var builder);
foreach (var symbol in ReferencedSymbols) foreach (var symbol in ReferencedSymbols)
builder.AddIfNotNull(await symbol.TryRehydrateAsync(solution, cancellationToken).ConfigureAwait(false)); builder.AddIfNotNull(await symbol.TryRehydrateAsync(solution, cancellationToken).ConfigureAwait(false));
...@@ -141,8 +144,8 @@ public static SerializableRenameLocation Dehydrate(RenameLocation location) ...@@ -141,8 +144,8 @@ public static SerializableRenameLocation Dehydrate(RenameLocation location)
public async Task<RenameLocation> RehydrateAsync(Solution solution, CancellationToken cancellation) public async Task<RenameLocation> RehydrateAsync(Solution solution, CancellationToken cancellation)
{ {
var document = solution.GetDocument(DocumentId); var document = solution.GetRequiredDocument(DocumentId);
var tree = await document.GetSyntaxTreeAsync(cancellation).ConfigureAwait(false); var tree = await document.GetRequiredSyntaxTreeAsync(cancellation).ConfigureAwait(false);
return new RenameLocation( return new RenameLocation(
CodeAnalysis.Location.Create(tree, Location), CodeAnalysis.Location.Create(tree, Location),
...@@ -169,11 +172,14 @@ public SerializableRenameLocations Dehydrate(Solution solution, CancellationToke ...@@ -169,11 +172,14 @@ public SerializableRenameLocations Dehydrate(Solution solution, CancellationToke
CommentsResult = _commentsResult.IsDefault ? null : _commentsResult.Select(r => SerializableRenameLocation.Dehydrate(r)).ToArray(), CommentsResult = _commentsResult.IsDefault ? null : _commentsResult.Select(r => SerializableRenameLocation.Dehydrate(r)).ToArray(),
}; };
internal static async Task<RenameLocations> RehydrateAsync(Solution solution, SerializableRenameLocations locations, CancellationToken cancellationToken) internal static async Task<RenameLocations?> TryRehydrateAsync(Solution solution, SerializableRenameLocations locations, CancellationToken cancellationToken)
{ {
if (locations == null) if (locations == null)
return null; return null;
if (locations.Symbol == null)
return null;
var symbol = await locations.Symbol.TryRehydrateAsync(solution, cancellationToken).ConfigureAwait(false); var symbol = await locations.Symbol.TryRehydrateAsync(solution, cancellationToken).ConfigureAwait(false);
if (symbol == null) if (symbol == null)
return null; return null;
...@@ -209,11 +215,17 @@ internal static async Task<RenameLocations> RehydrateAsync(Solution solution, Se ...@@ -209,11 +215,17 @@ internal static async Task<RenameLocations> RehydrateAsync(Solution solution, Se
commentsResult = builder.ToImmutable(); commentsResult = builder.ToImmutable();
} }
var originalSymbolResult = locations.OriginalSymbolResult == null
? null
: await locations.OriginalSymbolResult.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false);
Contract.ThrowIfNull(locations.MergedResult);
return new RenameLocations( return new RenameLocations(
symbol, symbol,
solution, solution,
locations.Options.Rehydrate(), locations.Options.Rehydrate(),
await locations.OriginalSymbolResult.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false), originalSymbolResult,
await locations.MergedResult.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false), await locations.MergedResult.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false),
overloadsResult, overloadsResult,
stringsResult, stringsResult,
...@@ -223,15 +235,15 @@ internal static async Task<RenameLocations> RehydrateAsync(Solution solution, Se ...@@ -223,15 +235,15 @@ internal static async Task<RenameLocations> RehydrateAsync(Solution solution, Se
internal class SerializableRenameLocations internal class SerializableRenameLocations
{ {
public SerializableSymbolAndProjectId Symbol; public SerializableSymbolAndProjectId? Symbol;
public SerializableRenameOptionSet Options; public SerializableRenameOptionSet Options;
public SerializableSearchResult OriginalSymbolResult; public SerializableSearchResult? OriginalSymbolResult;
public SerializableSearchResult MergedResult; public SerializableSearchResult? MergedResult;
// We use arrays so we can represent default immutable arrays. // We use arrays so we can represent default immutable arrays.
public SerializableSearchResult[] OverloadsResult; public SerializableSearchResult[]? OverloadsResult;
public SerializableRenameLocation[] StringsResult; public SerializableRenameLocation[]? StringsResult;
public SerializableRenameLocation[] CommentsResult; public SerializableRenameLocation[]? CommentsResult;
} }
internal class SerializableComplexifiedSpan internal class SerializableComplexifiedSpan
...@@ -257,7 +269,7 @@ internal class SerializableRelatedLocation ...@@ -257,7 +269,7 @@ internal class SerializableRelatedLocation
public TextSpan ConflictCheckSpan; public TextSpan ConflictCheckSpan;
public RelatedLocationType Type; public RelatedLocationType Type;
public bool IsReference; public bool IsReference;
public DocumentId DocumentId; public DocumentId? DocumentId;
public TextSpan ComplexifiedTargetSpan; public TextSpan ComplexifiedTargetSpan;
public RelatedLocation Rehydrate() public RelatedLocation Rehydrate()
...@@ -276,7 +288,7 @@ public static SerializableRelatedLocation Dehydrate(RelatedLocation location) ...@@ -276,7 +288,7 @@ public static SerializableRelatedLocation Dehydrate(RelatedLocation location)
internal class SerializableConflictResolution internal class SerializableConflictResolution
{ {
public string ErrorMessage; public string? ErrorMessage;
public bool ReplacementTextValid; public bool ReplacementTextValid;
...@@ -286,12 +298,12 @@ internal class SerializableConflictResolution ...@@ -286,12 +298,12 @@ internal class SerializableConflictResolution
// //
// We also flatten dictionaries into key/value tuples because jsonrpc only supports dictionaries with string keys. // We also flatten dictionaries into key/value tuples because jsonrpc only supports dictionaries with string keys.
public DocumentId[] DocumentIds; public DocumentId[]? DocumentIds;
public SerializableRelatedLocation[] RelatedLocations; public SerializableRelatedLocation[]? RelatedLocations;
public (DocumentId, TextChange[])[] DocumentTextChanges; public (DocumentId, TextChange[])[]? DocumentTextChanges;
public (DocumentId, ImmutableArray<(TextSpan oldSpan, TextSpan newSpan)>)[] DocumentToModifiedSpansMap; public (DocumentId, ImmutableArray<(TextSpan oldSpan, TextSpan newSpan)>)[]? DocumentToModifiedSpansMap;
public (DocumentId, ImmutableArray<SerializableComplexifiedSpan>)[] DocumentToComplexifiedSpansMap; public (DocumentId, ImmutableArray<SerializableComplexifiedSpan>)[]? DocumentToComplexifiedSpansMap;
public (DocumentId, ImmutableArray<SerializableRelatedLocation>)[] DocumentToRelatedLocationsMap; public (DocumentId, ImmutableArray<SerializableRelatedLocation>)[]? DocumentToRelatedLocationsMap;
public async Task<ConflictResolution> RehydrateAsync(Solution oldSolution, CancellationToken cancellationToken) public async Task<ConflictResolution> RehydrateAsync(Solution oldSolution, CancellationToken cancellationToken)
{ {
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
...@@ -31,14 +33,12 @@ internal static class ReferenceProcessing ...@@ -31,14 +33,12 @@ internal static class ReferenceProcessing
/// Given a symbol in a document, returns the "right" symbol that should be renamed in /// Given a symbol in a document, returns the "right" symbol that should be renamed in
/// the case the name binds to things like aliases _and_ the underlying type at once. /// the case the name binds to things like aliases _and_ the underlying type at once.
/// </summary> /// </summary>
public static async Task<ISymbol> GetRenamableSymbolAsync( public static async Task<ISymbol?> TryGetRenamableSymbolAsync(
Document document, int position, CancellationToken cancellationToken) Document document, int position, CancellationToken cancellationToken)
{ {
var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken: cancellationToken).ConfigureAwait(false); var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken: cancellationToken).ConfigureAwait(false);
if (symbol == null) if (symbol == null)
{
return null; return null;
}
var definitionSymbol = await FindDefinitionSymbolAsync(symbol, document.Project.Solution, cancellationToken).ConfigureAwait(false); var definitionSymbol = await FindDefinitionSymbolAsync(symbol, document.Project.Solution, cancellationToken).ConfigureAwait(false);
Contract.ThrowIfNull(definitionSymbol); Contract.ThrowIfNull(definitionSymbol);
...@@ -115,7 +115,7 @@ internal static class ReferenceProcessing ...@@ -115,7 +115,7 @@ internal static class ReferenceProcessing
} }
// in case this is e.g. an overridden property accessor, we'll treat the property itself as the definition symbol // in case this is e.g. an overridden property accessor, we'll treat the property itself as the definition symbol
var property = await GetPropertyFromAccessorOrAnOverrideAsync(bestSymbol, solution, cancellationToken).ConfigureAwait(false); var property = await TryGetPropertyFromAccessorOrAnOverrideAsync(bestSymbol, solution, cancellationToken).ConfigureAwait(false);
return property ?? bestSymbol; return property ?? bestSymbol;
} }
...@@ -214,7 +214,7 @@ static bool IsConstructorForType(ISymbol possibleConstructor, ISymbol possibleTy ...@@ -214,7 +214,7 @@ static bool IsConstructorForType(ISymbol possibleConstructor, ISymbol possibleTy
} }
} }
internal static async Task<ISymbol> GetPropertyFromAccessorOrAnOverrideAsync( internal static async Task<ISymbol?> TryGetPropertyFromAccessorOrAnOverrideAsync(
ISymbol symbol, Solution solution, CancellationToken cancellationToken) ISymbol symbol, Solution solution, CancellationToken cancellationToken)
{ {
if (symbol.IsPropertyAccessor()) if (symbol.IsPropertyAccessor())
...@@ -229,7 +229,7 @@ static bool IsConstructorForType(ISymbol possibleConstructor, ISymbol possibleTy ...@@ -229,7 +229,7 @@ static bool IsConstructorForType(ISymbol possibleConstructor, ISymbol possibleTy
if (originalSourceSymbol != null) if (originalSourceSymbol != null)
{ {
return await GetPropertyFromAccessorOrAnOverrideAsync(originalSourceSymbol, solution, cancellationToken).ConfigureAwait(false); return await TryGetPropertyFromAccessorOrAnOverrideAsync(originalSourceSymbol, solution, cancellationToken).ConfigureAwait(false);
} }
} }
...@@ -241,7 +241,7 @@ static bool IsConstructorForType(ISymbol possibleConstructor, ISymbol possibleTy ...@@ -241,7 +241,7 @@ static bool IsConstructorForType(ISymbol possibleConstructor, ISymbol possibleTy
foreach (var methodImplementor in methodImplementors) foreach (var methodImplementor in methodImplementors)
{ {
var propertyAccessorOrAnOverride = await GetPropertyFromAccessorOrAnOverrideAsync(methodImplementor, solution, cancellationToken).ConfigureAwait(false); var propertyAccessorOrAnOverride = await TryGetPropertyFromAccessorOrAnOverrideAsync(methodImplementor, solution, cancellationToken).ConfigureAwait(false);
if (propertyAccessorOrAnOverride != null) if (propertyAccessorOrAnOverride != null)
{ {
return propertyAccessorOrAnOverride; return propertyAccessorOrAnOverride;
...@@ -255,7 +255,7 @@ static bool IsConstructorForType(ISymbol possibleConstructor, ISymbol possibleTy ...@@ -255,7 +255,7 @@ static bool IsConstructorForType(ISymbol possibleConstructor, ISymbol possibleTy
private static async Task<bool> IsPropertyAccessorOrAnOverrideAsync( private static async Task<bool> IsPropertyAccessorOrAnOverrideAsync(
ISymbol symbol, Solution solution, CancellationToken cancellationToken) ISymbol symbol, Solution solution, CancellationToken cancellationToken)
{ {
var result = await GetPropertyFromAccessorOrAnOverrideAsync( var result = await TryGetPropertyFromAccessorOrAnOverrideAsync(
symbol, solution, cancellationToken).ConfigureAwait(false); symbol, solution, cancellationToken).ConfigureAwait(false);
return result != null; return result != null;
} }
...@@ -300,7 +300,8 @@ private static string TrimNameToAfterLastDot(string name) ...@@ -300,7 +300,8 @@ private static string TrimNameToAfterLastDot(string name)
if (originalSymbol.Kind == SymbolKind.Alias) if (originalSymbol.Kind == SymbolKind.Alias)
{ {
var location = originalSymbol.Locations.Single(); var location = originalSymbol.Locations.Single();
results.Add(new RenameLocation(location, solution.GetDocument(location.SourceTree).Id)); Contract.ThrowIfNull(location.SourceTree);
results.Add(new RenameLocation(location, solution.GetRequiredDocument(location.SourceTree).Id));
return results.ToImmutableAndFree(); return results.ToImmutableAndFree();
} }
...@@ -309,9 +310,10 @@ private static string TrimNameToAfterLastDot(string name) ...@@ -309,9 +310,10 @@ private static string TrimNameToAfterLastDot(string name)
{ {
if (location.IsInSource) if (location.IsInSource)
{ {
Contract.ThrowIfNull(location.SourceTree);
results.Add(new RenameLocation( results.Add(new RenameLocation(
location, location,
solution.GetDocument(location.SourceTree).Id, solution.GetRequiredDocument(location.SourceTree).Id,
isRenamableAccessor: isRenamableAccessor)); isRenamableAccessor: isRenamableAccessor));
} }
} }
...@@ -320,7 +322,10 @@ private static string TrimNameToAfterLastDot(string name) ...@@ -320,7 +322,10 @@ private static string TrimNameToAfterLastDot(string name)
// destructors declarations that match the name // destructors declarations that match the name
if (referencedSymbol.Kind == SymbolKind.NamedType && referencedSymbol.Locations.All(l => l.IsInSource)) if (referencedSymbol.Kind == SymbolKind.NamedType && referencedSymbol.Locations.All(l => l.IsInSource))
{ {
var syntaxFacts = solution.GetDocument(referencedSymbol.Locations[0].SourceTree).GetLanguageService<ISyntaxFactsService>(); var firstLocation = referencedSymbol.Locations[0];
Contract.ThrowIfNull(firstLocation.SourceTree);
var syntaxFacts = solution.GetRequiredDocument(firstLocation.SourceTree)
.GetRequiredLanguageService<ISyntaxFactsService>();
var namedType = (INamedTypeSymbol)referencedSymbol; var namedType = (INamedTypeSymbol)referencedSymbol;
foreach (var method in namedType.GetMembers().OfType<IMethodSymbol>()) foreach (var method in namedType.GetMembers().OfType<IMethodSymbol>())
...@@ -337,7 +342,8 @@ private static string TrimNameToAfterLastDot(string name) ...@@ -337,7 +342,8 @@ private static string TrimNameToAfterLastDot(string name)
if (!syntaxFacts.IsReservedOrContextualKeyword(token) && if (!syntaxFacts.IsReservedOrContextualKeyword(token) &&
token.ValueText == referencedSymbol.Name) token.ValueText == referencedSymbol.Name)
{ {
results.Add(new RenameLocation(location, solution.GetDocument(location.SourceTree).Id)); Contract.ThrowIfNull(location.SourceTree);
results.Add(new RenameLocation(location, solution.GetRequiredDocument(location.SourceTree).Id));
} }
} }
} }
...@@ -376,7 +382,8 @@ internal static async Task<IEnumerable<RenameLocation>> GetRenamableReferenceLoc ...@@ -376,7 +382,8 @@ internal static async Task<IEnumerable<RenameLocation>> GetRenamableReferenceLoc
// We also need to add the location of the alias // We also need to add the location of the alias
// itself // itself
var aliasLocation = location.Alias.Locations.Single(); var aliasLocation = location.Alias.Locations.Single();
results.Add(new RenameLocation(aliasLocation, solution.GetDocument(aliasLocation.SourceTree).Id)); Contract.ThrowIfNull(aliasLocation.SourceTree);
results.Add(new RenameLocation(aliasLocation, solution.GetRequiredDocument(aliasLocation.SourceTree).Id));
} }
} }
else else
...@@ -394,7 +401,8 @@ internal static async Task<IEnumerable<RenameLocation>> GetRenamableReferenceLoc ...@@ -394,7 +401,8 @@ internal static async Task<IEnumerable<RenameLocation>> GetRenamableReferenceLoc
// We also need to add the location of the alias itself // We also need to add the location of the alias itself
var aliasLocation = location.Alias.Locations.Single(); var aliasLocation = location.Alias.Locations.Single();
results.Add(new RenameLocation(aliasLocation, solution.GetDocument(aliasLocation.SourceTree).Id)); Contract.ThrowIfNull(aliasLocation.SourceTree);
results.Add(new RenameLocation(aliasLocation, solution.GetRequiredDocument(aliasLocation.SourceTree).Id));
} }
} }
else else
...@@ -459,7 +467,7 @@ internal static async Task<IEnumerable<RenameLocation>> GetRenamableReferenceLoc ...@@ -459,7 +467,7 @@ internal static async Task<IEnumerable<RenameLocation>> GetRenamableReferenceLoc
Document document, string renameText, ISyntaxFactsService syntaxFactsService, Document document, string renameText, ISyntaxFactsService syntaxFactsService,
ArrayBuilder<RenameLocation> renameLocations, CancellationToken cancellationToken) ArrayBuilder<RenameLocation> renameLocations, CancellationToken cancellationToken)
{ {
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var renameTextLength = renameText.Length; var renameTextLength = renameText.Length;
var renameStringsAndPositions = root var renameStringsAndPositions = root
...@@ -477,7 +485,7 @@ internal static async Task<IEnumerable<RenameLocation>> GetRenamableReferenceLoc ...@@ -477,7 +485,7 @@ internal static async Task<IEnumerable<RenameLocation>> GetRenamableReferenceLoc
private static async Task AddLocationsToRenameInCommentsAsync( private static async Task AddLocationsToRenameInCommentsAsync(
Document document, string renameText, ArrayBuilder<RenameLocation> renameLocations, CancellationToken cancellationToken) Document document, string renameText, ArrayBuilder<RenameLocation> renameLocations, CancellationToken cancellationToken)
{ {
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var renameTextLength = renameText.Length; var renameTextLength = renameText.Length;
var renameStringsAndPositions = root var renameStringsAndPositions = root
...@@ -508,8 +516,11 @@ internal static async Task<IEnumerable<RenameLocation>> GetRenamableReferenceLoc ...@@ -508,8 +516,11 @@ internal static async Task<IEnumerable<RenameLocation>> GetRenamableReferenceLoc
var matches = regex.Matches(renameString); var matches = regex.Matches(renameString);
foreach (Match match in matches) foreach (Match? match in matches)
{ {
if (match == null)
continue;
var start = renameStringPosition + match.Index; var start = renameStringPosition + match.Index;
Debug.Assert(renameText.Length == match.Length); Debug.Assert(renameText.Length == match.Length);
var matchTextSpan = new TextSpan(start, renameText.Length); var matchTextSpan = new TextSpan(start, renameText.Length);
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
#nullable enable
using System; using System;
using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text;
...@@ -48,7 +50,7 @@ public RenameLocation(ReferenceLocation referenceLocation, DocumentId documentId ...@@ -48,7 +50,7 @@ public RenameLocation(ReferenceLocation referenceLocation, DocumentId documentId
public bool Equals(RenameLocation other) public bool Equals(RenameLocation other)
=> Location == other.Location; => Location == other.Location;
public override bool Equals(object obj) public override bool Equals(object? obj)
{ {
return obj is RenameLocation loc && return obj is RenameLocation loc &&
Equals(loc); Equals(loc);
......
...@@ -2,8 +2,11 @@ ...@@ -2,8 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
#nullable enable
using System.Collections.Immutable; using System.Collections.Immutable;
using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.FindSymbols;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Rename namespace Microsoft.CodeAnalysis.Rename
{ {
...@@ -20,6 +23,7 @@ public class SearchResult ...@@ -20,6 +23,7 @@ public class SearchResult
ImmutableArray<ReferenceLocation> implicitLocations, ImmutableArray<ReferenceLocation> implicitLocations,
ImmutableArray<ISymbol> referencedSymbols) ImmutableArray<ISymbol> referencedSymbols)
{ {
Contract.ThrowIfNull(locations);
this.Locations = locations; this.Locations = locations;
this.ImplicitLocations = implicitLocations; this.ImplicitLocations = implicitLocations;
this.ReferencedSymbols = referencedSymbols; this.ReferencedSymbols = referencedSymbols;
......
...@@ -150,8 +150,10 @@ internal sealed partial class RenameLocations ...@@ -150,8 +150,10 @@ internal sealed partial class RenameLocations
if (result.HasValue) if (result.HasValue)
{ {
return await RenameLocations.RehydrateAsync( var rehydrated = await RenameLocations.TryRehydrateAsync(
solution, result.Value, cancellationToken).ConfigureAwait(false); solution, result.Value, cancellationToken).ConfigureAwait(false);
if (rehydrated != null)
return rehydrated;
} }
} }
} }
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
...@@ -35,7 +37,7 @@ public static partial class Renamer ...@@ -35,7 +37,7 @@ public static partial class Renamer
RenameOptionSet.From(solution, optionSet), RenameOptionSet.From(solution, optionSet),
nonConflictSymbols: null, cancellationToken).ConfigureAwait(false); nonConflictSymbols: null, cancellationToken).ConfigureAwait(false);
// This is a public entrypoint. So if rename failed to resolve conflicts, we report that back to caller as // This is a public entry-point. So if rename failed to resolve conflicts, we report that back to caller as
// an exception. // an exception.
if (resolution.ErrorMessage != null) if (resolution.ErrorMessage != null)
throw new ArgumentException(resolution.ErrorMessage); throw new ArgumentException(resolution.ErrorMessage);
...@@ -66,8 +68,8 @@ public static partial class Renamer ...@@ -66,8 +68,8 @@ public static partial class Renamer
public static async Task<RenameDocumentActionSet> RenameDocumentAsync( public static async Task<RenameDocumentActionSet> RenameDocumentAsync(
Document document, Document document,
string newDocumentName, string newDocumentName,
IReadOnlyList<string> newDocumentFolders = null, IReadOnlyList<string>? newDocumentFolders = null,
OptionSet optionSet = null, OptionSet? optionSet = null,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
if (document is null) if (document is null)
...@@ -109,7 +111,7 @@ internal static Task<RenameLocations> FindRenameLocationsAsync(Solution solution ...@@ -109,7 +111,7 @@ internal static Task<RenameLocations> FindRenameLocationsAsync(Solution solution
ISymbol symbol, ISymbol symbol,
string newName, string newName,
RenameOptionSet optionSet, RenameOptionSet optionSet,
ImmutableHashSet<ISymbol> nonConflictSymbols, ImmutableHashSet<ISymbol>? nonConflictSymbols,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
Contract.ThrowIfNull(solution); Contract.ThrowIfNull(solution);
...@@ -130,7 +132,7 @@ internal static Task<RenameLocations> FindRenameLocationsAsync(Solution solution ...@@ -130,7 +132,7 @@ internal static Task<RenameLocations> FindRenameLocationsAsync(Solution solution
WellKnownServiceHubServices.CodeAnalysisService, WellKnownServiceHubServices.CodeAnalysisService,
nameof(IRemoteRenamer.RenameSymbolAsync), nameof(IRemoteRenamer.RenameSymbolAsync),
solution, solution,
new object[] new object?[]
{ {
SerializableSymbolAndProjectId.Create(symbol, project, cancellationToken), SerializableSymbolAndProjectId.Create(symbol, project, cancellationToken),
newName, newName,
...@@ -156,7 +158,7 @@ internal static Task<RenameLocations> FindRenameLocationsAsync(Solution solution ...@@ -156,7 +158,7 @@ internal static Task<RenameLocations> FindRenameLocationsAsync(Solution solution
ISymbol symbol, ISymbol symbol,
string newName, string newName,
RenameOptionSet optionSet, RenameOptionSet optionSet,
ImmutableHashSet<ISymbol> nonConflictSymbols, ImmutableHashSet<ISymbol>? nonConflictSymbols,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
Contract.ThrowIfNull(solution); Contract.ThrowIfNull(solution);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册