ObjectLiteralExpression.java
package edu.udel.cis.vsl.tass.model.impl.expression.literal;
import edu.udel.cis.vsl.tass.model.IF.ModelFactoryIF;
import edu.udel.cis.vsl.tass.model.IF.expression.ExpressionIF;
import edu.udel.cis.vsl.tass.model.IF.expression.LiteralTypeIF;
import edu.udel.cis.vsl.tass.model.IF.expression.ObjectLiteralExpressionIF;
import edu.udel.cis.vsl.tass.model.IF.type.ArrayTypeIF;
import edu.udel.cis.vsl.tass.model.IF.type.RecordTypeIF;
import edu.udel.cis.vsl.tass.model.IF.type.TypeIF;
public class ObjectLiteralExpression extends LiteralExpression implements
ObjectLiteralExpressionIF {
private int objectLiteralID;
private LiteralTypeIF literalType;
public ObjectLiteralExpression(ModelFactoryIF factory,
ExpressionIF[] value, TypeIF type, int literalId,
int objectLiteralID) {
super(factory, value, type, literalId);
this.objectLiteralID = objectLiteralID;
if (type instanceof ArrayTypeIF) {
ArrayLiteralType join = new ArrayLiteralType((ArrayTypeIF) type,
value.length);
for (ExpressionIF element : value) {
if (element instanceof ObjectLiteralExpressionIF) {
computeJoin(join.elementLiteralType(),
((ObjectLiteralExpressionIF) element).literalType());
}
}
update(join, this);
} else if (type instanceof RecordTypeIF) {
RecordLiteralType join = new RecordLiteralType((RecordTypeIF) type);
this.literalType = new RecordLiteralType((RecordTypeIF) type);
computeJoin(join, literalType);
update(join, this);
} else {
this.literalType = new LiteralType(type);
}
}
private void computeJoin(LiteralTypeIF join, LiteralTypeIF literalType) {
TypeIF type = join.type();
assert type.equals(literalType.type());
if (type instanceof ArrayTypeIF) {
ArrayLiteralType arrayJoin = (ArrayLiteralType) join;
ArrayLiteralType arrayLiteralType = (ArrayLiteralType) literalType;
int extent = arrayLiteralType.extent();
int maxExtent = arrayJoin.extent();
if (extent > maxExtent) {
arrayJoin.setExtent(extent);
}
computeJoin(arrayJoin.elementLiteralType(), arrayLiteralType
.elementLiteralType());
} else if (type instanceof RecordTypeIF) {
RecordTypeIF recordType = (RecordTypeIF) type;
RecordLiteralType recordJoin = (RecordLiteralType) join;
RecordLiteralType recordLiteralType = (RecordLiteralType) literalType;
LiteralTypeIF[] joinFieldTypes = recordJoin.fieldLiteralTypes();
LiteralTypeIF[] literalFieldTypes = recordLiteralType
.fieldLiteralTypes();
int numFields = recordType.numFields();
for (int i = 0; i < numFields; i++) {
computeJoin(joinFieldTypes[i], literalFieldTypes[i]);
}
} else {
return;
}
}
/** Impose the new type on the given literal expression, recursively. */
void update(LiteralTypeIF newLiteralType, ObjectLiteralExpression expression) {
TypeIF type = newLiteralType.type();
assert type.equals(expression.type());
expression.setLiteralType(newLiteralType);
if (type instanceof ArrayTypeIF) {
ArrayLiteralType arrayLiteralType = (ArrayLiteralType) newLiteralType;
LiteralTypeIF elementLiteralType = arrayLiteralType
.elementLiteralType();
for (ExpressionIF child : expression.value()) {
if (child instanceof ObjectLiteralExpression) {
update(elementLiteralType, (ObjectLiteralExpression) child);
}
}
} else if (type instanceof RecordTypeIF) {
RecordLiteralType recordLiteralType = (RecordLiteralType) newLiteralType;
LiteralTypeIF[] fieldLiteralTypes = recordLiteralType
.fieldLiteralTypes();
int numFields = fieldLiteralTypes.length;
ExpressionIF[] children = expression.value();
for (int i = 0; i < numFields; i++) {
ExpressionIF child = children[i];
if (child instanceof ObjectLiteralExpression) {
update(fieldLiteralTypes[i],
(ObjectLiteralExpression) child);
}
}
}
}
void setLiteralType(LiteralTypeIF literalType) {
this.literalType = literalType;
}
@Override
public int objectLiteralID() {
return objectLiteralID;
}
@Override
public ExpressionIF[] value() {
return (ExpressionIF[]) super.value();
}
@Override
public LiteralTypeIF literalType() {
return literalType;
}
public String toString() {
ExpressionIF[] elements = value();
boolean flag = true;
String result = "{";
for (ExpressionIF element : elements) {
if (flag)
flag = false;
else
result += ", ";
if (element != null)
result += element.toString();
}
result += "}";
return result;
}
}