} else if (methodName.equals("getElementAsToken")) {
final InequalityTerm matrixTerm = baseTerm;
InequalityTerm returnTypeTerm = new MonotonicFunction() {
public Object getValue() throws IllegalActionException {
if (matrixTerm.getValue() instanceof MatrixType) {
MatrixType type = (MatrixType) matrixTerm
.getValue();
return type.getElementType();
} else {
return BaseType.UNKNOWN;
}
}
public InequalityTerm[] getVariables() {
if (matrixTerm.isSettable()) {
InequalityTerm[] terms = new InequalityTerm[1];
terms[0] = matrixTerm;
return terms;
} else {
return new InequalityTerm[0];
}
}
};
return returnTypeTerm;
} else if (methodName.equals("absolute")) {
// Return the same as the input type, unless
// complex, in which case, return double.
final InequalityTerm finalBaseTerm = baseTerm;
final InstanceInvokeExpr finalExpression = r;
InequalityTerm returnValueTerm = new MonotonicFunction() {
public Object getValue() throws IllegalActionException {
if (finalBaseTerm.getValue().equals(
BaseType.COMPLEX)) {
return BaseType.DOUBLE;
}
return finalBaseTerm.getValue();
}
public InequalityTerm[] getVariables() {
ArrayList list = new ArrayList();
if (finalBaseTerm.isSettable()) {
list.add(finalBaseTerm);
}
InequalityTerm[] terms = (InequalityTerm[]) list
.toArray(new InequalityTerm[list.size()]);
return terms;
}
public Object getAssociatedObject() {
return finalExpression;
}
};
return returnValueTerm;
}
} else if (SootUtilities.derivesFrom(baseClass,
PtolemyUtilities.componentPortClass)) {
// If we are invoking a method on a port.
TypedIOPort port = InlinePortTransformer.getPortValue(method,
(Local) r.getBase(), unit, localDefs, localUses);
if (port == null) {
throw new RuntimeException("Failed to find port for "
+ unit);
}
// Don't create constant terms for
// ports where we don't already know the type.
if (!port.getType().isInstantiable()) {
return null;
}
InequalityTerm portTypeTerm = new ConstantTerm(port.getType(),
port);
if (methodName.equals("broadcast")) {
// The type of the argument must be less than the
// type of the port.
InequalityTerm firstArgTerm = (InequalityTerm) objectToInequalityTerm
.get(r.getArg(0));
_addInequality(debug, solver, firstArgTerm, portTypeTerm);
// Return type is void.
return null;
} else if (methodName.equals("get")) {
if (r.getArgCount() == 2) {
// FIXME: array of portTypeTerm?
return portTypeTerm;
} else if (r.getArgCount() == 1) {
return portTypeTerm;
}
} else if (methodName.equals("send")) {
if (r.getArgCount() == 3) {
// The type of the argument must be less than the
// type of the port.
InequalityTerm secondArgTerm = (InequalityTerm) objectToInequalityTerm
.get(r.getArg(1));
_addInequality(debug, solver, secondArgTerm,
portTypeTerm);
// Return type is void.
return null;
} else if (r.getArgCount() == 2) {
// The type of the argument must be less than the
// type of the port.
InequalityTerm secondArgTerm = (InequalityTerm) objectToInequalityTerm
.get(r.getArg(1));
_addInequality(debug, solver, secondArgTerm,
portTypeTerm);
// Return type is void.
return null;
}
}
} else if (SootUtilities.derivesFrom(baseClass,
PtolemyUtilities.attributeClass)) {
// If we are invoking a method on a port.
Attribute attribute = InlineParameterTransformer
.getAttributeValue(method, (Local) r.getBase(), unit,
localDefs, localUses);
if (attribute == null) {
// A method invocation with a null base is bogus,
// so don't create a type constraint.
return null;
}
if (attribute instanceof Variable) {
Variable parameter = (Variable) attribute;
InequalityTerm parameterTypeTerm = new ConstantTerm(
parameter.getType(), parameter);
if (methodName.equals("setToken")) {
// The type of the argument must be less than the
// type of the parameter.
InequalityTerm firstArgTerm = (InequalityTerm) objectToInequalityTerm
.get(r.getArg(0));
_addInequality(debug, solver, firstArgTerm,
parameterTypeTerm);
// Return type is void.
return null;
} else if (methodName.equals("getToken")) {
// Return the type of the parameter.
return parameterTypeTerm;
}
}
}
} else if (value instanceof ArrayRef) {
// The type must be the same as the type of the
// base of the array.
return (InequalityTerm) objectToInequalityTerm
.get(((ArrayRef) value).getBase());
// If we call getElement or arrayValue on an array
// token, then the returned type is the element
// type of the array.
// InequalityTerm baseTerm =
// (InequalityTerm)objectToInequalityTerm.get(
// ((ArrayRef)value).getBase());
// ptolemy.data.type.ArrayType arrayType =
// new ptolemy.data.type.ArrayType(
// ptolemy.data.type.BaseType.UNKNOWN);
// _addInequality(debug, solver, baseTerm,
// new VariableTerm(arrayType, value));
// InequalityTerm returnTypeTerm = (InequalityTerm)
// arrayType.getElementTypeTerm();
// return returnTypeTerm;
} else if (value instanceof CastExpr) {
CastExpr castExpr = (CastExpr) value;
// The return type will be the type
// of the cast.
InequalityTerm baseTerm = (InequalityTerm) objectToInequalityTerm
.get(castExpr.getOp());
return baseTerm;
} else if (value instanceof NewExpr) {
NewExpr newExpr = (NewExpr) value;
RefType type = newExpr.getBaseType();
SootClass castClass = type.getSootClass();
// If we are creating a Token type...
if (SootUtilities.derivesFrom(castClass,
PtolemyUtilities.tokenClass)) {
InequalityTerm typeTerm = new ConstantTerm(PtolemyUtilities