Added setting position of generated nodes in javac's @Synchronized as a 'pilot' to see if we cause any problems with this approach. It does generate nicer error messages!

Example: Using @Synchronized with named lock on a static method, naming a non-existent or instance lock. That used to error on line -1.
This commit is contained in:
Reinier Zwitserloot committed 2012-07-16 22:51:56 +02:00
1 parent b1877a77be
commit fe4985e212
3 files changed
+28 -8

No files matched your search

@@ -78,16 +78,16 @@ public class HandleSynchronized extends JavacAnnotationHandler<Synchronized> {
lockName = isStatic ? STATIC_LOCK_NAME : INSTANCE_LOCK_NAME;
}
TreeMaker maker = methodNode.getTreeMaker();
TreeMaker maker = methodNode.getTreeMaker().at(ast.pos);
if (fieldExists(lockName, methodNode) == MemberExistsResult.NOT_EXISTS) {
if (!autoMake) {
annotationNode.addError("The field " + lockName + " does not exist.");
return;
}
JCExpression objectType = chainDots(methodNode, "java", "lang", "Object");
JCExpression objectType = chainDots(methodNode, ast.pos, "java", "lang", "Object");
//We use 'new Object[0];' because unlike 'new Object();', empty arrays *ARE* serializable!
JCNewArray newObjectArray = maker.NewArray(chainDots(methodNode, "java", "lang", "Object"),
JCNewArray newObjectArray = maker.NewArray(chainDots(methodNode, ast.pos, "java", "lang", "Object"),
List.<JCExpression>of(maker.Literal(Javac.getCtcInt(TypeTags.class, "INT"), 0)), null);
JCVariableDecl fieldDecl = recursiveSetGeneratedBy(maker.VarDef(
maker.Modifiers(Flags.PRIVATE | Flags.FINAL | (isStatic ? Flags.STATIC : 0)),
@@ -99,7 +99,7 @@ public class HandleSynchronized extends JavacAnnotationHandler<Synchronized> {
JCExpression lockNode;
if (isStatic) {
lockNode = chainDots(methodNode, methodNode.up().getName(), lockName);
lockNode = chainDots(methodNode, ast.pos, methodNode.up().getName(), lockName);
} else {
lockNode = maker.Select(maker.Ident(methodNode.toName("this")), methodNode.toName(lockName));
}
@@ -746,6 +746,8 @@ public class JavacHandlerUtil {
* In javac, dotted access of any kind, from {@code java.lang.String} to {@code var.methodName}
* is represented by a fold-left of {@code Select} nodes with the leftmost string represented by
* a {@code Ident} node. This method generates such an expression.
* <p>
* The position of the generated node(s) will be unpositioned (-1).
*
* For example, maker.Select(maker.Select(maker.Ident(NAME[java]), NAME[lang]), NAME[String]).
*
@@ -753,12 +755,30 @@ public class JavacHandlerUtil {
* @see com.sun.tools.javac.tree.JCTree.JCFieldAccess
*/
public static JCExpression chainDots(JavacNode node, String... elems) {
return chainDots(node, -1, elems);
}
/**
* In javac, dotted access of any kind, from {@code java.lang.String} to {@code var.methodName}
* is represented by a fold-left of {@code Select} nodes with the leftmost string represented by
* a {@code Ident} node. This method generates such an expression.
* <p>
* The position of the generated node(s) will be equal to the {@code pos} parameter.
*
* For example, maker.Select(maker.Select(maker.Ident(NAME[java]), NAME[lang]), NAME[String]).
*
* @see com.sun.tools.javac.tree.JCTree.JCIdent
* @see com.sun.tools.javac.tree.JCTree.JCFieldAccess
*/
public static JCExpression chainDots(JavacNode node, int pos, String... elems) {
assert elems != null;
assert elems.length > 0;
JCExpression e = node.getTreeMaker().Ident(node.toName(elems[0]));
TreeMaker maker = node.getTreeMaker();
if (pos != -1) maker = maker.at(pos);
JCExpression e = maker.Ident(node.toName(elems[0]));
for (int i = 1 ; i < elems.length ; i++) {
e = node.getTreeMaker().Select(e, node.toName(elems[i]));
e = maker.Select(e, node.toName(elems[i]));
}
return e;
@@ -776,7 +796,7 @@ public class JavacHandlerUtil {
* @see com.sun.tools.javac.tree.JCTree.JCFieldAccess
*/
public static JCExpression chainDotsString(JavacNode node, String elems) {
return chainDots(node, elems.split("\\."));
return chainDots(node, elems.split("\\."));
}
/**
@@ -1 +1 @@
-1:-1 ERROR non-static variable read cannot be referenced from a static context
5:9 ERROR non-static variable read cannot be referenced from a static context