From 75894d581c392bc77b423b051f960dcbd4727797 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 3 Apr 2024 12:15:33 +0200 Subject: [PATCH] C#: Remove unused classes from `Util` project --- .../Semmle.Autobuild.CSharp/DotNetRule.cs | 2 +- .../Entities/Expressions/Lambda.cs | 2 +- .../extractor/Semmle.Util.Tests/ActionMap.cs | 54 ------ .../extractor/Semmle.Util.Tests/TextTest.cs | 78 --------- csharp/extractor/Semmle.Util/ActionMap.cs | 45 ----- csharp/extractor/Semmle.Util/Enumerators.cs | 19 -- csharp/extractor/Semmle.Util/FileRenamer.cs | 34 ---- .../extractor/Semmle.Util/FuzzyDictionary.cs | 165 ------------------ .../extractor/Semmle.Util/SharedReference.cs | 18 -- ...gBuilder.cs => StringBuilderExtensions.cs} | 0 .../extractor/Semmle.Util/StringExtensions.cs | 41 ----- csharp/extractor/Semmle.Util/Text.cs | 105 ----------- csharp/extractor/Semmle.Util/Worklist.cs | 57 ------ 13 files changed, 2 insertions(+), 618 deletions(-) delete mode 100644 csharp/extractor/Semmle.Util.Tests/ActionMap.cs delete mode 100644 csharp/extractor/Semmle.Util.Tests/TextTest.cs delete mode 100644 csharp/extractor/Semmle.Util/ActionMap.cs delete mode 100644 csharp/extractor/Semmle.Util/Enumerators.cs delete mode 100644 csharp/extractor/Semmle.Util/FileRenamer.cs delete mode 100644 csharp/extractor/Semmle.Util/FuzzyDictionary.cs delete mode 100644 csharp/extractor/Semmle.Util/SharedReference.cs rename csharp/extractor/Semmle.Util/{StringBuilder.cs => StringBuilderExtensions.cs} (100%) delete mode 100644 csharp/extractor/Semmle.Util/StringExtensions.cs delete mode 100644 csharp/extractor/Semmle.Util/Text.cs delete mode 100644 csharp/extractor/Semmle.Util/Worklist.cs diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs index c1383731361a..1db24880be2d 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs @@ -32,7 +32,7 @@ public BuildScript Analyse(IAutobuilder builder, bool au if (auto) { NotDotNetProjects = builder.ProjectsOrSolutionsToBuild - .SelectMany(p => Enumerators.Singleton(p).Concat(p.IncludedProjects)) + .SelectMany(p => new[] { p }.Concat(p.IncludedProjects)) .OfType>() .Where(p => !p.DotNetProject); var notDotNetProject = NotDotNetProjects.FirstOrDefault(); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Lambda.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Lambda.cs index 37ea7465255e..cf9c682eb679 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Lambda.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Lambda.cs @@ -63,7 +63,7 @@ private Lambda(ExpressionNodeInfo info, ParenthesizedLambdaExpressionSyntax node public static Lambda Create(ExpressionNodeInfo info, ParenthesizedLambdaExpressionSyntax node) => new Lambda(info, node); private Lambda(ExpressionNodeInfo info, SimpleLambdaExpressionSyntax node) - : this(info.SetKind(ExprKind.LAMBDA), node.Body, Enumerators.Singleton(node.Parameter), null) { } + : this(info.SetKind(ExprKind.LAMBDA), node.Body, [node.Parameter], null) { } public static Lambda Create(ExpressionNodeInfo info, SimpleLambdaExpressionSyntax node) => new Lambda(info, node); diff --git a/csharp/extractor/Semmle.Util.Tests/ActionMap.cs b/csharp/extractor/Semmle.Util.Tests/ActionMap.cs deleted file mode 100644 index 8bed44b97a25..000000000000 --- a/csharp/extractor/Semmle.Util.Tests/ActionMap.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Xunit; -using Semmle.Util; - -using Assert = Xunit.Assert; - -namespace SemmleTests.Semmle.Util -{ - - public class ActionMapTests - { - [Fact] - public void TestAddthenOnAdd() - { - var am = new ActionMap(); - am.Add(1, 2); - int value = 0; - am.OnAdd(1, x => value = x); - Assert.Equal(2, value); - } - - [Fact] - public void TestOnAddthenAdd() - { - var am = new ActionMap(); - int value = 0; - am.OnAdd(1, x => value = x); - am.Add(1, 2); - Assert.Equal(2, value); - } - - [Fact] - public void TestNotAdded() - { - var am = new ActionMap(); - int value = 0; - am.OnAdd(1, x => value = x); - am.Add(2, 2); - Assert.Equal(0, value); - } - - [Fact] - public void TestMultipleActions() - { - var am = new ActionMap(); - int value1 = 0, value2 = 0; - am.OnAdd(1, x => value1 = x); - am.OnAdd(1, x => value2 = x); - am.Add(1, 2); - Assert.Equal(2, value1); - Assert.Equal(2, value2); - } - - } -} diff --git a/csharp/extractor/Semmle.Util.Tests/TextTest.cs b/csharp/extractor/Semmle.Util.Tests/TextTest.cs deleted file mode 100644 index 3a21f0b73edd..000000000000 --- a/csharp/extractor/Semmle.Util.Tests/TextTest.cs +++ /dev/null @@ -1,78 +0,0 @@ -using Xunit; -using System; -using Semmle.Util; - -using Assert = Xunit.Assert; - -namespace SemmleTests -{ - public class TextTest - { - //#################### PRIVATE VARIABLES #################### - #region - - /// - /// A shorter way of writing Environment.NewLine (it gets used repeatedly). - /// - private static readonly string NL = Environment.NewLine; - - #endregion - - //#################### TEST METHODS #################### - #region - - [Fact] - public void GetAllTest() - { - var input = new string[] - { - "Said once a young coder from Crewe,", - "'I like to write tests, so I do!", - "They help me confirm", - "That I don't need to squirm -", - "My code might look nice, but works too!'" - }; - - var text = new Text(input); - - Assert.Equal(string.Join(NL, input) + NL, text.GetAll()); - } - - [Fact] - public void GetPortionTest() - { - var input = new string[] - { - "There once was a jolly young tester", - "Who couldn't leave software to fester -", - "He'd prod and he'd poke", - "Until something bad broke,", - "And then he'd find someone to pester." - }; - - var text = new Text(input); - - // A single-line range (to test the special case). - Assert.Equal("jolly" + NL, text.GetPortion(0, 17, 0, 22)); - - // A two-line range. - Assert.Equal("prod and he'd poke" + NL + "Until" + NL, text.GetPortion(2, 5, 3, 5)); - - // A three-line range (to test that the middle line is included in full). - Assert.Equal("poke" + NL + "Until something bad broke," + NL + "And then" + NL, text.GetPortion(2, 19, 4, 8)); - - // An invalid but recoverable range (to test that a best effort is made rather than crashing). - Assert.Equal(NL + "Who couldn't leave software to fester -" + NL, text.GetPortion(0, int.MaxValue, 1, int.MaxValue)); - - // Some quite definitely dodgy ranges (to test that exceptions are thrown). - Assert.Throws(() => text.GetPortion(-1, 0, 0, 0)); - Assert.Throws(() => text.GetPortion(0, -1, 0, 0)); - Assert.Throws(() => text.GetPortion(0, 0, -1, 0)); - Assert.Throws(() => text.GetPortion(0, 0, 0, -1)); - Assert.Throws(() => text.GetPortion(3, 5, 2, 5)); - Assert.Throws(() => text.GetPortion(2, 5, int.MaxValue, 5)); - } - - #endregion - } -} diff --git a/csharp/extractor/Semmle.Util/ActionMap.cs b/csharp/extractor/Semmle.Util/ActionMap.cs deleted file mode 100644 index afcda9bb4944..000000000000 --- a/csharp/extractor/Semmle.Util/ActionMap.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Semmle.Util -{ - /// - /// A dictionary which performs an action when items are added to the dictionary. - /// The order in which keys and actions are added does not matter. - /// - /// - /// - public class ActionMap where TKey : notnull - { - public void Add(TKey key, TValue value) - { - - if (actions.TryGetValue(key, out var a)) - a(value); - values[key] = value; - } - - public void OnAdd(TKey key, Action action) - { - if (actions.TryGetValue(key, out var a)) - { - actions[key] = a + action; - } - else - { - actions.Add(key, action); - } - - if (values.TryGetValue(key, out var val)) - { - action(val); - } - } - - // Action associated with each key. - private readonly Dictionary> actions = new Dictionary>(); - - // Values associated with each key. - private readonly Dictionary values = new Dictionary(); - } -} diff --git a/csharp/extractor/Semmle.Util/Enumerators.cs b/csharp/extractor/Semmle.Util/Enumerators.cs deleted file mode 100644 index 16fad6cfa549..000000000000 --- a/csharp/extractor/Semmle.Util/Enumerators.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; - -namespace Semmle.Util -{ - public static class Enumerators - { - /// - /// Create an enumerable with a single element. - /// - /// - /// The type of the enumerable/element. - /// The element. - /// An enumerable containing a single element. - public static IEnumerable Singleton(T t) - { - yield return t; - } - } -} diff --git a/csharp/extractor/Semmle.Util/FileRenamer.cs b/csharp/extractor/Semmle.Util/FileRenamer.cs deleted file mode 100644 index 494e46856f83..000000000000 --- a/csharp/extractor/Semmle.Util/FileRenamer.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace Semmle.Util -{ - /// - /// Utility to temporarily rename a set of files. - /// - public sealed class FileRenamer : IDisposable - { - private readonly string[] files; - private const string suffix = ".codeqlhidden"; - - public FileRenamer(IEnumerable oldFiles) - { - files = oldFiles.Select(f => f.FullName).ToArray(); - - foreach (var file in files) - { - File.Move(file, file + suffix); - } - } - - public void Dispose() - { - foreach (var file in files) - { - File.Move(file + suffix, file); - } - } - } -} diff --git a/csharp/extractor/Semmle.Util/FuzzyDictionary.cs b/csharp/extractor/Semmle.Util/FuzzyDictionary.cs deleted file mode 100644 index 53a84d98a081..000000000000 --- a/csharp/extractor/Semmle.Util/FuzzyDictionary.cs +++ /dev/null @@ -1,165 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Semmle.Util -{ - /// - /// A dictionary from strings to elements of type T. - /// - /// - /// - /// This data structure is able to locate items based on an "approximate match" - /// of the key. This is used for example when attempting to identify two terms - /// in different trap files which are similar but not identical. - /// - /// The algorithm locates the closest match to a string based on a "distance function". - /// - /// Whilst many distance functions are possible, a bespoke algorithm is used here, - /// for efficiency and suitability for the domain. - /// - /// The distance is defined as the Hamming Distance of the numbers in the string. - /// Each string is split into the base "form" (stripped of numbers) and a vector of - /// numbers. (Numbers are non-negative integers in this context). - /// - /// Strings with a different "form" are considered different and have a distance - /// of infinity. - /// - /// This distance function is reflexive, symmetric and obeys the triangle inequality. - /// - /// E.g. foo(bar,1,2) has form "foo(bar,,)" and integers {1,2} - /// - /// distance(foo(bar,1,2), foo(bar,1,2)) = 0 - /// distance(foo(bar,1,2), foo(bar,1,3)) = 1 - /// distance(foo(bar,2,1), foo(bar,1,2)) = 2 - /// distance(foo(bar,1,2), foo(baz,1,2)) = infinity - /// - /// - /// The value type. - public class FuzzyDictionary where T : class - { - // All data items indexed by the "base string" (stripped of numbers) - private readonly Dictionary>> index = new Dictionary>>(); - - /// - /// Stores a new KeyValuePair in the data structure. - /// - /// The key. - /// The value. - public void Add(string k, T v) - { - var kv = new KeyValuePair(k, v); - - var root = StripDigits(k); - index.AddAnother(root, kv); - } - - /// - /// Computes the Hamming Distance between two sequences of the same length. - /// - /// Vector 1 - /// Vector 2 - /// The Hamming Distance. - private static int HammingDistance(IEnumerable v1, IEnumerable v2) where TElement : notnull - { - return v1.Zip(v2, (x, y) => x.Equals(y) ? 0 : 1).Sum(); - } - - /// - /// Locates the value with the smallest Hamming Distance from the query. - /// - /// The query string. - /// The distance between the query string and the stored string. - /// The best match, or null (default). - public T? FindMatch(string query, out int distance) - { - var root = StripDigits(query); - if (!index.TryGetValue(root, out var list)) - { - distance = 0; - return default(T); - } - - return BestMatch(query, list, (a, b) => HammingDistance(ExtractIntegers(a), ExtractIntegers(b)), out distance); - } - - /// - /// Returns the best match (with the smallest distance) for a query. - /// - /// The query string. - /// The list of candidate matches. - /// The distance function. - /// The distance between the query and the stored string. - /// The stored value. - private static T? BestMatch(string query, IEnumerable> candidates, Func distance, out int bestDistance) - { - var bestMatch = default(T); - bestDistance = 0; - var first = true; - - foreach (var candidate in candidates) - { - var d = distance(query, candidate.Key); - if (d == 0) - return candidate.Value; - - if (first || d < bestDistance) - { - bestDistance = d; - bestMatch = candidate.Value; - first = false; - } - } - - return bestMatch; - } - - /// - /// Removes all digits from a string. - /// - /// The input string. - /// String with digits removed. - private static string StripDigits(string input) - { - var result = new StringBuilder(); - foreach (var c in input.Where(c => !char.IsDigit(c))) - result.Append(c); - return result.ToString(); - } - - /// - /// Extracts and enumerates all non-negative integers in a string. - /// - /// The string to enumerate. - /// The sequence of integers. - private static IEnumerable ExtractIntegers(string input) - { - var inNumber = false; - var value = 0; - foreach (var c in input) - { - if (char.IsDigit(c)) - { - if (inNumber) - { - value = value * 10 + (c - '0'); - } - else - { - inNumber = true; - value = c - '0'; - } - } - else - { - if (inNumber) - { - yield return value; - inNumber = false; - } - } - } - } - } -} diff --git a/csharp/extractor/Semmle.Util/SharedReference.cs b/csharp/extractor/Semmle.Util/SharedReference.cs deleted file mode 100644 index ba87caeefaa4..000000000000 --- a/csharp/extractor/Semmle.Util/SharedReference.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Semmle.Util -{ - /// - /// An instance of this class maintains a shared reference to an object. - /// This makes it possible for several different parts of the code to - /// share access to an object that can change (that is, they all want - /// to refer to the same object, but the object to which they jointly - /// refer may vary over time). - /// - /// The type of the shared object. - public sealed class SharedReference where T : class - { - /// - /// The shared object to which different parts of the code want to refer. - /// - public T? Obj { get; set; } - } -} diff --git a/csharp/extractor/Semmle.Util/StringBuilder.cs b/csharp/extractor/Semmle.Util/StringBuilderExtensions.cs similarity index 100% rename from csharp/extractor/Semmle.Util/StringBuilder.cs rename to csharp/extractor/Semmle.Util/StringBuilderExtensions.cs diff --git a/csharp/extractor/Semmle.Util/StringExtensions.cs b/csharp/extractor/Semmle.Util/StringExtensions.cs deleted file mode 100644 index e56f106fe1fc..000000000000 --- a/csharp/extractor/Semmle.Util/StringExtensions.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace Semmle.Util -{ - public static class StringExtensions - { - public static (string, string) Split(this string self, int index0) - { - var split = self.Split(new[] { index0 }); - return (split[0], split[1]); - } - - public static (string, string, string) Split(this string self, int index0, int index1) - { - var split = self.Split(new[] { index0, index1 }); - return (split[0], split[1], split[2]); - } - - public static (string, string, string, string) Split(this string self, int index0, int index1, int index2) - { - var split = self.Split(new[] { index0, index1, index2 }); - return (split[0], split[1], split[2], split[3]); - } - - private static List Split(this string self, params int[] indices) - { - var ret = new List(); - var previousIndex = 0; - foreach (var index in indices.OrderBy(i => i)) - { - ret.Add(self.Substring(previousIndex, index - previousIndex)); - previousIndex = index; - } - - ret.Add(self.Substring(previousIndex)); - - return ret; - } - } -} diff --git a/csharp/extractor/Semmle.Util/Text.cs b/csharp/extractor/Semmle.Util/Text.cs deleted file mode 100644 index 38619fc0164d..000000000000 --- a/csharp/extractor/Semmle.Util/Text.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System; -using System.IO; - -namespace Semmle.Util -{ - /// - /// An instance of this class represents a piece of text, e.g. the text of a C# source file. - /// - public sealed class Text - { - //#################### PRIVATE VARIABLES #################### - #region - - /// - /// The text, stored line-by-line. - /// - private readonly string[] lines; - - #endregion - - //#################### CONSTRUCTORS #################### - #region - - /// - /// Constructs a text object from an array of lines. - /// - /// The lines of text. - public Text(string[] lines) - { - this.lines = lines; - } - - #endregion - - //#################### PUBLIC METHODS #################### - #region - - /// - /// Gets the whole text. - /// - /// The whole text. - public string GetAll() - { - using var sw = new StringWriter(); - foreach (var s in lines) - { - sw.WriteLine(s); - } - return sw.ToString(); - } - - /// - /// Gets the portion of text that lies in the specified location range. - /// - /// The row at which the portion starts. - /// The column in the start row at which the portion starts. - /// The row at which the portion ends. - /// The column in the end row at which the portion ends. - /// The portion of text that lies in the specified location range. - public string GetPortion(int startRow, int startColumn, int endRow, int endColumn) - { - // Perform some basic validation on the range bounds. - if (startRow < 0 || endRow < 0 || startColumn < 0 || endColumn < 0 || endRow >= lines.Length || startRow > endRow) - { - throw new Exception - ( - string.Format("Bad range ({0},{1}):({2},{3}) in a piece of text with {4} lines", startRow, startColumn, endRow, endColumn, lines.Length) - ); - } - - using var sw = new StringWriter(); - string line; - - for (var i = startRow; i <= endRow; ++i) - { - if (i == startRow && i == endRow) - { - // This is a single-line range, so take the bit between "startColumn" and "endColumn". - line = startColumn <= lines[i].Length ? lines[i].Substring(startColumn, endColumn - startColumn) : ""; - } - else if (i == startRow) - { - // This is the first line of a multi-line range, so take the bit from "startColumn" onwards. - line = startColumn <= lines[i].Length ? lines[i].Substring(startColumn) : ""; - } - else if (i == endRow) - { - // This is the last line of a multi-line range, so take the bit up to "endColumn". - line = endColumn <= lines[i].Length ? lines[i].Substring(0, endColumn) : lines[i]; - } - else - { - // This is a line in the middle of a multi-line range, so take the whole line. - line = lines[i]; - } - - sw.WriteLine(line); - } - - return sw.ToString(); - } - - #endregion - } -} diff --git a/csharp/extractor/Semmle.Util/Worklist.cs b/csharp/extractor/Semmle.Util/Worklist.cs deleted file mode 100644 index 0a71dbd4381e..000000000000 --- a/csharp/extractor/Semmle.Util/Worklist.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.Collections.Generic; - -namespace Semmle.Util -{ - /// - /// A worklist of items, providing the operations of adding an item, checking - /// whether there are new items and iterating a chunk of unprocessed items. - /// Any one item will only be accepted into the worklist once. - /// - public class Worklist - { - private readonly HashSet internalSet = new HashSet(); - private LinkedList internalList = new LinkedList(); - private bool hasNewElements = false; - - /// - /// Gets a value indicating whether this instance has had any new elements added - /// since the last time GetUnprocessedElements() was called. - /// - /// - /// true if this instance has new elements; otherwise, false. - /// - public bool HasNewElements => hasNewElements; - - /// - /// Add the specified element to the worklist. - /// - /// - /// If set to true element. - /// - public bool Add(T element) - { - if (internalSet.Contains(element)) - return false; - internalSet.Add(element); - internalList.AddLast(element); - hasNewElements = true; - return true; - } - - /// - /// Gets the unprocessed elements that have been accumulated since the last time - /// this method was called. If HasNewElements == true, the resulting list - /// will be non-empty. - /// - /// - /// The unprocessed elements. - /// - public LinkedList GetUnprocessedElements() - { - var result = internalList; - internalList = new LinkedList(); - hasNewElements = false; - return result; - } - } -}