/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/MethodGroup.cs
164 строки
5 KB
Julien Couvreur
Extension indexers: indexing with implicit indexers (#82453)
13 мар 2026, 21:12
Не верифицирован
13 мар 2026, 21:12
b2aa9f4
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System.Collections.Immutable; using System.Diagnostics; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.PooledObjects; namespace Microsoft.CodeAnalysis.CSharp { // pooled class used for input to overload resolution internal sealed class MethodGroup { internal BoundExpression Receiver { get; private set; } internal ArrayBuilder<MethodSymbol> Methods { get; } internal ArrayBuilder<TypeWithAnnotations> TypeArguments { get; } internal bool IsExtensionMethodGroup { get; private set; } internal DiagnosticInfo Error { get; private set; } internal LookupResultKind ResultKind { get; private set; } private MethodGroup() { this.Methods = new ArrayBuilder<MethodSymbol>(); this.TypeArguments = new ArrayBuilder<TypeWithAnnotations>(); } internal void PopulateWithSingleMethod( BoundExpression receiverOpt, MethodSymbol method, LookupResultKind resultKind = LookupResultKind.Viable, DiagnosticInfo error = null) { this.PopulateHelper(receiverOpt, resultKind, error); this.Methods.Add(method); } internal void PopulateWithExtensionMethods<TSymbol>( BoundExpression receiverOpt, ArrayBuilder<TSymbol> members, ImmutableArray<TypeWithAnnotations> typeArguments, LookupResultKind resultKind = LookupResultKind.Viable, DiagnosticInfo error = null) where TSymbol : Symbol { this.PopulateHelper(receiverOpt, resultKind, error); this.IsExtensionMethodGroup = true; foreach (var member in members) { if (member is MethodSymbol method) { Debug.Assert(method.IsExtensionMethod || method.IsExtensionBlockMember()); this.Methods.Add(method); } } if (!typeArguments.IsDefault) { this.TypeArguments.AddRange(typeArguments); } } internal void PopulateWithNonExtensionMethods( BoundExpression receiverOpt, ImmutableArray<MethodSymbol> methods, ImmutableArray<TypeWithAnnotations> typeArguments, LookupResultKind resultKind = LookupResultKind.Viable, DiagnosticInfo error = null) { this.PopulateHelper(receiverOpt, resultKind, error); this.Methods.AddRange(methods); if (!typeArguments.IsDefault) { this.TypeArguments.AddRange(typeArguments); } } private void PopulateHelper(BoundExpression receiverOpt, LookupResultKind resultKind, DiagnosticInfo error) { VerifyClear(); this.Receiver = receiverOpt; this.Error = error; this.ResultKind = resultKind; } public void Clear() { this.Receiver = null; this.Methods.Clear(); this.TypeArguments.Clear(); this.IsExtensionMethodGroup = false; this.Error = null; this.ResultKind = LookupResultKind.Empty; VerifyClear(); } public string Name { get { return this.Methods.Count > 0 ? this.Methods[0].Name : null; } } public BoundExpression InstanceOpt { get { if (this.Receiver == null) { return null; } if (this.Receiver.Kind == BoundKind.TypeExpression) { return null; } return this.Receiver; } } [Conditional("DEBUG")] private void VerifyClear() { Debug.Assert(this.Receiver == null); Debug.Assert(this.Methods.Count == 0); Debug.Assert(this.TypeArguments.Count == 0); Debug.Assert(!this.IsExtensionMethodGroup); Debug.Assert(this.Error == null); Debug.Assert(this.ResultKind == LookupResultKind.Empty); } #region "Poolable" public static MethodGroup GetInstance() { return Pool.Allocate(); } public void Free() { this.Clear(); Pool.Free(this); } //2) Expose the pool or the way to create a pool or the way to get an instance. // for now we will expose both and figure which way works better public static readonly ObjectPool<MethodGroup> Pool = CreatePool(); private static ObjectPool<MethodGroup> CreatePool() { ObjectPool<MethodGroup> pool = null; pool = new ObjectPool<MethodGroup>(() => new MethodGroup(), 10); return pool; } #endregion } }