Skip to content

Commit

Permalink
Fix for #1493: context imports and re-write in and instanceof checks
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Jul 6, 2023
1 parent 97948e8 commit 8e5798b
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import org.eclipse.debug.core.ILaunch
import org.eclipse.debug.core.ILaunchManager
import org.eclipse.debug.core.model.IThread
import org.eclipse.jdt.debug.core.IJavaDebugTarget
import org.eclipse.jdt.debug.core.IJavaObject
import org.eclipse.jdt.debug.eval.IEvaluationResult
import org.eclipse.jdt.internal.debug.ui.BreakpointUtils
import org.junit.Before
Expand Down Expand Up @@ -80,8 +81,65 @@ final class EvaluationEngineTests extends GroovyEclipseTestSuite {
}
}

@Test // https://github.com/groovy/groovy-eclipse/issues/1491
@Test
void testEvalSnippet3() {
def (launch, thread) = runToLine(3, '''\
|public class Main {
| public static void main(String[] args) {
| System.out.println("hello world");
| }
|}
|'''.stripMargin())

try {
IEvaluationResult result = evaluate('"baz" in args', thread)
assert !result.hasErrors() : result.errorMessages[0]
assert result.value.booleanValue
} finally {
launch.terminate()
}
}

@Test
void testEvalSnippet4() {
def (launch, thread) = runToLine(3, '''\
|public class Main {
| public static void main(String[] args) {
| System.out.println("hello world");
| }
|}
|'''.stripMargin())

try {
IEvaluationResult result = evaluate('"buzz" !in args', thread)
assert !result.hasErrors() : result.errorMessages[0]
assert result.value.booleanValue
} finally {
launch.terminate()
}
}

@Test
void testEvalSnippet5() {
def (launch, thread) = runToLine(3, '''\
|public class Main {
| public static void main(String[] args) {
| System.out.println("hello world");
| }
|}
|'''.stripMargin())

try {
IEvaluationResult result = evaluate('args[2] <=> args[1]', thread)
assert !result.hasErrors() : result.errorMessages[0]
assert result.value.intValue > 0 // 'baz' > 'bar'
} finally {
launch.terminate()
}
}

