Skip to content
Merged
3 changes: 3 additions & 0 deletions src/Compilers/CSharp/Portable/CSharpResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -4172,6 +4172,9 @@ You should consider suppressing the warning only if you're sure that you don't w
<data name="ERR_ExpressionTreeContainsNamedArgument" xml:space="preserve">
<value>An expression tree may not contain a named argument specification</value>
</data>
<data name="ERR_ExpressionTreeContainsNamedArgumentOutOfPosition" xml:space="preserve">
<value>An expression tree may not contain a named argument specification out of position</value>
</data>
<data name="ERR_ExpressionTreeContainsOptionalArgument" xml:space="preserve">
<value>An expression tree may not contain a call or invocation that uses optional arguments</value>
</data>
Expand Down
1 change: 1 addition & 0 deletions src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2397,6 +2397,7 @@ internal enum ErrorCode
ERR_InitInExtension = 9304,
ERR_ModifierOnUnnamedReceiverParameter = 9305,
ERR_ExtensionTypeNameDisallowed = 9306,
ERR_ExpressionTreeContainsNamedArgumentOutOfPosition = 9307,

// Note: you will need to do the following after adding errors:
// 1) Update ErrorFacts.IsBuildOnlyDiagnostic (src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs)
Expand Down
1 change: 1 addition & 0 deletions src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2513,6 +2513,7 @@ or ErrorCode.ERR_InstanceMemberWithUnnamedExtensionsParameter
or ErrorCode.ERR_InitInExtension
or ErrorCode.ERR_ModifierOnUnnamedReceiverParameter
or ErrorCode.ERR_ExtensionTypeNameDisallowed
or ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition
=> false,
};
#pragma warning restore CS8524 // The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value.
Expand Down
2 changes: 2 additions & 0 deletions src/Compilers/CSharp/Portable/Errors/MessageID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ internal enum MessageID
IDS_FeaturePartialEventsAndConstructors = MessageBase + 12852,
IDS_FeatureExtensions = MessageBase + 12853,
IDS_FeatureNullConditionalAssignment = MessageBase + 12854,
IDS_FeatureExpressionOptionalAndNamedArguments = MessageBase + 12855,
}

// Message IDs may refer to strings that need to be localized.
Expand Down Expand Up @@ -488,6 +489,7 @@ internal static LanguageVersion RequiredVersion(this MessageID feature)
case MessageID.IDS_FeaturePartialEventsAndConstructors:
case MessageID.IDS_FeatureExtensions:
case MessageID.IDS_FeatureNullConditionalAssignment:
case MessageID.IDS_FeatureExpressionOptionalAndNamedArguments:
return LanguageVersion.Preview;

