runtime(java): Improve the matching of contextual keywords

Commit: 
https://github.com/vim/vim/commit/5ccdcc482e299609ae8852a75b22190e38b9b5df
Author: Aliaksei Budavei <0x000...@gmail.com>
Date:   Thu Apr 4 21:51:18 2024 +0200

    runtime(java): Improve the matching of contextual keywords
    
    - Recognise a _record_ contextual keyword.
    - Recognise _non-sealed_, _sealed_, and _permits_ contextual
      keywords.
    - Admit _$_ to keyword characters.
    - Group _abstract_, _final_, _default_, _(non-)sealed_
      (apart from _(non-)sealed_, the incompossibility of these
      modifiers calls for attention).
    - Remove another _synchronized_ keyword redefinition.
    
    I have also replaced a function with an expression.  Before
    patch 8.1.0515, it should have been declared :function! to
    work with repeatable script sourcing; there is less to worry
    about with an expression.
    
    References:
    https://openjdk.org/jeps/395 (Records)
    https://openjdk.org/jeps/409 (Sealed Classes)
    https://docs.oracle.com/javase/specs/jls/se21/html/jls-3.html#jls-3.8
    
    closes: #14403
    
    Signed-off-by: Aliaksei Budavei <0x000...@gmail.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/syntax/java.vim b/runtime/syntax/java.vim
index 1f0c15803..22fc934a0 100644
--- a/runtime/syntax/java.vim
+++ b/runtime/syntax/java.vim
@@ -2,7 +2,7 @@
 " Language:    Java
 " Maintainer:  Claudio Fleiner <clau...@fleiner.com>
 " URL:          
https://github.com/fleiner/vim/blob/master/runtime/syntax/java.vim
-" Last Change: 2024 Mar 25
+" Last Change: 2024 Apr 04
 
 " Please check :help java.vim for comments on some of the options available.
 
@@ -19,6 +19,9 @@ endif
 let s:cpo_save = &cpo
 set cpo&vim
 
+" Admit the ASCII dollar sign to keyword characters (JLS-17, §3.8):
+execute printf('syntax iskeyword %s,$', &l:iskeyword)
+
 " some characters that cannot be in a java program (outside a string)
 syn match javaError "[\@`]"
 syn match javaError "<<<\|\.\.\|=>\|||=\|&&=\|\*\/"
@@ -27,16 +30,17 @@ syn match javaError "<<<\|\.\.\|=>\|||=\|&&=\|\*\/"
 syn match   javaError2 "#\|=<"
 hi def link javaError2 javaError
 
-" keyword definitions
+" Keywords (JLS-17, §3.9):
 syn keyword javaExternal       native package
-syn match javaExternal         "\<import\>\(\s\+static\>\)\?"
+syn match   javaExternal       "\<import\>\%(\s\+static\>\)\="
 syn keyword javaError          goto const
 syn keyword javaConditional    if else switch
 syn keyword javaRepeat         while for do
 syn keyword javaBoolean                true false
 syn keyword javaConstant       null
 syn keyword javaTypedef                this super
-syn keyword javaOperator       var new instanceof
+syn keyword javaOperator       new instanceof
+syn match   javaOperator       "\<var\>\%(\s*(\)\@!"
 " Since the yield statement, which could take a parenthesised operand,
 " and _qualified_ yield methods get along within the switch block
 " (JLS-17, §3.8), it seems futile to make a region definition for this
@@ -48,14 +52,15 @@ syn match   javaOperator    "\%(\%(::\|\.\)[[:space:]
]*\)\@80<!\<yield\>"
 syn keyword javaType           boolean char byte short int long float double
 syn keyword javaType           void
 syn keyword javaStatement      return
-syn keyword javaStorageClass   static synchronized transient volatile final 
strictfp serializable
+syn keyword javaStorageClass   static synchronized transient volatile strictfp 
serializable
 syn keyword javaExceptions     throw try catch finally
 syn keyword javaAssert         assert
-syn keyword javaMethodDecl     synchronized throws
-syn keyword javaClassDecl      extends implements interface
-" to differentiate the keyword class from MyClass.class we use a match here
+syn keyword javaMethodDecl     throws
+" Differentiate a "MyClass.class" literal from the keyword "class".
 syn match   javaTypedef                "\.\s*\<class\>"ms=s+1
-syn keyword javaClassDecl      enum
+syn keyword javaClassDecl      enum extends implements interface
+syn match   javaClassDecl      "\<permits\>\%(\s*(\)\@!"
+syn match   javaClassDecl      "\<record\>\%(\s*(\)\@!"
 syn match   javaClassDecl      "^class\>"
 syn match   javaClassDecl      "[^.]\s*\<class\>"ms=s+1
 syn match   javaAnnotation     
