Skip to content

Commit 1241770

Browse files
committed
Handle BinOp: e.g., "half = ip.getWidth / 2" so that it knows "half" is number.
1 parent 71296fa commit 1241770

1 file changed

Lines changed: 27 additions & 1 deletion

File tree

‎src/main/java/org/scijava/plugins/scripteditor/jython/JythonScriptParser.java‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.python.antlr.PythonTree;
4141
import org.python.antlr.ast.Assign;
4242
import org.python.antlr.ast.Attribute;
43+
import org.python.antlr.ast.BinOp;
4344
import org.python.antlr.ast.Call;
4445
import org.python.antlr.ast.ClassDef;
4546
import org.python.antlr.ast.Expr;
@@ -65,6 +66,7 @@
6566
import org.python.core.CompileMode;
6667
import org.python.core.CompilerFlags;
6768
import org.python.core.ParserFacade;
69+
import org.python.core.PyFloat;
6870
import org.python.core.PyInteger;
6971
import org.python.core.PyObject;
7072
import org.python.indexer.types.NModuleType;
@@ -354,7 +356,7 @@ static public DotAutocompletions parseRight(final PyObject right, final Scope sc
354356
// e.g. return 10
355357
// e.g. n = 42
356358
final Class<?> c = ((Num)right).getInternalN().getClass() == PyInteger.class ? Long.TYPE : Double.TYPE; // TODO this creates trouble for Scope.findVarsByType and would be perhaps easier as Long and Double (non-primitive).
357-
return new VarDotAutocompletions(c.toString());
359+
return new VarDotAutocompletions(c.toString()); // becomes "long" or "double"
358360
}
359361
if (right instanceof Str) {
360362
// Literal String
@@ -397,6 +399,30 @@ static public DotAutocompletions parseRight(final PyObject right, final Scope sc
397399
final Yield yield = (Yield)right;
398400
return parseRight(yield.getValue(), scope);
399401
}
402+
if (right instanceof BinOp) {
403+
// e.g., division, multiplication, addition, subtraction
404+
// What actual type is returned, I don't know: python allows operator overloading.
405+
final BinOp binop = (BinOp)right;
406+
// Weak attempt at finding out what is it (will not succeed if neither is a number)
407+
// TODO this should be done recursively
408+
JythonDev.printTrace("BinOp: weak attempt at finding out what kind of number it returns.");
409+
// First, check if any is a number
410+
final Class<?> typeL = binop.getLeft().isNumberType() ? ((Num)binop.getLeft()).getInternalN().getClass() : null,
411+
typeR = binop.getRight().isNumberType() ? ((Num)binop.getRight()).getInternalN().getClass() : null;
412+
if (null != typeL || null != typeR) {
413+
// If both are integers
414+
if (typeL == PyInteger.class && typeR == PyInteger.class)
415+
return new VarDotAutocompletions(Long.class.toString()); // long
416+
// If any is a float
417+
if (typeL == PyFloat.class || typeR == PyFloat.class)
418+
return new VarDotAutocompletions(Double.class.toString()); // double
419+
}
420+
// Go by whatever left is, or if empty, whatever right is: no guarantee to be correct, but can be correct often
421+
final DotAutocompletions da = parseRight(binop.getLeft(), scope);
422+
if (da != DotAutocompletions.EMPTY)
423+
return da;
424+
return parseRight(binop.getRight(), scope);
425+
}
400426

401427
JythonDev.printTrace("Unsupported 'right' is: " + right + " " + (right != null ? right.getClass() : ""));
402428

0 commit comments

Comments
 (0)