示例#1
0
        // Internal for unit tests only.
        internal MergedNamespaceDeclaration CalculateMergedRoot(CSharpCompilation compilation)
        {
            var oldRoot = _cache.MergedRoot.Value;

            if (_latestLazyRootDeclaration == null)
            {
                return(oldRoot);
            }
            else if (oldRoot == null)
            {
                return(MergedNamespaceDeclaration.Create(_latestLazyRootDeclaration.Value));
            }
            else
            {
                var oldRootDeclarations = oldRoot.Declarations;
                var builder             = ArrayBuilder <SingleNamespaceDeclaration> .GetInstance(oldRootDeclarations.Length + 1);

                builder.AddRange(oldRootDeclarations);
                builder.Add(_latestLazyRootDeclaration.Value);
                // Sort the root namespace declarations to match the order of SyntaxTrees.
                if (compilation != null)
                {
                    builder.Sort(new RootNamespaceLocationComparer(compilation));
                }
                return(MergedNamespaceDeclaration.Create(builder.ToImmutableAndFree()));
            }
        }
示例#2
0
 public static bool ContainsName(
     MergedNamespaceDeclaration mergedRoot,
     string name,
     SymbolFilter filter,
     CancellationToken cancellationToken)
 {
     return(ContainsNameHelper(
                mergedRoot,
                n => n == name,
                filter,
                t => t.MemberNames.Contains(name),
                cancellationToken));
 }
示例#3
0
            public Cache(DeclarationTable table)
            {
                this.MergedRoot = new Lazy <MergedNamespaceDeclaration>(
                    () => MergedNamespaceDeclaration.Create(table._allOlderRootDeclarations.InInsertionOrder.AsImmutable <SingleNamespaceDeclaration>()));

                this.TypeNames = new Lazy <ISet <string> >(
                    () => GetTypeNames(this.MergedRoot.Value));

                this.NamespaceNames = new Lazy <ISet <string> >(
                    () => GetNamespaceNames(this.MergedRoot.Value));

                this.ReferenceDirectives = new Lazy <ImmutableArray <ReferenceDirective> >(
                    () => MergedRoot.Value.Declarations.OfType <RootSingleNamespaceDeclaration>().SelectMany(r => r.ReferenceDirectives).AsImmutable());
            }
示例#4
0
        public static bool ContainsName(
            MergedNamespaceDeclaration mergedRoot,
            Func <string, bool> predicate,
            SymbolFilter filter,
            CancellationToken cancellationToken)
        {
            return(ContainsNameHelper(
                       mergedRoot, predicate, filter,
                       t =>
            {
                foreach (var name in t.MemberNames)
                {
                    if (predicate(name))
                    {
                        return true;
                    }
                }

                return false;
            }, cancellationToken));
        }
示例#5
0
        private static bool ContainsNameHelper(
            MergedNamespaceDeclaration mergedRoot,
            Func <string, bool> predicate,
            SymbolFilter filter,
            Func <SingleTypeDeclaration, bool> typePredicate,
            CancellationToken cancellationToken)
        {
            var includeNamespace = (filter & SymbolFilter.Namespace) == SymbolFilter.Namespace;
            var includeType      = (filter & SymbolFilter.Type) == SymbolFilter.Type;
            var includeMember    = (filter & SymbolFilter.Member) == SymbolFilter.Member;

            var stack = new Stack <MergedNamespaceOrTypeDeclaration>();

            stack.Push(mergedRoot);

            while (stack.Count > 0)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var current = stack.Pop();
                if (current == null)
                {
                    continue;
                }

                if (current.Kind == DeclarationKind.Namespace)
                {
                    if (includeNamespace && predicate(current.Name))
                    {
                        return(true);
                    }
                }
                else
                {
                    if (includeType && predicate(current.Name))
                    {
                        return(true);
                    }

                    if (includeMember)
                    {
                        var mergedType = (MergedTypeDeclaration)current;
                        foreach (var typeDecl in mergedType.Declarations)
                        {
                            if (typePredicate(typeDecl))
                            {
                                return(true);
                            }
                        }
                    }
                }

                foreach (var child in current.Children)
                {
                    if (child is MergedNamespaceOrTypeDeclaration childNamespaceOrType)
                    {
                        if (includeMember || includeType || childNamespaceOrType.Kind == DeclarationKind.Namespace)
                        {
                            stack.Push(childNamespaceOrType);
                        }
                    }
                }
            }

            return(false);
        }
        private ImmutableArray <MergedNamespaceOrTypeDeclaration> MakeChildren()
        {
            ArrayBuilder <SingleNamespaceDeclaration> namespaces = null;
            ArrayBuilder <SingleTypeDeclaration>      types      = null;
            bool allNamespacesHaveSameName = true;
            bool allTypesHaveSameIdentity  = true;

            foreach (var decl in _declarations)
            {
                foreach (var child in decl.Children)
                {
                    // it is either a type (more likely)
                    var asType = child as SingleTypeDeclaration;
                    if (asType != null)
                    {
                        // handle types
                        if (types == null)
                        {
                            types = ArrayBuilder <SingleTypeDeclaration> .GetInstance();
                        }
                        else if (allTypesHaveSameIdentity && !asType.Identity.Equals(types[0].Identity))
                        {
                            allTypesHaveSameIdentity = false;
                        }

                        types.Add(asType);
                        continue;
                    }

                    // or it is a namespace
                    var asNamespace = child as SingleNamespaceDeclaration;
                    if (asNamespace != null)
                    {
                        // handle namespace
                        if (namespaces == null)
                        {
                            namespaces = ArrayBuilder <SingleNamespaceDeclaration> .GetInstance();
                        }
                        else if (allNamespacesHaveSameName && !asNamespace.Name.Equals(namespaces[0].Name))
                        {
                            allNamespacesHaveSameName = false;
                        }

                        namespaces.Add(asNamespace);
                        continue;
                    }

                    // Not sure if we can get here, perhaps, if we have errors,
                    // but we care only about types and namespaces anyways.
                }
            }

            var children = ArrayBuilder <MergedNamespaceOrTypeDeclaration> .GetInstance();

            if (namespaces != null)
            {
                if (allNamespacesHaveSameName)
                {
                    children.Add(MergedNamespaceDeclaration.Create(namespaces.ToImmutableAndFree()));
                }
                else
                {
                    var namespaceGroups = namespaces.ToDictionary(n => n.Name, StringOrdinalComparer.Instance);
                    namespaces.Free();

                    foreach (var namespaceGroup in namespaceGroups.Values)
                    {
                        children.Add(MergedNamespaceDeclaration.Create(namespaceGroup));
                    }
                }
            }

            if (types != null)
            {
                if (allTypesHaveSameIdentity)
                {
                    children.Add(new MergedTypeDeclaration(types.ToImmutableAndFree()));
                }
                else
                {
                    var typeGroups = types.ToDictionary(t => t.Identity);
                    types.Free();

                    foreach (var typeGroup in typeGroups.Values)
                    {
                        children.Add(new MergedTypeDeclaration(typeGroup));
                    }
                }
            }

            return(children.ToImmutableAndFree());
        }