Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
andre15silva committed Jul 18, 2024
1 parent bcbbf4c commit ea5f78c
Show file tree
Hide file tree
Showing 6 changed files with 302 additions and 0 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Test

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/[email protected]
- name: Set up JDK 11
uses: actions/[email protected]
with:
java-version: '11'
distribution: 'adopt'
- name: Test with Maven
run: mvn test
86 changes: 86 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.github.assertkth</groupId>
<artifactId>extractor</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Java Code Extractor</name>
<description>A simple code extractor for Java.</description>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
<version>4.7.6</version>
</dependency>

<dependency>
<groupId>com.github.javaparser</groupId>
<artifactId>javaparser-symbol-solver-core</artifactId>
<version>3.26.1</version>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.github.assertkth.extractor.App</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
36 changes: 36 additions & 0 deletions src/main/java/com/github/assertkth/extractor/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.github.assertkth.extractor;

import java.util.List;
import java.util.concurrent.Callable;

import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

@Command(name = "App", mixinStandardHelpOptions = true, description = "Java Code Extractor")
public class App implements Callable<Integer> {

@Option(names = { "-i", "--input" }, required = true, description = "Input file")
private String input;

@Option(names = { "-l", "--lines" }, required = true, description = "List of modified lines")
private List<Integer> lines;

@Override
public Integer call() throws Exception {
String result = Extractor.extract(input, lines);

if (result != null) {
System.out.println(result);
return 0;
} else {
return 1;
}
}

public static void main(String[] args) {
int exitCode = new CommandLine(new App()).execute(args);
System.exit(exitCode);
}

}
60 changes: 60 additions & 0 deletions src/main/java/com/github/assertkth/extractor/Extractor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.github.assertkth.extractor;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.ConstructorDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;

public class Extractor {

public static String extract(String file, List<Integer> lines) throws IOException {
// Read the code and parse it
JavaParser parser = new JavaParser();
Node root = parser.parse(new FileInputStream(file)).getResult().get();

// Find biggest function in number of lines (methods or constructors) in the code that contain all given lines
Node function = null;
for (MethodDeclaration method : root.findAll(MethodDeclaration.class)) {
boolean containsAllLines = true;
for (int line : lines) {
if (!(method.getRange().isPresent() && method.getRange().get().begin.line <= line && method.getRange().get().end.line >= line)) {
containsAllLines = false;
break;
}
}
if (containsAllLines && (function == null || (method.getRange().get().end.line - method.getRange().get().begin.line) > (function.getRange().get().end.line - function.getRange().get().begin.line)))
function = method;
}
for (ConstructorDeclaration constructor : root.findAll(ConstructorDeclaration.class)) {
boolean containsAllLines = true;
for (int line : lines) {
if (!(constructor.getRange().isPresent() && constructor.getRange().get().begin.line <= line && constructor.getRange().get().end.line >= line)) {
containsAllLines = false;
break;
}
}
if (containsAllLines && (function == null || (constructor.getRange().get().end.line - constructor.getRange().get().begin.line) > (function.getRange().get().end.line - function.getRange().get().begin.line)))
function = constructor;
}

// Extract string from file that corresponds to the function (including javadoc)
String extracted = "";
if (function != null) {
Integer begin = function.getComment().isPresent() ? function.getComment().get().getRange().get().begin.line - 1 : function.getRange().get().begin.line - 1;
Integer end = function.getRange().get().end.line - 1;
String[] linesArray = new String[0];
try (FileInputStream fis = new FileInputStream(file)) {
linesArray = new String(fis.readAllBytes()).split("\n");
}
for (int i = begin; i <= end; i++) {
extracted += linesArray[i] + "\n";
}
}

return function != null ? extracted : null;
}
}
71 changes: 71 additions & 0 deletions src/test/java/com/github/assertkth/extractor/ExtractorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.github.assertkth.extractor;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

import java.io.IOException;
import java.util.List;

import org.junit.jupiter.api.Test;

import com.github.assertkth.extractor.Extractor;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.ConstructorDeclaration;

class ExtractorTest {

@Test
void testConstructor() throws IOException {
// Regular constructor
String function = Extractor.extract("src/test/resources/ExampleClass.java", List.of(3, 4));
assertEquals(" public ExampleClass() {\n" + //
" System.out.println(\"Constructor\");\n" + //
" }\n", function);
}

@Test
void testMethod1() throws IOException {
// Regular method
String function = Extractor.extract("src/test/resources/ExampleClass.java", List.of(7, 8, 9));
assertEquals(" public void method1() {\n" + //
" System.out.println(\"Method 1\");\n" + //
" }\n", function);
}

@Test
void testMethod2() throws IOException {
// Method with annotation
String function = Extractor.extract("src/test/resources/ExampleClass.java", List.of(12, 13, 14));
assertEquals(" @Override\n" + //
" private void method2() {\n" + //
" System.out.println(\"Method 2\");\n" + //
" System.out.println(\"Method 2\");\n" + //
" }\n", function);
}

@Test
void testMethod3() throws IOException {
// Method with Javadoc and annotation
String function = Extractor.extract("src/test/resources/ExampleClass.java", List.of(20, 22, 23));
assertEquals(" @Override\n" + //
" /*\n" + //
" * This is a javadoc comment\n" + //
" */\n" + //
" public void method3() {\n" + //
" // Normal comment\n" + //
" System.out.println(\"Method 3\");\n" + //
" System.out.println(\"Method 3\");\n" + //
" System.out.println(\"Method 3\");\n" + //
" }\n", function);
}

@Test
void testNoMethod() throws IOException {
String function = Extractor.extract("src/test/resources/ExampleClass.java", List.of(1, 2, 10, 23));
assertNull(function);

function = Extractor.extract("src/test/resources/ExampleClass.java", List.of(5, 6));
assertNull(function);
}

}
27 changes: 27 additions & 0 deletions src/test/resources/ExampleClass.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
public class ExampleClass {

public ExampleClass() {
System.out.println("Constructor");
}

public void method1() {
System.out.println("Method 1");
}

@Override
private void method2() {
System.out.println("Method 2");
System.out.println("Method 2");
}

@Override
/*
* This is a javadoc comment
*/
public void method3() {
// Normal comment
System.out.println("Method 3");
System.out.println("Method 3");
System.out.println("Method 3");
}
}

0 comments on commit ea5f78c

Please sign in to comment.