Exemplo n.º 1
0
  private List<ClassObject> parseAST(CompilationUnit compilationUnit, IFile iFile) {
    List<ClassObject> classObjects = new ArrayList<ClassObject>();
    List<AbstractTypeDeclaration> topLevelTypeDeclarations = compilationUnit.types();
    for (AbstractTypeDeclaration abstractTypeDeclaration : topLevelTypeDeclarations) {
      if (abstractTypeDeclaration instanceof TypeDeclaration) {
        TypeDeclaration topLevelTypeDeclaration = (TypeDeclaration) abstractTypeDeclaration;
        List<TypeDeclaration> typeDeclarations = new ArrayList<TypeDeclaration>();
        typeDeclarations.add(topLevelTypeDeclaration);
        typeDeclarations.addAll(getRecursivelyInnerTypes(topLevelTypeDeclaration));
        for (TypeDeclaration typeDeclaration : typeDeclarations) {
          final ClassObject classObject = new ClassObject();
          classObject.setIFile(iFile);
          classObject.setName(typeDeclaration.resolveBinding().getQualifiedName());
          classObject.setTypeDeclaration(typeDeclaration);

          if (typeDeclaration.isInterface()) {
            classObject.setInterface(true);
          }

          int modifiers = typeDeclaration.getModifiers();
          if ((modifiers & Modifier.ABSTRACT) != 0) classObject.setAbstract(true);

          if ((modifiers & Modifier.PUBLIC) != 0) classObject.setAccess(Access.PUBLIC);
          else if ((modifiers & Modifier.PROTECTED) != 0) classObject.setAccess(Access.PROTECTED);
          else if ((modifiers & Modifier.PRIVATE) != 0) classObject.setAccess(Access.PRIVATE);
          else classObject.setAccess(Access.NONE);

          if ((modifiers & Modifier.STATIC) != 0) classObject.setStatic(true);

          Type superclassType = typeDeclaration.getSuperclassType();
          if (superclassType != null) {
            ITypeBinding binding = superclassType.resolveBinding();
            String qualifiedName = binding.getQualifiedName();
            TypeObject typeObject = TypeObject.extractTypeObject(qualifiedName);
            classObject.setSuperclass(typeObject);
          }

          List<Type> superInterfaceTypes = typeDeclaration.superInterfaceTypes();
          for (Type interfaceType : superInterfaceTypes) {
            ITypeBinding binding = interfaceType.resolveBinding();
            String qualifiedName = binding.getQualifiedName();
            TypeObject typeObject = TypeObject.extractTypeObject(qualifiedName);
            classObject.addInterface(typeObject);
          }

          FieldDeclaration[] fieldDeclarations = typeDeclaration.getFields();
          for (FieldDeclaration fieldDeclaration : fieldDeclarations) {
            Type fieldType = fieldDeclaration.getType();
            ITypeBinding binding = fieldType.resolveBinding();
            List<VariableDeclarationFragment> fragments = fieldDeclaration.fragments();
            for (VariableDeclarationFragment fragment : fragments) {
              String qualifiedName = binding.getQualifiedName();
              TypeObject typeObject = TypeObject.extractTypeObject(qualifiedName);
              typeObject.setArrayDimension(
                  typeObject.getArrayDimension() + fragment.getExtraDimensions());
              FieldObject fieldObject =
                  new FieldObject(typeObject, fragment.getName().getIdentifier());
              fieldObject.setClassName(classObject.getName());
              fieldObject.setVariableDeclarationFragment(fragment);

              int fieldModifiers = fieldDeclaration.getModifiers();
              if ((fieldModifiers & Modifier.PUBLIC) != 0) fieldObject.setAccess(Access.PUBLIC);
              else if ((fieldModifiers & Modifier.PROTECTED) != 0)
                fieldObject.setAccess(Access.PROTECTED);
              else if ((fieldModifiers & Modifier.PRIVATE) != 0)
                fieldObject.setAccess(Access.PRIVATE);
              else fieldObject.setAccess(Access.NONE);

              if ((fieldModifiers & Modifier.STATIC) != 0) fieldObject.setStatic(true);

              classObject.addField(fieldObject);
            }
          }

          MethodDeclaration[] methodDeclarations = typeDeclaration.getMethods();
          for (MethodDeclaration methodDeclaration : methodDeclarations) {
            String methodName = methodDeclaration.getName().getIdentifier();
            final ConstructorObject constructorObject = new ConstructorObject();
            constructorObject.setMethodDeclaration(methodDeclaration);
            constructorObject.setName(methodName);
            constructorObject.setClassName(classObject.getName());

            int methodModifiers = methodDeclaration.getModifiers();
            if ((methodModifiers & Modifier.PUBLIC) != 0)
              constructorObject.setAccess(Access.PUBLIC);
            else if ((methodModifiers & Modifier.PROTECTED) != 0)
              constructorObject.setAccess(Access.PROTECTED);
            else if ((methodModifiers & Modifier.PRIVATE) != 0)
              constructorObject.setAccess(Access.PRIVATE);
            else constructorObject.setAccess(Access.NONE);

            List<SingleVariableDeclaration> parameters = methodDeclaration.parameters();
            for (SingleVariableDeclaration parameter : parameters) {
              Type parameterType = parameter.getType();
              ITypeBinding binding = parameterType.resolveBinding();
              String qualifiedName = binding.getQualifiedName();
              TypeObject typeObject = TypeObject.extractTypeObject(qualifiedName);
              typeObject.setArrayDimension(
                  typeObject.getArrayDimension() + parameter.getExtraDimensions());
              if (parameter.isVarargs()) {
                typeObject.setArrayDimension(1);
              }
              ParameterObject parameterObject =
                  new ParameterObject(typeObject, parameter.getName().getIdentifier());
              parameterObject.setSingleVariableDeclaration(parameter);
              constructorObject.addParameter(parameterObject);
            }

            Block methodBody = methodDeclaration.getBody();
            if (methodBody != null) {
              MethodBodyObject methodBodyObject = new MethodBodyObject(methodBody);
              constructorObject.setMethodBody(methodBodyObject);
            }

            if (methodDeclaration.isConstructor()) {
              classObject.addConstructor(constructorObject);
            } else {
              MethodObject methodObject = new MethodObject(constructorObject);
              List<IExtendedModifier> extendedModifiers = methodDeclaration.modifiers();
              for (IExtendedModifier extendedModifier : extendedModifiers) {
                if (extendedModifier.isAnnotation()) {
                  Annotation annotation = (Annotation) extendedModifier;
                  if (annotation.getTypeName().getFullyQualifiedName().equals("Test")) {
                    methodObject.setTestAnnotation(true);
                    break;
                  }
                }
              }
              Type returnType = methodDeclaration.getReturnType2();
              ITypeBinding binding = returnType.resolveBinding();
              String qualifiedName = binding.getQualifiedName();
              TypeObject typeObject = TypeObject.extractTypeObject(qualifiedName);
              methodObject.setReturnType(typeObject);

              if ((methodModifiers & Modifier.ABSTRACT) != 0) methodObject.setAbstract(true);
              if ((methodModifiers & Modifier.STATIC) != 0) methodObject.setStatic(true);
              if ((methodModifiers & Modifier.SYNCHRONIZED) != 0)
                methodObject.setSynchronized(true);
              if ((methodModifiers & Modifier.NATIVE) != 0) methodObject.setNative(true);

              classObject.addMethod(methodObject);
              FieldInstructionObject fieldInstruction = methodObject.isGetter();
              if (fieldInstruction != null)
                systemObject.addGetter(methodObject.generateMethodInvocation(), fieldInstruction);
              fieldInstruction = methodObject.isSetter();
              if (fieldInstruction != null)
                systemObject.addSetter(methodObject.generateMethodInvocation(), fieldInstruction);
              fieldInstruction = methodObject.isCollectionAdder();
              if (fieldInstruction != null)
                systemObject.addCollectionAdder(
                    methodObject.generateMethodInvocation(), fieldInstruction);
              MethodInvocationObject methodInvocation = methodObject.isDelegate();
              if (methodInvocation != null)
                systemObject.addDelegate(methodObject.generateMethodInvocation(), methodInvocation);
            }
          }
          classObjects.add(classObject);
        }
      }
    }
    return classObjects;
  }
  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;
  }