From d1182bbf45ffd392134cb2379b33913f744b69d0 Mon Sep 17 00:00:00 2001
From: Jan Lahoda <lahoda@gmail.com>
Date: Tue, 4 Feb 2014 21:25:29 +0100
Subject: #471: @SneakyThrows should work in NetBeans

---
 .../lombok/javac/handlers/HandleSneakyThrows.java  | 21 ++++++++++---
 src/utils/lombok/javac/Javac.java                  | 35 +++++++++++++++++++++-
 2 files changed, 51 insertions(+), 5 deletions(-)

(limited to 'src')

diff --git a/src/core/lombok/javac/handlers/HandleSneakyThrows.java b/src/core/lombok/javac/handlers/HandleSneakyThrows.java
index 0b444801..aa0c3c7e 100644
--- a/src/core/lombok/javac/handlers/HandleSneakyThrows.java
+++ b/src/core/lombok/javac/handlers/HandleSneakyThrows.java
@@ -40,12 +40,15 @@ import com.sun.tools.javac.code.Flags;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCAnnotation;
 import com.sun.tools.javac.tree.JCTree.JCBlock;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
 import com.sun.tools.javac.tree.JCTree.JCExpression;
 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
 import com.sun.tools.javac.tree.JCTree.JCStatement;
+import com.sun.tools.javac.tree.JCTree.JCTry;
 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.List;
+import lombok.javac.Javac;
 
 /**
  * Handles the {@code lombok.SneakyThrows} annotation for javac.
@@ -120,15 +123,25 @@ public class HandleSneakyThrows extends JavacAnnotationHandler<SneakyThrows> {
 		
 		Context context = node.getContext();
 		JCBlock tryBlock = setGeneratedBy(maker.Block(0, contents), source, context);
-		
 		JCExpression varType = chainDots(node, exception.split("\\."));
 		
-		JCVariableDecl catchParam = maker.VarDef(maker.Modifiers(Flags.FINAL), node.toName("$ex"), varType, null);
+		JCVariableDecl catchParam = maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER), node.toName("$ex"), varType, null);
 		JCExpression lombokLombokSneakyThrowNameRef = chainDots(node, "lombok", "Lombok", "sneakyThrow");
 		JCBlock catchBody = maker.Block(0, List.<JCStatement>of(maker.Throw(maker.Apply(
 				List.<JCExpression>nil(), lombokLombokSneakyThrowNameRef,
 				List.<JCExpression>of(maker.Ident(node.toName("$ex")))))));
-		
-		return setGeneratedBy(maker.Try(tryBlock, List.of(recursiveSetGeneratedBy(maker.Catch(catchParam, catchBody), source, context)), null), source, context);
+		JCTry tryStatement = maker.Try(tryBlock, List.of(recursiveSetGeneratedBy(maker.Catch(catchParam, catchBody), source, context)), null);
+		if (JavacHandlerUtil.inNetbeansEditor(node)) {
+			//set span (start and end position) of the try statement and the main block
+			//this allows NetBeans to dive into the statement correctly:
+			JCCompilationUnit top = (JCCompilationUnit) node.top().get();
+			int startPos = contents.head.pos;
+			int endPos = Javac.getEndPosition(contents.last().pos(), top);
+			tryBlock.pos = startPos;
+			tryStatement.pos = startPos;
+			Javac.storeEnd(tryBlock, endPos, top);
+			Javac.storeEnd(tryStatement, endPos, top);
+		}
+		return setGeneratedBy(tryStatement, source, context);
 	}
 }
diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java
index bdf5e7a0..e207c44a 100644
--- a/src/utils/lombok/javac/Javac.java
+++ b/src/utils/lombok/javac/Javac.java
@@ -177,7 +177,7 @@ public class Javac {
 	public static final TreeTag CTC_PREINC = treeTag("PREINC");
 	public static final TreeTag CTC_PREDEC = treeTag("PREDEC");
 	
-	private static final Method getExtendsClause, getEndPosition;
+	private static final Method getExtendsClause, getEndPosition, storeEnd;
 	
 	static {
 		getExtendsClause = getMethod(JCClassDecl.class, "getExtendsClause", new Class<?>[0]);
@@ -185,10 +185,32 @@ public class Javac {
 		
 		if (getJavaCompilerVersion() < 8) {
 			getEndPosition = getMethod(DiagnosticPosition.class, "getEndPosition", java.util.Map.class);
+			storeEnd = getMethod(java.util.Map.class, "put", Object.class, Object.class);
 		} else {
 			getEndPosition = getMethod(DiagnosticPosition.class, "getEndPosition", "com.sun.tools.javac.tree.EndPosTable");
+			Method storeEndMethodTemp;
+			Class<?> endPosTable;
+			try {
+				endPosTable = Class.forName("com.sun.tools.javac.tree.EndPosTable");
+			} catch (ClassNotFoundException ex) {
+				throw sneakyThrow(ex);
+			}
+			try {
+				storeEndMethodTemp = endPosTable.getMethod("storeEnd", JCTree.class, int.class);
+			} catch (NoSuchMethodException e) {
+				try {
+					endPosTable = Class.forName("com.sun.tools.javac.parser.JavacParser$AbstractEndPosTable");
+					storeEndMethodTemp = endPosTable.getDeclaredMethod("storeEnd", JCTree.class, int.class);
+				} catch (NoSuchMethodException ex) {
+					throw sneakyThrow(ex);
+				} catch (ClassNotFoundException ex) {
+					throw sneakyThrow(ex);
+				}
+			}
+			storeEnd = storeEndMethodTemp;
 		}
 		getEndPosition.setAccessible(true);
+		storeEnd.setAccessible(true);
 	}
 	
 	private static Method getMethod(Class<?> clazz, String name, Class<?>... paramTypes) {
@@ -250,6 +272,17 @@ public class Javac {
 		}
 	}
 	
+	public static void storeEnd(JCTree tree, int pos, JCCompilationUnit top) {
+		try {
+			Object endPositions = JCCOMPILATIONUNIT_ENDPOSITIONS.get(top);
+			storeEnd.invoke(endPositions, tree, pos);
+		} catch (IllegalAccessException e) {
+			throw sneakyThrow(e);
+		} catch (InvocationTargetException e) {
+			throw sneakyThrow(e.getCause());
+		}
+	}
+
 	private static final Class<?> JC_VOID_TYPE, JC_NO_TYPE;
 	
 	static {
-- 
cgit