-
Notifications
You must be signed in to change notification settings - Fork 0
Resolving Stage
The Resolving Stage is the second stage of the initialization of the Call Graph. The main goal of this stage is to attempt to resolve all of the method invocations that are inside of the current methods body, in order to determine what methods call what methods, thus creating functional dependencies.
What we are trying to do here is found out exactly what class a given class extends and any interfaces that it implements. From the parsing stage, we are given Names such as A for a class and I for an interface and we can use these along with our package and imports to determine the full class name and full interface names. (package.B extends package.A implements package2.I)
- There are no known issues.
Once class and interface names are resolved we will have soft links between all of our clazzes and interfaces and this enables us to traverse the inheritance tree when resolving methods.
What we are trying to do here if find out full qualified type of all method's parameters as well as its return type. From the parsing stage we are simply given their simple name, so we try to fully resolve those names here. (Example foo() returns type B, we need to get foo() returns pkg.B)
- If a type is unresolvable then it is set to null. A type that is unresolvable is a type which is declared outside of user defined types and outside of the java.util package.
Once the return types and parameters have been resolved, we can move onto resolving method invocations because we have the fully qualified types we will need.
What we are trying to do here is find out exactly what methods are being called by other methods. We can use our MethodDeclaration ASTNode to be able to achieve this. What we need from our MethodDeclaration is the ability to get method calls in the form of A.foo(Bar) where A is the class, foo is the method name and Bar is a parameter type. From here we can use our list of imports and the current package in order to find the fully qualified method name. If there is no class in front on the method call we can assume it is a local function and only search our current class.
- Generics are not well tested and some special cases may cause a method to be unresolvable.
- Resolving method invocations outside of method bodies will not work.
- Promoting number literals will not work. (foo(int) which really calls foo(double))
- When the type of a method is not known, the invocation will fail to resolve.
Once a method call is resolved, we know our current method calls it and we know the resolved is called by our current method. This information will be stored.