Skip to content

Commit

Permalink
method chaining bug fixed:
Browse files Browse the repository at this point in the history
method chaining only worked for method chains that were params of other methods
  • Loading branch information
miho committed Aug 19, 2015
1 parent c407c52 commit 383f9ec
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,11 @@ private void render(Invocation i, CodeBuilder cb, boolean inParam) {
return;
}

if (inParam) {
ObjectProvider objP = i.getObjectProvider();

if(objP.getInvocation().isPresent()) {
render(objP.getInvocation().get(),cb, true);
}
ObjectProvider objP = i.getObjectProvider();

if (objP.getInvocation().isPresent()) {
// TODO 19.08.2015 reconsider misuse of 'inParam' as 'inChain'
render(objP.getInvocation().get(), cb, true);
}

if (i.isConstructor()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ private String newVarName() {

/**
* Returns the previous intermediate variable name.
*
* @return previous intermediate variable name
*/
private String previousVarName() {
Expand All @@ -95,6 +96,7 @@ private String previousVarName() {

/**
* Returns the current intermediate variable name.
*
* @return current intermediate variable name
*/
private String currentVarName() {
Expand Down Expand Up @@ -132,7 +134,7 @@ private boolean isWhileLoop(Invocation inv) {
* @param invocations invocations that shall be considered
* @param inv invocation
* @return list that contains the specifried invocation and all connected
* invocations
* invocations
*/
private List<Invocation> getInvAndConnectedInvs(ControlFlow cf,
List<Invocation> invocations, Invocation inv) {
Expand Down Expand Up @@ -385,6 +387,7 @@ private void instrumentNonLoopInvocation(ControlFlow cf, int i,
Argument retValArg = Argument.nullArg();
Invocation nextI = null;
boolean retValIsObjectOfNextI = false;

if (!lastInvocation) {
nextI = invocations.get(i + 1);
retValIsObjectOfNextI = isRetValObjectOfNextInv(inv, nextI);
Expand All @@ -407,17 +410,26 @@ private void instrumentNonLoopInvocation(ControlFlow cf, int i,
// variable
if (invocationTarget.isPresent()) {
// search argument indices
int[] argumentsToReplace = invocationTarget.get().getArguments().stream().
filter(a -> Objects.equals(a.getInvocation().orElse(null), inv)).
mapToInt(a -> invocationTarget.get().getArguments().indexOf(a)).toArray();
int[] argumentsToReplace = invocationTarget.get().
getArguments().stream().
filter(a -> Objects.equals(a.getInvocation().
orElse(null), inv)).
mapToInt(a -> invocationTarget.get().
getArguments().indexOf(a)).toArray();
// replace args
for (int aIndex : argumentsToReplace) {
invocationTarget.get().getArguments().set(aIndex,
Argument.varArg(cf.getParent().getVariable(varName)));
Argument.varArg(cf.getParent().
getVariable(varName)));
}
}

if (retValIsObjectOfNextI && nextI !=null) {
}

if (nextI != null && nextI.getMethodName().contains("return")
&& inv.getMethodName().contains("toCSG")) {
System.out.println("");
}

if (retValIsObjectOfNextI && nextI != null) {
// if the result of the current invocation is used as
// invocation object then we need to call the next invocation
// on the previously defined tmp variable that stores the return
Expand Down Expand Up @@ -454,12 +466,9 @@ private void instrumentNonLoopInvocation(ControlFlow cf, int i,
*/
private boolean isRetValObjectOfNextInv(Invocation inv, Invocation nextI) {

boolean retValIsObjectOfNextI =
nextI.getObjectProvider().getInvocation().isPresent() &&
nextI.getObjectProvider().getInvocation().get().equals(inv);
// TODO 04.08.2015 chained method check buggy, needs to be modeled too
// = nextI.getVariableName() != null
// && nextI.getVariableName().isEmpty();
boolean retValIsObjectOfNextI
= nextI.getObjectProvider().getInvocation().isPresent()
&& nextI.getObjectProvider().getInvocation().get().equals(inv);
return retValIsObjectOfNextI;
}

Expand Down Expand Up @@ -540,7 +549,7 @@ private void instrumentWhileLoop(
// the original while-loop behavior
VisualCodeBuilder builder = new VisualCodeBuilder_Impl();
IfDeclaration ifDecl = builder.invokeIf(whileScope, Argument.varArg(cf.getParent().
getVariable(varName)));
getVariable(varName)));
Invocation conditionIfInv = whileScope.getControlFlow().
getInvocations().get(
whileScope.getControlFlow().getInvocations().
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package eu.mihosoft.vrl.lang.model;

import eu.mihosoft.vrl.lang.model.transform.*;
import eu.mihosoft.vrl.base.IOUtil;
import eu.mihosoft.vrl.instrumentation.InstrumentationEventType;
import eu.mihosoft.vrl.instrumentation.VRLInstrumentationUtil;
import groovy.lang.GroovyClassLoader;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import junit.framework.Assert;
import org.codehaus.groovy.control.CompilationFailedException;
import org.junit.Test;

/**
*
* @author Michael Hoffer &lt;[email protected]&gt;
*/
public class MethodChainingTest {

public static InputStream getResourceAsStream(String resourceName) {
return CommentTest.class.getResourceAsStream("/eu/mihosoft/vrl/lang/" + resourceName);
}

public static Reader getResourceAsStringReader(String resourceName) {

return new StringReader(getResourceAsString(resourceName));
}

public static String getResourceAsString(String resourceName) {
InputStream is = CommentTest.class.getResourceAsStream("/eu/mihosoft/vrl/lang/" + resourceName);
String tmpCode = IOUtil.convertStreamToString(is);
return tmpCode;
}

@Test
public void methodChaining() {
createInstrumentationTest("MethodChaining01.groovy");
}

public void createInstrumentationTest(String fileName) {

UIBinding.scopes.clear();

String code = getResourceAsString(fileName);

// checking whether sample code compiles and generate model
boolean successCompile = false;
try {
GroovyClassLoader gcl = new GroovyClassLoader();
gcl.parseClass(code);
successCompile = true;

} catch (Exception ex) {
Logger.getLogger(LangModelTest.class.getName()).log(Level.SEVERE, null, ex);
}

Assert.assertTrue(fileName + ": " + "Sample code must compile", successCompile);
Assert.assertTrue(fileName + ": " + "UIBindings.scopes must be initialized", UIBinding.scopes != null);
Assert.assertTrue(fileName + ": " + "UIBindings must contain exactly one scope, got " + UIBinding.scopes.size(), UIBinding.scopes.size() == 1);

// generating new code from model
String newCode = "";
CompilationUnitDeclaration cu = null;
for (Collection<Scope> scopeList : UIBinding.scopes.values()) {
for (Scope s : scopeList) {
if (s instanceof CompilationUnitDeclaration) {
cu = (CompilationUnitDeclaration) s;
newCode = Scope2Code.getCode(cu);
break;
}
}
}

System.out.println(newCode);

// InstrumentCode instrumentCode = new InstrumentCode();
//
// CompilationUnitDeclaration newCu = instrumentCode.transform(cu);
//
// String instrumentedCode = Scope2Code.getCode(newCu);
//
// VRLInstrumentationUtil.addEventHandler(InstrumentationEventType.PRE_INVOCATION,
// (evt) -> {
// System.out.println("pre-evt:\t" + evt.toString());
// });
// VRLInstrumentationUtil.addEventHandler(InstrumentationEventType.POST_INVOCATION,
// (evt) -> {
// System.out.println("post-evt:\t" + evt.toString());
// });

// System.out.println(instrumentedCode);
//
// try {
// GroovyClassLoader gcl = new GroovyClassLoader();
// Class<?> instrumentedCodeClass = gcl.parseClass(instrumentedCode);
// instrumentedCodeClass.getMethod("main", String[].class).
// invoke(instrumentedCodeClass, (Object) new String[0]);
//
// } catch (CompilationFailedException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
// Logger.getLogger(LangModelTest.class.getName()).log(Level.SEVERE, null, ex);
// }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,15 @@ public static String getResourceAsString(String resourceName) {

@Test
public void instrumentationTest() {
// createInstrumentationTest("Instrumentation01.groovy");
// createInstrumentationTest("Instrumentation02.groovy");
createInstrumentationTest("Instrumentation03.groovy");
}

public void createInstrumentationTest(String fileName) {

UIBinding.scopes.clear();

String fileName = "Instrumentation02.groovy";

String code = getResourceAsString(fileName);

// checking whether sample code compiles and generate model
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ package my.testpackage;
@eu.mihosoft.vrl.instrumentation.VRLVisualization
public class MyFileClass {

private MyFileClass m(int a) {
println("m: " + a);
return this;
}

public static void main(String[] args) {

int a = 2+3*2;
Expand All @@ -21,16 +16,5 @@ public class MyFileClass {
if (b<a) {
println("a<b: " + (b < a));
}

int i = 0;

while(i<a) {
// println("i: " + i);
i++;
}

MyFileClass mfc = new MyFileClass();

mfc.m(a).m(b)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* global comment*/

package my.testpackage;

/**
* class MyFileClass
*/
@eu.mihosoft.vrl.instrumentation.VRLVisualization
public class MyFileClass {

private MyFileClass m(int a) {
println("m: " + a);
return this;
}

public static void main(String[] args) {

int a = 2+3*2;
int b = 5-a;

if (b<a) {
println("a<b: " + (b < a));
}

int i = 0;

while(i<a) {
println("i: " + i);
i+=1;
}

MyFileClass mfc = new MyFileClass();

mfc.m(a).m(a)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

/**
*
* @author Michael Hoffer &lt;[email protected]&gt;
*/
@eu.mihosoft.vrl.instrumentation.VRLVisualization
public class MethodChaining01 {
public MethodChaining01 mym(int a) {
return this;
}

public MethodChaining01 mym2(int a) {
return new MethodChaining01().mym(1).mym(1); ;
}

public static void main(String[] args) {
new MethodChaining01().mym(1).mym2(2);
}
}

0 comments on commit 383f9ec

Please sign in to comment.