This project is a C++ extension of RefactoringMiner.
The goal of this project is to extend RefactoringMiner to detect refactorings in C++ programs. To achieve this, we have developed a separate tool that parses the Abstract Syntax Tree (AST) of a C++ program into a model. This model is then imported into RefactoringMiner, enabling it to detect refactorings in C++ source code.
Note: This project is still a work in progress. While the foundational features are in place, additional functionality and improvements are actively ongoing.
This repository contains two tools:
CAP: CAP is the C++ AST Parser that we developed specifically for RefactoringMiner. It traverses the AST of a C++ program to create a model representation that matches the exact format required by RefactoringMiner.
RefactoringMiner (adapted version): This is the adapted version of RefactoringMiner that has been extended to support the import of C++ models generated by CAP.
Make sure you are using Clang 18 and Java 17 to build CAP and the adapted version of RefactoringMiner, respectively.
Use the provided Makefile. Run the following command in tools/cap/:
make
This will produce an executable called cap in the same directory.
RefactoringMiner requires Gradle 7.4 or newer to build. Run the following command in tools/RefactoringMiner/ to build the project and skip the tests.
./gradlew build -x test
Using RefactoringMiner for C++ programs is currently a two-step process:
Use CAP to parse C++ source files and generate the required models for RefactoringMiner. To generate a model from a C++ source file run the following command in tools/cap/:
./cap <path to C++ source file> <path to output model>
Replace <path to C++ source file> with the path to a C++ source file, and <path to output model> with the path where the generated model of the C++ source file should be saved as JSON.
You have to generate one model for the parent version of the source file and another model for the current version of the source file. The parent version is the state of the file before modifications (i.e. the previous commit) and the current version is the most recent state of the file (i.e. the current commit).
Once the models are generated, you can use RefactoringMiner to analyze the models and detect refactorings. Run the following command in tools/RefactoringMiner/:
./gradlew run --args="-cpp <path to parent model> <path to current model>"
Replace <path to parent model> and <path to current model> with the paths to the generated models from Step 1.
Note: Currently, only detections at file level are supported. Refactoring detection in a repository (e.g. across commits) is not yet supported. At this time, models can only be generated for one source file at a time. Support for multiple files is actively being developed and will be available in a future update.
In this section, we will guide you through the process of using RefactoringMiner++ to detect several refactorings in C++ code. This involves generating C++ models using CAP and then importing those models into RefactoringMiner++.
To demonstrate this process, we have prepared an example program located in the demo/ folder.
This folder contains two versions of the program: one before it underwent several modifications(Parent) and one after (Current).
A video demonstration for this example is also available here.
1. Generate C++ models
Switch to the demo/ folder and execute the following commands to generate the parent as well as the current model.
Note: Make sure you have compiled CAP beforehand. See Build
../tools/cap/cap Parent.cpp Parent.json
../tools/cap/cap Current.cpp Current.json
2. Import models into RefactoringMiner
Switch to the tools/RefactoringMiner folder and execute the following command to import the generated models into the adapted version of RefactoringMiner. This will also print all detected refactorings and functionality related changes to the console.
./gradlew run --args="-cpp ../../demo/Parent.json ../../demo/Current.json"
This will print the following output to the console.
================================================================================
Detected Refactorings
================================================================================
The following refactorings were detected:
1)
Rename Class Circle renamed to CircleCalculator
The following lines of the current version were affected by this refactoring:
1
Lines changed in total: 1
2)
Rename Method public getArea(r double) : double renamed to public calcArea(radius double) : double in class CircleCalculator
The following lines of the current version were affected by this refactoring:
4
Lines changed in total: 1
3)
Add Attribute Modifier inline in attribute private PI : double from class CircleCalculator
The following lines of the current version were affected by this refactoring:
2
Lines changed in total: 1
4)
Add Attribute Modifier static in attribute private PI : double from class CircleCalculator
The following lines of the current version were affected by this refactoring:
2
Lines changed in total: 1
5)
Add Attribute Modifier const in attribute private PI : double from class CircleCalculator
The following lines of the current version were affected by this refactoring:
2
Lines changed in total: 1
6)
Add Method Modifier static in method public calcCircumference(radius double) : double from class CircleCalculator
The following lines of the current version were affected by this refactoring:
11
Lines changed in total: 1
7)
Rename Parameter r : double to radius : double in method public calcArea(radius double) : double from class CircleCalculator
The following lines of the current version were affected by this refactoring:
4
5
Lines changed in total: 2
8)
Add Method Modifier static in method public calcArea(radius double) : double from class CircleCalculator
The following lines of the current version were affected by this refactoring:
4
Lines changed in total: 1
================================================================================
Detected Functionality Changes
================================================================================
The following functionality related changes were detected:
Line 7 - 10: added operation
Line 12 - 12: modified statement
================================================================================
Summary
================================================================================
5 lines were affected by refactorings.
5 lines were affected by functionality related changes.