"@\([_$a-zA-Z][_$a-zA-Z0-9]*\.\)*[_$a-zA-Z][_$a-zA-Z0-9]*\>" contains=javaString
@@ -63,19 +68,27 @@ syn match   javaClassDecl   "@interface\>"
 syn keyword javaBranch         break continue nextgroup=javaUserLabelRef 
skipwhite
 syn match   javaUserLabelRef   "\k\+" contained
 syn match   javaVarArg         "\.\.\."
-syn keyword javaScopeDecl      public protected private abstract
+syn keyword javaScopeDecl      public protected private
+syn keyword javaConceptKind    abstract final
+syn match   javaConceptKind    "\<non-sealed\>"
+syn match   javaConceptKind    "\<sealed\>\%(\s*(\)\@!"
 syn match   javaConceptKind    "\<default\>\%(\s*\%(:\|->\)\)\@!"
 
-function s:isModuleInfoDeclarationCurrentBuffer() abort
-    return fnamemodify(bufname("%"), ":t") =~ '^module-info\%(\.class\>\)\@!'
-endfunction
-
-" Java Modules(Since Java 9, for "module-info.java" file)
-if s:isModuleInfoDeclarationCurrentBuffer()
-    syn keyword javaModuleStorageClass module transitive
-    syn keyword javaModuleStmt         open requires exports opens uses 
provides
-    syn keyword javaModuleExternal     to with
-    syn cluster javaTop 
add=javaModuleStorageClass,javaModuleStmt,javaModuleExternal
+" Note that a "module-info" file will be recognised with an arbitrary
+" file extension (or no extension at all) so that more than one such
+" declaration for the same Java module can be maintained for modular
+" testing in a project without attendant confusion for IDEs, with the
+" ".java\=" extension used for a production version and an arbitrary
+" extension used for a testing version.
+let s:module_info_cur_buf = fnamemodify(bufname("%"), ":t") =~ 
'^module-info\%(\.class\>\)\@!'
+lockvar s:module_info_cur_buf
+
+" Java modules (since Java 9, for "module-info.java" file).
+if s:module_info_cur_buf
+  syn keyword javaModuleStorageClass   module transitive
+  syn keyword javaModuleStmt           open requires exports opens uses 
provides
+  syn keyword javaModuleExternal       to with
+  syn cluster javaTop 
add=javaModuleStorageClass,javaModuleStmt,javaModuleExternal
 endif
 
 if exists("java_highlight_java_lang_ids")
@@ -111,7 +124,7 @@ if exists("java_highlight_all")  || 
exists("java_highlight_java")  || exists("ja
   syn match   javaC_JavaLang "\%(\<Enum\.\)\@<=\<EnumDesc\>"
   syn keyword javaC_JavaLang Boolean Character Class ClassLoader Compiler 
Double Float Integer Long Math Number Object Process Runtime SecurityManager 
String StringBuffer Thread ThreadGroup Byte Short Void InheritableThreadLocal 
Package RuntimePermission ThreadLocal StrictMath StackTraceElement Enum 
ProcessBuilder StringBuilder ClassValue Module ModuleLayer StackWalker Record
   syn match   javaC_JavaLang "\<System\>"      " See javaDebug.
-  " As of Java 21, java.lang.Compiler is no more (deprecated in Java 9).
+  " As of JDK 21, java.lang.Compiler is no more (deprecated in JDK 9).
   syn keyword javaLangDeprecated Compiler
   syn cluster javaTop add=javaC_JavaLang
   syn cluster javaClasses add=javaC_JavaLang
@@ -275,17 +288,17 @@ syn cluster javaTop 
add=javaString,javaStrTempl,javaCharacter,javaNumber,javaSpe
 
 if exists("java_highlight_functions")
   if java_highlight_functions == "indent"
-    syn match  javaFuncDef "^\(        \| \{8\}\)[_$a-zA-Z][_$a-zA-Z0-9_. 
\[\]<>]*([^-+*/]*)" 
contains=javaScopeDecl,javaType,javaStorageClass,@javaClasses,javaAnnotation
-    syn region javaFuncDef start=+^\(  \| \{8\}\)[$_a-zA-Z][$_a-zA-Z0-9_. 
\[\]<>]*([^-+*/]*,\s*+ end=+)+ 
contains=javaScopeDecl,javaType,javaStorageClass,@javaClasses,javaAnnotation
-    syn match  javaFuncDef "^  [$_a-zA-Z][$_a-zA-Z0-9_. \[\]<>]*([^-+*/]*)" 
contains=javaScopeDecl,javaType,javaStorageClass,@javaClasses,javaAnnotation
-    syn region javaFuncDef start=+^  [$_a-zA-Z][$_a-zA-Z0-9_. 
\[\]<>]*([^-+*/]*,\s*+ end=+)+ 
contains=javaScopeDecl,javaType,javaStorageClass,@javaClasses,javaAnnotation
+    syn match  javaFuncDef "^\(        \| \{8\}\)[_$a-zA-Z][_$a-zA-Z0-9_. 
\[\]<>]*([^-+*/]*)" 
contains=javaScopeDecl,javaConceptKind,javaType,javaStorageClass,@javaClasses,javaAnnotation
+    syn region javaFuncDef start=+^\(  \| \{8\}\)[$_a-zA-Z][$_a-zA-Z0-9_. 
\[\]<>]*([^-+*/]*,\s*+ end=+)+ 
contains=javaScopeDecl,javaConceptKind,javaType,javaStorageClass,@javaClasses,javaAnnotation
+    syn match  javaFuncDef "^  [$_a-zA-Z][$_a-zA-Z0-9_. \[\]<>]*([^-+*/]*)" 
contains=javaScopeDecl,javaConceptKind,javaType,javaStorageClass,@javaClasses,javaAnnotation
+    syn region javaFuncDef start=+^  [$_a-zA-Z][$_a-zA-Z0-9_. 
\[\]<>]*([^-+*/]*,\s*+ end=+)+ 
contains=javaScopeDecl,javaConceptKind,javaType,javaStorageClass,@javaClasses,javaAnnotation
   else
     " This line catches method declarations at any indentation>0, but it 
