예제 #1
0
  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;
  }