/*
* #%~
* VDM Code Generator
* %%
* Copyright (C) 2008 - 2014 Overture
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #~%
*/
package org.overture.codegen.vdm2java;
import java.util.LinkedList;
import org.overture.codegen.ir.IRInfo;
import org.overture.codegen.ir.SExpIR;
import org.overture.codegen.ir.STypeIR;
import org.overture.codegen.ir.analysis.AnalysisException;
import org.overture.codegen.ir.declarations.ADefaultClassDeclIR;
import org.overture.codegen.ir.declarations.AFieldDeclIR;
import org.overture.codegen.ir.declarations.ARecordDeclIR;
import org.overture.codegen.ir.declarations.AVarDeclIR;
import org.overture.codegen.ir.expressions.AAddrNotEqualsBinaryExpIR;
import org.overture.codegen.ir.expressions.AAndBoolBinaryExpIR;
import org.overture.codegen.ir.expressions.AApplyExpIR;
import org.overture.codegen.ir.expressions.ACastUnaryExpIR;
import org.overture.codegen.ir.expressions.AEqualsBinaryExpIR;
import org.overture.codegen.ir.expressions.AFieldExpIR;
import org.overture.codegen.ir.expressions.AIdentifierVarExpIR;
import org.overture.codegen.ir.expressions.AInstanceofExpIR;
import org.overture.codegen.ir.name.ATypeNameIR;
import org.overture.codegen.ir.patterns.AIdentifierPatternIR;
import org.overture.codegen.ir.statements.ABlockStmIR;
import org.overture.codegen.ir.statements.APlainCallStmIR;
import org.overture.codegen.ir.types.ABoolBasicTypeIR;
import org.overture.codegen.ir.types.AExternalTypeIR;
import org.overture.codegen.ir.types.AObjectTypeIR;
import org.overture.codegen.ir.types.ARecordTypeIR;
public class JavaFormatAssistant extends JavaClassCreatorBase
{
private IRInfo info;
public JavaFormatAssistant(IRInfo info)
{
this.info = info;
}
public ATypeNameIR consTypeName(ARecordDeclIR record)
throws AnalysisException
{
ADefaultClassDeclIR classDef = record.getAncestor(ADefaultClassDeclIR.class);
ATypeNameIR typeName = new ATypeNameIR();
if (classDef == null)
{
throw new AnalysisException("A Record declaration must always be defined inside a class");
} else
{
typeName.setDefiningClass(classDef.getName());
}
typeName.setName(record.getName());
return typeName;
}
public ABlockStmIR consVarFromCastedExp(ARecordDeclIR record,
String formalParamName, String varName) throws AnalysisException
{
// Construct a local var in a statement: RecordType varName = ((RecordType) formalParamName);
ARecordTypeIR recordType = new ARecordTypeIR();
recordType.setName(consTypeName(record));
AIdentifierPatternIR idPattern = new AIdentifierPatternIR();
idPattern.setName(varName);
ACastUnaryExpIR cast = new ACastUnaryExpIR();
cast.setType(recordType.clone());
AIdentifierVarExpIR varExp = new AIdentifierVarExpIR();
varExp.setType(new AObjectTypeIR());
varExp.setName(formalParamName);
varExp.setIsLocal(true);
cast.setExp(varExp);
AVarDeclIR localVar = info.getDeclAssistant().consLocalVarDecl(recordType, idPattern, cast);
ABlockStmIR stm = new ABlockStmIR();
stm.getLocalDefs().add(localVar);
return stm;
}
public AAndBoolBinaryExpIR extendAndExp(ARecordDeclIR record,
AFieldDeclIR field, SExpIR previous, String paramName)
throws AnalysisException
{
// By recursively calling this method an "and chain" of field
// comparisons can be constructed: fieldComp1 && fieldComp2 && fieldComp3 ....
AAndBoolBinaryExpIR nextAnd = new AAndBoolBinaryExpIR();
nextAnd.setType(new ABoolBasicTypeIR());
nextAnd.setLeft(previous);
nextAnd.setRight(consFieldComparison(record, field, paramName));
return nextAnd;
}
public AInstanceofExpIR consInstanceOf(ARecordDeclIR record,
String formalParamName)
{
// Example: objRef instanceof classType
ADefaultClassDeclIR enclosingClass = record.getAncestor(ADefaultClassDeclIR.class);
ATypeNameIR typeName = new ATypeNameIR();
typeName.setDefiningClass(enclosingClass.getName());
typeName.setName(record.getName());
ARecordTypeIR recordType = new ARecordTypeIR();
recordType.setName(typeName);
AIdentifierVarExpIR objRef = new AIdentifierVarExpIR();
objRef.setType(new AObjectTypeIR());
objRef.setIsLocal(true);
objRef.setName(formalParamName);
AInstanceofExpIR instanceOfExp = new AInstanceofExpIR();
instanceOfExp.setType(new ABoolBasicTypeIR());
instanceOfExp.setExp(objRef);
instanceOfExp.setCheckedType(recordType);
return instanceOfExp;
}
public AAddrNotEqualsBinaryExpIR consParamNotNullComp(
AIdentifierVarExpIR param)
{
AAddrNotEqualsBinaryExpIR fieldComparison = new AAddrNotEqualsBinaryExpIR();
fieldComparison.setType(new ABoolBasicTypeIR());
AIdentifierVarExpIR instanceField = new AIdentifierVarExpIR();
instanceField.setType(param.getType().clone());
instanceField.setIsLocal(false);
instanceField.setName(param.getName());
fieldComparison.setLeft(instanceField);
fieldComparison.setRight(info.getExpAssistant().consNullExp());
return fieldComparison;
}
public APlainCallStmIR consCallStm(AFieldDeclIR field)
{
APlainCallStmIR call = new APlainCallStmIR();
AExternalTypeIR classType = new AExternalTypeIR();
classType.setName(JavaFormat.UTILS_FILE);
AIdentifierVarExpIR argument = new AIdentifierVarExpIR();
argument.setType(field.getType().clone());
argument.setIsLocal(false);
argument.setName(field.getName());
call.setType(classType.clone());
call.setName("hashcode");
call.setClassType(classType.clone());
call.getArgs().add(argument);
return call;
}
public AEqualsBinaryExpIR consFieldComparison(ARecordDeclIR record,
AFieldDeclIR field, String formalParamName) throws AnalysisException
{
// Example: fieldName == formalParamName.fieldName
AEqualsBinaryExpIR fieldComparison = new AEqualsBinaryExpIR();
fieldComparison.setType(new ABoolBasicTypeIR());
AIdentifierVarExpIR instanceField = new AIdentifierVarExpIR();
instanceField.setType(field.getType().clone());
instanceField.setIsLocal(false);
instanceField.setName(field.getName());
AFieldExpIR formalParamField = new AFieldExpIR();
formalParamField.setType(field.getType().clone());
AIdentifierVarExpIR formalParam = new AIdentifierVarExpIR();
ARecordTypeIR recordType = new ARecordTypeIR();
recordType.setName(consTypeName(record));
formalParam.setType(recordType);
formalParam.setIsLocal(true);
formalParam.setName(formalParamName);
formalParamField.setObject(formalParam);
formalParamField.setMemberName(field.getName());
fieldComparison.setLeft(instanceField);
fieldComparison.setRight(formalParamField);
return fieldComparison;
}
public AApplyExpIR consUtilCallUsingRecFields(ARecordDeclIR record,
STypeIR returnType, String memberName)
{
LinkedList<AFieldDeclIR> fields = record.getFields();
AApplyExpIR call = consUtilCall(returnType, memberName);
LinkedList<SExpIR> args = call.getArgs();
for (AFieldDeclIR field : fields)
{
AIdentifierVarExpIR nextArg = new AIdentifierVarExpIR();
nextArg.setName(field.getName());
nextArg.setType(field.getType().clone());
nextArg.setIsLocal(false);
args.add(nextArg);
}
return call;
}
}