private Map<ValueNode, TypeExpr> getValueNodeToUnconstrainedTypeMap() {
//Map to hold the result of this function ValueNode->TypeExpr
final Map<ValueNode, TypeExpr> resultMap = new HashMap<ValueNode, TypeExpr>();
final AbstractRecordValueNode currentValueNode = (AbstractRecordValueNode)getValueNode();
final List<FieldName> hasFieldNames = ((RecordType)currentValueNode.getTypeExpr()).getHasFieldNames();
final int numFields = currentValueNode.getTypeExpr().rootRecordType().getNHasFields();
// get the context least constrained type
final TypeExpr contextLeastConstrainedType = getContext().getLeastConstrainedTypeExpr();
//build one that includes all of the new fields as well.
final Map<FieldName, TypeExpr> contextFieldsMap; //map of all the fields in the context RecordFieldName -> TypeExpr
if (contextLeastConstrainedType instanceof RecordType) {
contextFieldsMap = ((RecordType) contextLeastConstrainedType).getHasFieldsMap();
} else {
contextFieldsMap = new HashMap<FieldName, TypeExpr>();
}
final Map<FieldName, TypeExpr> allFieldsMap = new HashMap<FieldName, TypeExpr>(); //map containing all the context fields and fields added with the value editor, RecordFieldName -> TypeExpr
for (int i = 0; i < numFields; i++) {
final FieldName fieldName = hasFieldNames.get(i);
if (contextFieldsMap.containsKey(fieldName)) {
allFieldsMap.put(fieldName, contextFieldsMap.get(fieldName));
} else {
allFieldsMap.put(fieldName, TypeExpr.makeParametricType());
}
}
final RecordType leastConstrainedRecordType = TypeExpr.makePolymorphicRecordType(allFieldsMap);
// add the record node itself to the result map
resultMap.put(currentValueNode, leastConstrainedRecordType);
// add all the record field nodes to the result map
for (int j = 0; j < numFields; j++) {
ValueNode currentFieldNode = currentValueNode.getValueAt(j);
FieldName fieldName = hasFieldNames.get(j);
TypeExpr leastConstrainedRecordElementType = leastConstrainedRecordType.getHasFieldType(fieldName);
resultMap.put(currentFieldNode, leastConstrainedRecordElementType);