private static Binder ExtendBinderChain( CSharpSyntaxNode syntax, ImmutableArray<Alias> aliases, EEMethodSymbol method, Binder binder, bool hasDisplayClassThis, bool methodNotType) { var substitutedSourceMethod = GetSubstitutedSourceMethod(method.SubstitutedSourceMethod, hasDisplayClassThis); var substitutedSourceType = substitutedSourceMethod.ContainingType; var stack = ArrayBuilder<NamedTypeSymbol>.GetInstance(); for (var type = substitutedSourceType; (object)type != null; type = type.ContainingType) { stack.Add(type); } while (stack.Count > 0) { substitutedSourceType = stack.Pop(); binder = new InContainerBinder(substitutedSourceType, binder); if (substitutedSourceType.Arity > 0) { binder = new WithTypeArgumentsBinder(substitutedSourceType.TypeArguments, binder); } } stack.Free(); if (substitutedSourceMethod.Arity > 0) { binder = new WithTypeArgumentsBinder(substitutedSourceMethod.TypeArguments, binder); } if (methodNotType) { // Method locals and parameters shadow pseudo-variables. var typeNameDecoder = new EETypeNameDecoder(binder.Compilation, (PEModuleSymbol)substitutedSourceMethod.ContainingModule); binder = new PlaceholderLocalBinder( syntax, aliases, method, typeNameDecoder, binder); } binder = new EEMethodBinder(method, substitutedSourceMethod, binder); if (methodNotType) { binder = new SimpleLocalScopeBinder(method.LocalsForBinding, binder); } return binder; }
private static Binder ExtendBinderChain( CSharpSyntaxNode syntax, ImmutableArray<Alias> aliases, EEMethodSymbol method, Binder binder, bool hasDisplayClassThis, bool methodNotType, out ImmutableArray<LocalSymbol> declaredLocals) { var substitutedSourceMethod = GetSubstitutedSourceMethod(method.SubstitutedSourceMethod, hasDisplayClassThis); var substitutedSourceType = substitutedSourceMethod.ContainingType; var stack = ArrayBuilder<NamedTypeSymbol>.GetInstance(); for (var type = substitutedSourceType; (object)type != null; type = type.ContainingType) { stack.Add(type); } while (stack.Count > 0) { substitutedSourceType = stack.Pop(); binder = new InContainerBinder(substitutedSourceType, binder); if (substitutedSourceType.Arity > 0) { binder = new WithTypeArgumentsBinder(substitutedSourceType.TypeArguments, binder); } } stack.Free(); if (substitutedSourceMethod.Arity > 0) { binder = new WithTypeArgumentsBinder(substitutedSourceMethod.TypeArguments, binder); } // Method locals and parameters shadow pseudo-variables. // That is why we place PlaceholderLocalBinder and ExecutableCodeBinder before EEMethodBinder. if (methodNotType) { var typeNameDecoder = new EETypeNameDecoder(binder.Compilation, (PEModuleSymbol)substitutedSourceMethod.ContainingModule); binder = new PlaceholderLocalBinder( syntax, aliases, method, typeNameDecoder, binder); } Binder originalRootBinder = null; SyntaxNode declaredLocalsScopeDesignator = null; var executableBinder = new ExecutableCodeBinder(syntax, substitutedSourceMethod, binder, (rootBinder, declaredLocalsScopeDesignatorOpt) => { originalRootBinder = rootBinder; declaredLocalsScopeDesignator = declaredLocalsScopeDesignatorOpt; binder = new EEMethodBinder(method, substitutedSourceMethod, rootBinder); if (methodNotType) { binder = new SimpleLocalScopeBinder(method.LocalsForBinding, binder); } return binder; }); // We just need to trigger the process of building the binder map // so that the lambda above was executed. executableBinder.GetBinder(syntax); Debug.Assert(originalRootBinder != null); Debug.Assert(executableBinder.Next != binder); if (declaredLocalsScopeDesignator != null) { declaredLocals = originalRootBinder.GetDeclaredLocalsForScope(declaredLocalsScopeDesignator); } else { declaredLocals = ImmutableArray<LocalSymbol>.Empty; } return binder; }