@Override
  public void visitInnerClass(
      final String name, final String outerName, final String innerName, final int access) {
    if ((access & Opcodes.ACC_SYNTHETIC) != 0) return;
    if (!isCorrectName(innerName) || outerName == null) return;

    if ((getClassName(outerName) + "." + innerName).equals(myResult.getQualifiedName())) {
      // our result is inner class
      if (myParent instanceof PsiFileStub) {
        throw new OutOfOrderInnerClassException();
      }
    }

    if (!getClassName(outerName).equals(myResult.getQualifiedName())) return;

    final T innerSource = myInnersStrategy.findInnerClass(innerName, mySource);
    if (innerSource == null) return;

    final ClassReader reader = myInnersStrategy.readerForInnerClass(innerSource);
    if (reader == null) return;

    final StubBuildingVisitor<T> classVisitor =
        new StubBuildingVisitor<T>(innerSource, myInnersStrategy, myResult, access, innerName);
    reader.accept(classVisitor, ClassReader.SKIP_FRAMES);
  }
예제 #2
0
  private static void checkLeakingParameters(Class<?> jClass) throws IOException {
    final HashMap<Method, boolean[]> map = new HashMap<Method, boolean[]>();

    // collecting leakedParameters
    final ClassReader classReader =
        new ClassReader(
            new FileInputStream(
                jClass.getResource("/" + jClass.getName().replace('.', '/') + ".class").getFile()));
    classReader.accept(
        new ClassVisitor(Opcodes.ASM5) {
          @Override
          public MethodVisitor visitMethod(
              int access, String name, String desc, String signature, String[] exceptions) {
            final MethodNode node =
                new MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions);
            final Method method = new Method(classReader.getClassName(), name, desc);
            return new MethodVisitor(Opcodes.ASM5, node) {
              @Override
              public void visitEnd() {
                super.visitEnd();
                try {
                  map.put(
                      method,
                      LeakingParameters.build(classReader.getClassName(), node, false).parameters);
                } catch (AnalyzerException ignore) {
                }
              }
            };
          }
        },
        ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);

    for (java.lang.reflect.Method jMethod : jClass.getDeclaredMethods()) {
      Method method =
          new Method(
              Type.getType(jClass).getInternalName(),
              jMethod.getName(),
              Type.getMethodDescriptor(jMethod));
      Annotation[][] annotations = jMethod.getParameterAnnotations();
      for (int i = 0; i < annotations.length; i++) {
        boolean isLeaking = false;
        Annotation[] parameterAnnotations = annotations[i];
        for (Annotation parameterAnnotation : parameterAnnotations) {
          if (parameterAnnotation.annotationType() == ExpectLeaking.class) {
            isLeaking = true;
          }
        }
        assertEquals(method.toString() + " #" + i, isLeaking, map.get(method)[i]);
      }
    }
  }