mirror of
https://github.com/github/codeql.git
synced 2026-05-03 04:39:29 +02:00
C#: Add support for init only accessors
This commit is contained in:
@@ -76,6 +76,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
trapFile.compiler_generated(this);
|
||||
}
|
||||
|
||||
if (symbol.IsInitOnly)
|
||||
{
|
||||
trapFile.init_only_accessors(this);
|
||||
}
|
||||
}
|
||||
|
||||
public static new Accessor Create(Context cx, IMethodSymbol symbol) =>
|
||||
|
||||
@@ -26,6 +26,11 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.WriteTuple("accessors", accessorKey, kind, name, propKey, unboundAccessor);
|
||||
}
|
||||
|
||||
internal static void init_only_accessors(this TextWriter trapFile, Accessor accessorKey)
|
||||
{
|
||||
trapFile.WriteTuple("init_only_accessors", accessorKey);
|
||||
}
|
||||
|
||||
internal static void array_element_type(this TextWriter trapFile, ArrayType array, int dimension, int rank, Type elementType)
|
||||
{
|
||||
trapFile.WriteTuple("array_element_type", array, dimension, rank, elementType);
|
||||
|
||||
@@ -472,6 +472,9 @@ class Setter extends Accessor, @setter {
|
||||
result = Accessor.super.getDeclaration()
|
||||
}
|
||||
|
||||
/** Holds if this setter is an `init`-only accessor. */
|
||||
predicate isInitOnly() { init_only_accessors(this) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "Setter" }
|
||||
}
|
||||
|
||||
|
||||
@@ -604,6 +604,9 @@ case @accessor.kind of
|
||||
| 2 = @setter
|
||||
;
|
||||
|
||||
init_only_accessors(
|
||||
unique int id: @accessor ref);
|
||||
|
||||
accessor_location(
|
||||
int id: @accessor ref,
|
||||
int loc: @location ref);
|
||||
|
||||
44
csharp/ql/test/library-tests/csharp9/InitOnlyProperty.cs
Normal file
44
csharp/ql/test/library-tests/csharp9/InitOnlyProperty.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
public sealed class IsExternalInit
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class Base
|
||||
{
|
||||
public int Prop0 { get { return 1; } init { Prop1 = value; } }
|
||||
public virtual int Prop1 { get; init; }
|
||||
public virtual int Prop2 { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class Derived : Base
|
||||
{
|
||||
public override int Prop1 { get; init; }
|
||||
public int Prop2
|
||||
{
|
||||
get { return 0; }
|
||||
init
|
||||
{
|
||||
System.Console.WriteLine(value);
|
||||
Prop1 = value;
|
||||
Prop0 = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class C1
|
||||
{
|
||||
public void M1()
|
||||
{
|
||||
var d = new Derived
|
||||
{
|
||||
Prop1 = 1,
|
||||
Prop2 = 2,
|
||||
Prop0 = 0
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,88 @@ Discard.cs:
|
||||
# 10| 4: [BlockStmt] {...}
|
||||
# 10| 0: [ReturnStmt] return ...;
|
||||
# 10| 0: [IntLiteral] 0
|
||||
InitOnlyProperty.cs:
|
||||
# 3| [NamespaceDeclaration] namespace ... { ... }
|
||||
# 5| 1: [Class] IsExternalInit
|
||||
# 10| [Class] Base
|
||||
# 12| 5: [Property] Prop0
|
||||
# 12| -1: [TypeMention] int
|
||||
# 12| 3: [Getter] get_Prop0
|
||||
# 12| 4: [BlockStmt] {...}
|
||||
# 12| 0: [ReturnStmt] return ...;
|
||||
# 12| 0: [IntLiteral] 1
|
||||
# 12| 4: [Setter] set_Prop0
|
||||
#-----| 2: (Parameters)
|
||||
# 12| 0: [Parameter] value
|
||||
# 12| 4: [BlockStmt] {...}
|
||||
# 12| 0: [ExprStmt] ...;
|
||||
# 12| 0: [AssignExpr] ... = ...
|
||||
# 12| 0: [PropertyCall] access to property Prop1
|
||||
# 12| 1: [ParameterAccess] access to parameter value
|
||||
# 13| 6: [Property] Prop1
|
||||
# 13| -1: [TypeMention] int
|
||||
# 13| 3: [Getter] get_Prop1
|
||||
# 13| 4: [Setter] set_Prop1
|
||||
#-----| 2: (Parameters)
|
||||
# 13| 0: [Parameter] value
|
||||
# 14| 7: [Property] Prop2
|
||||
# 14| -1: [TypeMention] int
|
||||
# 14| 3: [Getter] get_Prop2
|
||||
# 14| 4: [Setter] set_Prop2
|
||||
#-----| 2: (Parameters)
|
||||
# 14| 0: [Parameter] value
|
||||
# 18| [Class] Derived
|
||||
#-----| 3: (Base types)
|
||||
# 18| 0: [TypeMention] Base
|
||||
# 20| 5: [Property] Prop1
|
||||
# 20| -1: [TypeMention] int
|
||||
# 20| 3: [Getter] get_Prop1
|
||||
# 20| 4: [Setter] set_Prop1
|
||||
#-----| 2: (Parameters)
|
||||
# 20| 0: [Parameter] value
|
||||
# 21| 6: [Property] Prop2
|
||||
# 21| -1: [TypeMention] int
|
||||
# 23| 3: [Getter] get_Prop2
|
||||
# 23| 4: [BlockStmt] {...}
|
||||
# 23| 0: [ReturnStmt] return ...;
|
||||
# 23| 0: [IntLiteral] 0
|
||||
# 24| 4: [Setter] set_Prop2
|
||||
#-----| 2: (Parameters)
|
||||
# 24| 0: [Parameter] value
|
||||
# 25| 4: [BlockStmt] {...}
|
||||
# 26| 0: [ExprStmt] ...;
|
||||
# 26| 0: [MethodCall] call to method WriteLine
|
||||
# 26| -1: [TypeAccess] access to type Console
|
||||
# 26| 0: [TypeMention] Console
|
||||
# 26| 0: [ParameterAccess] access to parameter value
|
||||
# 27| 1: [ExprStmt] ...;
|
||||
# 27| 0: [AssignExpr] ... = ...
|
||||
# 27| 0: [PropertyCall] access to property Prop1
|
||||
# 27| 1: [ParameterAccess] access to parameter value
|
||||
# 28| 2: [ExprStmt] ...;
|
||||
# 28| 0: [AssignExpr] ... = ...
|
||||
# 28| 0: [PropertyCall] access to property Prop0
|
||||
# 28| 1: [ParameterAccess] access to parameter value
|
||||
# 33| [Class] C1
|
||||
# 35| 5: [Method] M1
|
||||
# 35| -1: [TypeMention] Void
|
||||
# 36| 4: [BlockStmt] {...}
|
||||
# 37| 0: [LocalVariableDeclStmt] ... ...;
|
||||
# 37| 0: [LocalVariableDeclAndInitExpr] Derived d = ...
|
||||
# 37| -1: [TypeMention] Derived
|
||||
# 37| 0: [LocalVariableAccess] access to local variable d
|
||||
# 37| 1: [ObjectCreation] object creation of type Derived
|
||||
# 37| -2: [TypeMention] Derived
|
||||
# 38| -1: [ObjectInitializer] { ..., ... }
|
||||
# 39| 0: [MemberInitializer] ... = ...
|
||||
# 39| 0: [PropertyCall] access to property Prop1
|
||||
# 39| 1: [IntLiteral] 1
|
||||
# 40| 1: [MemberInitializer] ... = ...
|
||||
# 40| 0: [PropertyCall] access to property Prop2
|
||||
# 40| 1: [IntLiteral] 2
|
||||
# 41| 2: [MemberInitializer] ... = ...
|
||||
# 41| 0: [PropertyCall] access to property Prop0
|
||||
# 41| 1: [IntLiteral] 0
|
||||
LambdaModifier.cs:
|
||||
# 4| [Class] Class1
|
||||
# 6| 5: [Method] M1
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
| InitOnlyProperty.cs:12:42:12:45 | set_Prop0 | init |
|
||||
| InitOnlyProperty.cs:13:37:13:40 | set_Prop1 | init |
|
||||
| InitOnlyProperty.cs:14:37:14:39 | set_Prop2 | set |
|
||||
| InitOnlyProperty.cs:20:38:20:41 | set_Prop1 | init |
|
||||
| InitOnlyProperty.cs:24:9:24:12 | set_Prop2 | init |
|
||||
7
csharp/ql/test/library-tests/csharp9/initOnlyProperty.ql
Normal file
7
csharp/ql/test/library-tests/csharp9/initOnlyProperty.ql
Normal file
@@ -0,0 +1,7 @@
|
||||
import csharp
|
||||
|
||||
private string getType(Setter s) { if s.isInitOnly() then result = "init" else result = "set" }
|
||||
|
||||
from Setter s
|
||||
where s.fromSource()
|
||||
select s, getType(s)
|
||||
2
csharp/upgrades/TO_CHANGE/upgrade.properties
Normal file
2
csharp/upgrades/TO_CHANGE/upgrade.properties
Normal file
@@ -0,0 +1,2 @@
|
||||
description: Added 'init_only_accessors' relation.
|
||||
compatibility: backwards
|
||||
Reference in New Issue
Block a user