Skip to content

Commit

Permalink
Merge final release, with extra cache
Browse files Browse the repository at this point in the history
Final release, with extra cache
  • Loading branch information
rodrigorato authored Apr 24, 2018
2 parents 37b404b + b205352 commit 80fbe6a
Show file tree
Hide file tree
Showing 62 changed files with 1,299 additions and 47 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# Generated test outputs
*.my_out
*.my_extended_out

### Intellij+all ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
Expand Down
12 changes: 11 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,17 @@ run {
if (project.hasProperty('runArgs')) {
args findProperty('runArgs')
} else {
args = ['ist.meic.pa.GenericFunctions.examples.combine.CombineExample']
args = ['ist.meic.pa.GenericFunctions.examples.TestJ']
}
}

task runExtended (type: JavaExec) {
classpath sourceSets.main.runtimeClasspath
main = 'ist.meic.pa.GenericFunctionsExtended.WithGenericFunctions'
if (project.hasProperty('runArgs')) {
args findProperty('runArgs')
} else {
args = ['ist.meic.pa.GenericFunctionsExtended.examples.TestJ']
}
}

Expand Down
22 changes: 22 additions & 0 deletions runExtendedTests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

TESTS_DIR=./tests_outputs/

# Compile as described in the project guide
gradle compileJava build

