runtime(java): Fold multi-line comments with the syntax kind of &fdm (#15016)

Also:

- Restore the capability to mark as an error braces nested
  in parens with g:javaInParen.
- Try not to fold top-level-type bodies.  (Defining multiple
  package-private top level types in a single source file is
  not recommended as it can impose order among compilation
  units; so it is assumed that only one such top level type
  is usually defined.)
- Compose ‘method header’ highlighting and block braces
  folding.
- Do not highlight block braces whenever ‘method header’
  highlighting is requested.

This bundling of ‘method headers’ and block braces for
highlighting can be traced back to Vim v5.0; however, no
comment or documentation entry conveys any justification.
For example, it is hard to discover the connection between
block braces for "while", "if", etc., statements and method
body block braces.  The former behaviour can be attained in,
e.g. ~/.vim/after/syntax/java.vim:

------------------------------------------------------------
if exists("g:java_highlight_functions")
    syn clear javaBlock javaInParen
    syn match javaBlockOther "[{}]"
    syn region javaBlock transparent matchgroup=javaBlockStart
	\ start="\%(^\|^\S[^:]\+\)\@120<!{" end="}" fold
    hi def link javaBlockStart javaFuncDef
    hi def link javaBlockOther javaBlockStart

    if exists("g:java_mark_braces_in_parens_as_errors")
	syn match javaInParen contained "[{}]"
    endif
endif
------------------------------------------------------------

Note: Read ‘a method header omitting a _throws_ clause’ for
every ‘method header’ appellation used above.


Signed-off-by: Aliaksei Budavei <0x000c70@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/syntax/java.vim b/runtime/syntax/java.vim
index 1f71f9e..6f64bdc 100644
--- a/runtime/syntax/java.vim
+++ b/runtime/syntax/java.vim
@@ -3,7 +3,7 @@
 " Maintainer:		Aliaksei Budavei <0x000c70 AT gmail DOT com>
 " Former Maintainer:	Claudio Fleiner <claudio@fleiner.com>
 " Repository:		https://github.com/zzzyxwvut/java-vim.git
-" Last Change:		2024 Jun 10
+" Last Change:		2024 Jun 15
 
 " Please check :help java.vim for comments on some of the options available.
 
@@ -14,7 +14,6 @@
   endif
   " we define it here so that included files can test for it
   let main_syntax='java'
-  syn region javaFold start="{" end="}" transparent fold
 endif
 
 let s:cpo_save = &cpo
@@ -40,6 +39,18 @@
   endfunction
 endif
 
+function! JavaSyntaxFoldTextExpr() abort
+  return getline(v:foldstart) !~ '/\*\+\s*$'
+    \ ? foldtext()
+    \ : printf('+-%s%3d lines: ',
+	  \ v:folddashes,
+	  \ (v:foldend - v:foldstart + 1)) .
+	\ getline(v:foldstart + 1)
+endfunction
+
+" E120 for "fdt=s:JavaSyntaxFoldTextExpr()" before v8.2.3900.
+setlocal foldtext=JavaSyntaxFoldTextExpr()
+
 " Admit the ASCII dollar sign to keyword characters (JLS-17, §3.8):
 try
   exec 'syntax iskeyword ' . &l:iskeyword . ',$'
@@ -99,7 +110,7 @@
 syn match   javaClassDecl	"^class\>"
 syn match   javaClassDecl	"[^.]\s*\<class\>"ms=s+1
 syn match   javaAnnotation	"@\%(\K\k*\.\)*\K\k*\>"
-syn region  javaAnnotation	transparent matchgroup=javaAnnotationStart start=/@\%(\K\k*\.\)*\K\k*(/ end=/)/ skip=/\/\*.\{-}\*\/\|\/\/.*$/ contains=javaAnnotation,javaParenT,javaBraces,javaString,javaBoolean,javaNumber,javaTypedef,javaComment,javaLineComment
+syn region  javaAnnotation	transparent matchgroup=javaAnnotationStart start=/@\%(\K\k*\.\)*\K\k*(/ end=/)/ skip=/\/\*.\{-}\*\/\|\/\/.*$/ contains=javaAnnotation,javaParenT,javaBlock,javaString,javaBoolean,javaNumber,javaTypedef,javaComment,javaLineComment
 syn match   javaClassDecl	"@interface\>"
 syn keyword javaBranch		break continue nextgroup=javaUserLabelRef skipwhite
 syn match   javaUserLabelRef	"\k\+" contained
@@ -238,7 +249,7 @@
   syn cluster javaCommentSpecial2 add=javaComment2String,javaCommentCharacter,javaNumber,javaStrTempl
 endif
 
-syn region  javaComment		matchgroup=javaCommentStart start="/\*" end="\*/" contains=@javaCommentSpecial,javaTodo,javaCommentError,javaSpaceError,@Spell
+syn region  javaComment		 matchgroup=javaCommentStart start="/\*" end="\*/" contains=@javaCommentSpecial,javaTodo,javaCommentError,javaSpaceError,@Spell fold
 syn match   javaCommentStar	 contained "^\s*\*[^/]"me=e-1
 syn match   javaCommentStar	 contained "^\s*\*$"
 syn match   javaLineComment	"//.*" contains=@javaCommentSpecial2,javaTodo,javaCommentMarkupTag,javaSpaceError,@Spell
@@ -269,7 +280,7 @@
     call s:ReportOnce(v:exception)
   endtry
 
-  syn region javaDocComment	start="/\*\*" end="\*/" keepend contains=javaCommentTitle,@javaHtml,javaDocTags,javaDocSeeTag,javaDocCodeTag,javaDocSnippetTag,javaTodo,javaCommentError,javaSpaceError,@Spell
+  syn region javaDocComment	start="/\*\*" end="\*/" keepend contains=javaCommentTitle,@javaHtml,javaDocTags,javaDocSeeTag,javaDocCodeTag,javaDocSnippetTag,javaTodo,javaCommentError,javaSpaceError,@Spell fold
   exec 'syn region javaCommentTitle contained matchgroup=javaDocComment start="/\*\*" matchgroup=javaCommentTitle end="\.$" end="\.[ \t\r]\@=" end="\%(^\s*\**\s*\)\@' . s:ff.Peek('80', '') . '<=@"me=s-2,he=s-1 end="\*/"me=s-1,he=s-1 contains=@javaHtml,javaCommentStar,javaTodo,javaCommentError,javaSpaceError,@Spell,javaDocTags,javaDocSeeTag,javaDocCodeTag,javaDocSnippetTag'
   syn region javaCommentTitle	contained matchgroup=javaDocComment start="/\*\*\s*\r\=\n\=\s*\**\s*\%({@return\>\)\@=" matchgroup=javaCommentTitle end="}\%(\s*\.*\)*" contains=@javaHtml,javaCommentStar,javaTodo,javaCommentError,javaSpaceError,@Spell,javaDocTags,javaDocSeeTag,javaDocCodeTag,javaDocSnippetTag
   syn region javaDocTags	contained start="{@\%(li\%(teral\|nk\%(plain\)\=\)\|inherit[Dd]oc\|doc[rR]oot\|value\)\>" end="}"
@@ -348,8 +359,6 @@
     " Match: [@ɐ] [abstract] [<α, β>] Τʬ[<γ>][[][]] μʭʭ(/* ... */);
     exec 'syn region javaFuncDef start=/' . s:ff.Engine('\%#=2', '') . '^\s\+\%(\%(@\%(\K\k*\.\)*\K\k*\>\)\s\+\)*\%(p\%(ublic\|rotected\|rivate\)\s\+\)\=\%(\%(abstract\|default\)\s\+\|\%(\%(final\|\%(native\|strictfp\)\|s\%(tatic\|ynchronized\)\)\s\+\)*\)\=\%(<.*[[:space:]-]\@' . s:ff.Peek('1', '') . '<!>\s\+\)\=\%(void\|\%(b\%(oolean\|yte\)\|char\|short\|int\|long\|float\|double\|\%(\<\K\k*\>\.\)*\<' . s:ff.UpperCase('[$_[:upper:]]', '[^a-z0-9]') . '\k*\>\%(<[^(){}]*[[:space:]-]\@' . s:ff.Peek('1', '') . '<!>\)\=\)\%(\[\]\)*\)\s\+\<' . s:ff.LowerCase('[$_[:lower:]]', '[^A-Z0-9]') . '\k*\>\s*(/ end=/)/ skip=/\/\*.\{-}\*\/\|\/\/.*$/ contains=@javaFuncParams'
   endif
-
-  syn match javaBraces "[{}]"
 endif
 
 if exists("java_highlight_debug")
@@ -404,14 +413,18 @@
 endif
 
 if exists("java_mark_braces_in_parens_as_errors")
-  syn match javaInParen		 contained "[{}]"
-  hi def link javaInParen	javaError
+  syn match javaInParen contained "[{}]"
+  hi def link javaInParen javaError
 endif
 
+" Try not to fold top-level-type bodies under assumption that there is
+" but one such body.
+exec 'syn region javaBlock transparent start="\%(^\|^\S[^:]\+\)\@' . s:ff.Peek('120', '') . '<!{" end="}" fold'
+
 " catch errors caused by wrong parenthesis
-syn region  javaParenT	transparent matchgroup=javaParen  start="(" end=")" contains=@javaTop,javaParenT1
-syn region  javaParenT1 transparent matchgroup=javaParen1 start="(" end=")" contains=@javaTop,javaParenT2 contained
-syn region  javaParenT2 transparent matchgroup=javaParen2 start="(" end=")" contains=@javaTop,javaParenT  contained
+syn region  javaParenT	transparent matchgroup=javaParen  start="(" end=")" contains=@javaTop,javaInParen,javaParenT1
+syn region  javaParenT1 transparent matchgroup=javaParen1 start="(" end=")" contains=@javaTop,javaInParen,javaParenT2 contained
+syn region  javaParenT2 transparent matchgroup=javaParen2 start="(" end=")" contains=@javaTop,javaInParen,javaParenT contained
 syn match   javaParenError	 ")"
 " catch errors caused by wrong square parenthesis
 syn region  javaParenT	transparent matchgroup=javaParen  start="\[" end="\]" contains=@javaTop,javaParenT1
@@ -445,7 +458,7 @@
 
 " The @javaTop cluster comprises non-contained Java syntax groups.
 " Note that the syntax file "aidl.vim" relies on its availability.
-syn cluster javaTop contains=TOP,javaDocComment,javaFold,javaParenError,javaParenT
+syn cluster javaTop contains=TOP,javaDocComment,javaBlock,javaParenError,javaParenT
 
 if !exists("java_minlines")
   let java_minlines = 10
@@ -463,7 +476,6 @@
 hi def link javaLambdaDef		Function
 hi def link javaFuncDef		Function
 hi def link javaVarArg			Function
-hi def link javaBraces			Function
 hi def link javaBranch			Conditional
 hi def link javaUserLabelRef		javaUserLabel
 hi def link javaLabel			Label
@@ -533,4 +545,20 @@
 let &cpo = s:cpo_save
 unlet s:module_info_cur_buf s:ff s:cpo_save
 
+" See ":help vim9-mix".
+if !has("vim9script")
+  finish
+endif
+
+def! s:JavaSyntaxFoldTextExpr(): string
+  return getline(v:foldstart) !~ '/\*\+\s*$'
+    ? foldtext()
+    : printf('+-%s%3d lines: ',
+	  v:folddashes,
+	  (v:foldend - v:foldstart + 1)) ..
+	getline(v:foldstart + 1)
+enddef
+
+setlocal foldtext=s:JavaSyntaxFoldTextExpr()
+delfunction! g:JavaSyntaxFoldTextExpr
 " vim: sw=2 ts=8 noet sta