diff mbox series

[v5] userdiff: improve java hunk header regex

Message ID 20210811145341.43429-1-tsdh@gnu.org (mailing list archive)
State Superseded
Headers show
Series [v5] userdiff: improve java hunk header regex | expand

Commit Message

Tassilo Horn Aug. 11, 2021, 2:53 p.m. UTC
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

Comments

Junio C Hamano Aug. 11, 2021, 5:16 p.m. UTC | #1
Just a few whitespace nits that "git am" noticed for me.

Tassilo Horn <tsdh@gnu.org> writes:

> 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.

> 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.

> 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, 5:42 p.m. UTC | #2
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.

>> 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.

>> 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.

>> 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, 6:11 p.m. UTC | #3
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, 6:55 p.m. UTC | #4
Junio C Hamano <gitster@pobox.com> 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.

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
diff mbox series

Patch

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]?"