Exemple #1
0
        public static async Task <bool> IsValidNewMemberNameAsync(SemanticModel semanticModel, ISymbol symbol, string name, CancellationToken cancellationToken)
        {
            if (symbol.Kind == SymbolKind.NamedType)
            {
                TypeKind typeKind = ((INamedTypeSymbol)symbol).TypeKind;

                // If the symbol is a class or struct, the name can't be the same as any of its members.
                if (typeKind == TypeKind.Class || typeKind == TypeKind.Struct)
                {
                    var members = ((INamedTypeSymbol)symbol).GetMembers(name);
                    if (!members.IsDefaultOrEmpty)
                    {
                        return(false);
                    }
                }
            }

            var containingSymbol = symbol.ContainingSymbol;

            var containingNamespaceOrTypeSymbol = containingSymbol as INamespaceOrTypeSymbol;

            if (containingNamespaceOrTypeSymbol != null)
            {
                if (containingNamespaceOrTypeSymbol.Kind == SymbolKind.Namespace)
                {
                    // Make sure to use the compilation namespace so interfaces in referenced assemblies are considered
                    containingNamespaceOrTypeSymbol = semanticModel.Compilation.GetCompilationNamespace((INamespaceSymbol)containingNamespaceOrTypeSymbol);
                }
                else if (containingNamespaceOrTypeSymbol.Kind == SymbolKind.NamedType)
                {
                    TypeKind typeKind = ((INamedTypeSymbol)containingNamespaceOrTypeSymbol).TypeKind;

                    // If the containing type is a class or struct, the name can't be the same as the name of the containing
                    // type.
                    if ((typeKind == TypeKind.Class || typeKind == TypeKind.Struct) &&
                        containingNamespaceOrTypeSymbol.Name == name)
                    {
                        return(false);
                    }
                }

                // The name can't be the same as the name of an other member of the same type. At this point no special
                // consideration is given to overloaded methods.
                ImmutableArray <ISymbol> siblings = containingNamespaceOrTypeSymbol.GetMembers(name);
                if (!siblings.IsDefaultOrEmpty)
                {
                    return(false);
                }

                return(true);
            }
            else if (containingSymbol.Kind == SymbolKind.Method)
            {
                IMethodSymbol methodSymbol = (IMethodSymbol)containingSymbol;
                if (methodSymbol.Parameters.Any(i => i.Name == name) ||
                    methodSymbol.TypeParameters.Any(i => i.Name == name))
                {
                    return(false);
                }

                IMethodSymbol outermostMethod = methodSymbol;
                while (outermostMethod.ContainingSymbol.Kind == SymbolKind.Method)
                {
                    outermostMethod = (IMethodSymbol)outermostMethod.ContainingSymbol;
                    if (outermostMethod.Parameters.Any(i => i.Name == name) ||
                        outermostMethod.TypeParameters.Any(i => i.Name == name))
                    {
                        return(false);
                    }
                }

                foreach (var syntaxReference in outermostMethod.DeclaringSyntaxReferences)
                {
                    SyntaxNode syntaxNode = await syntaxReference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false);

                    LocalNameFinder localNameFinder = new LocalNameFinder(name);
                    localNameFinder.Visit(syntaxNode);
                    if (localNameFinder.Found)
                    {
                        return(false);
                    }
                }

                return(true);
            }
            else
            {
                return(true);
            }
        }
        public static async Task<bool> IsValidNewMemberNameAsync(SemanticModel semanticModel, ISymbol symbol, string name, CancellationToken cancellationToken)
        {
            if (symbol.Kind == SymbolKind.NamedType)
            {
                TypeKind typeKind = ((INamedTypeSymbol)symbol).TypeKind;

                // If the symbol is a class or struct, the name can't be the same as any of its members.
                if (typeKind == TypeKind.Class || typeKind == TypeKind.Struct)
                {
                    var members = (symbol as INamedTypeSymbol)?.GetMembers(name);
                    if (members.HasValue && !members.Value.IsDefaultOrEmpty)
                    {
                        return false;
                    }
                }
            }

            var containingSymbol = symbol.ContainingSymbol;

            var containingNamespaceOrTypeSymbol = containingSymbol as INamespaceOrTypeSymbol;
            if (containingNamespaceOrTypeSymbol != null)
            {
                if (containingNamespaceOrTypeSymbol.Kind == SymbolKind.Namespace)
                {
                    // Make sure to use the compilation namespace so interfaces in referenced assemblies are considered
                    containingNamespaceOrTypeSymbol = semanticModel.Compilation.GetCompilationNamespace((INamespaceSymbol)containingNamespaceOrTypeSymbol);
                }
                else if (containingNamespaceOrTypeSymbol.Kind == SymbolKind.NamedType)
                {
                    TypeKind typeKind = ((INamedTypeSymbol)containingNamespaceOrTypeSymbol).TypeKind;

                    // If the containing type is a class or struct, the name can't be the same as the name of the containing
                    // type.
                    if ((typeKind == TypeKind.Class || typeKind == TypeKind.Struct)
                        && containingNamespaceOrTypeSymbol.Name == name)
                    {
                        return false;
                    }
                }

                // The name can't be the same as the name of an other member of the same type. At this point no special
                // consideration is given to overloaded methods.
                ImmutableArray<ISymbol> siblings = containingNamespaceOrTypeSymbol.GetMembers(name);
                if (!siblings.IsDefaultOrEmpty)
                {
                    return false;
                }

                return true;
            }
            else if (containingSymbol.Kind == SymbolKind.Method)
            {
                IMethodSymbol methodSymbol = (IMethodSymbol)containingSymbol;
                if (methodSymbol.Parameters.Any(i => i.Name == name)
                    || methodSymbol.TypeParameters.Any(i => i.Name == name))
                {
                    return false;
                }

                IMethodSymbol outermostMethod = methodSymbol;
                while (outermostMethod.ContainingSymbol.Kind == SymbolKind.Method)
                {
                    outermostMethod = (IMethodSymbol)outermostMethod.ContainingSymbol;
                    if (outermostMethod.Parameters.Any(i => i.Name == name)
                        || outermostMethod.TypeParameters.Any(i => i.Name == name))
                    {
                        return false;
                    }
                }

                foreach (var syntaxReference in outermostMethod.DeclaringSyntaxReferences)
                {
                    SyntaxNode syntaxNode = await syntaxReference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false);
                    LocalNameFinder localNameFinder = new LocalNameFinder(name);
                    localNameFinder.Visit(syntaxNode);
                    if (localNameFinder.Found)
                    {
                        return false;
                    }
                }

                return true;
            }
            else
            {
                return true;
            }
        }