public void Add(AssemblyIdentity identity, TValue value) { KeyValuePair <AssemblyIdentity, TValue> pair = KeyValuePair.Create(identity, value); _map[identity.Name] = _map.TryGetValue(identity.Name, out OneOrMany <KeyValuePair <AssemblyIdentity, TValue> > sameName) ? sameName.Add(pair) : OneOrMany.Create(pair); }
internal sealed override OneOrMany <SyntaxList <AttributeListSyntax> > GetAttributeDeclarations() => OneOrMany.Create(default(SyntaxList <AttributeListSyntax>));
internal override OneOrMany <SyntaxList <AttributeDeclarationSyntax> > GetAttributeDeclarations() { return(OneOrMany.Create(((DelegateDeclarationSyntax)SyntaxNode).Attributes)); }
/// <summary> /// Method to merge attributes from the given attributesSyntaxLists and filter out attributes by attribute target. /// This is the first step in attribute binding. /// </summary> /// <remarks> /// This method can generate diagnostics for few cases where we have an invalid target specifier and the parser hasn't generated the necessary diagnostics. /// It should not perform any bind operations as it can lead to an attribute binding cycle. /// </remarks> private ImmutableArray <AttributeSyntax> GetAttributesToBind( OneOrMany <SyntaxList <AttributeListSyntax> > attributeDeclarationSyntaxLists, AttributeLocation symbolPart, DiagnosticBag diagnostics, CSharpCompilation compilation, out ImmutableArray <Binder> binders) { var attributeTarget = (IAttributeTargetSymbol)this; ArrayBuilder <AttributeSyntax> syntaxBuilder = null; ArrayBuilder <Binder> bindersBuilder = null; int attributesToBindCount = 0; for (int listIndex = 0; listIndex < attributeDeclarationSyntaxLists.Count; listIndex++) { var attributeDeclarationSyntaxList = attributeDeclarationSyntaxLists[listIndex]; if (attributeDeclarationSyntaxList.Any()) { int prevCount = attributesToBindCount; foreach (var attributeDeclarationSyntax in attributeDeclarationSyntaxList) { // We bind the attribute only if it has a matching target for the given ownerSymbol and attributeLocation. if (MatchAttributeTarget(attributeTarget, symbolPart, attributeDeclarationSyntax.Target, diagnostics)) { if (syntaxBuilder == null) { syntaxBuilder = new ArrayBuilder <AttributeSyntax>(); bindersBuilder = new ArrayBuilder <Binder>(); } var attributesToBind = attributeDeclarationSyntax.Attributes; syntaxBuilder.AddRange(attributesToBind); attributesToBindCount += attributesToBind.Count; } } if (attributesToBindCount != prevCount) { Debug.Assert(attributeDeclarationSyntaxList.Node != null); Debug.Assert(bindersBuilder != null); var syntaxTree = attributeDeclarationSyntaxList.Node.SyntaxTree; var binder = compilation.GetBinderFactory(syntaxTree).GetBinder((CSharpSyntaxNode)attributeDeclarationSyntaxList.Node); binder = new ContextualAttributeBinder(binder, this); Debug.Assert(!binder.InAttributeArgument, "Possible cycle in attribute binding"); for (int i = 0; i < attributesToBindCount - prevCount; i++) { bindersBuilder.Add(binder); } } } } if (syntaxBuilder != null) { binders = bindersBuilder.ToImmutableAndFree(); return(syntaxBuilder.ToImmutableAndFree()); } else { binders = ImmutableArray <Binder> .Empty; return(ImmutableArray <AttributeSyntax> .Empty); } }
internal override OneOrMany <SyntaxList <AttributeListSyntax> > GetAttributeDeclarations() { return(OneOrMany.Create(((ConstructorDeclarationSyntax)this.SyntaxNode).AttributeLists)); }
/// <summary> /// This method does the following set of operations in the specified order: /// (1) GetAttributesToBind: Merge attributes from the given attributesSyntaxLists and filter out attributes by attribute target. /// (2) BindAttributeTypes: Bind all the attribute types to enable early decode of certain well-known attributes by type. /// (3) EarlyDecodeWellKnownAttributes: Perform early decoding of certain well-known attributes that could be queried by the binder in subsequent steps. /// (NOTE: This step has the side effect of updating the symbol state based on the data extracted from well known attributes). /// (4) GetAttributes: Bind the attributes (attribute arguments and constructor) using bound attribute types. /// (5) DecodeWellKnownAttributes: Decode and validate bound well known attributes. /// (NOTE: This step has the side effect of updating the symbol state based on the data extracted from well known attributes). /// (6) StoreBoundAttributesAndDoPostValidation: /// (a) Store the bound attributes in lazyCustomAttributes in a thread safe manner. /// (b) Perform some additional post attribute validations, such as /// 1) Duplicate attributes, attribute usage target validation, etc. /// 2) Post validation for attributes dependant on other attributes /// These validations cannot be performed prior to step 6(a) as we might need to /// perform a GetAttributes() call on a symbol which can introduce a cycle in attribute binding. /// We avoid this cycle by performing such validations in PostDecodeWellKnownAttributes after lazyCustomAttributes have been set. /// NOTE: PostDecodeWellKnownAttributes SHOULD NOT change the symbol state. /// </summary> /// <remarks> /// Current design of early decoding well-known attributes doesn't permit decoding attribute arguments/constructor as this can lead to binding cycles. /// For well-known attributes used by the binder, where we need the decoded arguments, we must handle them specially in one of the following possible ways: /// (a) Avoid decoding the attribute arguments during binding and delay the corresponding binder tasks to a separate post-pass executed after binding. /// (b) As the cycles can be caused only when we are binding attribute arguments/constructor, special case the corresponding binder tasks based on the current BinderFlags. /// </remarks> /// <param name="attributesSyntaxLists"></param> /// <param name="lazyCustomAttributesBag"></param> /// <param name="symbolPart">Specific part of the symbol to which the attributes apply, or <see cref="AttributeLocation.None"/> if the attributes apply to the symbol itself.</param> /// <param name="earlyDecodingOnly">Indicates that only early decoding should be performed. WARNING: the resulting bag will not be sealed.</param> /// <returns>Flag indicating whether lazyCustomAttributes were stored on this thread. Caller should check for this flag and perform NotePartComplete if true.</returns> internal bool LoadAndValidateAttributes( OneOrMany<SyntaxList<AttributeListSyntax>> attributesSyntaxLists, ref CustomAttributesBag<CSharpAttributeData> lazyCustomAttributesBag, AttributeLocation symbolPart = AttributeLocation.None, bool earlyDecodingOnly = false) { var diagnostics = DiagnosticBag.GetInstance(); var compilation = this.DeclaringCompilation; ImmutableArray<Binder> binders; ImmutableArray<AttributeSyntax> attributesToBind = this.GetAttributesToBind(attributesSyntaxLists, symbolPart, diagnostics, compilation, out binders); Debug.Assert(!attributesToBind.IsDefault); ImmutableArray<CSharpAttributeData> boundAttributes; WellKnownAttributeData wellKnownAttributeData; if (attributesToBind.Any()) { Debug.Assert(!binders.IsDefault); Debug.Assert(binders.Length == attributesToBind.Length); // Initialize the bag so that data decoded from early attributes can be stored onto it. if (lazyCustomAttributesBag == null) { Interlocked.CompareExchange(ref lazyCustomAttributesBag, new CustomAttributesBag<CSharpAttributeData>(), null); } // Bind the attribute types and then early decode them. int totalAttributesCount = attributesToBind.Length; var attributeTypesBuilder = new NamedTypeSymbol[totalAttributesCount]; Binder.BindAttributeTypes(binders, attributesToBind, this, attributeTypesBuilder, diagnostics); ImmutableArray<NamedTypeSymbol> boundAttributeTypes = attributeTypesBuilder.AsImmutableOrNull(); this.EarlyDecodeWellKnownAttributeTypes(boundAttributeTypes, attributesToBind); this.PostEarlyDecodeWellKnownAttributeTypes(); // Bind the attribute in two stages - early and normal. var attributesBuilder = new CSharpAttributeData[totalAttributesCount]; // Early bind and decode some well-known attributes. EarlyWellKnownAttributeData earlyData = this.EarlyDecodeWellKnownAttributes(binders, boundAttributeTypes, attributesToBind, symbolPart, attributesBuilder); Debug.Assert(!attributesBuilder.Contains((attr) => attr != null && attr.HasErrors)); // Store data decoded from early bound well-known attributes. // TODO: what if this succeeds on another thread, not ours? lazyCustomAttributesBag.SetEarlyDecodedWellKnownAttributeData(earlyData); if (earlyDecodingOnly) { diagnostics.Free(); //NOTE: dropped. return false; } // Bind attributes. Binder.GetAttributes(binders, attributesToBind, boundAttributeTypes, attributesBuilder, diagnostics); boundAttributes = attributesBuilder.AsImmutableOrNull(); // All attributes must be bound by now. Debug.Assert(!boundAttributes.Any((attr) => attr == null)); // Validate attribute usage and Decode remaining well-known attributes. wellKnownAttributeData = this.ValidateAttributeUsageAndDecodeWellKnownAttributes(binders, attributesToBind, boundAttributes, diagnostics, symbolPart); // Store data decoded from remaining well-known attributes. // TODO: what if this succeeds on another thread but not this thread? lazyCustomAttributesBag.SetDecodedWellKnownAttributeData(wellKnownAttributeData); } else if (earlyDecodingOnly) { diagnostics.Free(); //NOTE: dropped. return false; } else { boundAttributes = ImmutableArray<CSharpAttributeData>.Empty; wellKnownAttributeData = null; Interlocked.CompareExchange(ref lazyCustomAttributesBag, CustomAttributesBag<CSharpAttributeData>.WithEmptyData(), null); this.PostEarlyDecodeWellKnownAttributeTypes(); } this.PostDecodeWellKnownAttributes(boundAttributes, attributesToBind, diagnostics, symbolPart, wellKnownAttributeData); // Store attributes into the bag. bool lazyAttributesStoredOnThisThread = false; if (lazyCustomAttributesBag.SetAttributes(boundAttributes)) { this.RecordPresenceOfBadAttributes(boundAttributes); this.AddDeclarationDiagnostics(diagnostics); lazyAttributesStoredOnThisThread = true; if (lazyCustomAttributesBag.IsEmpty) lazyCustomAttributesBag = CustomAttributesBag<CSharpAttributeData>.Empty; } Debug.Assert(lazyCustomAttributesBag.IsSealed); diagnostics.Free(); return lazyAttributesStoredOnThisThread; }
public void Zero() { Verify(OneOrMany.Create(ImmutableArray <int> .Empty)); Verify(new OneOrMany <int>(ImmutableArray <int> .Empty)); }
internal override OneOrMany <SyntaxList <AttributeListSyntax> > GetReturnTypeAttributeDeclarations() { // Constructors don't have return type attributes return(OneOrMany.Create(default(SyntaxList <AttributeListSyntax>))); }
public void ImplicitConversionOperator_FromArray_HasTwoItems() { int[] items = new OneOrMany <int>(1, 2); Assert.Equal(new int[] { 1, 2 }, items); }
> GetReturnTypeAttributeDeclarations() { // destructors can't have return type attributes return(OneOrMany.Create(default(SyntaxList <AttributeListSyntax>))); }
public void ImplicitConversionOperator_FromItem_HasOneItem() { int item = new OneOrMany <int>(1); Assert.Equal(1, item); }
internal override OneOrMany <SyntaxList <AttributeListSyntax> > GetAttributeDeclarations() => OneOrMany.Create(_attributeLists);
> GetAttributeDeclarations() { return(OneOrMany.Create(this.GetSyntax().AttributeLists)); }
internal override OneOrMany <SyntaxList <AttributeListSyntax> > GetAttributeDeclarations() { // destructors can't have return type attributes return(OneOrMany.Create(this.GetSyntax().AttributeLists)); }
public async Task <IActionResult> Details(string i) { string apiUrl = configuration.GetValue <string>("api:url"); string apiKey = configuration.GetValue <string>("api:key"); UriBuilder baseUri = new UriBuilder(apiUrl + "?apiKey=" + apiKey); Details details = null; if (i != null && i.Length > 0) { string queryToAppend = "i=" + i; if (baseUri.Query != null && baseUri.Query.Length > 1) { baseUri.Query = baseUri.Query.Substring(1) + "&" + queryToAppend; } else { baseUri.Query = queryToAppend; } string url = baseUri.ToString(); using (var httpClient = new HttpClient()) { using (var response = await httpClient.GetAsync(url)) { string apiResponse = await response.Content.ReadAsStringAsync(); JObject o = JObject.Parse(apiResponse); if ((string)o["Response"] == "True") { details = JsonConvert.DeserializeObject <Details>(apiResponse); } } } } Person actor = new Person() { Name = new List <String>() { details.Actors } }; Person director = new Person() { Name = details.Director }; Country c = new Country() { Name = details.Country }; int minDuration = 0; if (details.Runtime.Length > 0 && details.Runtime.Contains(' ')) { string[] sDuration = details.Runtime.Split(' '); if (sDuration.Length > 0) { minDuration = int.Parse(sDuration[0]); } } int hours = 0, minutes = 0; if (minDuration > 0) { hours = minDuration / 60; minutes = minDuration % 60; } OneOrMany <TimeSpan?> duration = new OneOrMany <TimeSpan?>(new TimeSpan(hours, minutes, 0)); var organization = new Organization() { Name = details.Production }; var movieSchema = new Schema.NET.Movie() { Actor = actor, CountryOfOrigin = c, Director = director, Duration = duration, SubtitleLanguage = details.Language, ProductionCompany = organization }; ViewBag.JsonLd = movieSchema.ToString(); return(View(details)); }
internal sealed override OneOrMany <SyntaxList <AttributeListSyntax> > GetAttributeDeclarations() { // TODO: This implementation looks strange. It might make sense for the Invoke method, but // not for constructor and other methods. return(OneOrMany.Create(((SourceNamedTypeSymbol)ContainingSymbol).GetAttributeDeclarations())); }
internal sealed override OneOrMany <SyntaxList <AttributeListSyntax> > GetAttributeDeclarations() { return(OneOrMany.Create(((BaseMethodDeclarationSyntax)this.SyntaxNode).AttributeLists)); }
internal sealed override OneOrMany <SyntaxList <AttributeListSyntax> > GetAttributeDeclarations() { return(OneOrMany.Create(this.GetSyntax().AttributeLists)); }
internal override OneOrMany <SyntaxList <AttributeListSyntax> > GetAttributeDeclarations() { return(OneOrMany.Create(Syntax.AttributeLists)); }
internal override OneOrMany <SyntaxList <AttributeListSyntax> > GetAttributeDeclarations() { return(OneOrMany.Create(this.AssociatedEvent.AttributeDeclarationSyntaxList)); }
/// <summary> /// This method does the following set of operations in the specified order: /// (1) GetAttributesToBind: Merge attributes from the given attributesSyntaxLists and filter out attributes by attribute target. /// (2) BindAttributeTypes: Bind all the attribute types to enable early decode of certain well-known attributes by type. /// (3) EarlyDecodeWellKnownAttributes: Perform early decoding of certain well-known attributes that could be queried by the binder in subsequent steps. /// (NOTE: This step has the side effect of updating the symbol state based on the data extracted from well known attributes). /// (4) GetAttributes: Bind the attributes (attribute arguments and constructor) using bound attribute types. /// (5) DecodeWellKnownAttributes: Decode and validate bound well known attributes. /// (NOTE: This step has the side effect of updating the symbol state based on the data extracted from well known attributes). /// (6) StoreBoundAttributesAndDoPostValidation: /// (a) Store the bound attributes in lazyCustomAttributes in a thread safe manner. /// (b) Perform some additional post attribute validations, such as /// 1) Duplicate attributes, attribute usage target validation, etc. /// 2) Post validation for attributes dependant on other attributes /// These validations cannot be performed prior to step 6(a) as we might need to /// perform a GetAttributes() call on a symbol which can introduce a cycle in attribute binding. /// We avoid this cycle by performing such validations in PostDecodeWellKnownAttributes after lazyCustomAttributes have been set. /// NOTE: PostDecodeWellKnownAttributes SHOULD NOT change the symbol state. /// </summary> /// <remarks> /// Current design of early decoding well-known attributes doesn't permit decoding attribute arguments/constructor as this can lead to binding cycles. /// For well-known attributes used by the binder, where we need the decoded arguments, we must handle them specially in one of the following possible ways: /// (a) Avoid decoding the attribute arguments during binding and delay the corresponding binder tasks to a separate post-pass executed after binding. /// (b) As the cycles can be caused only when we are binding attribute arguments/constructor, special case the corresponding binder tasks based on the current BinderFlags. /// </remarks> /// <param name="attributesSyntaxLists"></param> /// <param name="lazyCustomAttributesBag"></param> /// <param name="symbolPart">Specific part of the symbol to which the attributes apply, or <see cref="AttributeLocation.None"/> if the attributes apply to the symbol itself.</param> /// <param name="earlyDecodingOnly">Indicates that only early decoding should be performed. WARNING: the resulting bag will not be sealed.</param> /// <returns>Flag indicating whether lazyCustomAttributes were stored on this thread. Caller should check for this flag and perform NotePartComplete if true.</returns> internal bool LoadAndValidateAttributes( OneOrMany <SyntaxList <AttributeListSyntax> > attributesSyntaxLists, ref CustomAttributesBag <CSharpAttributeData> lazyCustomAttributesBag, AttributeLocation symbolPart = AttributeLocation.None, bool earlyDecodingOnly = false) { var diagnostics = DiagnosticBag.GetInstance(); var compilation = this.DeclaringCompilation; ImmutableArray <Binder> binders; ImmutableArray <AttributeSyntax> attributesToBind = this.GetAttributesToBind(attributesSyntaxLists, symbolPart, diagnostics, compilation, out binders); Debug.Assert(!attributesToBind.IsDefault); ImmutableArray <CSharpAttributeData> boundAttributes; WellKnownAttributeData wellKnownAttributeData; if (attributesToBind.Any()) { Debug.Assert(!binders.IsDefault); Debug.Assert(binders.Length == attributesToBind.Length); // Initialize the bag so that data decoded from early attributes can be stored onto it. if (lazyCustomAttributesBag == null) { Interlocked.CompareExchange(ref lazyCustomAttributesBag, new CustomAttributesBag <CSharpAttributeData>(), null); } // Bind the attribute types and then early decode them. int totalAttributesCount = attributesToBind.Length; var attributeTypesBuilder = new NamedTypeSymbol[totalAttributesCount]; Binder.BindAttributeTypes(binders, attributesToBind, this, attributeTypesBuilder, diagnostics); ImmutableArray <NamedTypeSymbol> boundAttributeTypes = attributeTypesBuilder.AsImmutableOrNull(); this.EarlyDecodeWellKnownAttributeTypes(boundAttributeTypes, attributesToBind); this.PostEarlyDecodeWellKnownAttributeTypes(); // Bind the attribute in two stages - early and normal. var attributesBuilder = new CSharpAttributeData[totalAttributesCount]; // Early bind and decode some well-known attributes. EarlyWellKnownAttributeData earlyData = this.EarlyDecodeWellKnownAttributes(binders, boundAttributeTypes, attributesToBind, symbolPart, attributesBuilder); Debug.Assert(!attributesBuilder.Contains((attr) => attr != null && attr.HasErrors)); // Store data decoded from early bound well-known attributes. // TODO: what if this succeeds on another thread, not ours? lazyCustomAttributesBag.SetEarlyDecodedWellKnownAttributeData(earlyData); if (earlyDecodingOnly) { diagnostics.Free(); //NOTE: dropped. return(false); } // Bind attributes. Binder.GetAttributes(binders, attributesToBind, boundAttributeTypes, attributesBuilder, diagnostics); boundAttributes = attributesBuilder.AsImmutableOrNull(); // All attributes must be bound by now. Debug.Assert(!boundAttributes.Any((attr) => attr == null)); // Validate attribute usage and Decode remaining well-known attributes. wellKnownAttributeData = this.ValidateAttributeUsageAndDecodeWellKnownAttributes(binders, attributesToBind, boundAttributes, diagnostics, symbolPart); // Store data decoded from remaining well-known attributes. // TODO: what if this succeeds on another thread but not this thread? lazyCustomAttributesBag.SetDecodedWellKnownAttributeData(wellKnownAttributeData); } else if (earlyDecodingOnly) { diagnostics.Free(); //NOTE: dropped. return(false); } else { boundAttributes = ImmutableArray <CSharpAttributeData> .Empty; wellKnownAttributeData = null; Interlocked.CompareExchange(ref lazyCustomAttributesBag, CustomAttributesBag <CSharpAttributeData> .WithEmptyData(), null); this.PostEarlyDecodeWellKnownAttributeTypes(); } this.PostDecodeWellKnownAttributes(boundAttributes, attributesToBind, diagnostics, symbolPart, wellKnownAttributeData); // Store attributes into the bag. bool lazyAttributesStoredOnThisThread = false; if (lazyCustomAttributesBag.SetAttributes(boundAttributes)) { this.RecordPresenceOfBadAttributes(boundAttributes); this.AddDeclarationDiagnostics(diagnostics); lazyAttributesStoredOnThisThread = true; if (lazyCustomAttributesBag.IsEmpty) { lazyCustomAttributesBag = CustomAttributesBag <CSharpAttributeData> .Empty; } } Debug.Assert(lazyCustomAttributesBag.IsSealed); diagnostics.Free(); return(lazyAttributesStoredOnThisThread); }
/// <summary> /// Method to merge attributes from the given attributesSyntaxLists and filter out attributes by attribute target. /// This is the first step in attribute binding. /// </summary> /// <remarks> /// This method can generate diagnostics for few cases where we have an invalid target specifier and the parser hasn't generated the necessary diagnostics. /// It should not perform any bind operations as it can lead to an attribute binding cycle. /// </remarks> private ImmutableArray<AttributeSyntax> GetAttributesToBind( OneOrMany<SyntaxList<AttributeListSyntax>> attributeDeclarationSyntaxLists, AttributeLocation symbolPart, DiagnosticBag diagnostics, CSharpCompilation compilation, out ImmutableArray<Binder> binders) { var attributeTarget = (IAttributeTargetSymbol)this; ArrayBuilder<AttributeSyntax> syntaxBuilder = null; ArrayBuilder<Binder> bindersBuilder = null; int attributesToBindCount = 0; for (int listIndex = 0; listIndex < attributeDeclarationSyntaxLists.Count; listIndex++) { var attributeDeclarationSyntaxList = attributeDeclarationSyntaxLists[listIndex]; if (attributeDeclarationSyntaxList.Any()) { int prevCount = attributesToBindCount; foreach (var attributeDeclarationSyntax in attributeDeclarationSyntaxList) { // We bind the attribute only if it has a matching target for the given ownerSymbol and attributeLocation. if (MatchAttributeTarget(attributeTarget, symbolPart, attributeDeclarationSyntax.Target, diagnostics)) { if (syntaxBuilder == null) { syntaxBuilder = new ArrayBuilder<AttributeSyntax>(); bindersBuilder = new ArrayBuilder<Binder>(); } var attributesToBind = attributeDeclarationSyntax.Attributes; syntaxBuilder.AddRange(attributesToBind); attributesToBindCount += attributesToBind.Count; } } if (attributesToBindCount != prevCount) { Debug.Assert(attributeDeclarationSyntaxList.Node != null); Debug.Assert(bindersBuilder != null); var syntaxTree = attributeDeclarationSyntaxList.Node.SyntaxTree; var binder = compilation.GetBinderFactory(syntaxTree).GetBinder((CSharpSyntaxNode)attributeDeclarationSyntaxList.Node); binder = new ContextualAttributeBinder(binder, this); Debug.Assert(!binder.InAttributeArgument, "Possible cycle in attribute binding"); for (int i = 0; i < attributesToBindCount - prevCount; i++) { bindersBuilder.Add(binder); } } } } if (syntaxBuilder != null) { binders = bindersBuilder.ToImmutableAndFree(); return syntaxBuilder.ToImmutableAndFree(); } else { binders = ImmutableArray<Binder>.Empty; return ImmutableArray<AttributeSyntax>.Empty; } }
private ImmutableArray <AttributeSyntax> GetAttributesToBind( OneOrMany <SyntaxList <AttributeListSyntax> > attributeDeclarationSyntaxLists, AttributeLocation symbolPart, BindingDiagnosticBag diagnostics, CSharpCompilation compilation, Func <AttributeSyntax, bool> attributeMatchesOpt, Binder rootBinderOpt, out ImmutableArray <Binder> binders) { var attributeTarget = (IAttributeTargetSymbol)this; ArrayBuilder <AttributeSyntax> syntaxBuilder = null; ArrayBuilder <Binder> bindersBuilder = null; int attributesToBindCount = 0; for (int listIndex = 0; listIndex < attributeDeclarationSyntaxLists.Count; listIndex++) { var attributeDeclarationSyntaxList = attributeDeclarationSyntaxLists[listIndex]; if (attributeDeclarationSyntaxList.Any()) { int prevCount = attributesToBindCount; foreach (var attributeDeclarationSyntax in attributeDeclarationSyntaxList) { // We bind the attribute only if it has a matching target for the given ownerSymbol and attributeLocation. if (MatchAttributeTarget(attributeTarget, symbolPart, attributeDeclarationSyntax.Target, diagnostics)) { if (syntaxBuilder == null) { syntaxBuilder = new ArrayBuilder <AttributeSyntax>(); bindersBuilder = new ArrayBuilder <Binder>(); } var attributesToBind = attributeDeclarationSyntax.Attributes; if (attributeMatchesOpt is null) { syntaxBuilder.AddRange(attributesToBind); attributesToBindCount += attributesToBind.Count; } else { foreach (var attribute in attributesToBind) { if (attributeMatchesOpt(attribute)) { syntaxBuilder.Add(attribute); attributesToBindCount++; } } } } } if (attributesToBindCount != prevCount) { Debug.Assert(attributeDeclarationSyntaxList.Node != null); Debug.Assert(bindersBuilder != null); var syntaxTree = attributeDeclarationSyntaxList.Node.SyntaxTree; var binder = rootBinderOpt ?? compilation.GetBinderFactory(syntaxTree).GetBinder(attributeDeclarationSyntaxList.Node); binder = new ContextualAttributeBinder(binder, this); Debug.Assert(!binder.InAttributeArgument || this is MethodSymbol { MethodKind: MethodKind.LambdaMethod }, "Possible cycle in attribute binding");