}
private void generateMultiClassIO (
List<TopLevelSourceElement> topLevelDefnsList) throws UnableToResolveForeignEntityException {
QualifiedName typeConstructorName = typeConstructorInfo.typeConstructor.getName();
// Import the top level class as a foreign type.
// ex. data foreign unsafe import jvm "org.olap.CubeType" public JCubeType;
makeForeignClassDeclaration(topLevelDefnsList);
for (int i = 0, n = typeConstructor.getNDataConstructors(); i < n; ++i) {
DataConstructor dc = typeConstructor.getNthDataConstructor(i);
makeForeignClassDeclaration(dc, topLevelDefnsList);
}
TypeExprDefn.TypeCons jClassTypeExpr =
TypeExprDefn.TypeCons.make(Name.TypeCons.makeUnqualified(typeConstructorInfo.calForeignTypeName));
// Import the constructors for each inner class (i.e. each data constructor)
// Pull in the constructor for the Java class.
for (int i = 0, n = javaClass.getNInnerClasses(); i < n; ++i) {
JavaClassRep innerClass = javaClass.getInnerClass(i);
assert (innerClass.getNConstructors() == 1);
JavaConstructor constructor = innerClass.getConstructor(0);
topLevelDefnsList.add(importJavaConstructor(constructor, true));
}
// Create accessors for fields in the top level class.
for (FieldName fn : typeConstructorInfo.commonFieldNames) {
Set<JavaTypeName> fieldTypes = typeConstructorInfo.allFieldTypeNames.get(fn);
// There will only be one type for common fields.
Iterator<JavaTypeName> types = fieldTypes.iterator();
JavaTypeName fieldType = types.next();
String foreignFieldTypeSting = typeConstructorInfo.calFieldForeignTypes.get(fn).get(fieldType);
generateFieldAccessor (
typeConstructorInfo.calForeignTypeName,
fn,
fieldType,
foreignFieldTypeSting,
typeConstructor.getNthDataConstructor(0),
topLevelDefnsList);
}
// Create accessors for the fields in the inner classes.
for (int i = 0, n = typeConstructor.getNDataConstructors(); i < n; ++i) {
DataConstructor dc = typeConstructor.getNthDataConstructor(i);
DataConstructorInfo dcInfo = (DataConstructorInfo)typeConstructorInfo.dataConstructorInfo.get(dc);
for (FieldName fn : dcInfo.allFieldNames) {
if (typeConstructorInfo.commonFieldNames.contains(fn)) {
continue;
}
JavaTypeName fieldType = (JavaTypeName)dcInfo.fieldTypeNames.get(fn);
String foreignFieldTypeSting = typeConstructorInfo.calFieldForeignTypes.get(fn).get(fieldType);
generateFieldAccessor (
dcInfo.calForeignTypeName,
fn,
fieldType,
foreignFieldTypeSting,
dc,
topLevelDefnsList);
}
}
// Bring in the 'getDCOrdinal()' method of the Java class.
String getDCOrdinalName = "j" + javaClass.getClassName().getUnqualifiedJavaSourceName() + "_getDCOrdinal";
SourceModel.TypeSignature getDCOrdinalTypeSignature =
TypeSignature.make(
TypeExprDefn.Function.make(
jClassTypeExpr,
INT_TYPE_EXPR_DEFN));
SourceModel.CALDoc.Comment.Function getDCOrdinalComment;
{
SourceModel.CALDoc.TextSegment.Plain textSegment =
SourceModel.CALDoc.TextSegment.Plain.make(
"\nRetrieve the ordinal value from an instance of " + typeConstructorInfo.calForeignTypeName + ".\n" +
"The ordinal can be used to determine which data constructor the " + typeConstructorInfo.calForeignTypeName + "\n" +
"instance corresponds to.");
SourceModel.CALDoc.TextBlock textBlock =
SourceModel.CALDoc.TextBlock.make(new SourceModel.CALDoc.TextSegment.TopLevel[]{textSegment});
getDCOrdinalComment =
SourceModel.CALDoc.Comment.Function.make(
textBlock,
null);
}
SourceModel.FunctionDefn getDCOrdinal =
FunctionDefn.Foreign.make(
getDCOrdinalComment,
getDCOrdinalName,
Scope.PRIVATE,
true,
"method getDCOrdinal",
getDCOrdinalTypeSignature);
topLevelDefnsList.add(getDCOrdinal);
// Create input function.
// inputCube :: JCube -> Cube;
// inputCube jCube =
// case (jCube_getDCOrdinal JCube) of
// 0 -> ...;
// 1 -> ...;
String inputFunctionName =
"input" + typeConstructor.getName().getUnqualifiedName();
String inputFunctionArgName = "j" + typeConstructorInfo.calForeignTypeName.substring(1);
Expr.Var inputFunctionArg = Expr.Var.make(Name.Function.makeUnqualified(inputFunctionArgName));
// Do the function type declaration.
// JCube -> Cube
TypeExprDefn inputFunctionType =
TypeExprDefn.Function.make(
TypeExprDefn.TypeCons.make(Name.TypeCons.makeUnqualified(typeConstructorInfo.calForeignTypeName)),
TypeExprDefn.TypeCons.make(Name.TypeCons.makeUnqualified(typeConstructorName.getUnqualifiedName())));
SourceModel.CALDoc.Comment.Function inputFunctionComment;
{
SourceModel.CALDoc.TextSegment.Plain textSegment =
SourceModel.CALDoc.TextSegment.Plain.make(