Have you ever encountered a problem where modifying your code inadvertently affected other parts of your program? I have been working on the development of an open-source static analysis tool called Inga. Its purpose is to automate the visualization of API endpoints and UI components influenced by code changes in a continuous integration (CI) environment.
What is AST?
To better understand how code analysis works, let's start by discussing the concept of an Abstract Syntax Tree (AST). When working with code, it is challenging to identify code references and analyze the structure solely based on characters. Therefore, before performing code analysis, we convert the code into AST, which represents the code's structure in a tree-like format.
AST contains the following essential data:
- Type (e.g., class, method)
- Name
- Code range
- Child nodes
How to find the Impact of Code Changes
Now, let's explore how we find the affected code changes using AST. Two key aspects are to consider: definitions (such as methods or members) and references. We compare the code and the AST.
Find Definitions
For example, if we make a code change within the block of the create
method, we can locate the affected definition by examining the start and end text positions of the corresponding AST node.
However, finding references is more complex. Since create
can be defined in multiple places within a project, we cannot rely on a simple search.
process | found name | |
---|---|---|
1 | Get package node name | app.service |
2 | Get class node name | app.service.Order |
3 | Get method node name | app.service.Order.create |
Find References
To find the method invocation, we search for a specific type of AST node that corresponds to the method call. In this case, we are looking for a node that matches the target method name create
, which we have just searched for. From there, we can traverse the tree upwards to determine the class name and eventually obtain the unique name "app.service.Order.create," which is associated with the target definition.
process | found name | |
---|---|---|
1 | Find the create method call |
create |
2 | Find the class definition of the order member |
Order.create |
3 | Find imports for Order
|
app.service.Order.create |
Conclusion
We can determine the entry points of call references by utilizing a cyclomatic approach to identify unique names within both definitions and references. This analysis technique allows us to work with projects written in multiple languages such as Java and Kotlin.
Inga is currently under development. If you find this tool interesting, please consider giving it a star ⭐️ and providing feedback. Thank you!
seachicken / inga
Visualizing the Impact of Code Changes
A static analysis tool that searches references from changed code to detect entry points that have a strong impact on the user.
Why?
Code changes daily, and it is always important to check the impact of changes In many cases, checking the impact of a change depends on how vigilant the author is in writing the code, making it difficult to detect unintended effects during the code review and QA phases. This tool improves software quality by detecting unintended changes at an early phase.
Supported Languages
- Java
- JavaScript
- Kotlin
- TypeScript
Usage
inga [options]
Options
--diff <string>
Analyze the result of git diff --unified=0
(use "-" to read from standard input)
--root-path <string>
Relative path of the project to be analyzed, so if you do not give this option, it defaults to the command execute path.
--include <string>
Filenames of glob pattern matching to include from analysis. (e.g. "core/**/*.ts")
--exclude
…
Top comments (2)
Nice work :)
This seems related to the coupling / sensitivity measurements in both static and dynamic analysis tools such as Klocwork & Veracode, but presented in a different way? I also came across this paper looking at the differences between static & dynamic coupling measurements: computerscijournal.org/vol3no1/sta...
Thank you for taking this on as a FOSS project!
The difference in purpose is that this tool aims to allow non-developers, such as QA, to see the impact of changes. (easy-to-understand reports are produced by inga-ui ).
I also want to run at high speed, so I attempt to analyze only static, text-based information as much as possible. As you can see in that link, it is difficult to analyze loosely coupled references such as dynamic bindings, but I will attempt to do so because I think it is possible to do a text-based analysis so that a person can read the code and recognize the linkage 😃