Set<ModuleName> mustHaveImports = new LinkedHashSet<ModuleName>();
Map<String, TypeSignature> castFunctions = new LinkedHashMap<String, TypeSignature>();
Map<QualifiedName, TypeConstructor> additionalForeignTypeDeclarations = new LinkedHashMap<QualifiedName, TypeConstructor>();
for (int i = 0, n = module.getNTypeConstructors(); i < n; ++i) {
TypeConstructor tc = module.getNthTypeConstructor(i);
if (typeConstructorsToIgnore.contains(tc.getName()) ||
tc.getForeignTypeInfo() != null) {
logMessage(Level.INFO, "Skipped type constructor " + tc.getName().getUnqualifiedName() + " because of ignore directive.");
continue;
}
// If the type constructor is declared as inputable/outputable in the containing module
// we skip it because generating inputable/outputable instances would conflict.
boolean alreadyInputableOutputable = false;
for (int j = 0, k = module.getNClassInstances(); j < k; ++j) {
ClassInstance ci = module.getNthClassInstance(j);
if (ci.getTypeClass().getName().equals(CAL_Prelude.TypeClasses.Inputable) ||
ci.getTypeClass().getName().equals(CAL_Prelude.TypeClasses.Outputable)) {
// Check the instance type
TypeExpr instanceTypeExpr = ci.getType();
TypeConsApp tca = instanceTypeExpr.rootTypeConsApp();
if (tca != null) {
if (tca.getRoot().getName().equals(tc.getName())) {
alreadyInputableOutputable = true;
}
}
}
}
if (alreadyInputableOutputable) {
logMessage(Level.INFO, "Skipped type constructor " + tc.getName().getUnqualifiedName() + " because it is alreayd an instance of Inputable or Outputable.");
continue;
}
// Build up info about the type constructor and data constructors.
TypeConstructorInfo typeConstructorInfo =
getTypeConstructorInfo (tc, typeToClassMappings, moduleToPackageMappings, module, targetPackage);
// Now we want to generate the Java class.
JavaDataClassGenerator javaDataClassGenerator =
new JavaDataClassGenerator(
targetPackage,
typeConstructorInfo);
JavaClassRep javaClass = javaDataClassGenerator.generateClassForType();
classReps.put(tc.getName(), javaClass);
classLogMessages.put(tc.getName(), javaDataClassGenerator.logMessages);
// Generate the CAL I/O
CAL_IO_Generator ioGenerator =
new CAL_IO_Generator (
typeConstructorInfo,
module,
javaClass);
Collection<TopLevelSourceElement> topLevelElements = ioGenerator.generateCAL_IO ();
allTopLevelElements.addAll(topLevelElements);
calLogMessages.addAll(ioGenerator.logMessages);
mustHaveImports.addAll(ioGenerator.getInputableImports());
castFunctions.putAll(ioGenerator.castFunctionNameToTypeSignature);
additionalForeignTypeDeclarations.putAll(ioGenerator.additionalForeignTypeDeclarations);
}
SourceModel.ModuleDefn moduleDefn = null;
if (allTopLevelElements.size() > 0) {
ModuleName newModuleName = ModuleName.make(module.getModuleName().toString() + "_JavaIO");
for (Map.Entry<String, TypeSignature> entry : castFunctions.entrySet()) {
String castFunctionName = (String)entry.getKey();
SourceModel.TypeSignature typeSignature = (TypeSignature)entry.getValue();
TypeExprDefn domain = ((TypeExprDefn.Function)typeSignature.getTypeExprDefn()).getDomain();
TypeExprDefn coDomain = ((TypeExprDefn.Function)typeSignature.getTypeExprDefn()).getCodomain();
SourceModel.CALDoc.TextSegment.Plain textSegment =
SourceModel.CALDoc.TextSegment.Plain.make(
"Cast an instance of " + domain.toString() + " to " + coDomain.toString());
SourceModel.CALDoc.TextBlock textBlock =
SourceModel.CALDoc.TextBlock.make(new SourceModel.CALDoc.TextSegment.TopLevel[]{textSegment});
SourceModel.CALDoc.Comment.Function functionComment =
SourceModel.CALDoc.Comment.Function.make(
textBlock,
null);
SourceModel.FunctionDefn castFunction =
FunctionDefn.Foreign.make(
functionComment,
castFunctionName,
Scope.PRIVATE,
true,
"cast",
typeSignature);
allTopLevelElements.add(castFunction);
}
for (Map.Entry<QualifiedName, TypeConstructor>entry : additionalForeignTypeDeclarations.entrySet()) {
QualifiedName typeConstructorName = (QualifiedName)entry.getKey();
TypeConstructor typeConstructor = (TypeConstructor)entry.getValue();
// Declare the java class as a foreign type.
// ex. data foreign unsafe import jvm "org.olap.CubeType" public JCubeType;
SourceModel.TypeConstructorDefn.ForeignType foreignType =
TypeConstructorDefn.ForeignType.make(
typeConstructorName.getUnqualifiedName(),
Scope.PRIVATE,
ForeignTypeInfo.getCalSourceName(typeConstructor.getForeignTypeInfo().getForeignType()),
Scope.PRIVATE,
null);
allTopLevelElements.add(foreignType);
}