Exemplo n.º 1
0
        private static void GetItemsFromConflictingTypes(
            INamespaceSymbol containingNamespaceSymbol,
            ConflictNameNode conflictTypeNodes,
            ArrayBuilder <SerializableImportCompletionItem> builder,
            ITypeSymbol receiverTypeSymbol,
            SemanticModel semanticModel,
            int position,
            StatisticCounter counter)
        {
            Debug.Assert(!conflictTypeNodes.NamespaceAndMethodNames.HasValue);

            foreach (var child in conflictTypeNodes.Children.Values)
            {
                if (child.NamespaceAndMethodNames == null)
                {
                    var childNamespace = containingNamespaceSymbol.GetMembers(child.Name).OfType <INamespaceSymbol>().FirstOrDefault();
                    if (childNamespace != null)
                    {
                        GetItemsFromConflictingTypes(childNamespace, child, builder, receiverTypeSymbol, semanticModel, position, counter);
                    }
                }
                else
                {
                    var types = containingNamespaceSymbol.GetMembers(child.Name).OfType <INamedTypeSymbol>();
                    foreach (var type in types)
                    {
                        var(namespaceName, methodNames) = child.NamespaceAndMethodNames.Value;
                        GetItemsFromTypeContainsPotentialMatches(type, namespaceName, methodNames, receiverTypeSymbol, semanticModel, position, counter, builder);
                    }
                }
            }
        }
Exemplo n.º 2
0
        private static ImmutableArray <SerializableImportCompletionItem> GetExtensionMethodItems(
            INamespaceSymbol rootNamespaceSymbol,
            ITypeSymbol receiverTypeSymbol,
            SemanticModel semanticModel,
            int position,
            ISet <string> namespaceFilter,
            MultiDictionary <string, string> methodNameFilter,
            StatisticCounter counter,
            CancellationToken cancellationToken)
        {
            var compilation = semanticModel.Compilation;

            using var _ = ArrayBuilder <SerializableImportCompletionItem> .GetInstance(out var builder);

            using var conflictTypeRootNode = new ConflictNameNode(name: string.Empty);

            foreach (var(fullyQualifiedContainerName, methodNames) in methodNameFilter)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var indexOfLastDot         = fullyQualifiedContainerName.LastIndexOf('.');
                var qualifiedNamespaceName = indexOfLastDot > 0 ? fullyQualifiedContainerName.Substring(0, indexOfLastDot) : string.Empty;

                if (namespaceFilter.Contains(qualifiedNamespaceName))
                {
                    continue;
                }

                // Container of extension method (static class in C# and Module in VB) can't be generic or nested.
                // Note that we might incorrectly ignore valid types, because, for example, calling `GetTypeByMetadataName`
                // would return null if we have multiple definitions of a type even though only one is accessible from here
                // (e.g. an internal type declared inside a shared document). In this case, we have to handle the conflicted
                // types explicitly here.
                //
                // TODO:
                // Alternatively, we can try to get symbols out of each assembly, instead of the compilation (which includes all references),
                // to avoid such conflict. We should give this approach a try and see if any perf improvement can be archieved.
                var containerSymbol = compilation.GetTypeByMetadataName(fullyQualifiedContainerName);

                if (containerSymbol != null)
                {
                    GetItemsFromTypeContainsPotentialMatches(containerSymbol, qualifiedNamespaceName, methodNames, receiverTypeSymbol, semanticModel, position, counter, builder);
                }
                else
                {
                    conflictTypeRootNode.Add(fullyQualifiedContainerName, (qualifiedNamespaceName, methodNames));
                }
            }

            var ticks = Environment.TickCount;

            GetItemsFromConflictingTypes(rootNamespaceSymbol, conflictTypeRootNode, builder, receiverTypeSymbol, semanticModel, position, counter);

            counter.GetSymbolExtraTicks = Environment.TickCount - ticks;

            return(builder.ToImmutable());
        }