Beispiel #1
0
        internal BinderFactory(
            CSharpCompilation compilation,
            SyntaxTree syntaxTree,
            bool ignoreAccessibility
            )
        {
            _compilation         = compilation;
            _syntaxTree          = syntaxTree;
            _ignoreAccessibility = ignoreAccessibility;

            _binderFactoryVisitorPool = new ObjectPool <BinderFactoryVisitor>(
                () => new BinderFactoryVisitor(this),
                64
                );

            // 50 is more or less a guess, but it seems to work fine for scenarios that I tried.
            // we need something big enough to keep binders for most classes and some methods
            // in a typical syntax tree.
            // On the other side, note that the whole factory is weakly referenced and therefore short lived,
            // making this cache big is not very useful.
            // I noticed that while compiling Roslyn C# compiler most caches never see
            // more than 50 items added before getting collected.
            _binderCache = new ConcurrentCache <BinderCacheKey, Binder>(50);

            _buckStopsHereBinder = new BuckStopsHereBinder(compilation);
        }
Beispiel #2
0
            private static Binder MakeNameBinder(bool isParameter, bool isTypeParameterRef, Symbol memberSymbol, CSharpCompilation compilation, SyntaxTree syntaxTree)
            {
                Binder binder = new BuckStopsHereBinder(compilation, syntaxTree);

                // All binders should have a containing symbol.
                Symbol containingSymbol = memberSymbol.ContainingSymbol;

                Debug.Assert((object)containingSymbol != null);
                binder = binder.WithContainingMemberOrLambda(containingSymbol);

                if (isParameter)
                {
                    ImmutableArray <ParameterSymbol> parameters = ImmutableArray <ParameterSymbol> .Empty;

                    switch (memberSymbol.Kind)
                    {
                    case SymbolKind.Method:
                        parameters = ((MethodSymbol)memberSymbol).Parameters;
                        break;

                    case SymbolKind.Property:
                        parameters = ((PropertySymbol)memberSymbol).Parameters;
                        break;

                    case SymbolKind.NamedType:
                    case SymbolKind.ErrorType:
                        NamedTypeSymbol typeSymbol = (NamedTypeSymbol)memberSymbol;
                        if (typeSymbol.IsDelegateType())
                        {
                            parameters = typeSymbol.DelegateInvokeMethod.Parameters;
                        }
                        break;
                    }

                    if (parameters.Length > 0)
                    {
                        binder = new WithParametersBinder(parameters, binder);
                    }
                }
                else
                {
                    Symbol currentSymbol = memberSymbol;
                    do
                    {
                        switch (currentSymbol.Kind)
                        {
                        case SymbolKind.NamedType:     // Includes delegates.
                        case SymbolKind.ErrorType:
                            NamedTypeSymbol typeSymbol = (NamedTypeSymbol)currentSymbol;
                            if (typeSymbol.Arity > 0)
                            {
                                binder = new WithClassTypeParametersBinder(typeSymbol, binder);
                            }
                            break;

                        case SymbolKind.Method:
                            MethodSymbol methodSymbol = (MethodSymbol)currentSymbol;
                            if (methodSymbol.Arity > 0)
                            {
                                binder = new WithMethodTypeParametersBinder(methodSymbol, binder);
                            }
                            break;
                        }
                        currentSymbol = currentSymbol.ContainingSymbol;
                    } while (isTypeParameterRef && !(currentSymbol is null));
                }

                return(binder);
            }
            // NOTE: We're not sharing code with the BinderFactory visitor, because we already have the
            // member symbol in hand, which makes things much easier.
            private static Binder MakeNameBinder(bool isParameter, Symbol memberSymbol, CSharpCompilation compilation)
            {
                Binder binder = new BuckStopsHereBinder(compilation);

                // All binders should have a containing symbol.
                Symbol containingSymbol = memberSymbol.ContainingSymbol;
                Debug.Assert((object)containingSymbol != null);
                binder = binder.WithContainingMemberOrLambda(containingSymbol);

                if (isParameter)
                {
                    ImmutableArray<ParameterSymbol> parameters = ImmutableArray<ParameterSymbol>.Empty;

                    switch (memberSymbol.Kind)
                    {
                        case SymbolKind.Method:
                            parameters = ((MethodSymbol)memberSymbol).Parameters;
                            break;
                        case SymbolKind.Property:
                            parameters = ((PropertySymbol)memberSymbol).Parameters;
                            break;
                        case SymbolKind.NamedType:
                        case SymbolKind.ErrorType:
                            NamedTypeSymbol typeSymbol = (NamedTypeSymbol)memberSymbol;
                            if (typeSymbol.IsDelegateType())
                            {
                                parameters = typeSymbol.DelegateInvokeMethod.Parameters;
                            }
                            break;
                    }

                    if (parameters.Length > 0)
                    {
                        binder = new WithParametersBinder(parameters, binder);
                    }
                }
                else
                {
                    switch (memberSymbol.Kind)
                    {
                        case SymbolKind.NamedType: // Includes delegates.
                        case SymbolKind.ErrorType:
                            NamedTypeSymbol typeSymbol = (NamedTypeSymbol)memberSymbol;
                            if (typeSymbol.Arity > 0)
                            {
                                binder = new WithClassTypeParametersBinder(typeSymbol, binder);
                            }
                            break;
                        case SymbolKind.Method:
                            MethodSymbol methodSymbol = (MethodSymbol)memberSymbol;
                            if (methodSymbol.Arity > 0)
                            {
                                binder = new WithMethodTypeParametersBinder(methodSymbol, binder);
                            }
                            break;
                    }
                }

                return binder;
            }