Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions core/src/org/sbml/jsbml/math/compiler/UnitsCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -727,12 +727,23 @@ private <T> ASTNode2Value<?> invalid() {
@Override
// TODO: Specify generic type T i.e. ASTNode2Value<?>
public <T> ASTNode2Value<?> lambda(List<ASTNode2> values) throws SBMLException {
// When the lambda node is first constructed, its child list may be empty;
// in that case, there is no body and no arguments yet, so we cannot derive
// any meaningful units. Returning an invalid unit definition here avoids
// out-of-bounds exceptions while signalling "units unknown".
if (values == null || values.isEmpty()) {
return invalid();
}

// For a fully-formed lambda expression, all but the last child are
// arguments; the last child is the body whose units we want to derive.
for (int i = 0; i < values.size() - 1; i++) {
namesToUnits.put(values.get(i).toString(),
values.get(i).compile(this));
namesToUnits.put(values.get(i).toString(), values.get(i).compile(this));
}
return new ASTNode2Value(values.get(values.size() - 1).compile(this)
.getUnits(), this);

return new ASTNode2Value(
values.get(values.size() - 1).compile(this).getUnits(),
this);
}

/* (non-Javadoc)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.sbml.jsbml.math.compiler;

import static org.junit.Assert.*;

import java.util.Collections;

import org.junit.Test;
import org.sbml.jsbml.math.ASTNode2;
// no import needed for ASTNode2Value since we are in the same package
// or, if you prefer, you could import:
// import org.sbml.jsbml.math.compiler.ASTNode2Value;

/**
* Regression tests for lambda handling in {@link UnitsCompiler}.
*/
public class UnitsCompilerLambdaTest {

/**
* Issue #248: Deriving units for a lambda expression while its child list
* is still empty must not cause an IndexOutOfBoundsException.
*/
@Test
public void testLambdaWithNoChildrenDoesNotThrow() throws Exception {
UnitsCompiler compiler = new UnitsCompiler(3, 1); // arbitrary level/version

ASTNode2Value<?> result = null;
try {
result = compiler.lambda(Collections.<ASTNode2>emptyList());
} catch (IndexOutOfBoundsException ex) {
fail("lambda() must not throw IndexOutOfBoundsException when values list is empty: " + ex);
}

assertNotNull("lambda() should return a non-null ASTNode2Value", result);
assertTrue("lambda() with no children should return invalid units",
result.getUnits().isInvalid());
}
}