# Delete old out files
rm tests_outputs/*my*out

# Run tests with Gradle and save output to file
for t in src/main/java/ist/meic/pa/GenericFunctionsExtended/examples/Test*.java; do
test_name=$(basename $t .java)
test_letter=$(echo $test_name | sed -r 's/Test//g')

gradle clean runExtended -PrunArgs='ist.meic.pa.GenericFunctionsExtended.examples.'$test_name -q > $TESTS_DIR$test_letter.my_extended_out

echo "Diff on "$test_name":"
colordiff --strip-trailing-cr $TESTS_DIR$test_letter.my_extended_out $TESTS_DIR$test_letter.out

done

3 changes: 3 additions & 0 deletions runTests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ TESTS_DIR=./tests_outputs/
# Compile as described in the project guide
gradle compileJava build

# Delete old out files
rm tests_outputs/*my*out

# Run tests with Gradle and save output to file
for t in src/main/java/ist/meic/pa/GenericFunctions/examples/Test*.java; do
test_name=$(basename $t .java)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import javassist.CtMethod;
import javassist.NotFoundException;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedList;

Expand Down Expand Up @@ -61,7 +60,7 @@ public static Object callBack(Class originalClass, String methodLongName, Object
invokedSuccessful = false;

// And if it's not the method we're running right now
if (!methodLongName.equals(getLongNameFromMethod(best))) {
if (!methodLongName.equals(MethodUtils.getLongNameFromMethod(best))) {
Object result = null;
try {
// Call the actual method
Expand All @@ -83,11 +82,6 @@ public static Object callBack(Class originalClass, String methodLongName, Object
return null; // We're done here!
}

private static String getLongNameFromMethod(Method m) {
String[] names = m.toString().split(" ");
return names[names.length -1];
}

private static void doBeforeMethods(Class originalClass, Object[] originalArgs){

Method[] methods = originalClass.getDeclaredMethods();
Expand Down Expand Up @@ -115,19 +109,7 @@ private static void doBeforeMethods(Class originalClass, Object[] originalArgs){
}
}

isSetup = true;
for (Method m : beforeMethods) {
m.setAccessible(true);

try {
m.invoke(null,originalArgs);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
isSetup = false;
MethodUtils.callMethodList(beforeMethods,originalArgs,"");
}

private static void doAfterMethods(Class originalClass, Object[] originalArgs){
Expand Down Expand Up @@ -157,20 +139,7 @@ private static void doAfterMethods(Class originalClass, Object[] originalArgs){
}
}

isSetup = true;
for (Method m : afterMethods) {

m.setAccessible(true);

try {
m.invoke(null,originalArgs);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
isSetup = false;
MethodUtils.callMethodList(afterMethods,originalArgs,"");

}

Expand All @@ -179,10 +148,9 @@ public static Method findBestMethod(Class originalClass, Object[] args) {

Method bestMethod = null;
for(Method candidate : allMethods) {
if(MethodUtils.isMethodApplicable(candidate, args) && !isSetupMethod(candidate)) {
if(MethodUtils.isMethodApplicable(candidate, args) && !MethodUtils.isSetupMethod(candidate)) {
if (bestMethod == null ||
MethodUtils.isMethodMoreSpecific(args, candidate, bestMethod)) {
//System.out.println("New best is\n" + candidate);
bestMethod = candidate;
}
}
Expand All @@ -191,30 +159,26 @@ public static Method findBestMethod(Class originalClass, Object[] args) {

}

public static boolean isSetupMethod(Method m) {
return m.isAnnotationPresent(AfterMethod.class) || m.isAnnotationPresent(BeforeMethod.class);
}

private String generateCallBackFunctionCall(String methodName, String returnClassName) {
String code = "";

if (returnClassName.equals("void")){
code += "if (!ist.meic.pa.GenericFunctions.injectors.GenericCallInjector.isSetup){" +
" ist.meic.pa.GenericFunctions.injectors.GenericCallInjector" +
code += "if (!" + GenericCallInjector.class.getCanonicalName() + ".isSetup){" +
" " + GenericCallInjector.class.getCanonicalName() +
" ." + callBackFunctionName + "($class, \"" + methodName + "\", $args);" +
" if(ist.meic.pa.GenericFunctions.injectors.GenericCallInjector.invokedSuccessful){" +
" if(" + GenericCallInjector.class.getCanonicalName() + ".invokedSuccessful){" +
" return;" +
" }" +
"}";
} else {
code += "Object ret = ist.meic.pa.GenericFunctions.injectors.GenericCallInjector" +
code += "Object ret = " + GenericCallInjector.class.getCanonicalName() +
" ." + callBackFunctionName + "($class, \"" + methodName + "\", $args);" +
"if(ret != null) {" +
" return (" + returnClassName + ")ret;" +
"}";
}

code += "if(!ist.meic.pa.GenericFunctions.injectors.GenericCallInjector" +
code += "if(!" + GenericCallInjector.class.getCanonicalName() +
" .existsApplicableMethod) {" +
" return " + (returnClassName.equals("void") ? "" : "null") + ";" +
"}";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,51 @@
package ist.meic.pa.GenericFunctions.injectors.utils;

import ist.meic.pa.GenericFunctions.AfterMethod;
import ist.meic.pa.GenericFunctions.BeforeMethod;
import ist.meic.pa.GenericFunctions.injectors.GenericCallInjector;

import java.lang.reflect.Method;
import java.util.List;

public class MethodUtils {

public static boolean isMethodMoreSpecific(Object[] originalArgs, Method thisMethod, Method thatMethod) {
public static Object callMethodList(List<Method> methods, Object[] arguments, String currentMethod) {
Object ret = null;
try {
for(Method m : methods) {
m.setAccessible(true);
if(isSetupMethod(m)){
GenericCallInjector.isSetup = true;
m.invoke(null, arguments);
GenericCallInjector.isSetup = false;
} else if(!currentMethod.equals(getLongNameFromMethod(m))) {
GenericCallInjector.beforeMethodsDone = true;
ret = m.invoke(null, arguments);
}
}

GenericCallInjector.beforeMethodsDone = false;
return ret;
} catch (Exception e) {
// Can't really do anything
e.printStackTrace();
}
return null;
}

public static String getLongNameFromMethod(Method m) {
String[] names = m.toString().split(" ");
return names[names.length - 1];
}

/**
* @return true if the method is a before or an after method
*/
public static boolean isSetupMethod(Method m) {
return m.isAnnotationPresent(AfterMethod.class) || m.isAnnotationPresent(BeforeMethod.class);
}

