From 5843fdbdd8e23757fa5a8936dfbb5d50b7b3ae82 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 25 Sep 2025 16:52:27 +0200 Subject: [PATCH] C#: Add a locations example. --- csharp/ql/test/library-tests/locations/A.cs | 35 +++++++++++++ csharp/ql/test/library-tests/locations/B.cs | 20 +++++++ csharp/ql/test/library-tests/locations/C.cs | 12 +++++ .../locations/locations.expected | 52 +++++++++++++++++++ .../test/library-tests/locations/locations.ql | 14 +++++ 5 files changed, 133 insertions(+) create mode 100644 csharp/ql/test/library-tests/locations/A.cs create mode 100644 csharp/ql/test/library-tests/locations/B.cs create mode 100644 csharp/ql/test/library-tests/locations/C.cs create mode 100644 csharp/ql/test/library-tests/locations/locations.expected create mode 100644 csharp/ql/test/library-tests/locations/locations.ql diff --git a/csharp/ql/test/library-tests/locations/A.cs b/csharp/ql/test/library-tests/locations/A.cs new file mode 100644 index 00000000000..7f641a0024e --- /dev/null +++ b/csharp/ql/test/library-tests/locations/A.cs @@ -0,0 +1,35 @@ +using System; + +public abstract class A +{ + public abstract T Prop { get; } + public abstract T this[int index] { get; set; } + public abstract event EventHandler Event; + public void Apply(T t) { } + public abstract object ToObject(T t); +} + +public class A2 : A +{ + public override string Prop => ""; + + public override string this[int i] + { + get { return ""; } + set { } + } + + public override event EventHandler Event + { + add { } + remove { } + } + + public override object ToObject(string t) => t; + + public void M() + { + A2 other = new(); + other.Apply(""); + } +} diff --git a/csharp/ql/test/library-tests/locations/B.cs b/csharp/ql/test/library-tests/locations/B.cs new file mode 100644 index 00000000000..c4cfa971116 --- /dev/null +++ b/csharp/ql/test/library-tests/locations/B.cs @@ -0,0 +1,20 @@ +using System; + +public class B : A +{ + public override int Prop => 0; + + public override int this[int i] + { + get { return 0; } + set { } + } + + public override event EventHandler Event + { + add { } + remove { } + } + + public override object ToObject(int t) => t; +} diff --git a/csharp/ql/test/library-tests/locations/C.cs b/csharp/ql/test/library-tests/locations/C.cs new file mode 100644 index 00000000000..a4063646d53 --- /dev/null +++ b/csharp/ql/test/library-tests/locations/C.cs @@ -0,0 +1,12 @@ +using System; + +class C +{ + public void M() + { + B b = new B(); + b.Apply(0); + A2 a2 = new A2(); + a2.Apply(""); + } +} diff --git a/csharp/ql/test/library-tests/locations/locations.expected b/csharp/ql/test/library-tests/locations/locations.expected new file mode 100644 index 00000000000..8b021b115d2 --- /dev/null +++ b/csharp/ql/test/library-tests/locations/locations.expected @@ -0,0 +1,52 @@ +member_locations +| A.cs:3:23:3:26 | A | A.cs:5:23:5:26 | Prop | A.cs:5:23:5:26 | A.cs:5:23:5:26 | +| A.cs:3:23:3:26 | A | A.cs:6:23:6:26 | Item | A.cs:6:23:6:26 | A.cs:6:23:6:26 | +| A.cs:3:23:3:26 | A | A.cs:7:40:7:44 | Event | A.cs:7:40:7:44 | A.cs:7:40:7:44 | +| A.cs:3:23:3:26 | A | A.cs:8:17:8:21 | Apply | A.cs:8:17:8:21 | A.cs:8:17:8:21 | +| A.cs:3:23:3:26 | A | A.cs:9:28:9:35 | ToObject | A.cs:9:28:9:35 | A.cs:9:28:9:35 | +| A.cs:3:23:3:26 | A | A.cs:5:23:5:26 | Prop | A.cs:5:23:5:26 | A.cs:5:23:5:26 | +| A.cs:3:23:3:26 | A | A.cs:6:23:6:26 | Item | A.cs:6:23:6:26 | A.cs:6:23:6:26 | +| A.cs:3:23:3:26 | A | A.cs:7:40:7:44 | Event | A.cs:7:40:7:44 | A.cs:7:40:7:44 | +| A.cs:3:23:3:26 | A | A.cs:8:17:8:21 | Apply | A.cs:8:17:8:21 | A.cs:8:17:8:21 | +| A.cs:3:23:3:26 | A | A.cs:9:28:9:35 | ToObject | A.cs:9:28:9:35 | A.cs:9:28:9:35 | +| A.cs:3:23:3:26 | A`1 | A.cs:5:23:5:26 | Prop | A.cs:5:23:5:26 | A.cs:5:23:5:26 | +| A.cs:3:23:3:26 | A`1 | A.cs:6:23:6:26 | Item | A.cs:6:23:6:26 | A.cs:6:23:6:26 | +| A.cs:3:23:3:26 | A`1 | A.cs:7:40:7:44 | Event | A.cs:7:40:7:44 | A.cs:7:40:7:44 | +| A.cs:3:23:3:26 | A`1 | A.cs:8:17:8:21 | Apply | A.cs:8:17:8:21 | A.cs:8:17:8:21 | +| A.cs:3:23:3:26 | A`1 | A.cs:9:28:9:35 | ToObject | A.cs:9:28:9:35 | A.cs:9:28:9:35 | +| A.cs:12:14:12:15 | A2 | A.cs:14:28:14:31 | Prop | A.cs:14:28:14:31 | A.cs:14:28:14:31 | +| A.cs:12:14:12:15 | A2 | A.cs:16:28:16:31 | Item | A.cs:16:28:16:31 | A.cs:16:28:16:31 | +| A.cs:12:14:12:15 | A2 | A.cs:22:40:22:44 | Event | A.cs:22:40:22:44 | A.cs:22:40:22:44 | +| A.cs:12:14:12:15 | A2 | A.cs:28:28:28:35 | ToObject | A.cs:28:28:28:35 | A.cs:28:28:28:35 | +| A.cs:12:14:12:15 | A2 | A.cs:30:17:30:17 | M | A.cs:30:17:30:17 | A.cs:30:17:30:17 | +| B.cs:3:14:3:14 | B | B.cs:5:25:5:28 | Prop | B.cs:5:25:5:28 | B.cs:5:25:5:28 | +| B.cs:3:14:3:14 | B | B.cs:7:25:7:28 | Item | B.cs:7:25:7:28 | B.cs:7:25:7:28 | +| B.cs:3:14:3:14 | B | B.cs:13:40:13:44 | Event | B.cs:13:40:13:44 | B.cs:13:40:13:44 | +| B.cs:3:14:3:14 | B | B.cs:19:28:19:35 | ToObject | B.cs:19:28:19:35 | B.cs:19:28:19:35 | +| C.cs:3:7:3:7 | C | C.cs:5:17:5:17 | M | C.cs:5:17:5:17 | C.cs:5:17:5:17 | +accessor_location +| A.cs:3:23:3:26 | A | A.cs:5:30:5:32 | get_Prop | A.cs:5:30:5:32 | A.cs:5:30:5:32 | +| A.cs:3:23:3:26 | A | A.cs:6:41:6:43 | get_Item | A.cs:6:41:6:43 | A.cs:6:41:6:43 | +| A.cs:3:23:3:26 | A | A.cs:6:46:6:48 | set_Item | A.cs:6:46:6:48 | A.cs:6:46:6:48 | +| A.cs:3:23:3:26 | A | A.cs:7:40:7:44 | add_Event | A.cs:7:40:7:44 | A.cs:7:40:7:44 | +| A.cs:3:23:3:26 | A | A.cs:7:40:7:44 | remove_Event | A.cs:7:40:7:44 | A.cs:7:40:7:44 | +| A.cs:3:23:3:26 | A | A.cs:5:30:5:32 | get_Prop | A.cs:5:30:5:32 | A.cs:5:30:5:32 | +| A.cs:3:23:3:26 | A | A.cs:6:41:6:43 | get_Item | A.cs:6:41:6:43 | A.cs:6:41:6:43 | +| A.cs:3:23:3:26 | A | A.cs:6:46:6:48 | set_Item | A.cs:6:46:6:48 | A.cs:6:46:6:48 | +| A.cs:3:23:3:26 | A | A.cs:7:40:7:44 | add_Event | A.cs:7:40:7:44 | A.cs:7:40:7:44 | +| A.cs:3:23:3:26 | A | A.cs:7:40:7:44 | remove_Event | A.cs:7:40:7:44 | A.cs:7:40:7:44 | +| A.cs:3:23:3:26 | A`1 | A.cs:5:30:5:32 | get_Prop | A.cs:5:30:5:32 | A.cs:5:30:5:32 | +| A.cs:3:23:3:26 | A`1 | A.cs:6:41:6:43 | get_Item | A.cs:6:41:6:43 | A.cs:6:41:6:43 | +| A.cs:3:23:3:26 | A`1 | A.cs:6:46:6:48 | set_Item | A.cs:6:46:6:48 | A.cs:6:46:6:48 | +| A.cs:3:23:3:26 | A`1 | A.cs:7:40:7:44 | add_Event | A.cs:7:40:7:44 | A.cs:7:40:7:44 | +| A.cs:3:23:3:26 | A`1 | A.cs:7:40:7:44 | remove_Event | A.cs:7:40:7:44 | A.cs:7:40:7:44 | +| A.cs:12:14:12:15 | A2 | A.cs:14:36:14:37 | get_Prop | A.cs:14:36:14:37 | A.cs:14:36:14:37 | +| A.cs:12:14:12:15 | A2 | A.cs:18:9:18:11 | get_Item | A.cs:18:9:18:11 | A.cs:18:9:18:11 | +| A.cs:12:14:12:15 | A2 | A.cs:19:9:19:11 | set_Item | A.cs:19:9:19:11 | A.cs:19:9:19:11 | +| A.cs:12:14:12:15 | A2 | A.cs:24:9:24:11 | add_Event | A.cs:24:9:24:11 | A.cs:24:9:24:11 | +| A.cs:12:14:12:15 | A2 | A.cs:25:9:25:14 | remove_Event | A.cs:25:9:25:14 | A.cs:25:9:25:14 | +| B.cs:3:14:3:14 | B | B.cs:5:33:5:33 | get_Prop | B.cs:5:33:5:33 | B.cs:5:33:5:33 | +| B.cs:3:14:3:14 | B | B.cs:9:9:9:11 | get_Item | B.cs:9:9:9:11 | B.cs:9:9:9:11 | +| B.cs:3:14:3:14 | B | B.cs:10:9:10:11 | set_Item | B.cs:10:9:10:11 | B.cs:10:9:10:11 | +| B.cs:3:14:3:14 | B | B.cs:15:9:15:11 | add_Event | B.cs:15:9:15:11 | B.cs:15:9:15:11 | +| B.cs:3:14:3:14 | B | B.cs:16:9:16:14 | remove_Event | B.cs:16:9:16:14 | B.cs:16:9:16:14 | diff --git a/csharp/ql/test/library-tests/locations/locations.ql b/csharp/ql/test/library-tests/locations/locations.ql new file mode 100644 index 00000000000..6c1dcc3e385 --- /dev/null +++ b/csharp/ql/test/library-tests/locations/locations.ql @@ -0,0 +1,14 @@ +import csharp + +query predicate member_locations(Type t, Member m, SourceLocation l) { + t = m.getDeclaringType() and + l = m.getLocation() and + not l instanceof EmptyLocation and + not m instanceof Constructor +} + +query predicate accessor_location(Type t, Accessor a, SourceLocation l) { + t = a.getDeclaringType() and + l = a.getLocation() and + not l instanceof EmptyLocation +}