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; }