Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2306,21 +2306,29 @@ private BoundExpression BindNameofOperatorInternal(InvocationExpressionSyntax no
var boundArgument = BindExpression(argument, diagnostics);

bool syntaxIsOk = CheckSyntaxForNameofArgument(argument, out string name, boundArgument.HasAnyErrors ? BindingDiagnosticBag.Discarded : diagnostics);
if (!boundArgument.HasAnyErrors && syntaxIsOk && boundArgument.Kind == BoundKind.MethodGroup)
if (boundArgument is BoundMethodGroup methodGroup)
{
var methodGroup = (BoundMethodGroup)boundArgument;
if (!methodGroup.TypeArgumentsOpt.IsDefaultOrEmpty)
if (!boundArgument.HasAnyErrors && syntaxIsOk)
{
// method group with type parameters not allowed
diagnostics.Add(ErrorCode.ERR_NameofMethodGroupWithTypeParameters, argument.Location);
if (!methodGroup.TypeArgumentsOpt.IsDefaultOrEmpty)
{
// method group with type parameters not allowed
diagnostics.Add(ErrorCode.ERR_NameofMethodGroupWithTypeParameters, argument.Location);
}
else
{
EnsureNameofExpressionSymbols(methodGroup, diagnostics);
}
}
else
}
else if (boundArgument is BoundPropertyAccess propertyAccess)
{
if (propertyAccess.PropertySymbol.GetIsNewExtensionMember())
{
EnsureNameofExpressionSymbols(methodGroup, diagnostics);
diagnostics.Add(ErrorCode.ERR_NameofExtensionMember, boundArgument.Syntax);
}
}

if (boundArgument is BoundNamespaceExpression nsExpr)
else if (boundArgument is BoundNamespaceExpression nsExpr)
{
diagnostics.AddAssembliesUsedByNamespaceReference(nsExpr.NamespaceSymbol);
}
Expand Down
3 changes: 3 additions & 0 deletions src/Compilers/CSharp/Portable/CSharpResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -8188,4 +8188,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="ERR_MisplacedExtension" xml:space="preserve">
<value>An extension member syntax is disallowed in nested position within an extension member syntax</value>
</data>
<data name="ERR_NameofExtensionMember" xml:space="preserve">
<value>Extension member are not allowed as an argument to 'nameof'.</value>
Copy link
Member

@jjonescz jjonescz Jun 18, 2025

Choose a reason for hiding this comment

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

"members" (plural) or "are is allowed"? #Resolved

</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ bool Cci.IMethodDefinition.IsExternal
{
CheckDefinitionInvariant();

return AdaptedMethodSymbol.IsExternal;
return !AdaptedMethodSymbol.ContainingType.IsExtension && AdaptedMethodSymbol.IsExternal;
}
}

Expand All @@ -422,7 +422,7 @@ bool Cci.IMethodDefinition.IsPlatformInvoke
get
{
CheckDefinitionInvariant();
return AdaptedMethodSymbol.GetDllImportData() != null;
return !AdaptedMethodSymbol.ContainingType.IsExtension && AdaptedMethodSymbol.GetDllImportData() != null;
}
}
#nullable disable
Expand All @@ -431,7 +431,7 @@ Cci.IPlatformInvokeInformation Cci.IMethodDefinition.PlatformInvokeData
get
{
CheckDefinitionInvariant();
return AdaptedMethodSymbol.GetDllImportData();
return AdaptedMethodSymbol.ContainingType.IsExtension ? null : AdaptedMethodSymbol.GetDllImportData();
Copy link
Member

@jjonescz jjonescz Jun 18, 2025

Choose a reason for hiding this comment

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

Do we need to adjust GetImplementationAttributes similarly? #Resolved

}
}

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 @@ -2409,6 +2409,7 @@ internal enum ErrorCode
ERR_PPShebangInProjectBasedProgram = 9314,

ERR_TooManyUserStrings_RestartRequired = 9315,
ERR_NameofExtensionMember = 9316,

// 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 @@ -2522,6 +2522,7 @@ or ErrorCode.ERR_CloseUnimplementedInterfaceMemberOperatorMismatch
or ErrorCode.ERR_OperatorMismatchOnOverride
or ErrorCode.ERR_BadCompoundAssignmentOpArgs
or ErrorCode.ERR_PPShebangInProjectBasedProgram
or ErrorCode.ERR_NameofExtensionMember
=> 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
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ public SourceExtensionImplementationMethodSymbol(MethodSymbol sourceMethod)
{
Debug.Assert(sourceMethod.GetIsNewExtensionMember());
Debug.Assert(sourceMethod.IsStatic || sourceMethod.ContainingType.ExtensionParameter is not null);
Debug.Assert(!sourceMethod.IsExtern);
Debug.Assert(!sourceMethod.IsExternal);

// Tracked by https://github.com/dotnet/roslyn/issues/78963 : Are we creating type parameters with the right emit behavior? Attributes, etc.
// Also, they should be IsImplicitlyDeclared
Expand Down Expand Up @@ -59,9 +57,9 @@ internal override int ParameterCount

internal sealed override bool IsAccessCheckedOnOverride => false;

public sealed override bool IsExtern => false;
public sealed override DllImportData? GetDllImportData() => null;
internal sealed override bool IsExternal => false;
public sealed override bool IsExtern => _originalMethod.IsExtern;
public sealed override DllImportData? GetDllImportData() => _originalMethod.GetDllImportData();
internal sealed override bool IsExternal => _originalMethod.IsExternal;
Copy link
Member

@jjonescz jjonescz Jun 18, 2025

Choose a reason for hiding this comment

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

Should we just delete these since the base class WrappedMethodSymbol already has this implementation? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

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

We've been leaning toward abstract+sealed design (pushing implementations down into leaves) so I intentionally left those despite the base/virtual implementation being sufficient


internal sealed override bool IsDeclaredReadOnly => false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -754,12 +754,7 @@ private static (DeclarationModifiers mods, bool hasExplicitAccessMod) MakeModifi
allowedModifiers |= DeclarationModifiers.Static;
}

allowedModifiers |= DeclarationModifiers.Async;

if (!isExtension)
{
allowedModifiers |= DeclarationModifiers.Extern;
}
allowedModifiers |= DeclarationModifiers.Async | DeclarationModifiers.Extern;

if (containingType.IsStructType())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,10 +449,7 @@ private static (DeclarationModifiers modifiers, bool hasExplicitAccessMod) MakeM
allowedModifiers |= DeclarationModifiers.ReadOnly;
}

if (!isExtension)
{
allowedModifiers |= DeclarationModifiers.Extern;
}
allowedModifiers |= DeclarationModifiers.Extern;

bool hasExplicitAccessMod;
var mods = ModifierUtils.MakeAndCheckNonTypeMemberModifiers(isOrdinaryMethod: false, isForInterfaceMember: isInterface,
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