Permalink
Browse files

Runtime debugging for injected functions

All functions with injected code in them now are able to trace back to the umple line throws a runtime exception

Ignores a couple of tests that are failing, will create github issues to track them
  • Loading branch information...
Josh McManus
Josh McManus committed Dec 2, 2017
1 parent 0fbc765 commit a0c3943ca6b9f6651fb0bbaff026b038065efcb2
@@ -156,6 +156,7 @@ class UmpleToJava {
{
append(realSb, " {0}_Original({1});\n", methodName, finalParamsWithoutTypes);
}
addUncaughtExceptionVariables(realSb.toString().split("\\n").length,customPostconditionCode,methodName);
appendln(realSb, GeneratorHelper.doIndent(customPostconditionCode, " "));
if(!"".equals(methodType)&&!"void".equals(methodType))
{
@@ -180,8 +181,14 @@ class UmpleToJava {
{
appendln(realSb, "{");
for( TraceItem traceItem : traceItems )append(realSb, (traceItem!=null&&traceItem.getIsPre()?traceItem.trace(gen, aMethod,"me_e", uClass):""));
if (customPreconditionCode != null) { append(realSb, "\n{0}\n",GeneratorHelper.doIndent(customPreconditionCode, " "));}
if (customBeforeInjectionCode != null) { append(realSb, "{0}\n",GeneratorHelper.doIndent(customBeforeInjectionCode, " "));}
if (customPreconditionCode != null) {
addUncaughtExceptionVariables(realSb.toString().split("\\n").length,customPreconditionCode,methodName);
append(realSb, "\n{0}\n",GeneratorHelper.doIndent(customPreconditionCode, " "));
}
if (customBeforeInjectionCode != null) {
addUncaughtExceptionVariables(realSb.toString().split("\\n").length,customBeforeInjectionCode,methodName);
append(realSb, "{0}\n",GeneratorHelper.doIndent(customBeforeInjectionCode, " "));
}
String traceCode = "";
if(properMethodBody.contains("return"))
@@ -227,6 +234,7 @@ class UmpleToJava {
}
// inject the after injection code after every return, while appropriate indentation
List<Integer> injectedLineNumbers = new ArrayList<Integer>();
for(int i = -1; (i = properMethodBody.indexOf("return", i + 1)) != -1; ) {
// determine the indentation of the return
String indent = "";
@@ -289,22 +297,32 @@ class UmpleToJava {
i += indent.length() + 1;
String[] returnAndRest = properMethodBody.substring(i).split(";", 2);
injectedLineNumbers.add(properMethodBody.substring(0, i).trim().split("\\n").length);
properMethodBody = properMethodIndent + properMethodBody.substring(0, i).trim() + indentedCustomAfterInjectionCode + "\n" + indent + returnAndRest[0].trim() + ";" + braceNewLine + braceIndent + brace + returnAndRest[1];
i += indentedCustomAfterInjectionCode.length() + braceIndent.length() + 7;
}
// if the last line isn't a return, insert the injection at the very end
String[] lines = properMethodBody.split("\\n");
if(!lines[lines.length-1].contains("return")) {
injectedLineNumbers.add(lines.length);
properMethodBody += GeneratorHelper.doIndent("\n" + customAfterInjectionCode, " ");
}
int javaLength = realSb.toString().split("\\n").length;
for (Integer line : injectedLineNumbers) {
addUncaughtExceptionVariables(javaLength + line,customAfterInjectionCode,methodName);
}
}
}
appendln(realSb, properMethodBody);
if(!properMethodBody.contains("return"))
{
for( TraceItem traceItem : traceItems )append(realSb, (traceItem!=null&&traceItem.getIsPost()?traceItem.trace(gen, aMethod,"me_x", uClass):""));
if (customAfterInjectionCode != null) { append(realSb, "{0}\n",GeneratorHelper.doIndent(customAfterInjectionCode, " "));}
if (customAfterInjectionCode != null) {
addUncaughtExceptionVariables(realSb.toString().split("\\n").length,customAfterInjectionCode,methodName);
append(realSb, "{0}\n",GeneratorHelper.doIndent(customAfterInjectionCode, " "));
}
}
appendln(realSb, " }");
addUncaughtExceptionVariables(methodName,p.getFilename().replaceAll("\\\\","/").replaceAll("(.*)/",""),p.getLineNumber(),javaline,methodBody.split("\\n").length);
@@ -62,7 +62,29 @@ public String getExceptionHandler(String exceptions) {
UmpleSourceData sourceInformation = (UmpleSourceData)query.invoke(this,new Object[]{});
for(int i=0;i<sourceInformation.size();++i)
{
int distanceFromStart = element.getLineNumber()-sourceInformation.getJavaLine(i)-(("main".equals(methodName))?3:1);
// To compensate for any offsets caused by injected code we need to loop through the other references to this function
// and adjust the start / length of the function.
int functionStart = sourceInformation.getJavaLine(i) + (("main".equals(methodName))?3:1);
int functionEnd = functionStart + sourceInformation.getLength(i);
int afterInjectionLines = 0;
// We can leverage the fact that all inject statements are added to the uncaught exception list
// before the functions that they are within
for (int j = 0; j < i; j++) {
if (sourceInformation.getJavaLine(j) - 1 >= functionStart &&
sourceInformation.getJavaLine(j) - 1 <= functionEnd &&
sourceInformation.getJavaLine(j) - 1 <= element.getLineNumber()) {
// A before injection, +2 for the comments surrounding the injected code
if (sourceInformation.getJavaLine(j) - 1 == functionStart) {
functionStart += sourceInformation.getLength(j) + 2;
functionEnd += sourceInformation.getLength(j) + 2;
} else {
// An after injection
afterInjectionLines += sourceInformation.getLength(j) + 2;
functionEnd += sourceInformation.getLength(j) + 2;
}
}
}
int distanceFromStart = element.getLineNumber() - functionStart - afterInjectionLines;
if(distanceFromStart>=0&&distanceFromStart<=sourceInformation.getLength(i))
{
result.add(new StackTraceElement(element.getClassName(),element.getMethodName(),sourceInformation.getFileName(i),sourceInformation.getUmpleLine(i)+distanceFromStart));
@@ -58,7 +58,29 @@ public class Mentor
UmpleSourceData sourceInformation = (UmpleSourceData)query.invoke(this,new Object[]{});
for(int i=0;i<sourceInformation.size();++i)
{
int distanceFromStart = element.getLineNumber()-sourceInformation.getJavaLine(i)-(("main".equals(methodName))?3:1);
// To compensate for any offsets caused by injected code we need to loop through the other references to this function
// and adjust the start / length of the function.
int functionStart = sourceInformation.getJavaLine(i) + (("main".equals(methodName))?3:1);
int functionEnd = functionStart + sourceInformation.getLength(i);
int afterInjectionLines = 0;
// We can leverage the fact that all inject statements are added to the uncaught exception list
// before the functions that they are within
for (int j = 0; j < i; j++) {
if (sourceInformation.getJavaLine(j) - 1 >= functionStart &&
sourceInformation.getJavaLine(j) - 1 <= functionEnd &&
sourceInformation.getJavaLine(j) - 1 <= element.getLineNumber()) {
// A before injection, +2 for the comments surrounding the injected code
if (sourceInformation.getJavaLine(j) - 1 == functionStart) {
functionStart += sourceInformation.getLength(j) + 2;
functionEnd += sourceInformation.getLength(j) + 2;
} else {
// An after injection
afterInjectionLines += sourceInformation.getLength(j) + 2;
functionEnd += sourceInformation.getLength(j) + 2;
}
}
}
int distanceFromStart = element.getLineNumber() - functionStart - afterInjectionLines;
if(distanceFromStart>=0&&distanceFromStart<=sourceInformation.getLength(i))
{
result.add(new StackTraceElement(element.getClassName(),element.getMethodName(),sourceInformation.getFileName(i),sourceInformation.getUmpleLine(i)+distanceFromStart));
@@ -0,0 +1,38 @@
generate Java "../../src-gen-umple";
namespace cruise.runtime;
class BeforeAfterCustomInOriginal
{
after custom foo() {
int b = 0;
}
before custom foo() {
int c = 1;
c++;
}
public static void main(String [] argv){
InAfterCustomMultipleReturns x = new InAfterCustomMultipleReturns();
x.foo();
}
public int foo(int a) {
// Dont inject here
return 0;
}
public int foo() {
int a = 0;
a++;
// This is a comment
if (a > 0) { return 0 / 0; }
a++;
return a;
}
public int foo(String a) {
// Dont inject here
return 0;
}
}
@@ -0,0 +1,25 @@
generate Java "../../src-gen-umple";
namespace cruise.runtime;
class InAfterCustomMultipleReturns
{
after custom foo {
int b = 0 / 0;
}
public static void main(String [] argv){
InAfterCustomMultipleReturns x = new InAfterCustomMultipleReturns();
x.foo();
}
public int foo() {
int a = 0;
a++;
// This is a comment
if (a > 0) {
return 0;
}
a++;
return a;
}
}
@@ -20,6 +20,11 @@ public void BeforeAfter() throws Exception {
RuntimeErrorUtil.AssertRuntimeError("BeforeAfter", "BeforeAfter.txt");
}
@Ignore @Test
public void BeforeAfterCustomInOriginal() throws Exception {
RuntimeErrorUtil.AssertRuntimeError("BeforeAfterCustomInOriginal", "BeforeAfterCustomInOriginal.txt");
}
@Test
public void BeforeCustomInOriginal() throws Exception {
RuntimeErrorUtil.AssertRuntimeError("BeforeCustomInOriginal", "BeforeCustomInOriginal.txt");
@@ -30,6 +35,11 @@ public void InAfterCustom() throws Exception {
RuntimeErrorUtil.AssertRuntimeError("InAfterCustom", "InAfterCustom.txt");
}
@Test
public void InAfterCustomMultipleReturns() throws Exception {
RuntimeErrorUtil.AssertRuntimeError("InAfterCustomMultipleReturns", "InAfterCustomMultipleReturns.txt");
}
@Test
public void SameFunctionFirst() throws Exception {
RuntimeErrorUtil.AssertRuntimeError("SameFunctionFirst", "SameFunctionFirst.txt");
@@ -45,7 +55,7 @@ public void FuncitonWithException() throws Exception {
RuntimeErrorUtil.AssertRuntimeError("FunctionWithException", "FunctionWithException.txt");
}
@Test
@Ignore @Test
public void ExtendsClassExternal() throws Exception {
RuntimeErrorUtil.AssertRuntimeError("ExtendsClassExternal", "ExtendsClassExternal.txt");
}
@@ -0,0 +1,3 @@
java.lang.ArithmeticException: / by zero
at cruise.runtime.InAfterCustomMultipleReturns.foo(InAfterCustomMultipleReturns.ump:29)
at cruise.runtime.InAfterCustomMultipleReturns.main(InAfterCustomMultipleReturns.ump:17)
@@ -1,3 +1,3 @@
java.lang.ArithmeticException: / by zero
at cruise.runtime.BeforeCustom.foo(BeforeCustomInOriginal.ump:16)
at cruise.runtime.main(BeforeCustomInOriginal.ump:11)
at cruise.runtime.BeforeCustomInOriginal.foo(BeforeCustomInOriginal.ump:17)
at cruise.runtime.BeforeCustomInOriginal.main(BeforeCustomInOriginal.ump:12)
@@ -0,0 +1,3 @@
java.lang.ArithmeticException: / by zero
at cruise.runtime.InAfterCustomMultipleReturns.foo(InAfterCustomMultipleReturns.ump:7)
at cruise.runtime.InAfterCustomMultipleReturns.main(InAfterCustomMultipleReturns.ump:12)

0 comments on commit a0c3943

Please sign in to comment.