Skip to content

Commit 4e63de3

Browse files
committed
C#: Introduce a new expr kind for when accessors are invoked directly.
1 parent 9d4d2b7 commit 4e63de3

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Invocation.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ private Invocation(ExpressionNodeInfo info)
2626

2727
private bool IsOperatorCall() => Kind == ExprKind.OPERATOR_INVOCATION;
2828

29+
private bool IsAccessorInvocation() => Kind == ExprKind.ACCESSOR_INVOCATION;
30+
31+
private bool IsValidMemberAccessKind()
32+
{
33+
return Kind == ExprKind.METHOD_INVOCATION ||
34+
IsEventDelegateCall() ||
35+
IsExplicitDelegateInvokeCall() ||
36+
IsOperatorCall() ||
37+
IsAccessorInvocation();
38+
}
39+
2940
protected override void PopulateExpression(TextWriter trapFile)
3041
{
3142
if (IsNameof(Syntax))
@@ -39,7 +50,7 @@ protected override void PopulateExpression(TextWriter trapFile)
3950
var target = TargetSymbol;
4051
switch (Syntax.Expression)
4152
{
42-
case MemberAccessExpressionSyntax memberAccess when Kind == ExprKind.METHOD_INVOCATION || IsEventDelegateCall() || IsExplicitDelegateInvokeCall() || IsOperatorCall():
53+
case MemberAccessExpressionSyntax memberAccess when IsValidMemberAccessKind():
4354
memberName = memberAccess.Name.Identifier.Text;
4455
if (Syntax.Expression.Kind() == SyntaxKind.SimpleMemberAccessExpression)
4556
// Qualified method call; `x.M()`
@@ -122,6 +133,14 @@ private static bool IsOperatorLikeCall(ExpressionNodeInfo info)
122133
original!.MethodKind == MethodKind.UserDefinedOperator;
123134
}
124135

136+
private static bool IsAccessorLikeInvocation(ExpressionNodeInfo info)
137+
{
138+
return info.SymbolInfo.Symbol is IMethodSymbol method &&
139+
method.TryGetExtensionMethod(out var original) &&
140+
(original!.MethodKind == MethodKind.PropertyGet ||
141+
original!.MethodKind == MethodKind.PropertySet);
142+
}
143+
125144
public IMethodSymbol? TargetSymbol
126145
{
127146
get
@@ -233,6 +252,10 @@ private static ExprKind GetKind(ExpressionNodeInfo info)
233252
{
234253
return ExprKind.OPERATOR_INVOCATION;
235254
}
255+
if (IsAccessorLikeInvocation(info))
256+
{
257+
return ExprKind.ACCESSOR_INVOCATION;
258+
}
236259
return ExprKind.METHOD_INVOCATION;
237260
}
238261

csharp/extractor/Semmle.Extraction.CSharp/Kinds/ExprKind.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ public enum ExprKind
133133
COLLECTION = 136,
134134
SPREAD_ELEMENT = 137,
135135
INTERPOLATED_STRING_INSERT = 138,
136+
ACCESSOR_INVOCATION = 139,
136137
DEFINE_SYMBOL = 999,
137138
}
138139
}

csharp/ql/lib/semmlecode.csharp.dbscheme

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,8 @@ case @expr.kind of
11941194
| 136 = @collection_expr
11951195
| 137 = @spread_element_expr
11961196
| 138 = @interpolated_string_insert_expr
1197+
/* C# 14.0 */
1198+
| 139 = @accessor_invocation_expr
11971199
/* Preprocessor */
11981200
| 999 = @define_symbol_expr
11991201
;
@@ -1268,9 +1270,9 @@ case @expr.kind of
12681270

12691271
@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr
12701272
| @delegate_invocation_expr | @object_creation_expr | @call_access_expr
1271-
| @local_function_invocation_expr | @function_pointer_invocation_expr;
1273+
| @local_function_invocation_expr | @function_pointer_invocation_expr | @accessor_invocation_expr;
12721274

1273-
@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr;
1275+
@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr | @accessor_invocation_expr;
12741276

12751277
@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr
12761278
| @object_creation_expr | @method_invocation_expr | @operator_invocation_expr;
@@ -1319,7 +1321,8 @@ dynamic_member_name(
13191321

13201322
@qualifiable_expr = @member_access_expr
13211323
| @method_invocation_expr
1322-
| @element_access_expr;
1324+
| @element_access_expr
1325+
| @accessor_invocation_expr;
13231326

13241327
conditional_access(
13251328
unique int id: @qualifiable_expr ref);

0 commit comments

Comments
 (0)