@Test // https://github.com/groovy/groovy-eclipse/issues/1491
void testEvalSnippet6() {
def (launch, thread) = runToLine(4, '''\
|public class Main {
| public static void main(String[] args) {
Expand All @@ -101,7 +159,7 @@ final class EvaluationEngineTests extends GroovyEclipseTestSuite {
}

@Test // https://github.com/groovy/groovy-eclipse/issues/1492
void testEvalSnippet4() {
void testEvalSnippet7() {
def (launch, thread) = runToLine(3, '''\
|public class Main {
| public static void main(String[] args) {
Expand All @@ -120,7 +178,7 @@ final class EvaluationEngineTests extends GroovyEclipseTestSuite {
}

@Test // https://github.com/groovy/groovy-eclipse/issues/1492
void testEvalSnippet5() {
void testEvalSnippet8() {
def (launch, thread) = runToLine(3, '''\
|public class Main {
| public static void main(String[] args) {
Expand All @@ -138,13 +196,92 @@ final class EvaluationEngineTests extends GroovyEclipseTestSuite {
}
}

@Test // https://github.com/groovy/groovy-eclipse/issues/1493
void testEvalSnippet9() {
def (launch, thread) = runToLine(4, '''\
|public class Main {
| public static void main(String[] args) {
| var pe = new org.codehaus.groovy.ast.expr.PropertyExpression(null, "foo");
| System.out.println("hello world");
| }
|}
|'''.stripMargin())

try {
IEvaluationResult result = evaluate('getProperty() instanceof ConstantExpression', thread, thread.findVariable('pe').value)
assert !result.hasErrors() : result.errorMessages[0]
assert result.value.booleanValue
} finally {
launch.terminate()
}
}

@Test // https://github.com/groovy/groovy-eclipse/issues/1493
void testEvalSnippet10() {
def (launch, thread) = runToLine(4, '''\
|public class Main {
| public static void main(String[] args) {
| var pe = new org.codehaus.groovy.ast.expr.PropertyExpression(null, "foo");
| System.out.println("hello world");
| }
|}
|'''.stripMargin())

try {
IEvaluationResult result = evaluate('getProperty() !instanceof VariableExpression', thread, thread.findVariable('pe').value)
assert !result.hasErrors() : result.errorMessages[0]
assert result.value.booleanValue
} finally {
launch.terminate()
}
}

@Test // https://github.com/groovy/groovy-eclipse/issues/1493
void testEvalSnippet11() {
def (launch, thread) = runToLine(3, '''\
|public class Main {
| public static void main(String[] args) {
| System.out.println("hello world");
| }
|}
|'''.stripMargin())

try {
IEvaluationResult result = evaluate('getState() instanceof State', thread, thread.threadObject) // State is an inner class
assert !result.hasErrors() : result.errorMessages[0]
assert result.value.booleanValue
} finally {
launch.terminate()
}
}

@Test
void testEvalSnippet12() {
def (launch, thread) = runToLine(4, '''\
|import static java.util.regex.Pattern.*;
|public class Main {
| public static void main(String[] args) {
| System.out.println("hello world");
| }
|}
|'''.stripMargin())

try {
IEvaluationResult result = evaluate('compile("") !== null', thread) // StaticImportVisitor and JDIScriptLoader transforms
assert !result.hasErrors() : result.errorMessages[0]
assert result.value.booleanValue
} finally {
launch.terminate()
}
}

//--------------------------------------------------------------------------

IEvaluationResult evaluate(String snippet, IThread thread) {
IEvaluationResult evaluate(String source, IThread thread, IJavaObject o = null) {
assert thread.isSuspended()
def result = new SynchronousQueue<IEvaluationResult>()
def engine = jdiPlugin.getEvaluationEngine(packageFragmentRoot.javaProject, (IJavaDebugTarget) thread.debugTarget)
engine.evaluate(snippet, thread.topStackFrame, result.&put, DebugEvent.EVALUATION, false)
engine.evaluate(source, *(o ? [o, thread] : [thread.topStackFrame]), result.&put, DebugEvent.EVALUATION, false)
result.poll(5, TimeUnit.SECONDS)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,23 @@ public ICompiledExpression getCompiledExpression(String snippet, IJavaStackFrame

@Override
public ICompiledExpression getCompiledExpression(String snippet, IJavaReferenceType type) throws DebugException {
return getCompiledExpression(snippet, type, Collections.emptyMap());
StringBuilder header = new StringBuilder();

String typeName = type.getName();
if (!typeName.endsWith("]")) {
int i = typeName.lastIndexOf('.');
if (i != -1) {
String packageName = typeName.substring(0, i);
if (!"java.lang".equals(packageName)) {
header.append("import ").append(packageName);
header.append(".*;\n");
}
}

header.append("import static ").append(typeName).append(".*;\n");
}

return getCompiledExpression(snippet, type, Collections.singletonMap("header", header.toString()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ private boolean invoke(String methodName, Object o1, Object o2) throws DebugExce
return result.getBooleanValue();
}

public boolean isCase(Object o1, Object o2) throws DebugException {
return invoke("isCase", o1, o2);
}

public boolean isEqual(Object o1, Object o2) throws DebugException {
return invoke("compareEqual", o1, o2);
}
Expand All @@ -81,6 +85,10 @@ public boolean isLessThanOrEqual(Object o1, Object o2) throws DebugException {
return invoke("compareLessThanEqual", o1, o2);
}

public boolean isNotCase(Object o1, Object o2) throws DebugException {
return invoke("isNotCase", o1, o2);
}

public boolean isNotEqual(Object o1, Object o2) throws DebugException {
return invoke("compareNotEqual", o1, o2);
}
Expand All @@ -91,6 +99,9 @@ public boolean isNotIdentical(Object o1, Object o2) throws DebugException {

static String methodNameFor(Token operation) {
switch (operation.getType()) {
case Types.COMPARE_TO:
return "compareTo";

case Types.COMPARE_LESS_THAN:
return "isLessThan";

Expand All @@ -103,6 +114,14 @@ static String methodNameFor(Token operation) {
case Types.COMPARE_GREATER_THAN_EQUAL:
return "isGreaterThanOrEqual";

case Types.KEYWORD_IN:
case Types.KEYWORD_INSTANCEOF:
return "isCase";

case Types.COMPARE_NOT_IN:
case Types.COMPARE_NOT_INSTANCEOF:
return "isNotCase";

case Types.COMPARE_EQUAL:
return "isEqual";

Expand All @@ -115,9 +134,6 @@ static String methodNameFor(Token operation) {
case Types.COMPARE_NOT_IDENTICAL:
return "isNotIdentical";

case Types.COMPARE_TO:
return "compareTo";

default:
return null;
}
Expand Down

0 comments on commit 8e5798b

Please sign in to comment.