Skip to content

Commit 9770f09

Browse files
committed
C#: Deprecate Record and introduce RecordClass instead. Also make flow summary support for record struct constructors.
1 parent 55cb2aa commit 9770f09

File tree

6 files changed

+40
-20
lines changed

6 files changed

+40
-20
lines changed

csharp/ql/lib/semmle/code/csharp/Type.qll

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,14 @@ class SimpleType extends ValueType, @simple_type {
451451
override SystemNamespace getDeclaringNamespace() { any() }
452452
}
453453

454+
/**
455+
* A `record` like type.
456+
* This can be either a `class` or a `struct`.
457+
*/
458+
abstract class RecordType extends ValueOrRefType {
459+
RecordType() { this.isRecord() }
460+
}
461+
454462
/**
455463
* The Boolean type, `bool`.
456464
*/
@@ -721,7 +729,7 @@ class Struct extends ValueType, @struct_type {
721729
* }
722730
* ```
723731
*/
724-
class RecordStruct extends Struct {
732+
class RecordStruct extends RecordType, Struct {
725733
RecordStruct() { this.isRecord() }
726734

727735
override string getAPrimaryQlClass() { result = "RecordStruct" }
@@ -781,6 +789,18 @@ class Class extends RefType, @class_type {
781789
override string getAPrimaryQlClass() { result = "Class" }
782790
}
783791

792+
/**
793+
* DEPRECATED: Use `RecordClass` instead.
794+
*/
795+
deprecated class Record extends Class {
796+
Record() { this.isRecord() }
797+
798+
/** Gets the clone method of this record. */
799+
RecordCloneMethod getCloneMethod() { result = this.getAMember() }
800+
801+
override string getAPrimaryQlClass() { result = "Record" }
802+
}
803+
784804
/**
785805
* A `record`, for example
786806
*
@@ -790,13 +810,11 @@ class Class extends RefType, @class_type {
790810
* }
791811
* ```
792812
*/
793-
class Record extends Class {
794-
Record() { this.isRecord() }
795-
813+
class RecordClass extends RecordType, Class {
796814
/** Gets the clone method of this record. */
797815
RecordCloneMethod getCloneMethod() { result = this.getAMember() }
798816

799-
override string getAPrimaryQlClass() { result = "Record" }
817+
override string getAPrimaryQlClass() { result = "RecordClass" }
800818
}
801819

802820
/**

csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ module SummaryComponentStack {
111111
class SummarizedCallable = Impl::Public::SummarizedCallable;
112112

113113
private predicate recordConstructorFlow(Constructor c, int i, Property p) {
114-
c = any(Record r).getAMember() and
114+
c = any(RecordType r).getAMember() and
115115
exists(string name |
116116
c.getParameter(i).getName() = name and
117117
c.getDeclaringType().getAMember(name) = p

csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,9 @@ class WithExpr extends Expr, @with_expr {
11751175
Expr getExpr() { result = this.getChild(0) }
11761176

11771177
/** Gets the clone method of the `record` that is targetted by this `with` expression. */
1178-
RecordCloneMethod getCloneMethod() { result = this.getExpr().getType().(Record).getCloneMethod() }
1178+
RecordCloneMethod getCloneMethod() {
1179+
result = this.getExpr().getType().(RecordClass).getCloneMethod()
1180+
}
11791181

11801182
override string toString() { result = "... with { ... }" }
11811183

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ ParenthesizedPattern.cs:
776776
# 26| 0: [TypeMention] string
777777
# 26| 2: [IntLiteral] 5
778778
Record.cs:
779-
# 4| [Record] Person
779+
# 4| [Record,RecordClass] Person
780780
# 4| 11: [NEOperator] !=
781781
#-----| 2: (Parameters)
782782
# 4| 0: [Parameter] left
@@ -806,7 +806,7 @@ Record.cs:
806806
# 9| 1: [TupleExpr] (..., ...)
807807
# 9| 0: [ParameterAccess] access to parameter first
808808
# 9| 1: [ParameterAccess] access to parameter last
809-
# 12| [Record] Teacher
809+
# 12| [Record,RecordClass] Teacher
810810
# 12| 12: [NEOperator] !=
811811
#-----| 2: (Parameters)
812812
# 12| 0: [Parameter] left
@@ -834,7 +834,7 @@ Record.cs:
834834
# 17| 4: [AssignExpr] ... = ...
835835
# 17| 0: [PropertyCall] access to property Subject
836836
# 17| 1: [ParameterAccess] access to parameter sub
837-
# 20| [Record] Student
837+
# 20| [Record,RecordClass] Student
838838
# 20| 12: [NEOperator] !=
839839
#-----| 2: (Parameters)
840840
# 20| 0: [Parameter] left
@@ -862,7 +862,7 @@ Record.cs:
862862
# 24| 4: [AssignExpr] ... = ...
863863
# 24| 0: [PropertyCall] access to property Level
864864
# 24| 1: [ParameterAccess] access to parameter level
865-
# 27| [Record] Person1
865+
# 27| [Record,RecordClass] Person1
866866
# 27| 12: [NEOperator] !=
867867
#-----| 2: (Parameters)
868868
# 27| 0: [Parameter] left
@@ -889,7 +889,7 @@ Record.cs:
889889
# 27| 4: [Setter] set_LastName
890890
#-----| 2: (Parameters)
891891
# 27| 0: [Parameter] value
892-
# 29| [Record] Teacher1
892+
# 29| [Record,RecordClass] Teacher1
893893
# 29| 13: [NEOperator] !=
894894
#-----| 2: (Parameters)
895895
# 29| 0: [Parameter] left
@@ -913,7 +913,7 @@ Record.cs:
913913
# 29| 4: [Setter] set_Subject
914914
#-----| 2: (Parameters)
915915
# 29| 0: [Parameter] value
916-
# 32| [Record] Student1
916+
# 32| [Record,RecordClass] Student1
917917
# 32| 13: [NEOperator] !=
918918
#-----| 2: (Parameters)
919919
# 32| 0: [Parameter] left
@@ -937,7 +937,7 @@ Record.cs:
937937
# 32| 4: [Setter] set_Level
938938
#-----| 2: (Parameters)
939939
# 32| 0: [Parameter] value
940-
# 35| [Record] Pet
940+
# 35| [Record,RecordClass] Pet
941941
# 35| 12: [NEOperator] !=
942942
#-----| 2: (Parameters)
943943
# 35| 0: [Parameter] left
@@ -963,7 +963,7 @@ Record.cs:
963963
# 38| -1: [TypeAccess] access to type Console
964964
# 38| 0: [TypeMention] Console
965965
# 38| 0: [StringLiteral] "Shredding furniture"
966-
# 41| [Record] Dog
966+
# 41| [Record,RecordClass] Dog
967967
# 41| 12: [NEOperator] !=
968968
#-----| 2: (Parameters)
969969
# 41| 0: [Parameter] left
@@ -1002,7 +1002,7 @@ Record.cs:
10021002
# 50| 0: [MethodCall] call to method ToString
10031003
# 50| -1: [LocalVariableAccess] access to local variable s
10041004
# 50| 1: [StringLiteral] " is a dog"
1005-
# 54| [Record] R1
1005+
# 54| [Record,RecordClass] R1
10061006
# 54| 12: [NEOperator] !=
10071007
#-----| 2: (Parameters)
10081008
# 54| 0: [Parameter] left
@@ -1022,7 +1022,7 @@ Record.cs:
10221022
# 54| 4: [Setter] set_A
10231023
#-----| 2: (Parameters)
10241024
# 54| 0: [Parameter] value
1025-
# 56| [Record] R2
1025+
# 56| [Record,RecordClass] R2
10261026
# 56| 13: [NEOperator] !=
10271027
#-----| 2: (Parameters)
10281028
# 56| 0: [Parameter] left

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import csharp
22

3-
query predicate records(Record t, string i, RecordCloneMethod clone) {
3+
query predicate records(RecordClass t, string i, RecordCloneMethod clone) {
44
t.getABaseInterface().toStringWithTypes() = i and
55
clone = t.getCloneMethod() and
66
t.fromSource()
@@ -10,7 +10,7 @@ private string getMemberName(Member m) {
1010
result = m.getDeclaringType().getQualifiedName() + "." + m.toStringWithTypes()
1111
}
1212

13-
query predicate members(Record t, string ms, string l) {
13+
query predicate members(RecordClass t, string ms, string l) {
1414
t.fromSource() and
1515
exists(Member m | t.hasMember(m) |
1616
ms = getMemberName(m) and

csharp/ql/test/library-tests/dataflow/tuples/PrintAst.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ Tuples.cs:
281281
# 81| 2: [ExprStmt] ...;
282282
# 81| 0: [MethodCall] call to method Sink<Int32>
283283
# 81| 0: [LocalVariableAccess] access to local variable q
284-
# 85| 9: [Record] R1
284+
# 85| 9: [RecordClass] R1
285285
# 85| 12: [NEOperator] !=
286286
#-----| 2: (Parameters)
287287
# 85| 0: [Parameter] left

0 commit comments

Comments
 (0)