Skip to content

Commit

Permalink
Add support for collection expressions in attributes (#69968)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcouv authored Sep 26, 2023
1 parent db312ba commit b925063
Show file tree
Hide file tree
Showing 3 changed files with 508 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1071,15 +1071,6 @@ public class XAttribute : System.Attribute
public XAttribute(int[] values) { }
}
""",
FixedState =
{
// THis will tart working once https://github.com/dotnet/roslyn/issues/69133 is fixed.
ExpectedDiagnostics =
{
// /0/Test0.cs(1,4): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
DiagnosticResult.CompilerError("CS0182").WithSpan(1, 4, 1, 13),
}
},
LanguageVersion = LanguageVersion.CSharp12,
}.RunAsync();
}
Expand Down
17 changes: 17 additions & 0 deletions src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -968,11 +968,21 @@ private TypedConstant VisitExpression(BoundExpression node, TypedConstantKind ty
return VisitTypeOfExpression((BoundTypeOfOperator)node, diagnostics, ref attrHasErrors, curArgumentHasErrors);
case BoundKind.ArrayCreation:
return VisitArrayCreation((BoundArrayCreation)node, diagnostics, ref attrHasErrors, curArgumentHasErrors);
case BoundKind.CollectionExpressionSpreadElement:
Binder.Error(diagnostics, ErrorCode.ERR_BadAttributeArgument, node.Syntax);
return CreateTypedConstant(node, TypedConstantKind.Error, diagnostics, ref attrHasErrors, curArgumentHasErrors);
default:
return CreateTypedConstant(node, TypedConstantKind.Error, diagnostics, ref attrHasErrors, curArgumentHasErrors);
}
}

private TypedConstant VisitArrayCollectionExpression(TypeSymbol type, BoundCollectionExpression collection, BindingDiagnosticBag diagnostics, ref bool attrHasErrors, bool curArgumentHasErrors)
{
var typedConstantKind = type.GetAttributeParameterTypedConstantKind(_binder.Compilation);
ImmutableArray<TypedConstant> elements = VisitArguments(collection.Elements, diagnostics, ref attrHasErrors, curArgumentHasErrors);
return CreateTypedConstant(collection, typedConstantKind, diagnostics, ref attrHasErrors, curArgumentHasErrors, arrayValue: elements);
}

private TypedConstant VisitConversion(BoundConversion node, BindingDiagnosticBag diagnostics, ref bool attrHasErrors, bool curArgumentHasErrors)
{
Debug.Assert(node.ConstantValueOpt == null);
Expand All @@ -989,6 +999,13 @@ private TypedConstant VisitConversion(BoundConversion node, BindingDiagnosticBag
var operand = node.Operand;
var operandType = operand.Type;

if (node.Conversion.IsCollectionExpression
&& node.Conversion.GetCollectionExpressionTypeKind(out _) == CollectionExpressionTypeKind.Array)
{
Debug.Assert(type.IsSZArray());
return VisitArrayCollectionExpression(type, (BoundCollectionExpression)operand, diagnostics, ref attrHasErrors, curArgumentHasErrors);
}

if ((object)type != null && operandType is object)
{
if (type.SpecialType == SpecialType.System_Object ||
Expand Down
Loading

0 comments on commit b925063

Please sign in to comment.