assumes
     " two things:
     "  1. class names are always capitalized (ie: Button)
     "  2. method names are never capitalized (except constructors, of course)
     "syn region javaFuncDef 
start=+^\s\+\(\(public\|protected\|private\|static\|abstract\|final\|native\|synchronized\)\s\+\)*\(\(void\|boolean\|char\|byte\|short\|int\|long\|float\|double\|\([A-Za-z_][A-Za-z0-9_$]*\.\)*[A-Z][A-Za-z0-9_$]*\)\(<[^>]*>\)\=\(\[\]\)*\s\+[a-z][A-Za-z0-9_$]*\|[A-Z][A-Za-z0-9_$]*\)\s*([^0-9]+
 end=+)+ 
contains=javaScopeDecl,javaType,javaStorageClass,javaComment,javaLineComment,@javaClasses
-    syn region javaFuncDef 
start=+^\s\+\%(\%(public\|protected\|private\|static\|\%(abstract\|default\)\|final\|native\|synchronized\)\s\+\)*\%(<.*>\s\+\)\?\%(\%(void\|boolean\|char\|byte\|short\|int\|long\|float\|double\|\%([A-Za-z_][A-Za-z0-9_$]*\.\)*[A-Z][A-Za-z0-9_$]*\)\%(<[^(){}]*>\)\=\%(\[\]\)*\s\+[a-z][A-Za-z0-9_$]*\|[A-Z][A-Za-z0-9_$]*\)\s*(+
 end=+)+ 
contains=javaScopeDecl,javaType,javaStorageClass,javaComment,javaLineComment,@javaClasses,javaAnnotation
+    syn region javaFuncDef 
start=+^\s\+\%(\%(public\|protected\|private\|static\|\%(abstract\|default\)\|final\|native\|synchronized\)\s\+\)*\%(<.*>\s\+\)\?\%(\%(void\|boolean\|char\|byte\|short\|int\|long\|float\|double\|\%([A-Za-z_][A-Za-z0-9_$]*\.\)*[A-Z][A-Za-z0-9_$]*\)\%(<[^(){}]*>\)\=\%(\[\]\)*\s\+[a-z][A-Za-z0-9_$]*\|[A-Z][A-Za-z0-9_$]*\)\s*(+
 end=+)+ 
contains=javaScopeDecl,javaConceptKind,javaType,javaStorageClass,javaComment,javaLineComment,@javaClasses,javaAnnotation
   endif
   syn match   javaLambdaDef "\<\K\k*\>\%(\<default\>\)\@<!\s*->"
   syn match  javaBraces  "[{}]"
@@ -440,10 +453,10 @@ hi def link htmlArg                       Type
 hi def link htmlString                 String
 hi def link javaSpaceError             Error
 
-if s:isModuleInfoDeclarationCurrentBuffer()
-    hi def link javaModuleStorageClass StorageClass
-    hi def link javaModuleStmt         Statement
-    hi def link javaModuleExternal     Include
+if s:module_info_cur_buf
+  hi def link javaModuleStorageClass   StorageClass
+  hi def link javaModuleStmt           Statement
+  hi def link javaModuleExternal       Include
 endif
 
 let b:current_syntax = "java"
@@ -452,9 +465,8 @@ if main_syntax == 'java'
   unlet main_syntax
 endif
 
-delfunction! s:isModuleInfoDeclarationCurrentBuffer
-let b:spell_options="contained"
+let b:spell_options = "contained"
 let &cpo = s:cpo_save
-unlet s:cpo_save
+unlet s:module_info_cur_buf s:cpo_save
 
 " vim: ts=8
