- General info
- Requirements
- API usage guidelines
- Location information
- How to build and run
- How to add as a Maven dependency
- Tool
ReExtractor is a library/API written in Java that can detect refactorings applied between two successive versions of a Java project.
Currently, it supports the detection of the following refactorings:
supported by ReExtractor 1.0 and newer versions
- Rename Method
- Rename Attribute
- Rename Class
- Move Class
- Extract Class
- Extract Method
- Inline Method
- Change Return Type
- Change Attribute Type
supported by ReExtractor 2.0 and newer versions
- Move Method
- Move Attribute
- Pull Up Method
- Pull Up Attribute
- Push Down Method
- Push Down Attribute
- Extract Superclass
- Extract Interface
- Extract and Move Method
- Move and Rename Class
- Extract Subclass
- Extract Variable
- Inline Variable
- Rename Variable
- Rename Parameter
- Move and Rename Attribute
- Change Variable Type
- Change Parameter Type
- Move and Rename Method
- Move and Inline Method
- Add Method Annotation
- Remove Method Annotation
- Modify Method Annotation
- Add Attribute Annotation
- Remove Attribute Annotation
- Modify Attribute Annotation
- Add Class Annotation
- Remove Class Annotation
- Modify Class Annotation
- Add Parameter Annotation
- Remove Parameter Annotation
- Modify Parameter Annotation
- Add Variable Annotation
- Remove Variable Annotation
- Modify Variable Annotation
- Add Parameter
- Remove Parameter
- Reorder Parameter
- Add Thrown Exception Type
- Remove Thrown Exception Type
- Change Thrown Exception Type
- Change Method Access Modifier
- Change Attribute Access Modifier
- Add Method Modifier (
final
,static
,abstract
,synchronized
) - Remove Method Modifier (
final
,static
,abstract
,synchronized
) - Add Attribute Modifier (
final
,static
,transient
,volatile
) - Remove Attribute Modifier (
final
,static
,transient
,volatile
) - Add Variable Modifier (
final
) - Add Parameter Modifier (
final
) - Remove Variable Modifier (
final
) - Remove Parameter Modifier (
final
) - Change Class Access Modifier
- Add Class Modifier (
final
,static
,abstract
) - Remove Class Modifier (
final
,static
,abstract
) - Change Type Declaration Kind (
class
,interface
,enum
) - Replace Loop with Pipeline
- Replace Anonymous with Lambda
- Replace Pipeline with Loop
- Split Conditional
- Invert Condition
- Merge Conditional
- Change Loop Type *
- Merge Declaration and Assignment *
- Replace if with Ternary Operator *
- Loop Interchange *
* not supported by other refactoring detection tools
Java 17 or newer
Apache Maven 3.8 or newer
ReExtractor can automatically detect refactorings between two successive versions of a git repository.
In the code snippet below we demonstrate how to print all refactorings performed at a specific commit in the toy project https://github.com/danilofes/refactoring-toy-example.git. The commit is identified by its SHA key, such as in the example below:
GitService gitService = new GitServiceImpl();
try (Repository repo = gitService.openRepository("E:/refactoring-toy-example")) {
RefactoringExtractorService extractor = new RefactoringExtractorServiceImpl();
extractor.detectAtCommit(repo, "d4bce13a443cf12da40a77c16c1e591f4f985b47", new RefactoringHandler() {
@Override
public void handle(String commitId, List<Refactoring> refactorings) {
System.out.println("Refactorings at " + commitId);
for (Refactoring ref : refactorings) {
System.out.println(ref.toString());
}
}
@Override
public void handleException(String commit, Exception e) {
System.err.println("Error processing commit " + commit);
e.printStackTrace(System.err);
}
});
}
All classes implementing the Refactoring
interface include refactoring-specific location information.
For example, ExtractOperationRefactoring
offers the following methods:
getSourceOperationBeforeExtraction()
: Returns the code entity associated with the source method in the parent commitgetSourceOperationAfterExtraction()
: Returns the code entity associated with the source method in the child commitgetExtractedOperation()
: Returns the code entity associated with the extracted method in the child commit
Each code entity offers the LocationInfo getLocation()
method to return a LocationInfo
object including the following properties:
String filePath
int startLine
int endLine
int startColumn
int endColumn
Alternatively, you can use the methods LocationInfo leftSide()
and LocationInfo rightSide()
to get the LocationInfo
objects for the left side (i.e., parent commit) and the right side (i.e., child commit) of the refactoring, respectively.
-
Clone repository
git clone https://github.com/lyoubo/ReExtractor.git
-
Cd in the locally cloned repository folder
cd ReExtractor
-
Build ReExtractor
mvn install
-
Run the API usage example shown in README
mvn compile exec:java -Dexec.mainClass="org.reextractor.ReExtractor" -Dexec.args="-c refactoring-toy-example d4bce13a443cf12da40a77c16c1e591f4f985b47"
-
Clone repository
git clone https://github.com/lyoubo/ReExtractor.git
-
Import project
Go to File -> Open...
Browse to the root directory of project ReExtractor
Click OK
The project will be built automatically.
-
Run the API usage examples shown in README
From the Project tab navigate to
org.reextractor.ReExtractor
Right-click on the file and select Run ReExtractor.main()
You can add the -json <path-to-json-file>
command arguments to save the JSON output in a file. The results are appended to the file after each processed commit.
In both cases, you will get the output in JSON format:
{
"results": [
{
"repository": "https://github.com/danilofes/refactoring-toy-example.git",
"sha1": "d4bce13a443cf12da40a77c16c1e591f4f985b47",
"url": "https://github.com/danilofes/refactoring-toy-example/commit/d4bce13a443cf12da40a77c16c1e591f4f985b47",
"refactorings": [
{
"type": "MOVE_OPERATION",
"description": "Move Method public barkBark(manager DogManager) : void from class org.animals.Dog to public barkBark(dog Dog) : void from class org.DogManager",
"leftSideLocation": [
{
"filePath": "src/org/animals/Dog.java",
"startLine": 14,
"endLine": 21,
"startColumn": 2,
"endColumn": 3,
"codeElementType": "METHOD_DECLARATION",
"description": "original method declaration",
"codeElement": "public barkBark(manager DogManager) : void"
}
],
"rightSideLocation": [
{
"filePath": "src/org/DogManager.java",
"startLine": 25,
"endLine": 32,
"startColumn": 2,
"endColumn": 3,
"codeElementType": "METHOD_DECLARATION",
"description": "moved method declaration",
"codeElement": "public barkBark(dog Dog) : void"
}
]
},
{
"type": "RENAME_PARAMETER",
"description": "Rename Parameter manager : DogManager to dog : Dog in method public barkBark(dog Dog) : void from class org.DogManager",
"leftSideLocation": [
{
"filePath": "src/org/animals/Dog.java",
"startLine": 14,
"endLine": 14,
"startColumn": 23,
"endColumn": 41,
"codeElementType": "SINGLE_VARIABLE_DECLARATION",
"description": "original variable declaration",
"codeElement": "manager : DogManager"
},
{
"filePath": "src/org/animals/Dog.java",
"startLine": 14,
"endLine": 21,
"startColumn": 2,
"endColumn": 3,
"codeElementType": "METHOD_DECLARATION",
"description": "original method declaration",
"codeElement": "public barkBark(manager DogManager) : void"
}
],
"rightSideLocation": [
{
"filePath": "src/org/DogManager.java",
"startLine": 25,
"endLine": 25,
"startColumn": 23,
"endColumn": 30,
"codeElementType": "SINGLE_VARIABLE_DECLARATION",
"description": "renamed variable declaration",
"codeElement": "dog : Dog"
},
{
"filePath": "src/org/DogManager.java",
"startLine": 25,
"endLine": 32,
"startColumn": 2,
"endColumn": 3,
"codeElementType": "METHOD_DECLARATION",
"description": "method declaration with renamed variable",
"codeElement": "public barkBark(dog Dog) : void"
}
]
},
{
"type": "CHANGE_PARAMETER_TYPE",
"description": "Change Parameter Type manager : DogManager to dog : Dog in method public barkBark(dog Dog) : void from class org.DogManager",
"leftSideLocation": [
{
"filePath": "src/org/animals/Dog.java",
"startLine": 14,
"endLine": 14,
"startColumn": 23,
"endColumn": 41,
"codeElementType": "SINGLE_VARIABLE_DECLARATION",
"description": "original variable declaration",
"codeElement": "manager : DogManager"
},
{
"filePath": "src/org/animals/Dog.java",
"startLine": 14,
"endLine": 21,
"startColumn": 2,
"endColumn": 3,
"codeElementType": "METHOD_DECLARATION",
"description": "original method declaration",
"codeElement": "public barkBark(manager DogManager) : void"
}
],
"rightSideLocation": [
{
"filePath": "src/org/DogManager.java",
"startLine": 25,
"endLine": 25,
"startColumn": 23,
"endColumn": 30,
"codeElementType": "SINGLE_VARIABLE_DECLARATION",
"description": "changed-type variable declaration",
"codeElement": "dog : Dog"
},
{
"filePath": "src/org/DogManager.java",
"startLine": 25,
"endLine": 32,
"startColumn": 2,
"endColumn": 3,
"codeElementType": "METHOD_DECLARATION",
"description": "method declaration with changed variable type",
"codeElement": "public barkBark(dog Dog) : void"
}
]
}
]
}
]
}
To add ReExtractor as a maven dependency in your project, add the following snippet to your project's pom.xml:
<dependency>
<groupId>io.github.lyoubo</groupId>
<artifactId>refactoring-extractor</artifactId>
<version>2.3.0</version>
</dependency>
To get refactoring information when inspecting a commit of a Java project, you can use our RefactoringExtractor tool.
- Git Repository: Local or cloned Java project
- Commit SHA1: Git commit ID
- JSON File Path: JSON output file