]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'sj/userdiff-c-sharp'
authorJunio C Hamano <gitster@pobox.com>
Tue, 16 Apr 2024 21:50:28 +0000 (14:50 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 16 Apr 2024 21:50:28 +0000 (14:50 -0700)
The userdiff patterns for C# has been updated.

Acked-by: Johannes Sixt <j6t@kdbg.org>
cf. <c2154457-3f2f-496e-9b8b-c8ea7257027b@kdbg.org>

* sj/userdiff-c-sharp:
  userdiff: better method/property matching for C#

21 files changed:
t/t4018/csharp-exclude-assignments [new file with mode: 0644]
t/t4018/csharp-exclude-control-statements [new file with mode: 0644]
t/t4018/csharp-exclude-exceptions [new file with mode: 0644]
t/t4018/csharp-exclude-generic-method-calls [new file with mode: 0644]
t/t4018/csharp-exclude-init-dispose [new file with mode: 0644]
t/t4018/csharp-exclude-iterations [new file with mode: 0644]
t/t4018/csharp-exclude-method-calls [new file with mode: 0644]
t/t4018/csharp-exclude-other [new file with mode: 0644]
t/t4018/csharp-method [new file with mode: 0644]
t/t4018/csharp-method-array [new file with mode: 0644]
t/t4018/csharp-method-explicit [new file with mode: 0644]
t/t4018/csharp-method-generics [new file with mode: 0644]
t/t4018/csharp-method-generics-alternate-spaces [new file with mode: 0644]
t/t4018/csharp-method-modifiers [new file with mode: 0644]
t/t4018/csharp-method-multiline [new file with mode: 0644]
t/t4018/csharp-method-params [new file with mode: 0644]
t/t4018/csharp-method-special-chars [new file with mode: 0644]
t/t4018/csharp-method-with-spacing [new file with mode: 0644]
t/t4018/csharp-property [new file with mode: 0644]
t/t4018/csharp-property-braces-same-line [new file with mode: 0644]
userdiff.c

diff --git a/t/t4018/csharp-exclude-assignments b/t/t4018/csharp-exclude-assignments
new file mode 100644 (file)
index 0000000..239f312
--- /dev/null
@@ -0,0 +1,20 @@
+class Example
+{
+    string Method(int RIGHT)
+    {
+        var constantAssignment = "test";
+        var methodAssignment = MethodCall();
+        var multiLineMethodAssignment = MethodCall(
+        );
+        var multiLine = "first"
+            + MethodCall()
+            +
+            ( MethodCall()
+            )
+            + MethodCall();
+
+        return "ChangeMe";
+    }
+
+    string MethodCall(int a = 0, int b = 0) => "test";
+}
diff --git a/t/t4018/csharp-exclude-control-statements b/t/t4018/csharp-exclude-control-statements
new file mode 100644 (file)
index 0000000..3a0f404
--- /dev/null
@@ -0,0 +1,34 @@
+class Example
+{
+    string Method(int RIGHT)
+    {
+        if (false)
+        {
+            return "out";
+        }
+        else { }
+        if (true) MethodCall(
+        );
+        else MethodCall(
+        );
+        switch ("test")
+        {
+            case "one":
+            return MethodCall(
+            );
+            case "two":
+            break;
+        }
+        (int, int) tuple = (1, 4);
+        switch (tuple)
+        {
+            case (1, 4):
+              MethodCall();
+                     break;
+        }
+
+        return "ChangeMe";
+    }
+
+    string MethodCall(int a = 0, int b = 0) => "test";
+}
diff --git a/t/t4018/csharp-exclude-exceptions b/t/t4018/csharp-exclude-exceptions
new file mode 100644 (file)
index 0000000..b1e6425
--- /dev/null
@@ -0,0 +1,29 @@
+using System;
+
+class Example
+{
+    string Method(int RIGHT)
+    {
+        try
+        {
+            throw new Exception("fail");
+        }
+        catch (Exception)
+        {
+        }
+        finally
+        {
+        }
+        try { } catch (Exception) {}
+        try
+        {
+            throw GetException(
+            );
+        }
+        catch (Exception) { }
+
+        return "ChangeMe";
+    }
+
+    Exception GetException() => new Exception("fail");
+}
diff --git a/t/t4018/csharp-exclude-generic-method-calls b/t/t4018/csharp-exclude-generic-method-calls
new file mode 100644 (file)
index 0000000..31af546
--- /dev/null
@@ -0,0 +1,12 @@
+class Example
+{
+    string Method(int RIGHT)
+    {
+        GenericMethodCall<int, int>(
+            );
+
+        return "ChangeMe";
+    }
+
+    string GenericMethodCall<T, T2>() => "test";
+}
diff --git a/t/t4018/csharp-exclude-init-dispose b/t/t4018/csharp-exclude-init-dispose
new file mode 100644 (file)
index 0000000..2bc8e19
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+
+class Example : IDisposable
+{
+    string Method(int RIGHT)
+    {
+        new Example();
+        new Example(
+            );
+        new Example { };
+        using (this)
+        {
+        }
+        var def =
+            this is default(
+                Example);
+
+        return "ChangeMe";
+    }
+
+    public void Dispose() {}
+}
diff --git a/t/t4018/csharp-exclude-iterations b/t/t4018/csharp-exclude-iterations
new file mode 100644 (file)
index 0000000..960aa18
--- /dev/null
@@ -0,0 +1,26 @@
+using System.Linq;
+
+class Example
+{
+    string Method(int RIGHT)
+    {
+        do { } while (true);
+        do MethodCall(
+        ); while (true);
+        while (true);
+        while (true) {
+            break;
+        }
+        for (int i = 0; i < 10; ++i)
+        {
+        }
+        foreach (int i in Enumerable.Range(0, 10))
+        {
+        }
+        int[] numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0];
+
+        return "ChangeMe";
+    }
+
+    string MethodCall(int a = 0, int b = 0) => "test";
+}
diff --git a/t/t4018/csharp-exclude-method-calls b/t/t4018/csharp-exclude-method-calls
new file mode 100644 (file)
index 0000000..51e2dc2
--- /dev/null
@@ -0,0 +1,20 @@
+class Example
+{
+    string Method(int RIGHT)
+    {
+        MethodCall();
+        MethodCall(1, 2);
+        MethodCall(
+            1, 2);
+        MethodCall(
+            1, 2,
+            3);
+        MethodCall(
+            1, MethodCall(),
+            2);
+
+        return "ChangeMe";
+    }
+
+    int MethodCall(int a = 0, int b = 0, int c = 0) => 42;
+}
diff --git a/t/t4018/csharp-exclude-other b/t/t4018/csharp-exclude-other
new file mode 100644 (file)
index 0000000..4d5581c
--- /dev/null
@@ -0,0 +1,18 @@
+class Example
+{
+    string Method(int RIGHT)
+    {
+        lock (this)
+        {
+        }
+        unsafe
+        {
+            byte[] bytes = [1, 2, 3];
+            fixed (byte* pointerToFirst = bytes)
+            {
+            }
+        }
+
+        return "ChangeMe";
+    }
+}
diff --git a/t/t4018/csharp-method b/t/t4018/csharp-method
new file mode 100644 (file)
index 0000000..16b367a
--- /dev/null
@@ -0,0 +1,10 @@
+class Example
+{
+    string Method(int RIGHT)
+    {
+        // Filler
+        // Filler
+
+        return "ChangeMe";
+    }
+}
diff --git a/t/t4018/csharp-method-array b/t/t4018/csharp-method-array
new file mode 100644 (file)
index 0000000..1126de8
--- /dev/null
@@ -0,0 +1,10 @@
+class Example
+{
+    string[] Method(int RIGHT)
+    {
+        // Filler
+        // Filler
+
+        return ["ChangeMe"];
+    }
+}
diff --git a/t/t4018/csharp-method-explicit b/t/t4018/csharp-method-explicit
new file mode 100644 (file)
index 0000000..5a71011
--- /dev/null
@@ -0,0 +1,12 @@
+using System;
+
+class Example : IDisposable
+{
+    void IDisposable.Dispose() // RIGHT
+    {
+        // Filler
+        // Filler
+        
+        // ChangeMe
+    }
+}
diff --git a/t/t4018/csharp-method-generics b/t/t4018/csharp-method-generics
new file mode 100644 (file)
index 0000000..b3216bf
--- /dev/null
@@ -0,0 +1,11 @@
+class Example<T1, T2>
+{
+    Example<int, string> Method<TA, TB>(TA RIGHT, TB b)
+    {
+        // Filler
+        // Filler
+        
+        // ChangeMe
+        return null;
+    }
+}
diff --git a/t/t4018/csharp-method-generics-alternate-spaces b/t/t4018/csharp-method-generics-alternate-spaces
new file mode 100644 (file)
index 0000000..9583621
--- /dev/null
@@ -0,0 +1,11 @@
+class Example<T1, T2>
+{
+    Example<int,string> Method<TA ,TB>(TA RIGHT, TB b)
+    {
+        // Filler
+        // Filler
+        
+        // ChangeMe
+        return null;
+    }
+}
diff --git a/t/t4018/csharp-method-modifiers b/t/t4018/csharp-method-modifiers
new file mode 100644 (file)
index 0000000..caefa8e
--- /dev/null
@@ -0,0 +1,13 @@
+using System.Threading.Tasks;
+
+class Example
+{
+    static internal async Task Method(int RIGHT)
+    {
+        // Filler
+        // Filler
+        
+        // ChangeMe
+        await Task.Delay(1);
+    }
+}
diff --git a/t/t4018/csharp-method-multiline b/t/t4018/csharp-method-multiline
new file mode 100644 (file)
index 0000000..3983ff4
--- /dev/null
@@ -0,0 +1,10 @@
+class Example
+{
+    string Method_RIGHT(
+        int a,
+        int b,
+        int c)
+    {
+        return "ChangeMe";
+    }
+}
diff --git a/t/t4018/csharp-method-params b/t/t4018/csharp-method-params
new file mode 100644 (file)
index 0000000..3f00410
--- /dev/null
@@ -0,0 +1,10 @@
+class Example
+{
+    string Method(int RIGHT, int b, int c = 42)
+    {
+        // Filler
+        // Filler
+        
+        return "ChangeMe";
+    }
+}
diff --git a/t/t4018/csharp-method-special-chars b/t/t4018/csharp-method-special-chars
new file mode 100644 (file)
index 0000000..e6c7bc0
--- /dev/null
@@ -0,0 +1,11 @@
+class @Some_Type
+{
+    @Some_Type @Method_With_Underscore(int RIGHT)
+    {
+        // Filler
+        // Filler
+        
+        // ChangeMe
+        return new @Some_Type();
+    }
+}
diff --git a/t/t4018/csharp-method-with-spacing b/t/t4018/csharp-method-with-spacing
new file mode 100644 (file)
index 0000000..233bb97
--- /dev/null
@@ -0,0 +1,10 @@
+class Example
+{
+       string   Method         ( int   RIGHT )
+    {
+        // Filler
+        // Filler
+
+        return "ChangeMe";
+    }
+}
diff --git a/t/t4018/csharp-property b/t/t4018/csharp-property
new file mode 100644 (file)
index 0000000..e56dfce
--- /dev/null
@@ -0,0 +1,11 @@
+class Example
+{
+    public bool RIGHT
+    {
+        get { return true; }
+        set
+        {
+            // ChangeMe
+        }
+    }
+}
diff --git a/t/t4018/csharp-property-braces-same-line b/t/t4018/csharp-property-braces-same-line
new file mode 100644 (file)
index 0000000..608131d
--- /dev/null
@@ -0,0 +1,10 @@
+class Example
+{
+    public bool RIGHT {
+        get { return true; }
+        set
+        {
+            // ChangeMe
+        }
+    }
+}
index 92ef649c99ef49d1b21688584ad7d3bbbff6b737..82bc76b910ad1ef98d0ca51669de1ca1ca7861ef 100644 (file)
@@ -90,12 +90,48 @@ PATTERNS("cpp",
         "|\\.[0-9][0-9]*([Ee][-+]?[0-9]+)?[fFlL]?"
         "|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->\\*?|\\.\\*|<=>"),
 PATTERNS("csharp",
-        /* Keywords */
-        "!^[ \t]*(do|while|for|if|else|instanceof|new|return|switch|case|throw|catch|using)\n"
-        /* Methods and constructors */
-        "^[ \t]*(((static|public|internal|private|protected|new|virtual|sealed|override|unsafe|async)[ \t]+)*[][<>@.~_[:alnum:]]+[ \t]+[<>@._[:alnum:]]+[ \t]*\\(.*\\))[ \t]*$\n"
-        /* Properties */
-        "^[ \t]*(((static|public|internal|private|protected|new|virtual|sealed|override|unsafe)[ \t]+)*[][<>@.~_[:alnum:]]+[ \t]+[@._[:alnum:]]+)[ \t]*$\n"
+        /*
+         * Jump over reserved keywords which are illegal method names, but which
+         * can be followed by parentheses without special characters in between,
+         * making them look like methods.
+         */
+        "!(^|[ \t]+)" /* Start of line or whitespace. */
+               "(do|while|for|foreach|if|else|new|default|return|switch|case|throw"
+               "|catch|using|lock|fixed)"
+               "([ \t(]+|$)\n" /* Whitespace, "(", or end of line. */
+        /*
+         * Methods/constructors:
+         * The strategy is to identify a minimum of two groups (any combination
+         * of keywords/type/name) before the opening parenthesis, and without
+         * final unexpected characters, normally only used in ordinary statements.
+         */
+        "^[ \t]*" /* Remove leading whitespace. */
+               "(" /* Start chunk header capture. */
+               "(" /* First group. */
+                       "[][[:alnum:]@_.]" /* Name. */
+                       "(<[][[:alnum:]@_, \t<>]+>)?" /* Optional generic parameters. */
+               ")+"
+               "([ \t]+" /* Subsequent groups, prepended with space. */
+                       "([][[:alnum:]@_.](<[][[:alnum:]@_, \t<>]+>)?)+"
+               ")+"
+               "[ \t]*" /* Optional space before parameters start. */
+               "\\(" /* Start of method parameters. */
+               "[^;]*" /* Allow complex parameters, but exclude statements (;). */
+               ")$\n" /* Close chunk header capture. */
+        /*
+         * Properties:
+         * As with methods, expect a minimum of two groups. But, more trivial than
+         * methods, the vast majority of properties long enough to be worth
+         * showing a chunk header for don't include "=:;,()" on the line they are
+         * defined, since they don't have a parameter list.
+         */
+        "^[ \t]*("
+               "([][[:alnum:]@_.](<[][[:alnum:]@_, \t<>]+>)?)+"
+               "([ \t]+"
+                       "([][[:alnum:]@_.](<[][[:alnum:]@_, \t<>]+>)?)+"
+               ")+" /* Up to here, same as methods regex. */
+               "[^;=:,()]*" /* Compared to methods, no parameter list allowed. */
+               ")$\n"
         /* Type definitions */
         "^[ \t]*(((static|public|internal|private|protected|new|unsafe|sealed|abstract|partial)[ \t]+)*(class|enum|interface|struct|record)[ \t]+.*)$\n"
         /* Namespace */