diff --git a/runtime/syntax/testdir/dumps/java_contextual_keywords_00.dump 
b/runtime/syntax/testdir/dumps/java_contextual_keywords_00.dump
new file mode 100644
index 000000000..fdd8173e5
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_contextual_keywords_00.dump
@@ -0,0 +1,20 @@
+>c+0#00e0003#ffffff0|l|a|s@1| 
+0#0000000&|C|o|n|t|e|x|t|u|a|l|K|e|y|w|o|r|d|s|T|e|s|t|s| @6|/+0#0000e05&@1| 
|S|e@1| |J|L|S|,| |§|3|.|9| |K|e|y|w|o|r|d|s|.| +0#0000000&@12
+|{| @73
+@4|p+0#00e0003&|r|i|v|a|t|e| 
+0#0000000&|C|o|n|t|e|x|t|u|a|l|K|e|y|w|o|r|d|s|T|e|s|t|s|(|)| |{| 
|t+0#af5f00255&|h|r|o|w| +0#0000000&|n+0#af5f00255&|e|w| 
+0#0000000&|E|r@1|o|r|(|)|;| |}| @14
+@75
+@4|/+0#0000e05&@1| |M|o|d|u|l|e|D|e|c|l|a|r|a|t|i|o|n|:| |m|o|d|u|l|e| 
|o|p|e|n|.| +0#0000000&@36
+@4|v+0#00e0003&|o|i|d| +0#0000000&|m|o|d|u|l|e|(|)| @2|{| |O|b|j|e|c|t| 
|m|o|d|u|l|e| |=| |n+0#e000002&|u|l@1|;+0#0000000&| @4|w|h|e|n|(|)|;| |}| @17
+@4|v+0#00e0003&|o|i|d| +0#0000000&|o|p|e|n|(|)| |{| |O|b|j|e|c|t| |o|p|e|n| 
|=| |n+0#e000002&|u|l@1|;+0#0000000&| @6|m|o|d|u|l|e|(|)|;| |}| @19
+@4|/+0#0000e05&@1| |M|o|d|u|l|e|D|i|r|e|c|t|i|v|e|:| |e|x|p|o|r|t|s| 
|o|p|e|n|s| |p|r|o|v|i|d|e|s| |r|e|q|u|i|r|e|s| |t|o| |u|s|e|s| |w|i|t|h|.| 
+0#0000000&@5
+@4|v+0#00e0003&|o|i|d| +0#0000000&|e|x|p|o|r|t|s|(|)| @1|{| |O|b|j|e|c|t| 
|e|x|p|o|r|t|s| |=| |n+0#e000002&|u|l@1|;+0#0000000&| @3|o|p|e|n|(|)|;| |}| @17
+@4|v+0#00e0003&|o|i|d| +0#0000000&|o|p|e|n|s|(|)| @3|{| |O|b|j|e|c|t| 
|o|p|e|n|s| |=| |n+0#e000002&|u|l@1|;+0#0000000&| @5|e|x|p|o|r|t|s|(|)|;| |}| 
@14
+@4|v+0#00e0003&|o|i|d| +0#0000000&|p|r|o|v|i|d|e|s|(|)| |{| |O|b|j|e|c|t| 
|p|r|o|v|i|d|e|s| |=| |n+0#e000002&|u|l@1|;+0#0000000&| @2|o|p|e|n|s|(|)|;| |}| 
@16
+@4|v+0#00e0003&|o|i|d| +0#0000000&|r|e|q|u|i|r|e|s|(|)| |{| |O|b|j|e|c|t| 
|r|e|q|u|i|r|e|s| |=| |n+0#e000002&|u|l@1|;+0#0000000&| 
@2|p|r|o|v|i|d|e|s|(|)|;| |}| @13
+@4|v+0#00e0003&|o|i|d| +0#0000000&|t|o|(|)| @2|{| |O|b|j|e|c|t| |t|o| |=| 
|n+0#e000002&|u|l@1|;+0#0000000&| @4|r|e|q|u|i|r|e|s|(|)|;| |}| @21
+@4|v+0#00e0003&|o|i|d| +0#0000000&|u|s|e|s|(|)| |{| |O|b|j|e|c|t| |u|s|e|s| 
|=| |n+0#e000002&|u|l@1|;+0#0000000&| @6|t|o|(|)|;| |}| @23
+@4|v+0#00e0003&|o|i|d| +0#0000000&|w|i|t|h|(|)| |{| |O|b|j|e|c|t| |w|i|t|h| 
|=| |n+0#e000002&|u|l@1|;+0#0000000&| @6|u|s|e|s|(|)|;| |}| @21
+@4|/+0#0000e05&@1| |R|e|q|u|i|r|e|s|M|o|d|i|f|i|e|r|:| |t|r|a|n|s|i|t|i|v|e|.| 
+0#0000000&@38
+@4|v+0#00e0003&|o|i|d| +0#0000000&|t|r|a|n|s|i|t|i|v|e|(|)| |{| |O|b|j|e|c|t| 
|t|r|a|n|s|i|t|i|v|e| |=| |n+0#e000002&|u|l@1|;+0#0000000&| @2|w|i|t|h|(|)|;| 
|}| @13
+@4|/+0#0000e05&@1| |L|o|c|a|l|V|a|r|i|a|b|l|e|T|y|p|e| ||| 
|L|a|m|b|d|a|P|a|r|a|m|e|t|e|r|T|y|p|e|:| |v|a|r|.| +0#0000000&@22
+@4|v+0#00e0003&|o|i|d| +0#0000000&|v|a|r|(|)| @1|{| |v+0#af5f00255&|a|r| 
+0#0000000&|v+0#af5f00255&|a|r| +0#0000000&|=| |n+0#af5f00255&|e|w| 
+0#0000000&|O|b|j|e|c|t|(|)|;| @2|t|r|a|n|s|i|t|i|v|e|(|)|;| |}| @15
+@57|1|,|1| @10|T|o|p| 
diff --git a/runtime/syntax/testdir/dumps/java_contextual_keywords_01.dump 
b/runtime/syntax/testdir/dumps/java_contextual_keywords_01.dump
new file mode 100644
index 000000000..5350984ca
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_contextual_keywords_01.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@3|v+0#00e0003&|o|i|d| +0#0000000&|u|s|e|s|(|)| |{| |O|b|j|e|c|t| 
|u|s|e|s| |=| |n+0#e000002&|u|l@1|;+0#0000000&| @6|t|o|(|)|;| |}| @23
+@4|v+0#00e0003&|o|i|d| +0#0000000&|w|i|t|h|(|)| |{| |O|b|j|e|c|t| |w|i|t|h| 
|=| |n+0#e000002&|u|l@1|;+0#0000000&| @6|u|s|e|s|(|)|;| |}| @21
+@4|/+0#0000e05&@1| |R|e|q|u|i|r|e|s|M|o|d|i|f|i|e|r|:| |t|r|a|n|s|i|t|i|v|e|.| 
+0#0000000&@38
+@4|v+0#00e0003&|o|i|d| +0#0000000&|t|r|a|n|s|i|t|i|v|e|(|)| |{| |O|b|j|e|c|t| 
|t|r|a|n|s|i|t|i|v|e| |=| |n+0#e000002&|u|l@1|;+0#0000000&| @2|w|i|t|h|(|)|;| 
|}| @13
+@4|/+0#0000e05&@1| |L|o|c|a|l|V|a|r|i|a|b|l|e|T|y|p|e| ||| 
|L|a|m|b|d|a|P|a|r|a|m|e|t|e|r|T|y|p|e|:| |v|a|r|.| +0#0000000&@22
+@4>v+0#00e0003&|o|i|d| +0#0000000&|v|a|r|(|)| @1|{| |v+0#af5f00255&|a|r| 
+0#0000000&|v+0#af5f00255&|a|r| +0#0000000&|=| |n+0#af5f00255&|e|w| 
+0#0000000&|O|b|j|e|c|t|(|)|;| @2|t|r|a|n|s|i|t|i|v|e|(|)|;| |}| @15
+@4|/+0#0000e05&@1| |Y|i|e|l|d|S|t|a|t|e|m|e|n|t|:| |y|i|e|l|d| |(|s|e@1| 
|j|a|v|a|_|s|w|i|t|c|h|.|j|a|v|a|)|.| +0#0000000&@22
+@4|v+0#00e0003&|o|i|d| +0#0000000&|y+0#af5f00255&|i|e|l|d|(+0#0000000&|)| 
@3|{| |O|b|j|e|c|t| |y+0#af5f00255&|i|e|l|d| +0#0000000&|=| 
|n+0#e000002&|u|l@1|;+0#0000000&| @5|v|a|r|(|)|;| |}| @18
+@4|/+0#0000e05&@1| |R|e|c|o|r|d|D|e|c|l|a|r|a|t|i|o|n|:| |r|e|c|o|r|d|.| 
+0#0000000&@41
+@4|v+0#00e0003&|o|i|d| +0#0000000&|r|e|c|o|r|d|(|)| @2|{| |O|b|j|e|c|t| 
|r+0#00e0003&|e|c|o|r|d| +0#0000000&|=| |n+0#e000002&|u|l@1|;+0#0000000&| 
@4|t+0#00e0003&|h|i|s|.+0#0000000&|y|i|e|l|d|(|)|;| |}| @11
+@4|/+0#0000e05&@1| 
|N|o|r|m|a|l|{|C|l|a|s@1|,|I|n|t|e|r|f|a|c|e|}|D|e|c|l|a|r|a|t|i|o|n|:| 
|n|o|n|-|s|e|a|l|e|d| |p|e|r|m|i|t|s| |s|e|a|l|e|d|.| +0#0000000&@5
+@4|v+0#00e0003&|o|i|d| +0#0000000&|p|e|r|m|i|t|s|(|)| @1|{| |O|b|j|e|c|t| 
|p+0#00e0003&|e|r|m|i|t|s| +0#0000000&|=| |n+0#e000002&|u|l@1|;+0#0000000&| 
@3|r|e|c|o|r|d|(|)|;| |}| @15
+@4|v+0#00e0003&|o|i|d| +0#0000000&|s|e|a|l|e|d|(|)| @2|{| |O|b|j|e|c|t| 
|s+0#4040ff13&|e|a|l|e|d| +0#0000000&|=| |n+0#e000002&|u|l@1|;+0#0000000&| 
@4|p|e|r|m|i|t|s|(|)|;| |}| @14
+@4|/+0#0000e05&@1| |G|u|a|r|d|:| |w|h|e|n| |(|s|e@1| 
|j|a|v|a|_|s|w|i|t|c|h|.|j|a|v|a|)|.| +0#0000000&@32
+@4|v+0#00e0003&|o|i|d| +0#0000000&|w|h|e|n|(|)| |{| |O|b|j|e|c|t| |w|h|e|n| 
|=| |n+0#e000002&|u|l@1|;+0#0000000&| @6|s|e|a|l|e|d|(|)|;| |}| @19
+@75
+@4|s+0#4040ff13&|e|a|l|e|d| +0#0000000&|i+0#00e0003&|n|t|e|r|f|a|c|e| 
+0#0000000&|I|1| |p+0#00e0003&|e|r|m|i|t|s| +0#0000000&|C|1|,| |I|3| |{| |}| @32
+@4|s+0#4040ff13&|e|a|l|e|d| +0#0000000&|i+0#00e0003&|n|t|e|r|f|a|c|e| 
+0#0000000&|I|2| |p+0#00e0003&|e|r|m|i|t|s| +0#0000000&|C|1|,| |I|3| |{| |}| @32
+@4|n+0#4040ff13&|o|n|-|s|e|a|l|e|d| +0#0000000&|i+0#00e0003&|n|t|e|r|f|a|c|e| 
+0#0000000&|I|3| |e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|I|1|,| |I|2| |{| |}| @28
+@57|1|9|,|2|-|5| @7|4@1|%| 
diff --git a/runtime/syntax/testdir/dumps/java_contextual_keywords_02.dump 
b/runtime/syntax/testdir/dumps/java_contextual_keywords_02.dump
new file mode 100644
index 000000000..1e0c36391
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_contextual_keywords_02.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@3|n+0#4040ff13&|o|n|-|s|e|a|l|e|d| 
+0#0000000&|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|I|3| 
|e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|I|1|,| |I|2| |{| |}| @28
+@4|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|I|4| |e+0#00e0003&|x|t|e|n|d|s| 
+0#0000000&|I|3| |{| |}| @43
+@75
+@4|a+0#4040ff13&|b|s|t|r|a|c|t| +0#0000000&|s+0#4040ff13&|e|a|l|e|d| 
+0#0000000&|c+0#00e0003&|l|a|s@1| +0#0000000&|C|1| 
|i+0#00e0003&|m|p|l|e|m|e|n|t|s| +0#0000000&|I|1|,| |I|2| 
|p+0#00e0003&|e|r|m|i|t|s| +0#0000000&|C|2|,| |C|3| |{| |}| @9
+@4|a+0#4040ff13&|b|s|t|r|a|c|t| +0#0000000&|n+0#4040ff13&|o|n|-|s|e|a|l|e|d| 
+0#0000000&|c+0#00e0003&|l|a|s@1| +0#0000000&|C|2| |e+0#00e0003&|x|t|e|n|d|s| 
+0#0000000&|C|1| |{| |}| @27
+@4>f+0#4040ff13&|i|n|a|l| +0#0000000&|c+0#00e0003&|l|a|s@1| +0#0000000&|C|3| 
|e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|C|1| |i+0#00e0003&|m|p|l|e|m|e|n|t|s| 
+0#0000000&|I|3| |{| |}| @27
+@4|c+0#00e0003&|l|a|s@1| +0#0000000&|C|4| |e+0#00e0003&|x|t|e|n|d|s| 
+0#0000000&|C|2| |{| |}| @47
+@75
+@4|r+0#00e0003&|e|c|o|r|d| +0#0000000&|R|(|)| |i+0#00e0003&|m|p|l|e|m|e|n|t|s| 
+0#0000000&|I|3| |{| |}| @42
+@4|e+0#00e0003&|n|u|m| +0#0000000&|E| |i+0#00e0003&|m|p|l|e|m|e|n|t|s| 
+0#0000000&|I|3| |{| |I|N|S|T|A|N|C|E| |}| @37
+@75
+@4|s+0#00e0003&|t|a|t|i|c| +0#0000000&|<|T|>| |I|<|T|>| |i|1|(|)| |{| 
|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|v+0#af5f00255&|a|r| 
+0#0000000&|v+0#af5f00255&|a|r|)+0#0000000&| |-|>| 
|v+0#af5f00255&|a|r|;+0#0000000&| |}| @21
+@4|s+0#00e0003&|t|a|t|i|c| +0#0000000&|<|T|>| |I|<|T|>| |i|2|(|)| |{| 
|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|T| |v+0#af5f00255&|a|r|)+0#0000000&| 
|-|>| |v+0#af5f00255&|a|r|;+0#0000000&| |}| @23
+@4|s+0#00e0003&|t|a|t|i|c| +0#0000000&|<|T|>| |I|<|T|>| |i|3|(|)| |{| 
|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|v+0#af5f00255&|a|r|)+0#0000000&| |-|>| 
|v+0#af5f00255&|a|r|;+0#0000000&| |}| @25
+@4|s+0#00e0003&|t|a|t|i|c| +0#0000000&|<|T|>| |I|<|T|>| |i|4|(|)| |{| 
|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|v+0#af5f00255&|a|r| +0#0000000&|-|>| 
|v+0#af5f00255&|a|r|;+0#0000000&| |}| @27
+@4|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|I|<|T|>| |{| |T| |i|(|T| |i|)|;| 
|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|I|<|T|>| |s|e|l|f|(|)| |{| 
|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|t+0#00e0003&|h|i|s|;+0#0000000&| |}| |}| 
@5
+|}| @73
+|~+0#4040ff13&| @73
+|~| @73
+| +0#0000000&@56|3|7|,|2|-|5| @7|B|o|t| 
diff --git a/runtime/syntax/testdir/dumps/java_contextual_keywords_99.dump 
b/runtime/syntax/testdir/dumps/java_contextual_keywords_99.dump
new file mode 100644
index 000000000..b429c8192
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_contextual_keywords_99.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@3|s+0#4040ff13&|e|a|l|e|d| 
+0#0000000&|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|I|1| 
|p+0#00e0003&|e|r|m|i|t|s| +0#0000000&|C|1|,| |I|3| |{| |}| @32
+@4|s+0#4040ff13&|e|a|l|e|d| +0#0000000&|i+0#00e0003&|n|t|e|r|f|a|c|e| 
+0#0000000&|I|2| |p+0#00e0003&|e|r|m|i|t|s| +0#0000000&|C|1|,| |I|3| |{| |}| @32
+@4|n+0#4040ff13&|o|n|-|s|e|a|l|e|d| +0#0000000&|i+0#00e0003&|n|t|e|r|f|a|c|e| 
+0#0000000&|I|3| |e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|I|1|,| |I|2| |{| |}| @28
+@4|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|I|4| |e+0#00e0003&|x|t|e|n|d|s| 
+0#0000000&|I|3| |{| |}| @43
+@75
+@4|a+0#4040ff13&|b|s|t|r|a|c|t| +0#0000000&|s+0#4040ff13&|e|a|l|e|d| 
+0#0000000&|c+0#00e0003&|l|a|s@1| +0#0000000&|C|1| 
|i+0#00e0003&|m|p|l|e|m|e|n|t|s| +0#0000000&|I|1|,| |I|2| 
|p+0#00e0003&|e|r|m|i|t|s| +0#0000000&|C|2|,| |C|3| |{| |}| @9
+@4|a+0#4040ff13&|b|s|t|r|a|c|t| +0#0000000&|n+0#4040ff13&|o|n|-|s|e|a|l|e|d| 
+0#0000000&|c+0#00e0003&|l|a|s@1| +0#0000000&|C|2| |e+0#00e0003&|x|t|e|n|d|s| 
+0#0000000&|C|1| |{| |}| @27
+@4|f+0#4040ff13&|i|n|a|l| +0#0000000&|c+0#00e0003&|l|a|s@1| +0#0000000&|C|3| 
|e+0#00e0003&|x|t|e|n|d|s| +0#0000000&|C|1| |i+0#00e0003&|m|p|l|e|m|e|n|t|s| 
+0#0000000&|I|3| |{| |}| @27
+@4|c+0#00e0003&|l|a|s@1| +0#0000000&|C|4| |e+0#00e0003&|x|t|e|n|d|s| 
+0#0000000&|C|2| |{| |}| @47
+@75
+@4|r+0#00e0003&|e|c|o|r|d| +0#0000000&|R|(|)| |i+0#00e0003&|m|p|l|e|m|e|n|t|s| 
+0#0000000&|I|3| |{| |}| @42
+@4|e+0#00e0003&|n|u|m| +0#0000000&|E| |i+0#00e0003&|m|p|l|e|m|e|n|t|s| 
+0#0000000&|I|3| |{| |I|N|S|T|A|N|C|E| |}| @37
+@75
+@4|s+0#00e0003&|t|a|t|i|c| +0#0000000&|<|T|>| |I|<|T|>| |i|1|(|)| |{| 
|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|v+0#af5f00255&|a|r| 
+0#0000000&|v+0#af5f00255&|a|r|)+0#0000000&| |-|>| 
|v+0#af5f00255&|a|r|;+0#0000000&| |}| @21
+@4|s+0#00e0003&|t|a|t|i|c| +0#0000000&|<|T|>| |I|<|T|>| |i|2|(|)| |{| 
|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|T| |v+0#af5f00255&|a|r|)+0#0000000&| 
|-|>| |v+0#af5f00255&|a|r|;+0#0000000&| |}| @23
+@4|s+0#00e0003&|t|a|t|i|c| +0#0000000&|<|T|>| |I|<|T|>| |i|3|(|)| |{| 
|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|(|v+0#af5f00255&|a|r|)+0#0000000&| |-|>| 
|v+0#af5f00255&|a|r|;+0#0000000&| |}| @25
+@4|s+0#00e0003&|t|a|t|i|c| +0#0000000&|<|T|>| |I|<|T|>| |i|4|(|)| |{| 
|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|v+0#af5f00255&|a|r| +0#0000000&|-|>| 
|v+0#af5f00255&|a|r|;+0#0000000&| |}| @27
+@4|i+0#00e0003&|n|t|e|r|f|a|c|e| +0#0000000&|I|<|T|>| |{| |T| |i|(|T| |i|)|;| 
|d+0#4040ff13&|e|f|a|u|l|t| +0#0000000&|I|<|T|>| |s|e|l|f|(|)| |{| 
|r+0#af5f00255&|e|t|u|r|n| +0#0000000&|t+0#00e0003&|h|i|s|;+0#0000000&| |}| |}| 
@5
+>}| @73
+@57|4|8|,|1| @9|B|o|t| 
diff --git a/runtime/syntax/testdir/input/java_contextual_keywords.java 
b/runtime/syntax/testdir/input/java_contextual_keywords.java
new file mode 100644
index 000000000..094037964
--- /dev/null
+++ b/runtime/syntax/testdir/input/java_contextual_keywords.java
@@ -0,0 +1,48 @@
+class ContextualKeywordsTests          // See JLS, §3.9 Keywords.
+{
+       private ContextualKeywordsTests() { throw new Error(); }
+
+       // ModuleDeclaration: module open.
+       void module()   { Object module = null;         when(); }
+       void open()     { Object open = null;           module(); }
+       // ModuleDirective: exports opens provides requires to uses with.
+       void exports()  { Object exports = null;        open(); }
+       void opens()    { Object opens = null;          exports(); }
+       void provides() { Object provides = null;       opens(); }
+       void requires() { Object requires = null;       provides(); }
+       void to()       { Object to = null;             requires(); }
+       void uses()     { Object uses = null;           to(); }
+       void with()     { Object with = null;           uses(); }
+       // RequiresModifier: transitive.
+       void transitive() { Object transitive = null;   with(); }
+       // LocalVariableType | LambdaParameterType: var.
+       void var()      { var var = new Object();       transitive(); }
+       // YieldStatement: yield (see java_switch.java).
+       void yield()    { Object yield = null;          var(); }
+       // RecordDeclaration: record.
+       void record()   { Object record = null;         this.yield(); }
+       // Normal{Class,Interface}Declaration: non-sealed permits sealed.
+       void permits()  { Object permits = null;        record(); }
+       void sealed()   { Object sealed = null;         permits(); }
+       // Guard: when (see java_switch.java).
+       void when()     { Object when = null;           sealed(); }
+
+       sealed interface I1 permits C1, I3 { }
+       sealed interface I2 permits C1, I3 { }
+       non-sealed interface I3 extends I1, I2 { }
+       interface I4 extends I3 { }
+
+       abstract sealed class C1 implements I1, I2 permits C2, C3 { }
+       abstract non-sealed class C2 extends C1 { }
+       final class C3 extends C1 implements I3 { }
+       class C4 extends C2 { }
+
+       record R() implements I3 { }
+       enum E implements I3 { INSTANCE }
+
+       static <T> I<T> i1() { return (var var) -> var; }
+       static <T> I<T> i2() { return (T var) -> var; }
+       static <T> I<T> i3() { return (var) -> var; }
+       static <T> I<T> i4() { return var -> var; }
+       interface I<T> { T i(T i); default I<T> self() { return this; } }
+}

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1rsTFl-008VLa-N0%40256bit.org.

Raspunde prin e-mail lui