threads / patch / 56261

v5userdiff: improve java hunk header regex

Subject: [PATCH v5] userdiff: improve java hunk header regex

## tl;dr

5 messages between Aug 11, 2021 and Aug 11, 2021. Diffs are folded; open one to read it.

replies: 4people: 2as markdown or json

Tassilo Horn· Aug 11, 2021, 14:53 UTC · lore

Currently, the git diff hunk headers show the wrong method signature if the method has a qualified return type, an array return type, or a generic return type because the regex doesn't allow dots (.), [], or < and > in the return type. Also, type parameter declarations couldn't be matched.

Add several t4018 tests asserting the right hunk headers for different cases:
  - enum constant change
  - change in generic method with bounded type parameters
  - change in generic method with wildcard
  - field change in a nested class
Signed-off-by: Tassilo Horn <tsdh@gnu.org>
---
 t/t4018/java-class-member-function          | 6 +++++-
 t/t4018/java-enum-constant                  | 6 ++++++
 t/t4018/java-method-return-generic-bounded  | 9 +++++++++
 t/t4018/java-method-return-generic-wildcard | 9 +++++++++
 t/t4018/java-nested-field                   | 6 ++++++
 userdiff.c                                  | 6 +++++-
 6 files changed, 40 insertions(+), 2 deletions(-)
 create mode 100644 t/t4018/java-enum-constant
 create mode 100644 t/t4018/java-method-return-generic-bounded
 create mode 100644 t/t4018/java-method-return-generic-wildcard
 create mode 100644 t/t4018/java-nested-field
Show changes to 6 files +40 −2

t/t4018/java-class-member-function, t/t4018/java-enum-constant, t/t4018/java-method-return-generic-bounded, t/t4018/java-method-return-generic-wildcard, t/t4018/java-nested-field, userdiff.c

diff --git a/t/t4018/java-class-member-function b/t/t4018/java-class-member-function
index 298bc7a71b..a8d7850412 100644
--- a/t/t4018/java-class-member-function
+++ b/t/t4018/java-class-member-function
@@ -3,6 +3,10 @@ public class Beer
 	int special;
 	public static void main(String RIGHT[])
 	{
-		System.out.print("ChangeMe");
+            someMethodCall();
+            someOtherMethod("17")
+                .doThat();
+            // Whatever
+            System.out.print("ChangeMe");
 	}
 }
