private static int[] spanFor( CompilationInfo info, JavaSource js, final PackageMemberAnnotation annotation) { final int[] result = new int[] {-1, -1}; class TaskImpl implements Task<CompilationInfo> { @Override public void run(final CompilationInfo parameter) { TypeElement clazz = parameter.getElements().getTypeElement(annotation.getClassName()); if (clazz == null) { // XXX: log return; } Element resolved = null; if (annotation instanceof FieldAnnotation) { FieldAnnotation fa = (FieldAnnotation) annotation; for (VariableElement var : ElementFilter.fieldsIn(clazz.getEnclosedElements())) { if (var.getSimpleName().contentEquals(fa.getFieldName())) { resolved = var; break; } } } else if (annotation instanceof MethodAnnotation) { MethodAnnotation ma = (MethodAnnotation) annotation; for (ExecutableElement method : ElementFilter.methodsIn(clazz.getEnclosedElements())) { if (method.getSimpleName().contentEquals(ma.getMethodName())) { if (ma.getMethodSignature() .equals(SourceUtils.getJVMSignature(ElementHandle.create(method))[2])) { resolved = method; break; } } } } else if (annotation instanceof ClassAnnotation) { resolved = clazz; } if (resolved == null) { // XXX: log return; } final Element resolvedFin = resolved; new CancellableTreePathScanner<Void, Void>() { @Override public Void visitVariable(VariableTree node, Void p) { if (resolvedFin.equals(parameter.getTrees().getElement(getCurrentPath()))) { int[] span = parameter.getTreeUtilities().findNameSpan(node); if (span != null) { result[0] = span[0]; result[1] = span[1]; } } return super.visitVariable(node, p); } @Override public Void visitMethod(MethodTree node, Void p) { if (resolvedFin.equals(parameter.getTrees().getElement(getCurrentPath()))) { int[] span = parameter.getTreeUtilities().findNameSpan(node); if (span != null) { result[0] = span[0]; result[1] = span[1]; } } return super.visitMethod(node, p); } @Override public Void visitClass(ClassTree node, Void p) { if (resolvedFin.equals(parameter.getTrees().getElement(getCurrentPath()))) { int[] span = parameter.getTreeUtilities().findNameSpan(node); if (span != null) { result[0] = span[0]; result[1] = span[1]; } } return super.visitClass(node, p); } }.scan(parameter.getCompilationUnit(), null); } }; final TaskImpl convertor = new TaskImpl(); if (info != null) { convertor.run(info); } else { try { js.runUserActionTask( new Task<CompilationController>() { @Override public void run(CompilationController parameter) throws Exception { parameter.toPhase( Phase.RESOLVED); // XXX: ENTER should be enough in most cases, but not for // anonymous innerclasses. convertor.run(parameter); } }, true); } catch (IOException ex) { Exceptions.printStackTrace(ex); } } return result; }