Example #1
0
        private static async Task AddImplicitConflictsAsync(
            ISymbol renamedSymbol,
            ISymbol originalSymbol,
            IEnumerable <ReferenceLocation> implicitReferenceLocations,
            SemanticModel semanticModel,
            Location originalDeclarationLocation,
            int newDeclarationLocationStartingPosition,
            MutableConflictResolution conflictResolution,
            CancellationToken cancellationToken)
        {
            {
                var renameRewriterService =
                    conflictResolution.CurrentSolution.Workspace.Services.GetLanguageServices(renamedSymbol.Language)
                    .GetRequiredService <IRenameRewriterLanguageService>();
                var implicitUsageConflicts = renameRewriterService.ComputePossibleImplicitUsageConflicts(renamedSymbol, semanticModel, originalDeclarationLocation, newDeclarationLocationStartingPosition, cancellationToken);
                foreach (var implicitUsageConflict in implicitUsageConflicts)
                {
                    Contract.ThrowIfNull(implicitUsageConflict.SourceTree);
                    conflictResolution.AddOrReplaceRelatedLocation(new RelatedLocation(
                                                                       implicitUsageConflict.SourceSpan, conflictResolution.OldSolution.GetRequiredDocument(implicitUsageConflict.SourceTree).Id, RelatedLocationType.UnresolvableConflict));
                }
            }

            if (implicitReferenceLocations.IsEmpty())
            {
                return;
            }

            foreach (var implicitReferenceLocationsPerLanguage in implicitReferenceLocations.GroupBy(loc => loc.Document.Project.Language))
            {
                // the location of the implicit reference defines the language rules to check.
                // E.g. foreach in C# using a MoveNext in VB that is renamed to MOVENEXT (within VB)
                var renameRewriterService = implicitReferenceLocationsPerLanguage.First().Document.Project.LanguageServices.GetRequiredService <IRenameRewriterLanguageService>();
                var implicitConflicts     = await renameRewriterService.ComputeImplicitReferenceConflictsAsync(
                    originalSymbol,
                    renamedSymbol,
                    implicitReferenceLocationsPerLanguage,
                    cancellationToken).ConfigureAwait(false);

                foreach (var implicitConflict in implicitConflicts)
                {
                    Contract.ThrowIfNull(implicitConflict.SourceTree);
                    conflictResolution.AddRelatedLocation(new RelatedLocation(
                                                              implicitConflict.SourceSpan, conflictResolution.OldSolution.GetRequiredDocument(implicitConflict.SourceTree).Id, RelatedLocationType.UnresolvableConflict));
                }
            }
        }
Example #2
0
 private static void AddConflictingSymbolLocations(IEnumerable <ISymbol> conflictingSymbols, MutableConflictResolution conflictResolution, IDictionary <Location, Location> reverseMappedLocations)
 {
     foreach (var newSymbol in conflictingSymbols)
     {
         foreach (var newLocation in newSymbol.Locations)
         {
             if (newLocation.IsInSource)
             {
                 if (reverseMappedLocations.TryGetValue(newLocation, out var oldLocation))
                 {
                     conflictResolution.AddOrReplaceRelatedLocation(new RelatedLocation(oldLocation.SourceSpan, conflictResolution.OldSolution.GetDocument(oldLocation.SourceTree).Id, RelatedLocationType.UnresolvableConflict));
                 }
             }
         }
     }
 }
