Skip to content

Commit

Permalink
Refactor junit, javac smooth functions (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikosik committed Nov 16, 2024
1 parent d72fdc1 commit de6c82f
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 79 deletions.
Original file line number Diff line number Diff line change
@@ -1,59 +1,14 @@
package org.smoothbuild.stdlib.compress;

import static org.smoothbuild.stdlib.java.UnjarFunc.JAR_MANIFEST_PATH;
import static org.smoothbuild.virtualmachine.bytecode.helper.FileStruct.fileContent;
import static org.smoothbuild.virtualmachine.bytecode.helper.FileStruct.filePath;
import static org.smoothbuild.virtualmachine.evaluate.plugin.UnzipBlob.unzipBlob;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
import org.smoothbuild.virtualmachine.bytecode.BytecodeException;
import org.smoothbuild.virtualmachine.bytecode.expr.base.BArray;
import org.smoothbuild.virtualmachine.bytecode.expr.base.BBlob;
import org.smoothbuild.virtualmachine.bytecode.expr.base.BTuple;
import org.smoothbuild.virtualmachine.evaluate.plugin.NativeApi;

public class UnzipHelper {
private static final Predicate<String> NOT_MANIFEST_PREDICATE = f -> !f.equals(JAR_MANIFEST_PATH);

public static HashMap<String, BTuple> filesFromLibJars(
NativeApi nativeApi, BArray libJars, Predicate<String> filter) throws BytecodeException {
var result = new HashMap<String, BTuple>();
var jars = libJars.elements(BTuple.class);
for (int i = 0; i < jars.size(); i++) {
var jarFile = jars.get(i);
var classes = filesFromJar(nativeApi, jarFile, filter);
if (classes == null) {
return null;
}
for (var entry : classes.entrySet()) {
var path = entry.getKey();
if (result.put(path, entry.getValue()) != null) {
nativeApi
.log()
.error("File " + path + " is contained by two different library jar files.");
return null;
}
}
}
return result;
}

public static Map<String, BTuple> filesFromJar(NativeApi nativeApi, BTuple jarFile)
throws BytecodeException {
return filesFromJar(nativeApi, jarFile, NOT_MANIFEST_PREDICATE);
}

private static Map<String, BTuple> filesFromJar(
NativeApi nativeApi, BTuple jarFile, Predicate<String> filter) throws BytecodeException {
var files = unzipToArrayB(nativeApi, fileContent(jarFile), filter);
if (files == null) {
return null;
}
return files.elements(BTuple.class).toMap(f -> filePath(f).toJavaString(), x -> x);
}

public static BArray unzipToArrayB(
NativeApi nativeApi, BBlob blob, Predicate<String> includePredicate)
throws BytecodeException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.smoothbuild.stdlib.file;

import static org.smoothbuild.virtualmachine.bytecode.helper.FileStruct.filePath;

import java.util.HashMap;
import org.smoothbuild.virtualmachine.bytecode.BytecodeException;
import org.smoothbuild.virtualmachine.bytecode.expr.base.BArray;
import org.smoothbuild.virtualmachine.bytecode.expr.base.BTuple;
import org.smoothbuild.virtualmachine.evaluate.plugin.NativeApi;

public class FileHelper {
public static HashMap<String, BTuple> fileArrayArrayToMap(
NativeApi nativeApi, BArray fileArrayArray) throws BytecodeException {
var result = new HashMap<String, BTuple>();
for (BArray fileArray : fileArrayArray.elements(BArray.class)) {
if (fileArrayToMap(nativeApi, fileArray, result)) {
return null;
}
}
return result;
}

public static HashMap<String, BTuple> fileArrayToMap(NativeApi nativeApi, BArray fileArray)
throws BytecodeException {
var result = new HashMap<String, BTuple>();
if (fileArrayToMap(nativeApi, fileArray, result)) {
return null;
}
return result;
}

private static boolean fileArrayToMap(
NativeApi nativeApi, BArray fileArray, HashMap<String, BTuple> result)
throws BytecodeException {
for (var entry : fileArray.elements(BTuple.class)) {
var path = filePath(entry).toJavaString();
if (result.put(path, entry) != null) {
nativeApi.log().error("File " + path + " is contained by two different library jar files.");
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

import static java.nio.charset.Charset.defaultCharset;
import static org.smoothbuild.common.collect.List.listOfAll;
import static org.smoothbuild.stdlib.compress.UnzipHelper.filesFromLibJars;
import static org.smoothbuild.stdlib.java.util.JavaNaming.isClassFilePredicate;
import static org.smoothbuild.stdlib.file.FileHelper.fileArrayArrayToMap;

import java.io.IOException;
import java.io.StringWriter;
Expand All @@ -22,24 +21,24 @@
public class JavacFunc {
public static BValue func(NativeApi nativeApi, BTuple args) throws BytecodeException {
BArray srcs = (BArray) args.get(0);
BArray libs = (BArray) args.get(1);
BArray fileArrayArray = (BArray) args.get(1);
BArray options = (BArray) args.get(2);

return new Worker(nativeApi, srcs, libs, options).execute();
return new Worker(nativeApi, srcs, fileArrayArray, options).execute();
}

private static class Worker {
private final JavaCompiler compiler;
private final NativeApi nativeApi;
private final BArray srcs;
private final BArray libs;
private final BArray fileArrayArray;
private final BArray options;

public Worker(NativeApi nativeApi, BArray srcs, BArray libs, BArray options) {
public Worker(NativeApi nativeApi, BArray srcs, BArray fileArrayArray, BArray options) {
this.compiler = ToolProvider.getSystemJavaCompiler();
this.nativeApi = nativeApi;
this.srcs = srcs;
this.libs = libs;
this.fileArrayArray = fileArrayArray;
this.options = options;
}

Expand All @@ -62,7 +61,7 @@ public BArray compile(BArray files) throws BytecodeException {
var diagnostic = new LoggingDiagnosticListener(nativeApi);
var options = options();
var standardJFM = compiler.getStandardFileManager(diagnostic, null, defaultCharset());
var libsClasses = classesFromJarFiles(nativeApi, libs);
var libsClasses = filesToInputClassFiles(nativeApi, fileArrayArray);
if (libsClasses == null) {
return null;
}
Expand Down Expand Up @@ -125,11 +124,12 @@ private static Iterable<InputSourceFile> toJavaFiles(Iterable<BTuple> sourceFile
}
}

public static Iterable<InputClassFile> classesFromJarFiles(
NativeApi nativeApi, BArray libraryJars) throws BytecodeException {
var filesMap = filesFromLibJars(nativeApi, libraryJars, isClassFilePredicate());
return filesMap == null
? null
: listOfAll(filesMap.entrySet()).map(e -> new InputClassFile(e.getValue(), e.getKey()));
public static Iterable<InputClassFile> filesToInputClassFiles(
NativeApi nativeApi, BArray fileArrayArray) throws BytecodeException {
var result = fileArrayArrayToMap(nativeApi, fileArrayArray);
if (result == null) {
return null;
}
return listOfAll(result.entrySet()).map(e -> new InputClassFile(e.getValue(), e.getKey()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
import static okio.Okio.buffer;
import static org.smoothbuild.common.bucket.base.Path.path;
import static org.smoothbuild.common.reflect.ClassLoaders.mapClassLoader;
import static org.smoothbuild.stdlib.compress.UnzipHelper.filesFromJar;
import static org.smoothbuild.stdlib.compress.UnzipHelper.filesFromLibJars;
import static org.smoothbuild.stdlib.file.FileHelper.fileArrayArrayToMap;
import static org.smoothbuild.stdlib.file.FileHelper.fileArrayToMap;
import static org.smoothbuild.stdlib.java.junit.JUnitCoreWrapper.newInstance;
import static org.smoothbuild.stdlib.java.util.JavaNaming.isClassFilePredicate;
import static org.smoothbuild.stdlib.java.util.JavaNaming.toBinaryName;
import static org.smoothbuild.virtualmachine.bytecode.helper.FileStruct.fileContent;
import static org.smoothbuild.virtualmachine.bytecode.helper.FileStruct.filePath;
Expand All @@ -30,16 +29,16 @@
public class JunitFunc {
public static BValue func(NativeApi nativeApi, BTuple args)
throws IOException, BytecodeException {
BTuple tests = (BTuple) args.get(0);
BArray testFileArray = (BArray) args.get(0);
BArray deps = (BArray) args.get(1);
BString include = (BString) args.get(2);

try {
var filesFromTests = filesFromJar(nativeApi, tests);
var filesFromTests = fileArrayToMap(nativeApi, testFileArray);
if (filesFromTests == null) {
return null;
}
var filesFromDeps = filesFromLibJars(nativeApi, deps, isClassFilePredicate());
var filesFromDeps = fileArrayArrayToMap(nativeApi, deps);
if (filesFromDeps == null) {
return null;
}
Expand Down
12 changes: 9 additions & 3 deletions src/standard-library/src/main/smooth/std_lib.smooth
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,20 @@ Blob jar([File] files, Blob manifest = 0x);
[String] options = [],
) = javac_(
srcs = srcs,
libs = libs,
libs = jarsToFiles(libs),
options = concat([["-source", source, "-target", target], options]));

@Native("org.smoothbuild.stdlib.java.javac.JavacFunc")
[File] javac_([File] srcs, [File] libs = [], [String] options = []);
[File] javac_([File] srcs, [[File]] libs = [], [String] options = []);

String junit(File tests, [File] deps = [], String include = "**Test.class") =
junit_(unzip(tests.content), jarsToFiles(deps), include);

@Native("org.smoothbuild.stdlib.java.junit.JunitFunc")
String junit(File tests, [File] deps = [], String include = "**Test.class");
String junit_([File] tests, [[File]] deps, String include);

[[File]] jarsToFiles([File] libs) =
map(libs, (File lib) -> filterFiles(unzip(lib.content), "**.class"));

@Native("org.smoothbuild.stdlib.string.ToBlobFunc")
Blob toBlob(String string);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,28 @@

import static com.google.common.truth.Truth.assertThat;
import static org.smoothbuild.common.bucket.base.Path.path;
import static org.smoothbuild.stdlib.java.javac.JavacFunc.classesFromJarFiles;
import static org.smoothbuild.virtualmachine.testing.JarTester.jarByteString;
import static org.smoothbuild.stdlib.java.javac.JavacFunc.filesToInputClassFiles;

import org.junit.jupiter.api.Test;
import org.smoothbuild.virtualmachine.bytecode.expr.base.BTuple;
import org.smoothbuild.virtualmachine.testing.VmTestContext;

public class JavacFuncTest extends VmTestContext {
@Test
void files_from_library_jars_are_accessible_as_java_objects() throws Exception {
BTuple file1 = bFile(path("my/package/MyKlass.class"));
BTuple file2 = bFile(path("my/package/MyKlass2.class"));
BTuple jar = bFile("myFile.jar", bBlob(jarByteString(file1, file2)));
assertThat(classesFromJarFiles(nativeApi(), bArray(jar)))
var file1 = bFile(path("my/package/MyKlass.class"));
var file2 = bFile(path("my/package/MyKlass2.class"));
var fileArrayArray = bArray(bArray(file1, file2));
assertThat(filesToInputClassFiles(nativeApi(), fileArrayArray))
.containsExactly(new InputClassFile(file1), new InputClassFile(file2));
}

@Test
void duplicate_class_file_exception() throws Exception {
String name = "my/package/MyKlass.class";
BTuple file1 = bFile(path(name));
BTuple jar = bFile("myFile.jar", bBlob(jarByteString(file1)));
var name = "my/package/MyKlass.class";
var file1 = bFile(path(name));
var fileArrayArray = bArray(bArray(file1), bArray(file1));
var nativeApi = nativeApi();
assertThat(classesFromJarFiles(nativeApi, bArray(jar, jar))).isNull();
assertThat(filesToInputClassFiles(nativeApi, fileArrayArray)).isNull();
assertThat(nativeApi.messages())
.isEqualTo(bArray(
bErrorLog("File " + name + " is contained by two different library jar files.")));
Expand Down

0 comments on commit de6c82f

Please sign in to comment.