예제 #1
0
            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;
                        var 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 && !Equals(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;
                }
            }
예제 #2
0
            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);
            }
예제 #3
0
            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.Count())
                            {
                                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;
                }
            }
예제 #4
0
            private IEnumerable<ISymbol> GetSymbolsInNewSolution(Document newDocument, SemanticModel newDocumentSemanticModel, RenameActionAnnotation conflictAnnotation, SyntaxNodeOrToken tokenOrNode)
            {
                var 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 RenameActionAnnotation GetAnnotationForInvocationExpression(InvocationExpressionSyntax invocationExpression)
            {
                var identifierToken = default(SyntaxToken);
                var expressionOfInvocation = invocationExpression.Expression;

                while (expressionOfInvocation != null)
                {
                    switch (expressionOfInvocation.Kind())
                    {
                        case SyntaxKind.IdentifierName:
                        case SyntaxKind.GenericName:
                            identifierToken = ((SimpleNameSyntax)expressionOfInvocation).Identifier;
                            break;

                        case SyntaxKind.SimpleMemberAccessExpression:
                            identifierToken = ((MemberAccessExpressionSyntax)expressionOfInvocation).Name.Identifier;
                            break;

                        case SyntaxKind.QualifiedName:
                            identifierToken = ((QualifiedNameSyntax)expressionOfInvocation).Right.Identifier;
                            break;

                        case SyntaxKind.AliasQualifiedName:
                            identifierToken = ((AliasQualifiedNameSyntax)expressionOfInvocation).Name.Identifier;
                            break;

                        case SyntaxKind.ParenthesizedExpression:
                            expressionOfInvocation = ((ParenthesizedExpressionSyntax)expressionOfInvocation).Expression;
                            continue;
                    }

                    break;
                }

                if (identifierToken != default(SyntaxToken) && !_annotatedIdentifierTokens.Contains(identifierToken))
                {
                    var symbolInfo = _semanticModel.GetSymbolInfo(invocationExpression, _cancellationToken);
                    IEnumerable<ISymbol> symbols = null;
                    if (symbolInfo.Symbol == null)
                    {
                        return null;
                    }
                    else
                    {
                        symbols = SpecializedCollections.SingletonEnumerable(symbolInfo.Symbol);
                    }

                    RenameDeclarationLocationReference[] renameDeclarationLocations =
                                                                                ConflictResolver.CreateDeclarationLocationAnnotationsAsync(
                                                                                    _solution,
                                                                                    symbols,
                                                                                    _cancellationToken)
                                                                                        .WaitAndGetResult(_cancellationToken);

                    var renameAnnotation = new RenameActionAnnotation(
                                                identifierToken.Span,
                                                isRenameLocation: false,
                                                prefix: null,
                                                suffix: null,
                                                renameDeclarationLocations: renameDeclarationLocations,
                                                isOriginalTextLocation: false,
                                                isNamespaceDeclarationReference: false,
                                                isInvocationExpression: true,
                                                isMemberGroupReference: false);

                    return renameAnnotation;
                }

                return null;
            }
            private async Task<SyntaxToken> RenameAndAnnotateAsync(SyntaxToken token, SyntaxToken newToken, bool isRenameLocation, bool isOldText)
            {
                try
                {
                    if (_isProcessingComplexifiedSpans)
                    {
                        // Rename Token
                        if (isRenameLocation)
                        {
                            var annotation = _renameAnnotations.GetAnnotations(token).OfType<RenameActionAnnotation>().FirstOrDefault();
                            if (annotation != null)
                            {
                                newToken = RenameToken(token, newToken, annotation.Prefix, annotation.Suffix);
                                AddModifiedSpan(annotation.OriginalSpan, newToken.Span);
                            }
                            else
                            {
                                newToken = RenameToken(token, newToken, prefix: null, suffix: null);
                            }
                        }

                        return newToken;
                    }

                    var symbols = RenameUtilities.GetSymbolsTouchingPosition(token.Span.Start, _semanticModel, _solution.Workspace, _cancellationToken);

                    string suffix = null;
                    string prefix = isRenameLocation && _renameLocations[token.Span].IsRenamableAccessor
                        ? newToken.ValueText.Substring(0, newToken.ValueText.IndexOf('_') + 1)
                        : null;

                    if (symbols.Count() == 1)
                    {
                        var symbol = symbols.Single();

                        if (symbol.IsConstructor())
                        {
                            symbol = symbol.ContainingSymbol;
                        }

                        var sourceDefinition = await SymbolFinder.FindSourceDefinitionAsync(symbol, _solution, _cancellationToken).ConfigureAwait(false);
                        symbol = sourceDefinition ?? symbol;

                        if (symbol is INamedTypeSymbol)
                        {
                            var namedTypeSymbol = (INamedTypeSymbol)symbol;
                            if (namedTypeSymbol.IsImplicitlyDeclared &&
                                namedTypeSymbol.IsDelegateType() &&
                                namedTypeSymbol.AssociatedSymbol != null)
                            {
                                suffix = "EventHandler";
                            }
                        }

                        // This is a conflicting namespace declaration token. Even if the rename results in conflict with this namespace
                        // conflict is not shown for the namespace so we are tracking this token
                        if (!isRenameLocation && symbol is INamespaceSymbol && token.GetPreviousToken().IsKind(SyntaxKind.NamespaceKeyword))
                        {
                            return newToken;
                        }
                    }

                    // Rename Token
                    if (isRenameLocation && !this.AnnotateForComplexification)
                    {
                        var oldSpan = token.Span;
                        newToken = RenameToken(token, newToken, prefix, suffix);

                        AddModifiedSpan(oldSpan, newToken.Span);
                    }

                    RenameDeclarationLocationReference[] renameDeclarationLocations =
                        ConflictResolver.CreateDeclarationLocationAnnotationsAsync(_solution, symbols, _cancellationToken)
                                .WaitAndGetResult(_cancellationToken);

                    var isNamespaceDeclarationReference = false;
                    if (isRenameLocation && token.GetPreviousToken().IsKind(SyntaxKind.NamespaceKeyword))
                    {
                        isNamespaceDeclarationReference = true;
                    }

                    var isMemberGroupReference = _semanticFactsService.IsNameOfContext(_semanticModel, token.Span.Start, _cancellationToken);

                    var renameAnnotation =
                            new RenameActionAnnotation(
                                token.Span,
                                isRenameLocation,
                                prefix,
                                suffix,
                                renameDeclarationLocations: renameDeclarationLocations,
                                isOriginalTextLocation: isOldText,
                                isNamespaceDeclarationReference: isNamespaceDeclarationReference,
                                isInvocationExpression: false,
                                isMemberGroupReference: isMemberGroupReference);

                    newToken = _renameAnnotations.WithAdditionalAnnotations(newToken, renameAnnotation, new RenameTokenSimplificationAnnotation() { OriginalTextSpan = token.Span });

                    _annotatedIdentifierTokens.Add(token);
                    if (_renameRenamableSymbolDeclaration != null && _renamableDeclarationLocation == token.GetLocation())
                    {
                        newToken = _renameAnnotations.WithAdditionalAnnotations(newToken, _renameRenamableSymbolDeclaration);
                    }

                    return newToken;
                }
                catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
                {
                    throw ExceptionUtilities.Unreachable;
                }
            }
예제 #7
0
            private async Task <bool> CheckForConflictAsync(
                ConflictResolution conflictResolution,
                ISymbol renamedSymbolInNewSolution,
                Document newDocument,
                RenameActionAnnotation conflictAnnotation,
                IEnumerable <ISymbol> newReferencedSymbols)
            {
                bool hasConflict;
                var  solution = conflictResolution.NewSolution;

                if (conflictAnnotation.IsNamespaceDeclarationReference)
                {
                    hasConflict = false;
                }
                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.Count())
                        {
                            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);
            }
            private async Task<SyntaxToken> RenameAndAnnotateAsync(SyntaxToken token, SyntaxToken newToken, bool isRenameLocation, bool isOldText)
            {
                if (this.isProcessingComplexifiedSpans)
                {
                    // Rename Token
                    if (isRenameLocation)
                    {
                        var annotation = this.renameAnnotations.GetAnnotations(token).OfType<RenameActionAnnotation>().FirstOrDefault();
                        if (annotation != null)
                        {
                            newToken = RenameToken(token, newToken, annotation.Suffix, annotation.IsAccessorLocation);
                            AddModifiedSpan(annotation.OriginalSpan, newToken.Span);
                        }
                        else
                        {
                            newToken = RenameToken(token, newToken, suffix: null, isAccessorLocation: false);
                        }
                    }

                    return newToken;
                }

                var symbols = RenameUtilities.GetSymbolsTouchingPosition(token.Span.Start, this.semanticModel, this.solution.Workspace, this.cancellationToken);

                string suffix = null;
                if (symbols.Count() == 1)
                {
                    var symbol = symbols.Single();

                    if (symbol.IsConstructor())
                    {
                        symbol = symbol.ContainingSymbol;
                    }

                    var sourceDefinition = await SymbolFinder.FindSourceDefinitionAsync(symbol, solution, cancellationToken).ConfigureAwait(false);
                    symbol = sourceDefinition ?? symbol;

                    if (symbol is INamedTypeSymbol)
                    {
                        var namedTypeSymbol = (INamedTypeSymbol)symbol;
                        if (namedTypeSymbol.IsImplicitlyDeclared &&
                            namedTypeSymbol.IsDelegateType() &&
                            namedTypeSymbol.AssociatedSymbol != null)
                        {
                            suffix = "EventHandler";
                        }
                    }

                    // This is a conflicting namespace declaration token. Even if the rename results in conflict with this namespace
                    // conflict is not shown for the namespace so we are tracking this token
                    if (!isRenameLocation && symbol is INamespaceSymbol && token.GetPreviousToken().IsKind(SyntaxKind.NamespaceKeyword))
                    {
                        return newToken;
                    }
                }

                // Rename Token
                if (isRenameLocation && !this.AnnotateForComplexification)
                {
                    var oldSpan = token.Span;
                    newToken = RenameToken(
                        token,
                        newToken,
                        suffix: suffix,
                        isAccessorLocation: isRenameLocation && this.renameLocations[token.Span].IsRenamableAccessor);

                    AddModifiedSpan(oldSpan, newToken.Span);
                }

                RenameDeclarationLocationReference[] renameDeclarationLocations =
                    ConflictResolver.CreateDeclarationLocationAnnotationsAsync(solution, symbols, cancellationToken)
                            .WaitAndGetResult_Hack(cancellationToken);

                var isNamespaceDeclarationReference = false;
                if (isRenameLocation && token.GetPreviousToken().IsKind(SyntaxKind.NamespaceKeyword))
                {
                    isNamespaceDeclarationReference = true;
                }

                var renameAnnotation =
                        new RenameActionAnnotation(
                            token.Span,
                            isRenameLocation,
                            isRenameLocation ? this.renameLocations[token.Span].IsRenamableAccessor : false,
                            suffix,
                            renameDeclarationLocations: renameDeclarationLocations,
                            isOriginalTextLocation: isOldText,
                            isNamespaceDeclarationReference: isNamespaceDeclarationReference,
                            isInvocationExpression: false);

                newToken = this.renameAnnotations.WithAdditionalAnnotations(newToken, renameAnnotation, new RenameTokenSimplificationAnnotation() { OriginalTextSpan = token.Span });

                annotatedIdentifierTokens.Add(token);
                if (this.renameRenamableSymbolDeclaration != null && renamableDeclarationLocation == token.GetLocation())
                {
                    newToken = this.renameAnnotations.WithAdditionalAnnotations(newToken, this.renameRenamableSymbolDeclaration);
                }

                return newToken;
            }
예제 #9
0
            private async Task<bool> CheckForConflictAsync(
                ConflictResolution conflictResolution,
                ISymbol renamedSymbolInNewSolution,
                Document newDocument,
                RenameActionAnnotation conflictAnnotation,
                IEnumerable<ISymbol> newReferencedSymbols)
            {
                bool hasConflict;
                var solution = conflictResolution.NewSolution;

                if (conflictAnnotation.IsNamespaceDeclarationReference)
                {
                    hasConflict = false;
                }
                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.Count())
                        {
                            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(metadataSymbolDisplayFormat);
                            var oldMetadataName = conflictAnnotation.RenameDeclarationLocationReferences[symbolIndex].Name;
                            if (newLocation.IsInSource ||
                                !HeuristicMetadataNameEquivalenceCheck(
                                    oldMetadataName,
                                    newMetadataName,
                                    originalText,
                                    replacementText))
                            {
                                hasConflict = true;
                                break;
                            }
                        }

                        symbolIndex++;
                    }
                }

                return hasConflict;
            }