public static boolean isMethodMoreSpecific(Object[] originalArgs, Method thisMethod, Method thatMethod) {
return compareMethodArguments(originalArgs, thisMethod, thatMethod) < 0;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ist.meic.pa.GenericFunctionsExtended;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AfterMethod {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ist.meic.pa.GenericFunctionsExtended;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface BeforeMethod {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ist.meic.pa.GenericFunctionsExtended;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface GenericFunction {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package ist.meic.pa.GenericFunctionsExtended;

import ist.meic.pa.GenericFunctionsExtended.translator.GenericFunctionTranslator;
import javassist.ClassPool;
import javassist.Loader;
import javassist.NotFoundException;
import javassist.Translator;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

public class WithGenericFunctions {
public static void main(String[] args) {

try {
// Get our translator that will do our instrumentation
Translator translator = new GenericFunctionTranslator();

// Get the current class pool and add our translator to it's loader
ClassPool classPool = ClassPool.getDefault();
Loader classLoader = new Loader();
classLoader.addTranslator(classPool, translator);

// Get the new parameters for the class we're about to hand over control to
String[] parameters = Arrays.copyOfRange(args, 1, args.length);

// Hand over control, providing the right arguments
classLoader.run(args[0], parameters);

} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("No main class was specified! Can't hand over control, ending.");
System.exit(-1);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | NotFoundException e) {
// Can't really do anything about this, let's just end the program
System.out.println("Reflection failed...");
System.exit(-1);
} catch (Throwable throwable) {
System.out.println("Failed to run main class! - " + throwable.getMessage());
System.exit(-1);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ist.meic.pa.GenericFunctionsExtended.examples;


import ist.meic.pa.GenericFunctionsExtended.examples.domain.Black;
import ist.meic.pa.GenericFunctionsExtended.examples.domain.Blue;
import ist.meic.pa.GenericFunctionsExtended.examples.domain.Color;
import ist.meic.pa.GenericFunctionsExtended.examples.domain.Red;

public class TestA {
public static void main(String[] args) {
Color[] colors = new Color[] { new Red(), new Blue(), new Black()};
for(Color c : colors) System.out.println(Color.mix(c));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ist.meic.pa.GenericFunctionsExtended.examples;


import ist.meic.pa.GenericFunctionsExtended.examples.domain.Com;

public class TestB {
public static void main(String[] args) {
Object[] objects = new Object[] { new Object(), "Foo", 123};
for(Object c : objects) System.out.println(Com.bine(c));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ist.meic.pa.GenericFunctionsExtended.examples;

import ist.meic.pa.GenericFunctionsExtended.examples.domain.Black;
import ist.meic.pa.GenericFunctionsExtended.examples.domain.Color;
import ist.meic.pa.GenericFunctionsExtended.examples.domain.Red;

public class TestC {
public static void main(String[] args) {
Object colors = new Object[] { new Red(), 2.9, new Black(), "Holla!"};
System.out.println(Color.mix(colors));
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ist.meic.pa.GenericFunctionsExtended.examples;


import ist.meic.pa.GenericFunctionsExtended.examples.domain.Com;

public class TestD {
public static void main(String[] args) {
Object objects = new Object[] { "Foo", new Integer[] {123, -12}};
System.out.println(Com.bine(objects));

Object numbers = new Object[] { 123, new Integer[] {456 , 21}};
System.out.println(Com.bine(numbers));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ist.meic.pa.GenericFunctionsExtended.examples;

import ist.meic.pa.GenericFunctionsExtended.examples.domain.Identify;

public class TestE {
public static void main(String[] args) {
Object objects = new Object[] { 123, "Foo", 1.2};
System.out.println(Identify.it(objects));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ist.meic.pa.GenericFunctionsExtended.examples;

import ist.meic.pa.GenericFunctionsExtended.examples.domain.Bug;
import ist.meic.pa.GenericFunctionsExtended.examples.domain.C1;
import ist.meic.pa.GenericFunctionsExtended.examples.domain.C2;

public class TestF {
public static void main(String[] args) {
Object c1 = new C1(), c2 = new C2();
Bug.bug(c1);
Bug.bug(c2);
}
}
Loading

0 comments on commit 80fbe6a

Please sign in to comment.