diff --git a/t/t4018/java-enum-constant b/t/t4018/java-enum-constant
new file mode 100644
index 0000000000..a1931c8379
--- /dev/null
+++ b/t/t4018/java-enum-constant
@@ -0,0 +1,6 @@
+private enum RIGHT {
+    ONE,
+    TWO,
+    THREE,
+    ChangeMe
+}
diff --git a/t/t4018/java-method-return-generic-bounded b/t/t4018/java-method-return-generic-bounded
new file mode 100644
index 0000000000..66dd78c379
--- /dev/null
+++ b/t/t4018/java-method-return-generic-bounded
@@ -0,0 +1,9 @@
+class MyExample {
+    public <T extends Bar & Foo<T>, R> Map<T, R[]> foo(String[] RIGHT) {
+        someMethodCall();
+        someOtherMethod()
+            .doThat();
+        // Whatever...
+        return (List<T>) Arrays.asList("ChangeMe");
+    }
+}
diff --git a/t/t4018/java-method-return-generic-wildcard b/t/t4018/java-method-return-generic-wildcard
new file mode 100644
index 0000000000..96e9e5f2c1
--- /dev/null
+++ b/t/t4018/java-method-return-generic-wildcard
@@ -0,0 +1,9 @@
+class MyExample {
+    public List<? extends Comparable> foo(String[] RIGHT) {
+        someMethodCall();
+        someOtherMethod()
+            .doThat();
+        // Whatever...
+        return Arrays.asList("ChangeMe");
+    }
+}
diff --git a/t/t4018/java-nested-field b/t/t4018/java-nested-field
new file mode 100644
index 0000000000..d92d3ec688
--- /dev/null
+++ b/t/t4018/java-nested-field
@@ -0,0 +1,6 @@
+class MyExample {
+    private static class RIGHT {
+        // change an inner class field
+        String inner = "ChangeMe";
+    }
+}
diff --git a/userdiff.c b/userdiff.c
index 3c3bbe38b0..6644931ce1 100644
--- a/userdiff.c
+++ b/userdiff.c
@@ -142,7 +142,11 @@ PATTERNS("html",
 	 "[^<>= \t]+"),
 PATTERNS("java",
 	 "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
-	 "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$",
+         /* Class, enum, and interface declarations */
+         "^[ \t]*(([a-z]+[ \t]+)*(class|enum|interface)[ \t]+[A-Za-z][A-Za-z0-9_$]*[ \t]+.*)$\n"
+         /* Method definitions; note that constructor signatures are not */
+         /* matched because they are indistinguishable from method calls. */
+         "^[ \t]*(([A-Za-z_<>&][][?&<>.,A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$",
 	 /* -- */
 	 "[a-zA-Z_][a-zA-Z0-9_]*"
 	 "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
-- 
2.32.0
Junio C Hamano· Aug 11, 2021, 17:16 UTC · re: Tassilo Horn · lore

Re: [PATCH v5] userdiff: improve java hunk header regex

Just a few whitespace nits that "git am" noticed for me.
Tassilo Horn <tsdh@gnu.org> writes:
Show 14 quoted lines
> diff --git a/t/t4018/java-class-member-function b/t/t4018/java-class-member-function
> index 298bc7a71b..a8d7850412 100644
> --- a/t/t4018/java-class-member-function
> +++ b/t/t4018/java-class-member-function
> @@ -3,6 +3,10 @@ public class Beer
>  	int special;
>  	public static void main(String RIGHT[])
>  	{
> -		System.out.print("ChangeMe");
> +            someMethodCall();
> +            someOtherMethod("17")
> +                .doThat();
> +            // Whatever
> +            System.out.print("ChangeMe");

I notice that the original used HT (horizontal tab) to indent, but the new one uses runs of SP (space). This project has no written preference for coding style for Java, which means it would have been more appreciated if the original style were kept.

Show 12 quoted lines
> diff --git a/t/t4018/java-enum-constant b/t/t4018/java-enum-constant
> new file mode 100644
> index 0000000000..a1931c8379
> --- /dev/null
> +++ b/t/t4018/java-enum-constant
> @@ -0,0 +1,6 @@
> +private enum RIGHT {
> +    ONE,
> +    TWO,
> +    THREE,
> +    ChangeMe
> +}

For these new tests, you'd be the one setting what styles to use ;-) After all, we serve users from projects with different style, and having variety in our test patterns is not bad.

Show 17 quoted lines
> diff --git a/userdiff.c b/userdiff.c
> index 3c3bbe38b0..6644931ce1 100644
> --- a/userdiff.c
> +++ b/userdiff.c
> @@ -142,7 +142,11 @@ PATTERNS("html",
>  	 "[^<>= \t]+"),
>  PATTERNS("java",
>  	 "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
> -	 "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$",
> +         /* Class, enum, and interface declarations */
> +         "^[ \t]*(([a-z]+[ \t]+)*(class|enum|interface)[ \t]+[A-Za-z][A-Za-z0-9_$]*[ \t]+.*)$\n"
> +         /* Method definitions; note that constructor signatures are not */
> +         /* matched because they are indistinguishable from method calls. */
> +         "^[ \t]*(([A-Za-z_<>&][][?&<>.,A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$",
>  	 /* -- */
>  	 "[a-zA-Z_][a-zA-Z0-9_]*"
>  	 "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"

This hunk does violate project convention that our codebase uses leading HT to indent (and align with extra SPs if needed).

Tassilo Horn· Aug 11, 2021, 17:42 UTC · re: Junio C Hamano · lore

Re: [PATCH v5] userdiff: improve java hunk header regex

Junio C Hamano <gitster@pobox.com> writes:
> Just a few whitespace nits that "git am" noticed for me.
Ah, indeed.  Should all be fixed in v6.
Show 19 quoted lines
>> diff --git a/t/t4018/java-class-member-function b/t/t4018/java-class-member-function
>> index 298bc7a71b..a8d7850412 100644
>> --- a/t/t4018/java-class-member-function
>> +++ b/t/t4018/java-class-member-function
>> @@ -3,6 +3,10 @@ public class Beer
>>  	int special;
>>  	public static void main(String RIGHT[])
>>  	{
>> -		System.out.print("ChangeMe");
>> +            someMethodCall();
>> +            someOtherMethod("17")
>> +                .doThat();
>> +            // Whatever
>> +            System.out.print("ChangeMe");
>
> I notice that the original used HT (horizontal tab) to indent, but
> the new one uses runs of SP (space).  This project has no written
> preference for coding style for Java, which means it would have been
> more appreciated if the original style were kept.
Fixed in v6.
Show 16 quoted lines
>> diff --git a/t/t4018/java-enum-constant b/t/t4018/java-enum-constant
>> new file mode 100644
>> index 0000000000..a1931c8379
>> --- /dev/null
>> +++ b/t/t4018/java-enum-constant
>> @@ -0,0 +1,6 @@
>> +private enum RIGHT {
>> +    ONE,
>> +    TWO,
>> +    THREE,
>> +    ChangeMe
>> +}
>
> For these new tests, you'd be the one setting what styles to use ;-)
> After all, we serve users from projects with different style, and
> having variety in our test patterns is not bad.
I completely agree.
Show 20 quoted lines
>> diff --git a/userdiff.c b/userdiff.c
>> index 3c3bbe38b0..6644931ce1 100644
>> --- a/userdiff.c
>> +++ b/userdiff.c
>> @@ -142,7 +142,11 @@ PATTERNS("html",
>>  	 "[^<>= \t]+"),
>>  PATTERNS("java",
>>  	 "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
>> -	 "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$",
>> +         /* Class, enum, and interface declarations */
>> +         "^[ \t]*(([a-z]+[ \t]+)*(class|enum|interface)[ \t]+[A-Za-z][A-Za-z0-9_$]*[ \t]+.*)$\n"
>> +         /* Method definitions; note that constructor signatures are not */
>> +         /* matched because they are indistinguishable from method calls. */
>> +         "^[ \t]*(([A-Za-z_<>&][][?&<>.,A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$",
>>  	 /* -- */
>>  	 "[a-zA-Z_][a-zA-Z0-9_]*"
>>  	 "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
>
> This hunk does violate project convention that our codebase uses
> leading HT to indent (and align with extra SPs if needed).
Also fixed in v6.

That leads to the question if you'd welcome a patch adding a .dir-locals.el to the repository with the right settings so that it'll just work for contributors using the One True Editor. Would you?

Bye, Tassilo

Junio C Hamano· Aug 11, 2021, 18:11 UTC · re: Tassilo Horn · lore

Re: [PATCH v5] userdiff: improve java hunk header regex

Tassilo Horn <tsdh@gnu.org> writes:
> That leads to the question if you'd welcome a patch adding a
> .dir-locals.el to the repository with the right settings so that it'll
> just work for contributors using the One True Editor.  Would you?

If your one true editor honored what is in .editorconfig, perhaps there was no need for us to be having this conversation? I dunno.

Our .gitattributes (the top one and also in subdirectories) try to give reasonable whitespace rules for files, and specifically, files in t/t????/ directories that are used as test vectors completely disable whitespace checking, while everywhere else we insist certain styles in the top-level .gitattributes file.

Thanks.
Tassilo Horn· Aug 11, 2021, 18:55 UTC · re: Junio C Hamano · lore

Re: [PATCH v5] userdiff: improve java hunk header regex

Junio C Hamano <gitster@pobox.com> writes:
Show 7 quoted lines
>> That leads to the question if you'd welcome a patch adding a
>> .dir-locals.el to the repository with the right settings so that
>> it'll just work for contributors using the One True Editor.  Would
>> you?
>
> If your one true editor honored what is in .editorconfig, perhaps
> there was no need for us to be having this conversation?  I dunno.

Ah, I'm sorry, I wasn't aware of that. I've installed the editorconfig Emacs plugin [1] which seems to do the trick.

Bye, Tassilo

[1] https://github.com/editorconfig/editorconfig-emacs

← back to recent threads