// C# 13.0 features.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ private void VisitCall(
ImmutableArray<BoundExpression> arguments,
ImmutableArray<RefKind> argumentRefKindsOpt,
ImmutableArray<string> argumentNamesOpt,
ImmutableArray<int> argsToParamsOpt,
BitVector defaultArguments,
BoundNode node)
{
Expand All @@ -328,14 +329,22 @@ private void VisitCall(
{
Error(ErrorCode.ERR_ExpressionTreeContainsIndexedProperty, node);
}
else if (hasDefaultArgument(arguments, defaultArguments))
else if (hasDefaultArgument(arguments, defaultArguments) &&
!_compilation.IsFeatureEnabled(MessageID.IDS_FeatureExpressionOptionalAndNamedArguments))
{
Error(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, node);
}
else if (!argumentNamesOpt.IsDefaultOrEmpty)
else if (!argumentNamesOpt.IsDefaultOrEmpty &&
!_compilation.IsFeatureEnabled(MessageID.IDS_FeatureExpressionOptionalAndNamedArguments))
{
Error(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, node);
}
else if (!argumentNamesOpt.IsDefaultOrEmpty &&
hasNamedArgumentOutOfOrder(argsToParamsOpt))
{
Debug.Assert(_compilation.IsFeatureEnabled(MessageID.IDS_FeatureExpressionOptionalAndNamedArguments));
Error(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, node);
}
else if (IsComCallWithRefOmitted(method, arguments, argumentRefKindsOpt))
{
Error(ErrorCode.ERR_ComRefCallInExpressionTree, node);
Expand Down Expand Up @@ -366,6 +375,22 @@ static bool hasDefaultArgument(ImmutableArray<BoundExpression> arguments, BitVec

return false;
}

static bool hasNamedArgumentOutOfOrder(ImmutableArray<int> argsToParamsOpt)
{
if (argsToParamsOpt.IsDefaultOrEmpty)
{
return false;
}
for (int i = 0; i < argsToParamsOpt.Length; i++)
{
if (argsToParamsOpt[i] != i)
{
return true;
}
}
return false;
}
}

public override BoundNode Visit(BoundNode node)
Expand Down Expand Up @@ -474,7 +499,7 @@ public override BoundNode VisitCall(BoundCall node)

do
{
VisitCall(node.Method, null, node.Arguments, node.ArgumentRefKindsOpt, node.ArgumentNamesOpt, node.DefaultArguments, node);
visitCall(node);
CheckReferenceToMethodIfLocalFunction(node, node.Method);
this.VisitList(node.Arguments);
}
Expand All @@ -484,14 +509,19 @@ public override BoundNode VisitCall(BoundCall node)
}
else
{
VisitCall(node.Method, null, node.Arguments, node.ArgumentRefKindsOpt, node.ArgumentNamesOpt, node.DefaultArguments, node);
visitCall(node);
CheckReceiverIfField(node.ReceiverOpt);
CheckReferenceToMethodIfLocalFunction(node, node.Method);
this.Visit(node.ReceiverOpt);
this.VisitList(node.Arguments);
}

return null;

void visitCall(BoundCall node)
{
VisitCall(node.Method, null, node.Arguments, node.ArgumentRefKindsOpt, node.ArgumentNamesOpt, node.ArgsToParamsOpt, node.DefaultArguments, node);
}
}

/// <summary>
Expand Down Expand Up @@ -520,13 +550,13 @@ public override BoundNode VisitCollectionElementInitializer(BoundCollectionEleme
Error(ErrorCode.ERR_ExtensionCollectionElementInitializerInExpressionTree, node);
}

VisitCall(node.AddMethod, null, node.Arguments, default(ImmutableArray<RefKind>), default(ImmutableArray<string>), node.DefaultArguments, node);
VisitCall(node.AddMethod, null, node.Arguments, default(ImmutableArray<RefKind>), default(ImmutableArray<string>), default(ImmutableArray<int>), node.DefaultArguments, node);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: could we use some named parameters here for clarity?

return base.VisitCollectionElementInitializer(node);
}

public override BoundNode VisitObjectCreationExpression(BoundObjectCreationExpression node)
{
VisitCall(node.Constructor, null, node.Arguments, node.ArgumentRefKindsOpt, node.ArgumentNamesOpt, node.DefaultArguments, node);
VisitCall(node.Constructor, null, node.Arguments, node.ArgumentRefKindsOpt, node.ArgumentNamesOpt, node.ArgsToParamsOpt, node.DefaultArguments, node);
return base.VisitObjectCreationExpression(node);
}

Expand All @@ -536,7 +566,7 @@ public override BoundNode VisitIndexerAccess(BoundIndexerAccess node)
var method = indexer.GetOwnOrInheritedGetMethod() ?? indexer.GetOwnOrInheritedSetMethod();
if ((object)method != null)
{
VisitCall(method, indexer, node.Arguments, node.ArgumentRefKindsOpt, node.ArgumentNamesOpt, node.DefaultArguments, node);
VisitCall(method, indexer, node.Arguments, node.ArgumentRefKindsOpt, node.ArgumentNamesOpt, node.ArgsToParamsOpt, node.DefaultArguments, node);
}
CheckReceiverIfField(node.ReceiverOpt);
return base.VisitIndexerAccess(node);
Expand Down
5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading