Пример #1
0
  public void visitLocalVariable(
      final String name,
      final String desc,
      final String signature,
      final Label start,
      final Label end,
      final int index) {
    buf.setLength(0);
    buf.append(tab2).append("LOCALVARIABLE ").append(name).append(' ');
    appendDescriptor(FIELD_DESCRIPTOR, desc);
    buf.append(' ');
    appendLabel(start);
    buf.append(' ');
    appendLabel(end);
    buf.append(' ').append(index).append('\n');

    if (signature != null) {
      buf.append(tab2);
      appendDescriptor(FIELD_SIGNATURE, signature);

      TraceSignatureVisitor sv = new TraceSignatureVisitor(0);
      SignatureReader r = new SignatureReader(signature);
      r.acceptType(sv);
      buf.append(tab2).append("// declaration: ").append(sv.getDeclaration()).append('\n');
    }
    text.add(buf.toString());
  }
 /** Creates a {@link Descriptor} based on a signature (such as {@code Ljava/lang/String;}. */
 @SuppressWarnings("unchecked")
 Pair<Descriptor, Entity> create(
     String signature,
     EntityDescriptorStore store,
     FieldDescriptor fieldDescriptor,
     Map<Type, Class<?>> types) {
   SignatureReader r = new SignatureReader(signature);
   EntitySignatureVisitor entitySignatureVisitor =
       new EntitySignatureVisitor(signature, store, fieldDescriptor, types);
   r.accept(entitySignatureVisitor);
   return entitySignatureVisitor.getDescriptor();
 }
Пример #3
0
  @Test
  public void testAsm() {
    // String sig = "<E:Ljava/lang/Number;F:Ljava/lang/Object;>Ljava/lang/Object;";
    // String sig =
    // "<V:Ljava/lang/Object;>Lcom/pongasoft/kiwidoc/testdata/pubdir1/Pub1Class2<Ljava/lang/Integer;Ljava/lang/Float;>;Lcom/pongasoft/kiwidoc/testdata/pubdir1/Pub1Interface2<TV;>;";
    // String sig =
    // "<K:Ljava/lang/Object;>(TK;Lorg/hamcrest/Matcher<TK;>;Ljava/util/Set<Ljava/lang/String;>;)V";
    // String sig
    // ="<E:Ljava/lang/Object;F:Ljava/lang/Number;G:Ljava/lang/Number;:Ljava/lang/Comparable<Ljava/lang/Number;>;H:TE;I::Ljava/util/List<TE;>;J::Ljava/util/List<Ljava/lang/Number;>;K::Ljava/util/List<+Ljava/lang/Number;>;L::Ljava/util/List<-Ljava/lang/Number;>;M::Ljava/util/List<+Ljava/util/List<Ljava/lang/Number;>;>;>Ljava/lang/Object;";
    String sig =
        "<E:Ljava/lang/Object;F:Ljava/lang/Number;G:Ljava/lang/Number;:Ljava/lang/Comparable<Ljava/lang/Number;>;H:TE;I::Ljava/util/List<TE;>;J::Ljava/util/List<Ljava/lang/Number;>;K::Ljava/util/List<+Ljava/lang/Number;>;L::Ljava/util/List<-Ljava/lang/Number;>;M::Ljava/util/List<+Ljava/util/List<Ljava/lang/Number;>;>;N:Lcom/pongasoft/kiwidoc/testdata/pubdir1/C1$Inner1;:Lcom/pongasoft/kiwidoc/testdata/pubdir1/I1$Inner1;:Ljava/util/List<+Lcom/pongasoft/kiwidoc/testdata/pubdir1/C1$Inner1;>;>Ljava/lang/Object;";
    // String sig = "<K:Ljava/util/List<+Ljava/lang/Number;>;>Ljava/lang/Object;";
    // String sig = "Ljava/util/HashMap<TK;TV;>.HashIterator<TK;>;";
    SignatureReader reader = new SignatureReader(sig);

    reader.accept(new MySignatureVisitor(""));
  }
Пример #4
0
 @Override
 public void visit(
     int version,
     int flags,
     String name,
     @Nullable String signature,
     @Nullable String superName,
     @Nullable String[] interfaces) {
   Preconditions.checkState(
       name.endsWith(classSymbol.name),
       "Name : '" + name + "' should ends with " + classSymbol.name);
   Preconditions.checkState(!BytecodeCompleter.isSynthetic(flags), name + " is synthetic");
   className = name;
   if (signature != null) {
     SignatureReader signatureReader = new SignatureReader(signature);
     signatureReader.accept(new TypeParameterDeclaration(classSymbol));
     ReadGenericSignature readGenericSignature = new ReadGenericSignature();
     signatureReader.accept(readGenericSignature);
     ((ClassJavaType) classSymbol.type).interfaces = readGenericSignature.interfaces();
   } else {
     if (superName == null) {
       Preconditions.checkState(
           "java/lang/Object".equals(className),
           "superName must be null only for java/lang/Object, but not for " + className);
       // TODO(Godin): what about interfaces and annotations
     } else {
       ((ClassJavaType) classSymbol.type).supertype = getClassSymbol(superName).type;
     }
     ((ClassJavaType) classSymbol.type).interfaces = getCompletedClassSymbolsType(interfaces);
   }
   // if class has already access flags set (inner class) then do not reset those.
   // The important access flags are the one defined in the outer class.
   if ((classSymbol.flags & Flags.ACCESS_FLAGS) != 0) {
     classSymbol.flags |= bytecodeCompleter.filterBytecodeFlags(flags & ~Flags.ACCESS_FLAGS);
   } else {
     classSymbol.flags |= bytecodeCompleter.filterBytecodeFlags(flags);
   }
   classSymbol.members = new Scope(classSymbol);
 }
Пример #5
0
 @Override
 public MethodVisitor visitMethod(
     int flags,
     String name,
     String desc,
     @Nullable String signature,
     @Nullable String[] exceptions) {
   Preconditions.checkNotNull(name);
   Preconditions.checkNotNull(desc);
   if (!BytecodeCompleter.isSynthetic(flags)) {
     Preconditions.checkState(
         (flags & Opcodes.ACC_BRIDGE) == 0,
         "bridge method not marked as synthetic in class " + className);
     // TODO(Godin): according to JVMS 4.7.24 - parameter can be marked as synthetic
     MethodJavaType type =
         new MethodJavaType(
             convertAsmTypes(org.objectweb.asm.Type.getArgumentTypes(desc)),
             convertAsmType(org.objectweb.asm.Type.getReturnType(desc)),
             getCompletedClassSymbolsType(exceptions),
             classSymbol);
     final JavaSymbol.MethodJavaSymbol methodSymbol =
         new JavaSymbol.MethodJavaSymbol(
             bytecodeCompleter.filterBytecodeFlags(flags), name, type, classSymbol);
     classSymbol.members.enter(methodSymbol);
     if (signature != null) {
       SignatureReader signatureReader = new SignatureReader(signature);
       signatureReader.accept(new TypeParameterDeclaration(methodSymbol));
       signatureReader.accept(new ReadMethodSignature(methodSymbol));
     }
     methodSymbol.parameters = new Scope(methodSymbol);
     for (int i = 0; i < type.argTypes.size(); i += 1) {
       methodSymbol.parameters.enter(
           new JavaSymbol.VariableJavaSymbol(0, "arg" + i, methodSymbol));
     }
     // checks for annotations on the method and its parameters
     return new BytecodeMethodVisitor(methodSymbol, this);
   }
   return null;
 }
Пример #6
0
 public MethodParameters(String desc) {
   super(Opcodes.ASM5);
   parameters = new ArrayList<Param>();
   SignatureReader reader = new SignatureReader(desc);
   reader.accept(this);
 }
Пример #7
0
  private void insertDeclMethod(String type, String signature, String desc, String name, int access)
      throws URISyntaxException {
    String sig;
    if (signature != null) {
      sig = extractSignature(signature);
      // TypeVariables
      SignatureReader sr = new SignatureReader(signature);
      sr.accept(new SigVisitor(Opcodes.ASM4));
    } else {
      sig = extractSignature(desc);
    }
    // Typedepency methods
    String TypeSig = sig;
    // Loop over all parameters in the signature
    String[] params;

    if ((TypeSig != null) && (!TypeSig.equals(""))) {
      params = TypeSig.split(",");
      for (int i = 0; i < params.length; i++) {
        this.insert(
            this.typeDependency,
            values.sourceLocation(
                "java+parameter", "", LogPath + "/" + name + "(" + sig + ")" + "/" + params[i] + i),
            values.sourceLocation(printParameterType(params[i]), "", params[i]));
      }
    }

    // Return type
    if (type.equals("java+constructor")) {
      this.insert(
          this.typeDependency,
          values.sourceLocation("java+constructor", "", LogPath + "/" + name + "(" + sig + ")"),
          values.sourceLocation("java+class", "", LogPath));
    } else {
      String rType = null;
      if (signature != null) {
        rType = Signature.toString(signature);
      } else {
        rType = Signature.toString(desc);
      }
      rType = rType.substring(0, rType.indexOf(' '));
      this.insert(
          this.typeDependency,
          values.sourceLocation("java+method", "", LogPath + "/" + name + "(" + sig + ")"),
          values.sourceLocation(printParameterType(rType), "", rType));
    }

    this.insert(
        this.declarations,
        values.sourceLocation(type, "", LogPath + "/" + name + "(" + sig + ")"),
        values.sourceLocation(jarFile + "!" + ClassFile));
    for (int fs = 0; fs < 15; fs++) {
      if ((access & (0x0001 << fs)) != 0) {
        this.insert(
            this.modifiers,
            values.sourceLocation(type, "", LogPath + "/" + name + "(" + sig + ")"),
            mapFieldAccesCode(0x0001 << fs, METHODE));
      }
    }

    // Containment of methods.
    this.insert(
        this.containment,
        values.sourceLocation(classScheme, "", LogPath),
        values.sourceLocation(type, "", LogPath + "/" + name + "(" + sig + ")"));

    // Deprecated method emit type annotation dependency Deprecated.
    if ((access & 0x20000) == 0x20000)
      this.insert(
          this.annotations,
          values.sourceLocation("java+method", "", LogPath + "/" + name + "(" + sig + ")"),
          values.sourceLocation("java+interface", "", "/java/lang/Deprecated"));
    // <|java+method:///Main/Main/FindMe(java.lang.String)|,|java+interface:///java/lang/Deprecated|>,

  }
  private ClassObject parseBytecode(File file) {
    final ClassObject co = new ClassObject();
    try {
      FileInputStream fin = new FileInputStream(file);
      ClassReader cr = new ClassReader(new DataInputStream(fin));
      ClassNode cn = new ClassNode();
      cr.accept(cn, ClassReader.SKIP_DEBUG);

      String name = cn.name;
      co.setName(name.replaceAll("/", "."));

      if ((cn.access & Opcodes.ACC_INTERFACE) != 0) co.setInterface(true);
      else if ((cn.access & Opcodes.ACC_ABSTRACT) != 0) co.setAbstract(true);

      if ((cn.access & Opcodes.ACC_PUBLIC) != 0) co.setAccess(Access.PUBLIC);
      else if ((cn.access & Opcodes.ACC_PROTECTED) != 0) co.setAccess(Access.PROTECTED);
      else if ((cn.access & Opcodes.ACC_PRIVATE) != 0) co.setAccess(Access.PRIVATE);
      if ((cn.access & Opcodes.ACC_STATIC) != 0) co.setStatic(true);

      String superClass = cn.superName;
      co.setSuperclass(superClass.replaceAll("/", "."));

      List interfaces = cn.interfaces;
      for (Object anInterface : interfaces) {
        String interfaceString = (String) anInterface;
        co.addInterface(interfaceString.replaceAll("/", "."));
      }

      List fields = cn.fields;
      for (Object field : fields) {
        FieldNode fieldNode = (FieldNode) field;
        Type fieldType = Type.getType(fieldNode.desc);
        TypeObject typeObject = new TypeObject(fieldType.getClassName());
        if (fieldNode.signature != null) {
          TraceSignatureVisitor v = new TraceSignatureVisitor(ClassReader.SKIP_DEBUG);
          SignatureReader r = new SignatureReader(fieldNode.signature);
          r.accept(v);
          String declaration = v.getDeclaration();
          if (declaration.contains("<") && declaration.contains(">"))
            typeObject.setGeneric(
                declaration.substring(declaration.indexOf("<") + 1, declaration.lastIndexOf(">")));
        }
        FieldObject fo = new FieldObject(typeObject, fieldNode.name);

        if ((fieldNode.access & Opcodes.ACC_PUBLIC) != 0) fo.setAccess(Access.PUBLIC);
        else if ((fieldNode.access & Opcodes.ACC_PROTECTED) != 0) fo.setAccess(Access.PROTECTED);
        else if ((fieldNode.access & Opcodes.ACC_PRIVATE) != 0) fo.setAccess(Access.PRIVATE);
        if ((fieldNode.access & Opcodes.ACC_STATIC) != 0) fo.setStatic(true);
        co.addField(fo);
      }

      List methods = cn.methods;
      for (Object method : methods) {
        MethodNode methodNode = (MethodNode) method;

        final ConstructorObject constructorObject = new ConstructorObject();

        if ((methodNode.access & Opcodes.ACC_PUBLIC) != 0)
          constructorObject.setAccess(Access.PUBLIC);
        else if ((methodNode.access & Opcodes.ACC_PROTECTED) != 0)
          constructorObject.setAccess(Access.PROTECTED);
        else if ((methodNode.access & Opcodes.ACC_PRIVATE) != 0)
          constructorObject.setAccess(Access.PRIVATE);

        if (methodNode.signature != null) {
          TraceSignatureVisitor v = new TraceSignatureVisitor(ClassReader.SKIP_DEBUG);
          SignatureReader r = new SignatureReader(methodNode.signature);
          r.accept(v);
          String declaration = v.getDeclaration();
          String temp = declaration;
          if (temp.startsWith("(")) temp = temp.substring(1, temp.length());
          if (temp.endsWith("")) temp = temp.substring(0, temp.length() - 1);
          if (!temp.equals("")) {
            ParameterAnalyzer analyzer = new ParameterAnalyzer(temp);
            for (String token : analyzer.getParameters()) {
              if (token.contains("<") && token.contains(">")) {
                TypeObject typeObject = new TypeObject(token.substring(0, token.indexOf("<")));
                typeObject.setGeneric(
                    token.substring(token.indexOf("<") + 1, token.lastIndexOf(">")));
                constructorObject.addParameter(typeObject);
              } else {
                constructorObject.addParameter(new TypeObject(token));
              }
            }
          }
        } else {
          Type[] argumentTypes = Type.getArgumentTypes(methodNode.desc);
          for (Type argumentType : argumentTypes)
            constructorObject.addParameter(new TypeObject(argumentType.getClassName()));
        }
        if (methodNode.instructions.size() > 0) {
          Map<String, Integer> labelIndexMap = new HashMap<String, Integer>();
          List<LoopObject> activeLoops = new ArrayList<LoopObject>();

          Iterator insnIt = methodNode.instructions.iterator();
          int index = 0;
          while (insnIt.hasNext()) {
            AbstractInsnNode ainsn = (AbstractInsnNode) insnIt.next();

            if (ainsn instanceof LabelNode) {
              LabelNode labelNode = (LabelNode) ainsn;
              Label label = labelNode.getLabel();
              LoopObject loop = new LoopObject(label.toString());
              activeLoops.add(loop);
              labelIndexMap.put(label.toString(), index);
            }

            if (ainsn instanceof JumpInsnNode) {
              JumpInsnNode jumpNode = (JumpInsnNode) ainsn;
              Label label = jumpNode.label.getLabel();
              if (labelIndexMap.containsKey(label.toString())) {
                LoopObject matchingLoop = null;
                for (LoopObject loop : activeLoops) {
                  if (loop.getLabel().equals(label.toString())) {
                    matchingLoop = loop;
                    break;
                  }
                }
                if (matchingLoop != null) {
                  constructorObject.addLoop(matchingLoop);
                  activeLoops.remove(matchingLoop);
                }
              }
            }

            if (ainsn instanceof FieldInsnNode) {
              FieldInsnNode fieldInsnNode = (FieldInsnNode) ainsn;
              Type fieldType = Type.getType(fieldInsnNode.desc);
              FieldInstructionObject fieldObject =
                  new FieldInstructionObject(
                      fieldInsnNode.owner.replaceAll("/", "."),
                      fieldType.getClassName(),
                      fieldInsnNode.name);
              constructorObject.addFieldInstruction(fieldObject);
              for (LoopObject loop : activeLoops) {
                loop.addFieldInstruction(fieldObject);
              }
            }

            if ((ainsn.getOpcode() == Opcodes.INVOKEVIRTUAL)
                || (ainsn.getOpcode() == Opcodes.INVOKESTATIC)
                || (ainsn.getOpcode() == Opcodes.INVOKESPECIAL)
                || (ainsn.getOpcode() == Opcodes.INVOKEINTERFACE)) {

              MethodInsnNode minsn = (MethodInsnNode) ainsn;
              MethodInvocationObject mio =
                  new MethodInvocationObject(
                      minsn.owner.replaceAll("/", "."),
                      minsn.name,
                      Type.getReturnType(minsn.desc).getClassName());
              Type[] argTypes = Type.getArgumentTypes(minsn.desc);
              for (Type argType : argTypes) mio.addParameter(argType.getClassName());

              constructorObject.addMethodInvocation(mio);
              for (LoopObject loop : activeLoops) {
                loop.addMethodInvocation(mio);
              }
            }

            if ((ainsn.getOpcode() == Opcodes.NEW) || (ainsn.getOpcode() == Opcodes.ANEWARRAY)) {

              TypeInsnNode tinsn = (TypeInsnNode) ainsn;
              constructorObject.addObjectInstantiation(tinsn.desc.replaceAll("/", "."));
            }
            index++;
          }
        }

        if (methodNode.name.equals("<init>")) {
          constructorObject.setName(co.getName());
          co.addConstructor(constructorObject);
        } else {
          Type returnType = Type.getReturnType(methodNode.desc);
          constructorObject.setName(methodNode.name);
          MethodObject methodObject = new MethodObject(constructorObject);
          TypeObject typeObject = new TypeObject(returnType.getClassName());
          if (methodNode.signature != null) {
            TraceSignatureVisitor v = new TraceSignatureVisitor(ClassReader.SKIP_DEBUG);
            SignatureReader r = new SignatureReader(methodNode.signature);
            r.accept(v);
            String genericReturnType = v.getReturnType();
            if (genericReturnType.contains("<") && genericReturnType.contains(">"))
              typeObject.setGeneric(
                  genericReturnType.substring(
                      genericReturnType.indexOf("<") + 1, genericReturnType.lastIndexOf(">")));
          }

          methodObject.setReturnType(typeObject);
          methodObject.setClassName(co.getName());
          if ((methodNode.access & Opcodes.ACC_ABSTRACT) != 0) methodObject.setAbstract(true);
          if ((methodNode.access & Opcodes.ACC_STATIC) != 0) methodObject.setStatic(true);
          co.addMethod(methodObject);
        }
      }
      fin.close();
    } catch (FileNotFoundException fnfe) {
      fnfe.printStackTrace();
    } catch (IOException ioe) {
      ioe.printStackTrace();
    }

    return co;
  }