예제 #1
0
        // Internal for unit tests only.
        internal MergedDeclaration CalculateMergedRoot(LanguageCompilation compilation)
        {
            var oldRoot = _cache.MergedRoot.Value;

            if (_latestLazyRootDeclaration == null)
            {
                return(oldRoot);
            }
            else if (oldRoot == null)
            {
                return(MergedDeclaration.Create(_latestLazyRootDeclaration.Value));
            }
            else
            {
                var oldRootDeclarations = oldRoot.Declarations;
                var builder             = ArrayBuilder <SingleDeclaration> .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(MergedDeclaration.Create(builder.ToImmutableAndFree()));
            }
        }
예제 #2
0
 public static bool ContainsName(
     MergedDeclaration mergedRoot,
     string name,
     SymbolFilter filter,
     CancellationToken cancellationToken)
 {
     return(ContainsNameHelper(
                mergedRoot,
                n => n == name,
                filter,
                t => t.ChildNames.Contains(name),
                cancellationToken));
 }
예제 #3
0
            public Cache(DeclarationTable table)
            {
                this.MergedRoot = new Lazy <MergedDeclaration>(
                    () => MergedDeclaration.Create(table._allOlderRootDeclarations.InInsertionOrder.AsImmutable <SingleDeclaration>()));

                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 <RootSingleDeclaration>().SelectMany(r => r.ReferenceDirectives).AsImmutable());
            }
예제 #4
0
        private void MakeChildren()
        {
            ArrayBuilder <SingleDeclaration> nestedDeclarations = null;

            foreach (var decl in this.Declarations)
            {
                foreach (var child in decl.Children)
                {
                    var asSingle = child as SingleDeclaration;
                    if (asSingle != null)
                    {
                        if (nestedDeclarations == null)
                        {
                            nestedDeclarations = ArrayBuilder <SingleDeclaration> .GetInstance();
                        }
                        nestedDeclarations.Add(asSingle);
                    }
                }
            }

            var members = ArrayBuilder <MergedDeclaration> .GetInstance();

            var memberNames = ArrayBuilder <string> .GetInstance();

            if (nestedDeclarations != null)
            {
                var membersGrouped = nestedDeclarations.ToDictionary(m => m.Identity);
                nestedDeclarations.Free();

                foreach (var memberGroup in membersGrouped.Values)
                {
                    var merged = new MergedDeclaration(memberGroup);
                    members.Add(merged);
                    if (merged.Name != null)
                    {
                        memberNames.Add(merged.Name);
                    }
                }
            }

            ImmutableInterlocked.InterlockedInitialize(ref _lazyChildren, members.ToImmutableAndFree());
            ImmutableInterlocked.InterlockedInitialize(ref _lazyChildNames, memberNames.ToImmutableAndFree());
        }
예제 #5
0
        public static bool ContainsName(
            MergedDeclaration mergedRoot,
            Func <string, bool> predicate,
            SymbolFilter filter,
            CancellationToken cancellationToken)
        {
            return(ContainsNameHelper(
                       mergedRoot, predicate, filter,
                       t =>
            {
                foreach (var child in t.Children)
                {
                    if (predicate(child.Name))
                    {
                        return true;
                    }
                }

                return false;
            }, cancellationToken));
        }
예제 #6
0
 public static MergedDeclaration Create(
     MergedDeclaration mergedDeclaration,
     SingleDeclaration declaration)
 {
     return(new MergedDeclaration(mergedDeclaration._declarations.Add(declaration)));
 }
예제 #7
0
        private static bool ContainsNameHelper(
            MergedDeclaration mergedRoot,
            Func <string, bool> predicate,
            SymbolFilter filter,
            Func <SingleDeclaration, 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 <MergedDeclaration>();

            stack.Push(mergedRoot);

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

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

                if (current.IsNamespace)
                {
                    if (includeNamespace && predicate(current.Name))
                    {
                        return(true);
                    }
                }
                else
                {
                    if (includeType && predicate(current.Name))
                    {
                        return(true);
                    }

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

                foreach (var child in current.Children)
                {
                    if (child is MergedDeclaration childNamespaceOrType)
                    {
                        if (includeMember || includeType || childNamespaceOrType.IsNamespace)
                        {
                            stack.Push(childNamespaceOrType);
                        }
                    }
                }
            }

            return(false);
        }