Skip to content

Commit eeacd62

Browse files
CopilotPhenX
andcommitted
Improve error handling for invalid extension methods
Co-authored-by: PhenX <42170+PhenX@users.noreply.github.com>
1 parent d8194fd commit eeacd62

1 file changed

Lines changed: 19 additions & 11 deletions

File tree

src/EntityFrameworkCore.Projectables.Generator/ProjectableInterpreter.cs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -188,29 +188,37 @@ x is IPropertySymbol xProperty &&
188188
// For extension methods, determine the target type and handle parameters
189189
if (methodSymbol is { IsExtensionMethod: true })
190190
{
191-
// For extension methods, get the target type
192-
// For traditional extensions: it's the type of the first parameter (with 'this' modifier)
193-
// For C# 14 implicit extensions: it's the ReceiverType
194-
ITypeSymbol targetTypeSymbol;
191+
// Determine the extended type:
192+
// - For traditional extensions (static): First parameter with 'this' modifier
193+
// - For C# 14 implicit extensions (non-static): ReceiverType property
194+
ITypeSymbol? targetTypeSymbol = null;
195195

196-
// Check if this is a C# 14 implicit extension by checking if the method is non-static
197-
// but IsExtensionMethod is true (traditional extensions are always static)
196+
// Detect C# 14 implicit extension: IsExtensionMethod but not static
197+
// Traditional extension methods are always static
198198
isImplicitExtension = !member.Modifiers.Any(SyntaxKind.StaticKeyword);
199199

200200
if (methodSymbol.ReceiverType is not null)
201201
{
202-
// C# 14 implicit extension or Roslyn provides ReceiverType
202+
// ReceiverType is available (C# 14 implicit extension or newer Roslyn API)
203203
targetTypeSymbol = methodSymbol.ReceiverType;
204204
}
205205
else if (methodSymbol.Parameters.Length > 0)
206206
{
207-
// Traditional extension method with 'this' parameter
207+
// Traditional extension method: get type from first parameter
208208
targetTypeSymbol = methodSymbol.Parameters.First().Type;
209209
}
210-
else
210+
211+
if (targetTypeSymbol is null)
211212
{
212-
// Shouldn't happen, but fallback to containing type
213-
targetTypeSymbol = memberSymbol.ContainingType;
213+
// Invalid extension method - neither ReceiverType nor parameters available
214+
// This shouldn't happen for valid extension methods, so report an error
215+
var diagnostic = Diagnostic.Create(
216+
Diagnostics.RequiresExpressionBodyDefinition,
217+
member.GetLocation(),
218+
memberSymbol.Name
219+
);
220+
context.ReportDiagnostic(diagnostic);
221+
return null;
214222
}
215223

216224
descriptor.TargetClassNamespace = targetTypeSymbol.ContainingNamespace.IsGlobalNamespace ? null : targetTypeSymbol.ContainingNamespace.ToDisplayString();

0 commit comments

Comments
 (0)