package org.overture.codegen.tests;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import org.overture.ast.analysis.AnalysisException;
import org.overture.ast.definitions.SClassDefinition;
import org.overture.ast.lex.Dialect;
import org.overture.ast.modules.AModuleModules;
import org.overture.ast.node.INode;
import org.overture.codegen.ir.IRGenerator;
import org.overture.codegen.ir.IRStatus;
import org.overture.codegen.ir.PIR;
import org.overture.codegen.ir.expressions.AIdentifierVarExpIR;
import org.overture.codegen.tests.util.FirstVarFinder;
import org.overture.config.Settings;
import org.overture.typechecker.util.TypeCheckerUtil;
import org.overture.typechecker.util.TypeCheckerUtil.TypeCheckResult;
/**
* Tests if the {@link AIdentifierVarExpIR#getIsLocal()} works as intended. For simplicity each test specification
* includes a single variable occurrence in some context.
*
* @author pvj
*/
public class LocalVarTest
{
public static final String ROOT = "src" + File.separatorChar + "test"
+ File.separatorChar + "resources" + File.separatorChar
+ "local_var_test_specs";
public static boolean LOCAL = true;
public static boolean NOT_LOCAL = false;
@Test
public void letVarInOp()
{
checkLocal("LetVarInOp.vdmsl", "v", LOCAL);
}
@Test
public void opParam()
{
checkLocal("OpParam.vdmsl", "x", LOCAL);
}
@Test
public void valueReadInOp()
{
checkLocal("ValueReadInOp.vdmsl", "q", NOT_LOCAL);
}
@Test
public void stateRead()
{
checkLocal("StateRead.vdmsl", "h", NOT_LOCAL);
}
@Test
public void dcl()
{
checkLocal("Dcl.vdmsl", "m", LOCAL);
}
@Test
public void tupPatternInFunc()
{
checkLocal("TupPatternInFunc.vdmsl", "a", LOCAL);
}
@Test
public void tupPatternVal()
{
checkLocal("TupPatternVal.vdmsl", "p", NOT_LOCAL);
}
@Test
public void lambdaParamReturn()
{
checkLocal("LambdaParamReturn.vdmsl", "o", LOCAL);
}
@Test
public void lambdaValReturn()
{
checkLocal("LambdaValReturn.vdmsl", "val", NOT_LOCAL);
}
@Test
public void instanceVar()
{
checkLocal("InstanceVar.vdmpp", "iv", NOT_LOCAL);
}
@Test
public void instanceVarParent()
{
checkLocal("InstanceVarParent.vdmpp", "field", NOT_LOCAL);
}
protected void checkLocal(String spec, String expectedVarName,
boolean expectedLocalVal)
{
AIdentifierVarExpIR var = findVar(consIrModule(spec));
Assert.assertTrue("Could not find variable occurrence in module", var != null);
Assert.assertTrue("Expected name of variable occurence to be "
+ expectedVarName + " but it was "
+ var.getName(), var.getName().equals(expectedVarName));
Assert.assertTrue("Expected 'getIsLocal()' to be " + expectedLocalVal
+ " but it was not", var.getIsLocal() == expectedLocalVal);
}
protected AIdentifierVarExpIR findVar(List<PIR> irNodes)
{
try
{
FirstVarFinder finder = new FirstVarFinder();
for (PIR n : irNodes)
{
n.apply(finder);
if (finder.getVar() != null)
{
// As soon as we find an occurrence return it.
return finder.getVar();
}
}
} catch (org.overture.codegen.ir.analysis.AnalysisException e)
{
}
return null;
}
protected List<PIR> consIrModule(String fileName)
{
File file = new File(ROOT + File.separatorChar + fileName);
String tcErrMsg = "Expected VDM specification to parse and type check";
List<? extends INode> nodes;
if (fileName.endsWith(".vdmsl"))
{
Settings.dialect = Dialect.VDM_SL;
TypeCheckResult<List<AModuleModules>> tcRes = TypeCheckerUtil.typeCheckSl(file);
Assert.assertTrue(tcErrMsg, tcRes.parserResult.errors.isEmpty()
&& tcRes.errors.isEmpty());
nodes = tcRes.result;
} else
{
Settings.dialect = Dialect.VDM_PP;
TypeCheckResult<List<SClassDefinition>> tcRes = TypeCheckerUtil.typeCheckPp(file);
Assert.assertTrue(tcErrMsg, tcRes.parserResult.errors.isEmpty()
&& tcRes.errors.isEmpty());
nodes = tcRes.result;
}
IRGenerator irGen = new IRGenerator();
try
{
List<PIR> irRes = new LinkedList<>();
for (INode n : nodes)
{
IRStatus<PIR> res = irGen.generateFrom(n);
Assert.assertTrue("Expected IR node to generate without problems", irRes != null
&& res.canBeGenerated());
irRes.add(res.getIrNode());
}
return irRes;
} catch (AnalysisException e)
{
Assert.fail("Problems encountered when trying to generate IR node: "
+ e.getMessage());
}
return null;
}
}