Example #3
0
        /// <summary>
        /// Computes an adds conflicts relating to declarations, which are independent of
        /// location-based checks. Examples of these types of conflicts include renaming a member to
        /// the same name as another member of a type: binding doesn't change (at least from the
        /// perspective of find all references), but we still need to track it.
        /// </summary>
        private static async Task AddDeclarationConflictsAsync(
            ISymbol renamedSymbol,
            ISymbol renameSymbol,
            IEnumerable <ISymbol> referencedSymbols,
            MutableConflictResolution conflictResolution,
            IDictionary <Location, Location> reverseMappedLocations,
            CancellationToken cancellationToken)
        {
            try
            {
                var project = conflictResolution.CurrentSolution.GetProject(renamedSymbol.ContainingAssembly, cancellationToken);

                if (renamedSymbol.ContainingSymbol.IsKind(SymbolKind.NamedType))
                {
                    var otherThingsNamedTheSame = renamedSymbol.ContainingType.GetMembers(renamedSymbol.Name)
                                                  .Where(s => !s.Equals(renamedSymbol) &&
                                                         string.Equals(s.MetadataName, renamedSymbol.MetadataName, StringComparison.Ordinal));

                    IEnumerable <ISymbol> otherThingsNamedTheSameExcludeMethodAndParameterizedProperty;

                    // Possibly overloaded symbols are excluded here and handled elsewhere
                    var semanticFactsService = project.LanguageServices.GetService <ISemanticFactsService>();
                    if (semanticFactsService.SupportsParameterizedProperties)
                    {
                        otherThingsNamedTheSameExcludeMethodAndParameterizedProperty = otherThingsNamedTheSame
                                                                                       .Where(s => !s.MatchesKind(SymbolKind.Method, SymbolKind.Property) ||
                                                                                              !renamedSymbol.MatchesKind(SymbolKind.Method, SymbolKind.Property));
                    }
                    else
                    {
                        otherThingsNamedTheSameExcludeMethodAndParameterizedProperty = otherThingsNamedTheSame
                                                                                       .Where(s => s.Kind != SymbolKind.Method || renamedSymbol.Kind != SymbolKind.Method);
                    }

                    AddConflictingSymbolLocations(otherThingsNamedTheSameExcludeMethodAndParameterizedProperty, conflictResolution, reverseMappedLocations);
                }


                if (renamedSymbol.IsKind(SymbolKind.Namespace) && renamedSymbol.ContainingSymbol.IsKind(SymbolKind.Namespace))
                {
                    var otherThingsNamedTheSame = ((INamespaceSymbol)renamedSymbol.ContainingSymbol).GetMembers(renamedSymbol.Name)
                                                  .Where(s => !s.Equals(renamedSymbol) &&
                                                         !s.IsKind(SymbolKind.Namespace) &&
                                                         string.Equals(s.MetadataName, renamedSymbol.MetadataName, StringComparison.Ordinal));

                    AddConflictingSymbolLocations(otherThingsNamedTheSame, conflictResolution, reverseMappedLocations);
                }

                if (renamedSymbol.IsKind(SymbolKind.NamedType) && renamedSymbol.ContainingSymbol is INamespaceOrTypeSymbol)
                {
                    var otherThingsNamedTheSame = ((INamespaceOrTypeSymbol)renamedSymbol.ContainingSymbol).GetMembers(renamedSymbol.Name)
                                                  .Where(s => !s.Equals(renamedSymbol) &&
                                                         string.Equals(s.MetadataName, renamedSymbol.MetadataName, StringComparison.Ordinal));

                    var conflictingSymbolLocations = otherThingsNamedTheSame.Where(s => !s.IsKind(SymbolKind.Namespace));
                    if (otherThingsNamedTheSame.Any(s => s.IsKind(SymbolKind.Namespace)))
                    {
                        conflictingSymbolLocations = conflictingSymbolLocations.Concat(renamedSymbol);
                    }

                    AddConflictingSymbolLocations(conflictingSymbolLocations, conflictResolution, reverseMappedLocations);
                }

                // Some types of symbols (namespaces, cref stuff, etc) might not have ContainingAssemblies
                if (renamedSymbol.ContainingAssembly != null)
                {
                    // There also might be language specific rules we need to include
                    var languageRenameService = project.LanguageServices.GetService <IRenameRewriterLanguageService>();
                    var languageConflicts     = await languageRenameService.ComputeDeclarationConflictsAsync(
                        conflictResolution.ReplacementText,
                        renamedSymbol,
                        renameSymbol,
                        referencedSymbols,
                        conflictResolution.OldSolution,
                        conflictResolution.CurrentSolution,
                        reverseMappedLocations,
                        cancellationToken).ConfigureAwait(false);

                    foreach (var languageConflict in languageConflicts)
                    {
                        conflictResolution.AddOrReplaceRelatedLocation(new RelatedLocation(languageConflict.SourceSpan, conflictResolution.OldSolution.GetDocument(languageConflict.SourceTree).Id, RelatedLocationType.UnresolvableConflict));
                    }
                }
            }
            catch (Exception e) when(FatalError.ReportUnlessCanceled(e))
            {
                // A NullReferenceException is happening in this method, but the dumps do not
                // contain information about this stack frame because this method is async and
                // therefore the exception filter in IdentifyConflictsAsync is insufficient.
                // See https://devdiv.visualstudio.com/DevDiv/_workitems?_a=edit&id=378642

                throw ExceptionUtilities.Unreachable;
            }
        }
Example #4
0
 private static bool IsRenameValid(MutableConflictResolution conflictResolution, ISymbol renamedSymbol)
 {
     // if we rename an identifier and it now binds to a symbol from metadata this should be treated as
     // an invalid rename.
     return(conflictResolution.ReplacementTextValid && renamedSymbol != null && renamedSymbol.Locations.Any(loc => loc.IsInSource));
 }