// Create a new child variable scope to handle the alternate and any let variables it contains.
variableContext.pushJavaScope();
// Get this alternative's variables. These have to be added to the active list of scope variables
TypeExpr fieldTypes[] = SCJavaDefn.getFieldTypesForDC(firstDC);
for (final AltVarIndexPair altVarIndexPair : getAltVarIndexList(alt, firstDC)) {
String altVar = altVarIndexPair.getAltVar();
int fieldIndex = altVarIndexPair.getIndex();
QualifiedName qn = QualifiedName.make(currentModuleName, altVar);
VarInfo.DCMember vi = variableContext.addDCField(qn, fieldTypes[fieldIndex]);
boolean fieldIsStrict =
!LECCMachineConfiguration.IGNORE_STRICTNESS_ANNOTATIONS;
for (final DataConstructor tagDC : group) {
fieldIsStrict = fieldIsStrict && tagDC.isArgStrict(fieldIndex);
}
if (fieldIsStrict) {
vi.setEvaluated(true);
}
String fieldName = SCJavaDefn.getJavaFieldNameFromDC(firstDC, fieldIndex);
String fieldGetterName = "get" + fieldName;
// Generate the code defining the variable.
if (fieldIsStrict) {
if (SCJavaDefn.canTypeBeUnboxed(fieldTypes[fieldIndex])) {
// This is a strict field of a primitive type so has both a boxed and unboxed form.
JavaExpression unboxedInitializer =
new JavaExpression.MethodInvocation.Instance(caseVar,
fieldGetterName + "_As_" + SCJavaDefn.getNameForPrimitive(fieldTypes[fieldIndex]),
SCJavaDefn.typeExprToTypeName(fieldTypes[fieldIndex]),
JavaExpression.MethodInvocation.InvocationType.VIRTUAL);
vi.updateUnboxedVarDef(unboxedInitializer);
JavaExpression localVar = new LocalVariable(vi.getJavaName()+"$U", vi.getUnboxedType());
vi.updateUnboxedReference(localVar);
JavaExpression boxedDef = SCJavaDefn.boxExpression(vi.getUnboxedType(), localVar);
vi.updateStrictReference(boxedDef);
vi.updateLazyReference(boxedDef);
} else {
// RTValue altVarName = ((DCClass)caseVar).getFieldn();
JavaExpression initializer = new JavaExpression.MethodInvocation.Instance(caseVar, fieldGetterName, JavaTypeNames.RTVALUE, JavaExpression.MethodInvocation.InvocationType.VIRTUAL);
vi.updateStrictVarDef (initializer);
JavaExpression localVar = new LocalVariable(vi.getJavaName(), JavaTypeNames.RTVALUE);
vi.updateStrictReference(localVar);
vi.updateLazyReference(localVar);
}
} else {
// RTValue altVarName = ((DCClass)caseVar).getFieldn();
JavaExpression initializer = new JavaExpression.MethodInvocation.Instance(caseVar, fieldGetterName, JavaTypeNames.RTVALUE, JavaExpression.MethodInvocation.InvocationType.VIRTUAL);
vi.updateLazyVarDef (initializer);
JavaExpression localVar = new LocalVariable(vi.getJavaName(), JavaTypeNames.RTVALUE);
vi.updateLazyReference(localVar);
JavaExpression evaluatedVar = SCJavaDefn.createInvocation(localVar, SCJavaDefn.EVALUATE, SCJavaDefn.EXECUTION_CONTEXT_VAR);
vi.updateStrictReference(evaluatedVar);
if (SCJavaDefn.canTypeBeUnboxed(fieldTypes[fieldIndex])) {
vi.updateUnboxedReference(SCJavaDefn.unboxValue(vi.getUnboxedType(), evaluatedVar));
}
}
}
// Compile the actual body of the alternate.
JavaStatement altStatement = genS_R(alt.getAltExpr(), variableContext);
caseBlock.addStatement(variableContext.popJavaScope());
caseBlock.addStatement(altStatement);
switchStatement.addCase(new SwitchStatement.IntCaseGroup(caseLabels, caseBlock));
}
} else {
// Matching notation for switch alternate.
Map<FieldName, String> fieldNameToVarNameMap = ((SwitchAlt.Matching)alt).getFieldNameToVarNameMap();
Block caseBlock = new Block();
int[] caseLabels = new int[altTags.size()];
int index = 0;
DataConstructor firstDC = null;
// Must be a data constructor tag, since there are field names (see Expression.Switch.SwitchAlt).
for (final Object altTag : altTags) {
DataConstructor tagDC = (DataConstructor)altTag;
if (firstDC == null) {
firstDC = tagDC;
} else if (tagDC.getOrdinal() < firstDC.getOrdinal()) {
firstDC = tagDC;
}
caseBlock.addStatement(new LineComment(tagDC.getName().getQualifiedName()));
caseLabels[index] = tagDC.getOrdinal();
index++;
}
caseBlock.addStatement(new LineComment("Decompose data type to access members."));
// Create a new child variable scope to handle the alternate and any let variables it contains.
variableContext.pushJavaScope();
for (int iField = 0; iField < firstDC.getArity(); ++iField) {
FieldName fn = firstDC.getNthFieldName(iField);
String altVar = fieldNameToVarNameMap.get(fn);
if (altVar == null) {
continue;
}
QualifiedName qn = QualifiedName.make(currentModuleName, altVar);
TypeExpr fieldType = SCJavaDefn.getFieldTypeForDC(firstDC, fn);
VarInfo.DCMember vi = variableContext.addDCField(qn, fieldType);
boolean fieldIsStrict = !LECCMachineConfiguration.IGNORE_STRICTNESS_ANNOTATIONS;
for (final Object altTag : altTags) {