Skip to content

Commit a931c59

Browse files
committed
C#: Allow attributes on local functions
1 parent 89a4cff commit a931c59

File tree

9 files changed

+60
-6
lines changed

9 files changed

+60
-6
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lgtm,codescanning
2+
* The `LocalFunction` class now extends `Attributable`. This is a C# 9 change.

csharp/ql/src/semmle/code/csharp/Attribute.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ private import TypeRef
1010
* An element that can have attributes. Either an assembly (`Assembly`), a field (`Field`),
1111
* a parameter (`Parameter`), an operator (`Operator`), a method (`Method`), a constructor (`Constructor`),
1212
* a destructor (`Destructor`), a callable accessor (`CallableAccessor`), a value or reference type
13-
* (`ValueOrRefType`), or a declaration with accessors (`DeclarationWithAccessors`).
13+
* (`ValueOrRefType`), a declaration with accessors (`DeclarationWithAccessors`), or a local function
14+
* (`LocalFunction`).
1415
*/
1516
class Attributable extends @attributable {
1617
/** Gets an attribute attached to this element, if any. */

csharp/ql/src/semmle/code/csharp/Callable.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,7 @@ class ExplicitConversionOperator extends ConversionOperator {
972972
* }
973973
* ```
974974
*/
975-
class LocalFunction extends Callable, Modifiable, @local_function {
975+
class LocalFunction extends Callable, Modifiable, Attributable, @local_function {
976976
override string getName() { local_functions(this, result, _, _) }
977977

978978
override LocalFunction getUnboundDeclaration() { local_functions(this, _, _, result) }
@@ -996,4 +996,6 @@ class LocalFunction extends Callable, Modifiable, @local_function {
996996
override Parameter getRawParameter(int i) { result = getParameter(i) }
997997

998998
override string getAPrimaryQlClass() { result = "LocalFunction" }
999+
1000+
override string toString() { result = Callable.super.toString() }
9991001
}

csharp/ql/src/semmlecode.csharp.dbscheme

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,8 @@ tokens(
227227
@external_element = @externalMetric | @externalDefect | @externalDataElement;
228228

229229
@attributable = @assembly | @field | @parameter | @operator | @method | @constructor
230-
| @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors;
230+
| @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors
231+
| @local_function;
231232

232233
/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/
233234

@@ -986,7 +987,7 @@ case @expr.kind of
986987
| 109 = @local_function_invocation_expr
987988
| 110 = @ref_expr
988989
| 111 = @discard_expr
989-
/* C# 8.0 */
990+
/* C# 8.0 */
990991
| 112 = @range_expr
991992
| 113 = @index_expr
992993
| 114 = @switch_expr

csharp/ql/test/library-tests/csharp9/LocalFunction.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
22
using System.Threading.Tasks;
33

4-
public class Class1
4+
public class LocalFunction
55
{
66
public async Task M1()
77
{
@@ -15,4 +15,15 @@ public async Task M1()
1515

1616
static extern void localExtern();
1717
}
18+
19+
public void M2()
20+
{
21+
[Obsolete]
22+
int? dup([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] bool b, int? i)
23+
{
24+
return 2 * i;
25+
}
26+
27+
dup(true, 42);
28+
}
1829
}

csharp/ql/test/library-tests/csharp9/LocalFunctions.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ localFunctionModifier
66
| LocalFunction.cs:16:9:16:41 | localExtern | extern |
77
| LocalFunction.cs:16:9:16:41 | localExtern | private |
88
| LocalFunction.cs:16:9:16:41 | localExtern | static |
9+
| LocalFunction.cs:21:9:25:9 | dup | private |
10+
localFunctionAttribute
11+
| LocalFunction.cs:21:9:25:9 | dup | LocalFunction.cs:21:10:21:17 | [Obsolete(...)] |

csharp/ql/test/library-tests/csharp9/LocalFunctions.ql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ query predicate noBody(LocalFunction lf) { not lf.hasBody() }
55
query predicate localFunctionModifier(LocalFunction lf, string modifier) {
66
lf.hasModifier(modifier)
77
}
8+
9+
query predicate localFunctionAttribute(LocalFunction lf, Attribute a) { a = lf.getAnAttribute() }

csharp/ql/test/library-tests/csharp9/PrintAst.expected

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Discard.cs:
4848
# 10| 0: [ReturnStmt] return ...;
4949
# 10| 0: [IntLiteral] 0
5050
LocalFunction.cs:
51-
# 4| [Class] Class1
51+
# 4| [Class] LocalFunction
5252
# 6| 5: [Method] M1
5353
# 6| -1: [TypeMention] Task
5454
# 7| 4: [BlockStmt] {...}
@@ -77,6 +77,36 @@ LocalFunction.cs:
7777
# 14| 0: [IntLiteral] 2
7878
# 16| 3: [LocalFunctionStmt] localExtern(...)
7979
# 16| 0: [LocalFunction] localExtern
80+
# 19| 6: [Method] M2
81+
# 19| -1: [TypeMention] Void
82+
# 20| 4: [BlockStmt] {...}
83+
# 21| 0: [LocalFunctionStmt] dup(...)
84+
# 21| 0: [LocalFunction] dup
85+
#-----| 0: (Attributes)
86+
# 21| 1: [Attribute] [Obsolete(...)]
87+
# 21| 0: [TypeMention] ObsoleteAttribute
88+
#-----| 2: (Parameters)
89+
# 22| 0: [Parameter] b
90+
# 22| -1: [TypeMention] bool
91+
#-----| 0: (Attributes)
92+
# 22| 1: [Attribute] [NotNullWhen(...)]
93+
# 22| -1: [TypeMention] NotNullWhenAttribute
94+
# 22| 0: [BoolLiteral] true
95+
# 22| 1: [Parameter] i
96+
# 22| -1: [TypeMention] int?
97+
# 22| 1: [TypeMention] int
98+
# 23| 4: [BlockStmt] {...}
99+
# 24| 0: [ReturnStmt] return ...;
100+
# 24| 0: [MulExpr] ... * ...
101+
# 24| 0: [CastExpr] (...) ...
102+
# 24| 1: [IntLiteral] 2
103+
# 24| 1: [ParameterAccess] access to parameter i
104+
# 27| 1: [ExprStmt] ...;
105+
# 27| 0: [LocalFunctionCall] call to local function dup
106+
# 27| -1: [LocalFunctionAccess] access to local function dup
107+
# 27| 0: [BoolLiteral] true
108+
# 27| 1: [CastExpr] (...) ...
109+
# 27| 1: [IntLiteral] 42
80110
NativeInt.cs:
81111
# 3| [Class] NativeInt
82112
# 5| 5: [Method] M1
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
description: Added 'local_function' to 'attributable'.
2+
compatibility: backwards

0 commit comments

Comments
 (0)