/*
* #%~
* 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.io.StringWriter;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;
import org.overture.ast.intf.lex.ILexLocation;
import org.overture.ast.lex.Dialect;
import org.overture.ast.types.PType;
import org.overture.ast.util.ClonableString;
import org.overture.codegen.assistant.LocationAssistantIR;
import org.overture.codegen.assistant.TypeAssistantIR;
import org.overture.codegen.ir.INode;
import org.overture.codegen.ir.IRInfo;
import org.overture.codegen.ir.PIR;
import org.overture.codegen.ir.SExpIR;
import org.overture.codegen.ir.SStmIR;
import org.overture.codegen.ir.STypeIR;
import org.overture.codegen.ir.SourceNode;
import org.overture.codegen.ir.analysis.AnalysisException;
import org.overture.codegen.ir.declarations.AFormalParamLocalParamIR;
import org.overture.codegen.ir.declarations.AInterfaceDeclIR;
import org.overture.codegen.ir.declarations.AMethodDeclIR;
import org.overture.codegen.ir.declarations.ANamedTypeDeclIR;
import org.overture.codegen.ir.declarations.ARecordDeclIR;
import org.overture.codegen.ir.declarations.ATypeDeclIR;
import org.overture.codegen.ir.declarations.AVarDeclIR;
import org.overture.codegen.ir.declarations.SClassDeclIR;
import org.overture.codegen.ir.expressions.AAbsUnaryExpIR;
import org.overture.codegen.ir.expressions.AApplyExpIR;
import org.overture.codegen.ir.expressions.ABoolLiteralExpIR;
import org.overture.codegen.ir.expressions.ACastUnaryExpIR;
import org.overture.codegen.ir.expressions.AEqualsBinaryExpIR;
import org.overture.codegen.ir.expressions.AFieldNumberExpIR;
import org.overture.codegen.ir.expressions.AHeadUnaryExpIR;
import org.overture.codegen.ir.expressions.AHistoryExpIR;
import org.overture.codegen.ir.expressions.AIsolationUnaryExpIR;
import org.overture.codegen.ir.expressions.AMinusUnaryExpIR;
import org.overture.codegen.ir.expressions.ANewExpIR;
import org.overture.codegen.ir.expressions.ANotEqualsBinaryExpIR;
import org.overture.codegen.ir.expressions.ANotUnaryExpIR;
import org.overture.codegen.ir.expressions.APlusUnaryExpIR;
import org.overture.codegen.ir.expressions.AQuoteLiteralExpIR;
import org.overture.codegen.ir.expressions.ASeqToStringUnaryExpIR;
import org.overture.codegen.ir.expressions.AStringToSeqUnaryExpIR;
import org.overture.codegen.ir.expressions.ATernaryIfExpIR;
import org.overture.codegen.ir.expressions.AUndefinedExpIR;
import org.overture.codegen.ir.expressions.SBinaryExpIR;
import org.overture.codegen.ir.expressions.SLiteralExpIR;
import org.overture.codegen.ir.expressions.SNumericBinaryExpIR;
import org.overture.codegen.ir.expressions.SUnaryExpIR;
import org.overture.codegen.ir.expressions.SVarExpIR;
import org.overture.codegen.ir.name.ATokenNameIR;
import org.overture.codegen.ir.name.ATypeNameIR;
import org.overture.codegen.ir.statements.ABlockStmIR;
import org.overture.codegen.ir.statements.AForLoopStmIR;
import org.overture.codegen.ir.statements.AStartStmIR;
import org.overture.codegen.ir.types.ABoolBasicTypeIR;
import org.overture.codegen.ir.types.ACharBasicTypeIR;
import org.overture.codegen.ir.types.AClassTypeIR;
import org.overture.codegen.ir.types.AInterfaceTypeIR;
import org.overture.codegen.ir.types.AMethodTypeIR;
import org.overture.codegen.ir.types.AObjectTypeIR;
import org.overture.codegen.ir.types.ARecordTypeIR;
import org.overture.codegen.ir.types.AStringTypeIR;
import org.overture.codegen.ir.types.ATupleTypeIR;
import org.overture.codegen.ir.types.AUnionTypeIR;
import org.overture.codegen.ir.types.AUnknownTypeIR;
import org.overture.codegen.ir.types.AVoidTypeIR;
import org.overture.codegen.ir.types.SBasicTypeIR;
import org.overture.codegen.ir.types.SMapTypeIR;
import org.overture.codegen.ir.types.SSeqTypeIR;
import org.overture.codegen.ir.types.SSetTypeIR;
import org.overture.codegen.merging.MergeVisitor;
import org.overture.codegen.merging.TemplateCallable;
import org.overture.codegen.trans.funcvalues.FuncValAssistant;
import org.overture.codegen.utils.GeneralUtils;
import org.overture.config.Settings;
import org.overture.typechecker.assistant.type.PTypeAssistantTC;
public class JavaFormat
{
public static final String TYPE_DECL_PACKAGE_SUFFIX = "types";
public static final String CLASS_EXTENSION = ".class";
public static final String UTILS_FILE = "Utils";
public static final String SEQ_UTIL_FILE = "SeqUtil";
public static final String SET_UTIL_FILE = "SetUtil";
public static final String MAP_UTIL_FILE = "MapUtil";
protected IRInfo info;
protected FuncValAssistant funcValAssist;
protected MergeVisitor mergeVisitor;
protected JavaValueSemantics valueSemantics;
protected JavaFormatAssistant javaFormatAssistant;
protected JavaRecordCreator recCreator;
protected JavaVarPrefixManager varPrefixManager;
protected Logger log = Logger.getLogger(this.getClass().getName());
public JavaFormat(JavaVarPrefixManager varPrefixManager,
String templateRoot, IRInfo info)
{
this.varPrefixManager = varPrefixManager;
this.valueSemantics = new JavaValueSemantics(this);
this.recCreator = new JavaRecordCreator(this);
TemplateCallable[] templateCallables = TemplateCallableManager.constructTemplateCallables(this, valueSemantics);
this.mergeVisitor = new MergeVisitor(new JavaTemplateManager(templateRoot), templateCallables);
this.funcValAssist = null;
this.info = info;
this.javaFormatAssistant = new JavaFormatAssistant(this.info);
}
public JavaValueSemantics getValueSemantics()
{
return valueSemantics;
}
public void setValueSemantics(JavaValueSemantics valueSemantics)
{
this.valueSemantics = valueSemantics;
}
public JavaRecordCreator getRecCreator()
{
return recCreator;
}
public JavaFormatAssistant getJavaFormatAssistant()
{
return javaFormatAssistant;
}
public String getJavaNumber()
{
return "Number";
}
public IRInfo getIrInfo()
{
return info;
}
public void setFunctionValueAssistant(
FuncValAssistant functionValueAssistant)
{
this.funcValAssist = functionValueAssistant;
}
public void setJavaSettings(JavaSettings javaSettings)
{
valueSemantics.setJavaSettings(javaSettings);
}
public JavaSettings getJavaSettings()
{
return valueSemantics.getJavaSettings();
}
public void clear()
{
mergeVisitor.init();
valueSemantics.clear();
this.funcValAssist = null;
}
public MergeVisitor getMergeVisitor()
{
return mergeVisitor;
}
public String format(AMethodTypeIR methodType) throws AnalysisException
{
final String OBJ = "Object";
if (funcValAssist == null)
{
return OBJ;
}
AInterfaceDeclIR methodTypeInterface = funcValAssist.findInterface(methodType);
if (methodTypeInterface == null)
{
return OBJ; // Should not happen
}
AInterfaceTypeIR methodClass = new AInterfaceTypeIR();
methodClass.setName(methodTypeInterface.getName());
LinkedList<STypeIR> params = methodType.getParams();
for (STypeIR param : params)
{
methodClass.getTypes().add(param.clone());
}
methodClass.getTypes().add(methodType.getResult().clone());
return methodClass != null ? format(methodClass) : OBJ;
}
public String format(INode node) throws AnalysisException
{
return format(node, false);
}
public String formatIgnoreContext(INode node) throws AnalysisException
{
return format(node, true);
}
private String format(INode node, boolean ignoreContext)
throws AnalysisException
{
StringWriter writer = new StringWriter();
node.apply(mergeVisitor, writer);
return writer.toString() + getNumberDereference(node, ignoreContext);
}
private String findNumberDereferenceCall(STypeIR type)
{
if (type == null || type.parent() instanceof AHistoryExpIR)
{
return "";
}
final String DOUBLE_VALUE = ".doubleValue()";
final String LONG_VALUE = ".longValue()";
if (info.getAssistantManager().getTypeAssistant().isInt(type))
{
return LONG_VALUE;
} else if (info.getAssistantManager().getTypeAssistant().isRealOrRat(type))
{
return DOUBLE_VALUE;
} else
{
PTypeAssistantTC typeAssistant = info.getTcFactory().createPTypeAssistant();
SourceNode sourceNode = type.getSourceNode();
if (sourceNode != null
&& !(sourceNode.getVdmNode() instanceof PType))
{
PType vdmType = (PType) sourceNode.getVdmNode();
if (typeAssistant.isNumeric(vdmType))
{
return DOUBLE_VALUE;
}
}
return "";
}
}
private String getNumberDereference(INode node, boolean ignoreContext)
{
if (ignoreContext && node instanceof SExpIR)
{
SExpIR exp = (SExpIR) node;
STypeIR type = exp.getType();
if (isNumberDereferenceCandidate(exp))
{
return findNumberDereferenceCall(type);
}
}
INode parent = node.parent();
if (parent instanceof SNumericBinaryExpIR
|| parent instanceof AAbsUnaryExpIR
|| parent instanceof AMinusUnaryExpIR
|| parent instanceof APlusUnaryExpIR
|| parent instanceof AIsolationUnaryExpIR)
{
SExpIR exp = (SExpIR) node;
STypeIR type = exp.getType();
if (isNumberDereferenceCandidate(exp))
{
return findNumberDereferenceCall(type);
}
}
// No dereference is needed
return "";
}
private static boolean isNumberDereferenceCandidate(SExpIR node)
{
boolean fitsCategory = !(node instanceof SNumericBinaryExpIR)
&& !(node instanceof ATernaryIfExpIR)
&& !(node instanceof SLiteralExpIR)
&& !(node instanceof AIsolationUnaryExpIR)
&& !(node instanceof SUnaryExpIR);
boolean isException = node instanceof AHeadUnaryExpIR
|| node instanceof AQuoteLiteralExpIR
|| node instanceof ACastUnaryExpIR;
return fitsCategory || isException;
}
public String formatName(INode node) throws AnalysisException
{
if (node instanceof ANewExpIR)
{
ANewExpIR newExp = (ANewExpIR) node;
return formatTypeName(node, newExp.getName());
} else if (node instanceof ARecordTypeIR)
{
ARecordTypeIR record = (ARecordTypeIR) node;
ATypeNameIR typeName = record.getName();
return formatTypeName(node, typeName);
}
throw new AnalysisException("Unexpected node in formatName: "
+ node.getClass().getName());
}
public String formatTypeName(INode node, ATypeNameIR typeName)
{
// Type names are also used for quotes, which do not have a defining class.
if (typeName.getDefiningClass() != null
&& !getJavaSettings().genRecsAsInnerClasses())
{
String typeNameStr = "";
if (JavaCodeGenUtil.isValidJavaPackage(getJavaSettings().getJavaRootPackage()))
{
typeNameStr += getJavaSettings().getJavaRootPackage() + ".";
}
typeNameStr += typeName.getDefiningClass()
+ TYPE_DECL_PACKAGE_SUFFIX + ".";
typeNameStr += typeName.getName();
return typeNameStr;
}
SClassDeclIR classDef = node.getAncestor(SClassDeclIR.class);
String definingClass = typeName.getDefiningClass() != null
&& classDef != null
&& !classDef.getName().equals(typeName.getDefiningClass())
? typeName.getDefiningClass() + "." : "";
return definingClass + typeName.getName();
}
public String format(SExpIR exp, boolean leftChild) throws AnalysisException
{
String formattedExp = format(exp);
JavaPrecedence precedence = new JavaPrecedence();
INode parent = exp.parent();
if (!(parent instanceof SExpIR))
{
return formattedExp;
}
boolean isolate = precedence.mustIsolate((SExpIR) parent, exp, leftChild);
return isolate ? "(" + formattedExp + ")" : formattedExp;
}
public String formatUnary(SExpIR exp) throws AnalysisException
{
return format(exp, false);
}
public String formatNotUnary(SExpIR exp) throws AnalysisException
{
String formattedExp = format(exp, false);
boolean doNotWrap = exp instanceof ABoolLiteralExpIR
|| formattedExp.startsWith("(") && formattedExp.endsWith(")");
return doNotWrap ? "!" + formattedExp : "!(" + formattedExp + ")";
}
public String formatTemplateTypes(List<STypeIR> types)
throws AnalysisException
{
if (types.isEmpty())
{
return "";
}
return "<" + formattedTypes(types, "") + ">";
}
private String formattedTypes(List<STypeIR> types, String typePostFix)
throws AnalysisException
{
STypeIR firstType = types.get(0);
if (info.getAssistantManager().getTypeAssistant().isBasicType(firstType))
{
firstType = info.getAssistantManager().getTypeAssistant().getWrapperType((SBasicTypeIR) firstType);
}
StringWriter writer = new StringWriter();
writer.append(format(firstType) + typePostFix);
for (int i = 1; i < types.size(); i++)
{
STypeIR currentType = types.get(i);
if (info.getAssistantManager().getTypeAssistant().isBasicType(currentType))
{
currentType = info.getAssistantManager().getTypeAssistant().getWrapperType((SBasicTypeIR) currentType);
}
writer.append(", " + format(currentType) + typePostFix);
}
String result = writer.toString();
return result;
}
public String formatTypeArg(STypeIR type) throws AnalysisException
{
if (type == null)
{
return null;
} else
{
List<STypeIR> types = new LinkedList<STypeIR>();
types.add(type);
return formattedTypes(types, CLASS_EXTENSION);
}
}
public String formatTypeArgs(ATupleTypeIR tupleType)
throws AnalysisException
{
return formatTypeArgs(tupleType.getTypes());
}
public String formatTypeArgs(List<STypeIR> types) throws AnalysisException
{
if (types.isEmpty())
{
return "";
}
return formattedTypes(types, CLASS_EXTENSION);
}
public String formatEqualsBinaryExp(AEqualsBinaryExpIR node)
throws AnalysisException
{
STypeIR leftNodeType = node.getLeft().getType();
if (leftNodeType instanceof SSeqTypeIR
|| leftNodeType instanceof SSetTypeIR
|| leftNodeType instanceof SMapTypeIR)
{
return handleCollectionComparison(node);
} else
{
return handleEquals(node);
}
}
public String formatNotEqualsBinaryExp(ANotEqualsBinaryExpIR node)
throws AnalysisException
{
ANotUnaryExpIR transformed = transNotEquals(node);
return formatNotUnary(transformed.getExp());
}
private ANotUnaryExpIR transNotEquals(ANotEqualsBinaryExpIR notEqual)
{
ANotUnaryExpIR notUnary = new ANotUnaryExpIR();
notUnary.setType(new ABoolBasicTypeIR());
AEqualsBinaryExpIR equal = new AEqualsBinaryExpIR();
equal.setType(new ABoolBasicTypeIR());
equal.setLeft(notEqual.getLeft().clone());
equal.setRight(notEqual.getRight().clone());
notUnary.setExp(equal);
// Replace the "notEqual" expression with the transformed expression
INode parent = notEqual.parent();
// It may be the case that the parent is null if we execute e.g. [1] <> [1] in isolation
if (parent != null)
{
parent.replaceChild(notEqual, notUnary);
notEqual.parent(null);
}
return notUnary;
}
private String handleEquals(AEqualsBinaryExpIR valueType)
throws AnalysisException
{
return String.format("%s.equals(%s, %s)", UTILS_FILE, format(valueType.getLeft()), format(valueType.getRight()));
}
private String handleCollectionComparison(SBinaryExpIR node)
throws AnalysisException
{
// In VDM the types of the equals are compatible when the AST passes the type check
SExpIR leftNode = node.getLeft();
SExpIR rightNode = node.getRight();
String empty = "Utils.empty(%s)";
if (isEmptyCollection(leftNode.getType()))
{
return String.format(empty, format(node.getRight()));
} else if (isEmptyCollection(rightNode.getType()))
{
return String.format(empty, format(node.getLeft()));
}
return UTILS_FILE + ".equals(" + format(node.getLeft()) + ", "
+ format(node.getRight()) + ")";
}
private boolean isEmptyCollection(STypeIR type)
{
if (type instanceof SSeqTypeIR)
{
SSeqTypeIR seq = (SSeqTypeIR) type;
return seq.getEmpty();
} else if (type instanceof SSetTypeIR)
{
SSetTypeIR set = (SSetTypeIR) type;
return set.getEmpty();
} else if (type instanceof SMapTypeIR)
{
SMapTypeIR map = (SMapTypeIR) type;
return map.getEmpty();
}
return false;
}
public String format(List<AFormalParamLocalParamIR> params)
throws AnalysisException
{
StringWriter writer = new StringWriter();
if (params.size() <= 0)
{
return "";
}
final String finalPrefix = " final ";
AFormalParamLocalParamIR firstParam = params.get(0);
writer.append(finalPrefix);
writer.append(format(firstParam));
for (int i = 1; i < params.size(); i++)
{
AFormalParamLocalParamIR param = params.get(i);
writer.append(", ");
writer.append(finalPrefix);
writer.append(format(param));
}
return writer.toString();
}
public String formatSuperType(SClassDeclIR classDecl)
{
return classDecl.getSuperNames().isEmpty() ? ""
: "extends " + classDecl.getSuperNames().get(0);
}
public String formatInterfaces(SClassDeclIR classDecl)
{
LinkedList<AInterfaceDeclIR> interfaces = classDecl.getInterfaces();
if (interfaces == null)
{
return "";
}
List<String> interfaceNames = new LinkedList<>();
for(AInterfaceDeclIR i : interfaces)
{
interfaceNames.add(i.getName());
}
return formatInterfaceNames(interfaceNames, "implements");
}
public String formatInterfaces(AInterfaceDeclIR inter)
{
if(inter.getExtension() == null || inter.getExtension().isEmpty())
{
return "";
}
List<String> interfaceNames = new LinkedList<>();
for(ATokenNameIR e : inter.getExtension())
{
interfaceNames.add(e.getName());
}
return formatInterfaceNames(interfaceNames, "extends");
}
private String formatInterfaceNames(List<String> interfaceNames, String keyword) {
String implementsClause = keyword;
String sep = " ";
if (interfaceNames.isEmpty())
{
// All classes must be declared Serializable when traces are being generated.
if (info.getSettings().generateTraces()
|| getJavaSettings().makeClassesSerializable())
{
return implementsClause + sep
+ java.io.Serializable.class.getName();
} else
{
return "";
}
}
for (int i = 0; i < interfaceNames.size(); i++)
{
implementsClause += sep + interfaceNames.get(i);
sep = ", ";
}
if (info.getSettings().generateTraces()
|| getJavaSettings().makeClassesSerializable())
{
implementsClause += sep + java.io.Serializable.class.getName();
}
return implementsClause;
}
public String formatArgs(List<? extends SExpIR> exps)
throws AnalysisException
{
StringWriter writer = new StringWriter();
if (exps.size() <= 0)
{
return "";
}
SExpIR firstExp = exps.get(0);
writer.append(format(firstExp));
for (int i = 1; i < exps.size(); i++)
{
SExpIR exp = exps.get(i);
writer.append(", " + format(exp));
}
return writer.toString();
}
public boolean isNull(INode node)
{
return node == null;
}
public boolean isVoidType(STypeIR node)
{
return node instanceof AVoidTypeIR;
}
public String formatInitialExp(SExpIR exp) throws AnalysisException
{
// Examples:
// private int a; (exp == null || exp instanceof AUndefinedExpIR)
// private int a = 2; (otherwise)
return exp == null || exp instanceof AUndefinedExpIR ? ""
: " = " + format(exp);
}
public String formatThrows(List<STypeIR> types) throws AnalysisException
{
if (!types.isEmpty())
{
StringBuilder sb = new StringBuilder();
sb.append(IJavaConstants.THROWS);
sb.append(' ');
String sep = "";
for (STypeIR t : types)
{
sb.append(sep);
sb.append(format(t));
sep = ", ";
}
return sb.toString();
} else
{
return "";
}
}
public String formatOperationBody(SStmIR body) throws AnalysisException
{
String NEWLINE = "\n";
if (body == null)
{
return ";";
}
StringWriter generatedBody = new StringWriter();
generatedBody.append("{" + NEWLINE + NEWLINE);
generatedBody.append(handleOpBody(body));
generatedBody.append(NEWLINE + "}");
return generatedBody.toString();
}
private String handleOpBody(SStmIR body) throws AnalysisException
{
AMethodDeclIR method = body.getAncestor(AMethodDeclIR.class);
if (method == null)
{
log.error("Could not find enclosing method when formatting operation body. Got: "
+ body);
} else if (method.getAsync() != null && method.getAsync())
{
return "new VDMThread(){ " + "\tpublic void run() {" + "\t "
+ format(body) + "\t} " + "}.start();";
}
return format(body);
}
public String formatTemplateParam(INode potentialBasicType)
throws AnalysisException
{
if (potentialBasicType == null)
{
return "";
}
TypeAssistantIR typeAssistant = info.getAssistantManager().getTypeAssistant();
if (potentialBasicType instanceof STypeIR
&& typeAssistant.isNumericType((STypeIR) potentialBasicType))
{
return "Number";
} else if (potentialBasicType instanceof ABoolBasicTypeIR)
{
return "Boolean";
} else if (potentialBasicType instanceof ACharBasicTypeIR)
{
return "Character";
} else
{
return format(potentialBasicType);
}
}
public boolean isSeqType(SExpIR exp)
{
return info.getAssistantManager().getTypeAssistant().isSeqType(exp);
}
public boolean isMapType(SExpIR exp)
{
return info.getAssistantManager().getTypeAssistant().isMapType(exp);
}
public boolean isStringType(STypeIR type)
{
return info.getAssistantManager().getTypeAssistant().isStringType(type);
}
public boolean isStringType(SExpIR exp)
{
return info.getAssistantManager().getTypeAssistant().isStringType(exp);
}
public String buildString(List<SExpIR> exps) throws AnalysisException
{
StringBuilder sb = new StringBuilder();
sb.append("new String(new char[]{");
if (exps.size() > 0)
{
sb.append(format(exps.get(0)));
for (int i = 1; i < exps.size(); i++)
{
sb.append(", " + format(exps.get(i)));
}
}
sb.append("})");
return sb.toString();
}
public String formatElementType(STypeIR type) throws AnalysisException
{
if (type instanceof SSetTypeIR)
{
SSetTypeIR setType = (SSetTypeIR) type;
return format(setType.getSetOf());
} else if (type instanceof SSeqTypeIR)
{
SSeqTypeIR seqType = (SSeqTypeIR) type;
return format(seqType.getSeqOf());
} else if (type instanceof AStringTypeIR)
{
return format(new ACharBasicTypeIR());
} else
{
log.error("Expected set, seq or string type when trying to format element type. Got: "
+ type);
return format(new AUnknownTypeIR());
}
}
public boolean isLoopVar(AVarDeclIR localVar)
{
return localVar.parent() instanceof AForLoopStmIR;
}
public boolean isLambda(AApplyExpIR applyExp)
{
SExpIR root = applyExp.getRoot();
if (root instanceof AApplyExpIR
&& root.getType() instanceof AMethodTypeIR)
{
return true;
}
if (!(root instanceof SVarExpIR))
{
return false;
}
SVarExpIR varExp = (SVarExpIR) root;
return varExp.getIsLambda() != null && varExp.getIsLambda();
}
public String escapeStr(String str)
{
String escaped = "";
for (int i = 0; i < str.length(); i++)
{
char currentChar = str.charAt(i);
escaped += GeneralUtils.isEscapeSequence(currentChar)
? StringEscapeUtils.escapeJava(currentChar + "")
: currentChar + "";
}
return escaped;
}
public static boolean castNotNeeded(STypeIR type)
{
return type instanceof AObjectTypeIR || type instanceof AUnknownTypeIR
|| type instanceof AUnionTypeIR;
}
public String escapeChar(char c)
{
return GeneralUtils.isEscapeSequence(c)
? StringEscapeUtils.escapeJavaScript(c + "") : c + "";
}
public boolean isInnerClass(SClassDeclIR node)
{
return info.getDeclAssistant().isInnerClass(node);
}
public String formatStartStmExp(AStartStmIR node) throws AnalysisException
{
String str = format(node.getExp());
if (node.getExp().getType() instanceof AClassTypeIR)
{
return str;
} else
{
return "((Thread)" + str + ")";
}
}
public boolean genDecl(ATypeDeclIR node)
{
return !(node.getDecl() instanceof ANamedTypeDeclIR);
}
public boolean genTypeDecl(ATypeDeclIR node)
{
if (node.getDecl() instanceof ARecordDeclIR)
{
return getJavaSettings().genRecsAsInnerClasses();
} else
{
return info.getSettings().generateInvariants();
}
}
public static boolean isSeqConversion(AFieldNumberExpIR node)
{
INode parent = node.parent();
return parent instanceof ASeqToStringUnaryExpIR
|| parent instanceof AStringToSeqUnaryExpIR;
}
public static boolean isScoped(ABlockStmIR block)
{
return block != null && block.getScoped() != null && block.getScoped();
}
public static boolean isMainClass(SClassDeclIR clazz)
{
return clazz != null && clazz.getTag() instanceof JavaMainTag;
}
public String formatVdmSource(PIR irNode)
{
if (getJavaSettings().printVdmLocations() && irNode != null)
{
org.overture.ast.node.INode vdmNode = LocationAssistantIR.getVdmNode(irNode);
if (vdmNode != null)
{
ILexLocation loc = info.getLocationAssistant().findLocation(vdmNode);
if (loc != null)
{
return String.format("/* %s %d:%d */\n", loc.getFile().getName(), loc.getStartLine(), loc.getStartPos());
}
}
}
return "";
}
public String getQuotePackagePrefix()
{
String settings = getJavaSettings().getJavaRootPackage();
if (settings != null && !settings.trim().isEmpty())
{
return settings + "." + JavaCodeGen.JAVA_QUOTES_PACKAGE + ".";
} else
{
return JavaCodeGen.JAVA_QUOTES_PACKAGE + ".";
}
}
public boolean genClassInvariant(SClassDeclIR clazz)
{
if (!info.getSettings().generateInvariants())
{
return false;
}
return clazz.getInvariant() != null;
}
public static String formatMetaData(List<ClonableString> metaData)
{
if (metaData == null || metaData.isEmpty())
{
return "";
}
StringBuilder sb = new StringBuilder();
for (ClonableString str : metaData)
{
sb.append(str.value).append('\n');
}
return sb.append('\n').toString();
}
public static boolean isVdmSl()
{
return Settings.dialect == Dialect.VDM_SL;
}
public String genIteratorName()
{
return info.getTempVarNameGen().nextVarName(varPrefixManager.getIteVarPrefixes().iterator());
}
public String genThreadName()
{
return info.getTempVarNameGen().nextVarName("nextThread_");
}
public String genForIndexToVarName()
{
return info.getTempVarNameGen().nextVarName(varPrefixManager.getIteVarPrefixes().forIndexToVar());
}
public String genForIndexByVarName()
{
return info.getTempVarNameGen().nextVarName(varPrefixManager.getIteVarPrefixes().forIndexByVar());
}
public static String getString(ClonableString c)
{
return c.value;
}
public boolean isUndefined(ACastUnaryExpIR cast)
{
return info.getExpAssistant().isUndefined(cast);
}
}