Subject: bug#14593: 24.3; java-mode indentation of try-with-resources statement

From: Alan Mackenzie <[email-masked]>
Date: Sat, 13 Jul 2013 19:19:36 +0000

Hello, Patrick.

On Wed, 12 Jun 2013 00:24:13, Patrick Brinich-Langlois
<[email-masked]> wrote:

> Java's try-with-resources statement (new in version 1.7) is indented
> incorrectly in java-mode. Steps to reproduce:

> * Create a new file. Enable java-mode and electric-indent-mode.
> * Type the following:

> public class Test {
>     public static void main(String[] args) {
>         Path dir = Paths.get(System.getProperty("user.home"));
>         try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
>                 System.out.println("test");
>             }
>     }
> }

> The two lines after the try statement are indented an additional four
> spaces. The final two closing braces are indented properly.

This is indeed the case.  

The following patch should hopefully handle this case properly.  After
applying it, either recompile all the cc-*.el files, or just recompile
cc-langs.el, cc-engine.el, cc-fonts.el, and cc-mode.el.

Please confirm to me that the patch does indeed fix the bug, or report
any further problems which aren't fixed.  Thanks!

diff -r a86a481f7a63 cc-engine.el
--- a/cc-engine.el	Mon May 27 12:17:11 2013 +0000
+++ b/cc-engine.el	Sun Jul 07 14:15:36 2013 +0000
@@ -1140,9 +1140,13 @@
 		   (not (memq sym '(boundary ignore nil))))
 	  ;; Need to investigate closer whether we've crossed
 	  ;; between a substatement and its containing statement.
-	  (if (setq saved (if (looking-at c-block-stmt-1-key)
-			      ptok
-			    pptok))
+	  (if (setq saved
+		    (cond ((and (looking-at c-block-stmt-1-2-key)
+				(eq (char-after ptok) ?\())
+			   pptok)
+			  ((looking-at c-block-stmt-1-key)
+			   ptok)
+			  (t pptok)))
 	      (cond ((> start saved) (setq pos saved))
 		    ((= start saved) (setq ret 'up)))))
 
@@ -8026,7 +8030,8 @@
 	 (or (looking-at c-block-stmt-1-key)
 	     (and (eq (char-after) ?\()
 		  (zerop (c-backward-token-2 1 t lim))
-		  (looking-at c-block-stmt-2-key)))
+		  (or (looking-at c-block-stmt-2-key)
+		      (looking-at c-block-stmt-1-2-key))))
 	 (point))))
 
 (defun c-after-special-operator-id (&optional lim)
diff -r a86a481f7a63 cc-fonts.el
--- a/cc-fonts.el	Mon May 27 12:17:11 2013 +0000
+++ b/cc-fonts.el	Sun Jul 07 14:15:36 2013 +0000
@@ -1274,7 +1274,8 @@
 			    (goto-char match-pos)
 			    (backward-char)
 			    (c-backward-token-2)
-			    (looking-at c-block-stmt-2-key)))
+			    (or (looking-at c-block-stmt-2-key)
+				(looking-at c-block-stmt-1-2-key))))
 		     (setq context nil
 			   c-restricted-<>-arglists t))
 		    ;; Near BOB.
diff -r a86a481f7a63 cc-langs.el
--- a/cc-langs.el	Mon May 27 12:17:11 2013 +0000
+++ b/cc-langs.el	Sun Jul 07 14:15:36 2013 +0000
@@ -2181,6 +2181,18 @@
   t (c-make-keywords-re t (c-lang-const c-block-stmt-1-kwds)))
 (c-lang-defvar c-block-stmt-1-key (c-lang-const c-block-stmt-1-key))
 
+(c-lang-defconst c-block-stmt-1-2-kwds
+  "Statement keywords optionally followed by a paren sexp.
+Keywords here should also be in `c-block-stmt-1-key'."
+  t nil
+  java '("try"))
+
+(c-lang-defconst c-block-stmt-1-2-key
+  ;; Regexp matching the start of a statement which may be followed by a
+  ;; paren sexp and will then be followed by a substatement.
+  t (c-make-keywords-re t (c-lang-const c-block-stmt-1-2-kwds)))
+(c-lang-defvar c-block-stmt-1-2-key (c-lang-const c-block-stmt-1-2-key))
+
 (c-lang-defconst c-block-stmt-2-kwds
   "Statement keywords followed by a paren sexp and then by a substatement."
   t    '("for" "if" "switch" "while")

-- 
Alan Mackenzie (Nuremberg, Germany).