private IEnumerable <ISymbol> GetSymbolsInNewSolution(Document newDocument, SemanticModel newDocumentSemanticModel, RenameActionAnnotation conflictAnnotation, SyntaxNodeOrToken tokenOrNode) { IEnumerable <ISymbol> newReferencedSymbols = RenameUtilities.GetSymbolsTouchingPosition(tokenOrNode.Span.Start, newDocumentSemanticModel, newDocument.Project.Solution.Workspace, _cancellationToken); if (conflictAnnotation.IsInvocationExpression) { IEnumerable <ISymbol> invocationReferencedSymbols = null; if (tokenOrNode.IsNode) { invocationReferencedSymbols = SymbolsForEnclosingInvocationExpressionWorker((SyntaxNode)tokenOrNode, newDocumentSemanticModel, _cancellationToken); } if (invocationReferencedSymbols != null) { newReferencedSymbols = invocationReferencedSymbols; } } // if there are more than one symbol, then remove the alias symbols. // When using (not declaring) an alias, the alias symbol and the target symbol are returned // by GetSymbolsTouchingPosition if (newReferencedSymbols.Skip(1).Any()) { newReferencedSymbols = newReferencedSymbols.Where(a => a.Kind != SymbolKind.Alias); } return(newReferencedSymbols); }
private async Task <bool> CheckForConflictAsync( ConflictResolution conflictResolution, ISymbol renamedSymbolInNewSolution, Document newDocument, RenameActionAnnotation conflictAnnotation, IEnumerable <ISymbol> newReferencedSymbols) { try { bool hasConflict; var solution = conflictResolution.NewSolution; if (conflictAnnotation.IsNamespaceDeclarationReference) { hasConflict = false; } else if (conflictAnnotation.IsMemberGroupReference) { if (!conflictAnnotation.RenameDeclarationLocationReferences.Any()) { hasConflict = false; } else { // Ensure newReferencedSymbols contains at least one of the original referenced // symbols, and allow any new symbols to be added to the set of references. hasConflict = true; var newLocationTasks = newReferencedSymbols.Select(async symbol => await GetSymbolLocationAsync(solution, symbol, _cancellationToken).ConfigureAwait(false)); var newLocations = (await Task.WhenAll(newLocationTasks).ConfigureAwait(false)).Where(loc => loc != null && loc.IsInSource); foreach (var originalReference in conflictAnnotation.RenameDeclarationLocationReferences.Where(loc => loc.IsSourceLocation)) { var adjustedStartPosition = conflictResolution.GetAdjustedTokenStartingPosition(originalReference.TextSpan.Start, originalReference.DocumentId); if (newLocations.Any(loc => loc.SourceSpan.Start == adjustedStartPosition)) { hasConflict = false; break; } } } } else if (!conflictAnnotation.IsRenameLocation && conflictAnnotation.IsOriginalTextLocation && conflictAnnotation.RenameDeclarationLocationReferences.Length > 1 && newReferencedSymbols.Count() == 1) { // an ambiguous situation was resolved through rename in non reference locations hasConflict = false; } else if (newReferencedSymbols.Count() != conflictAnnotation.RenameDeclarationLocationReferences.Length) { // Don't show conflicts for errors in the old solution that now bind in the new solution. if (newReferencedSymbols.Count() != 0 && conflictAnnotation.RenameDeclarationLocationReferences.Length == 0) { hasConflict = false; } else { hasConflict = true; } } else { hasConflict = false; int symbolIndex = 0; foreach (var symbol in newReferencedSymbols) { if (conflictAnnotation.RenameDeclarationLocationReferences[symbolIndex].SymbolLocationsCount != symbol.Locations.Length) { hasConflict = true; break; } var newLocation = await GetSymbolLocationAsync(solution, symbol, _cancellationToken).ConfigureAwait(false); if (newLocation != null && conflictAnnotation.RenameDeclarationLocationReferences[symbolIndex].IsSourceLocation) { // location was in source before, but not after rename if (!newLocation.IsInSource) { hasConflict = true; break; } var renameDeclarationLocationReference = conflictAnnotation.RenameDeclarationLocationReferences[symbolIndex]; var newAdjustedStartPosition = conflictResolution.GetAdjustedTokenStartingPosition(renameDeclarationLocationReference.TextSpan.Start, renameDeclarationLocationReference.DocumentId); if (newAdjustedStartPosition != newLocation.SourceSpan.Start) { hasConflict = true; break; } if (conflictAnnotation.RenameDeclarationLocationReferences[symbolIndex].IsOverriddenFromMetadata) { var overridingSymbol = await SymbolFinder.FindSymbolAtPositionAsync(solution.GetDocument(newLocation.SourceTree), newLocation.SourceSpan.Start, cancellationToken : _cancellationToken).ConfigureAwait(false); if (overridingSymbol != null && renamedSymbolInNewSolution != overridingSymbol) { if (!overridingSymbol.IsOverride) { hasConflict = true; break; } else { var overriddenSymbol = overridingSymbol.OverriddenMember(); if (overriddenSymbol == null || !overriddenSymbol.Locations.All(loc => loc.IsInMetadata)) { hasConflict = true; break; } } } } } else { var newMetadataName = symbol.ToDisplayString(s_metadataSymbolDisplayFormat); var oldMetadataName = conflictAnnotation.RenameDeclarationLocationReferences[symbolIndex].Name; if (newLocation == null || newLocation.IsInSource || !HeuristicMetadataNameEquivalenceCheck( oldMetadataName, newMetadataName, _originalText, _replacementText)) { hasConflict = true; break; } } symbolIndex++; } } return(hasConflict); } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }