package org.overture.codegen.tests.other; import java.io.StringWriter; import java.util.LinkedList; import java.util.List; import org.junit.Assert; import org.junit.Test; import org.overture.ast.util.ClonableString; import org.overture.codegen.ir.INode; import org.overture.codegen.ir.IRConstants; import org.overture.codegen.ir.analysis.AnalysisException; import org.overture.codegen.ir.declarations.ACatchClauseDeclIR; import org.overture.codegen.ir.declarations.AFieldDeclIR; import org.overture.codegen.ir.declarations.AMethodDeclIR; import org.overture.codegen.ir.declarations.AVarDeclIR; import org.overture.codegen.ir.expressions.ATypeArgExpIR; import org.overture.codegen.ir.patterns.AIdentifierPatternIR; import org.overture.codegen.ir.statements.AMetaStmIR; import org.overture.codegen.ir.statements.AReturnStmIR; import org.overture.codegen.ir.statements.ASkipStmIR; import org.overture.codegen.ir.statements.ATryStmIR; import org.overture.codegen.ir.types.ABoolBasicTypeIR; import org.overture.codegen.ir.types.AClassTypeIR; import org.overture.codegen.ir.types.AExternalTypeIR; import org.overture.codegen.ir.types.AMethodTypeIR; import org.overture.codegen.ir.types.ARealNumericBasicTypeIR; import org.overture.codegen.ir.types.AVoidTypeIR; import org.overture.codegen.merging.MergeVisitor; import org.overture.codegen.utils.GeneralUtils; import org.overture.codegen.vdm2java.JavaCodeGen; import org.overture.codegen.vdm2java.JavaFormat; public class IRTest { private JavaCodeGen javaCodeGen; public IRTest() { this.javaCodeGen = new JavaCodeGen(); } @Test public void testVolatileField() { AFieldDeclIR fieldDecl = new AFieldDeclIR(); fieldDecl.setAccess("public"); fieldDecl.setFinal(false); fieldDecl.setInitial(javaCodeGen.getInfo().getExpAssistant().consBoolLiteral(true)); fieldDecl.setVolatile(true); fieldDecl.setStatic(true); fieldDecl.setName("flag"); fieldDecl.setType(new ABoolBasicTypeIR()); String expected = "public static volatile Boolean flag = true;"; compare(expected, fieldDecl); } @Test public void testTypeArg() { AClassTypeIR classA = new AClassTypeIR(); classA.setName("A"); ATypeArgExpIR typeArg = new ATypeArgExpIR(); typeArg.setType(classA); String expected = "A.class"; compare(expected, typeArg); } @Test public void testCatchClause() { ACatchClauseDeclIR catchClause = consCatchClause(); String expected = "catch(Exception e1) { return 42L; }"; compare(expected, catchClause); } @Test public void testTryNoCatch() { ATryStmIR tryStm = new ATryStmIR(); tryStm.setStm(consReturnIntLit(4)); tryStm.setFinally(consReturnIntLit(19)); String expected = "try { return 4L; } finally { return 19L; }"; compare(expected, tryStm); } @Test public void testTryNoFinal() { ATryStmIR tryStm = new ATryStmIR(); tryStm.setStm(consReturnIntLit(5)); for (int i = 0; i < 2; i++) { tryStm.getCatchClauses().add(consCatchClause()); } String expected = "try { return 5L; } catch(Exception e1) { return 42L; } catch(Exception e1) { return 42L; }"; compare(expected, tryStm); } @Test public void testOpRaises() { AMethodDeclIR method = new AMethodDeclIR(); method.setAbstract(false); method.setAccess(IRConstants.PUBLIC); method.setAsync(false); method.setBody(new ASkipStmIR()); AMethodTypeIR t = new AMethodTypeIR(); t.setResult(new AVoidTypeIR()); method.setName("op"); method.setMethodType(t); method.setStatic(false); AExternalTypeIR runtimeExpType = new AExternalTypeIR(); runtimeExpType.setName("RuntimeException"); method.getRaises().add(runtimeExpType); // For one exception compare("public void op() throws RuntimeException { /* skip */ }", method); AExternalTypeIR npeType = new AExternalTypeIR(); npeType.setName("NullPointerException"); method.getRaises().add(npeType); compare("public void op() throws RuntimeException, NullPointerException { /* skip */ }", method); } @Test public void testFinalVarDecl() { AIdentifierPatternIR id = new AIdentifierPatternIR(); id.setName("x"); AVarDeclIR varDecl = javaCodeGen.getInfo().getDeclAssistant().consLocalVarDecl(new ARealNumericBasicTypeIR(), id, javaCodeGen.getInfo().getExpAssistant().consUndefinedExp()); varDecl.setFinal(true); String expected = "final Number x = null;"; compare(expected, varDecl); } @Test public void testMetaStm() { String metaDataStr = "/*@ some meta data @*/"; List<ClonableString> metaData = new LinkedList<ClonableString>(); metaData.add(new ClonableString("/*@ some meta data @*/")); AMetaStmIR meta = new AMetaStmIR(); meta.setMetaData(metaData); String expected = metaDataStr; compare(expected, meta); } private void compare(String expected, INode node) { StringWriter writer = new StringWriter(); try { JavaFormat javaFormat = javaCodeGen.getJavaFormat(); javaFormat.getMergeVisitor().init(); MergeVisitor mergeVisitor = javaFormat.getMergeVisitor(); node.apply(mergeVisitor, writer); if (mergeVisitor.getMergeErrors().isEmpty()) { String actual = GeneralUtils.cleanupWhiteSpaces(writer.toString()); Assert.assertEquals("Got unexpected code generator output", expected, actual); } else { Assert.fail("Could print node: " + node); } } catch (AnalysisException e) { e.printStackTrace(); Assert.fail("Could not print field declaration"); } } private AReturnStmIR consReturnIntLit(long n) { AReturnStmIR returnStm = new AReturnStmIR(); returnStm.setExp(javaCodeGen.getInfo().getExpAssistant().consIntLiteral(n)); return returnStm; } private ACatchClauseDeclIR consCatchClause() { AExternalTypeIR externalType = new AExternalTypeIR(); externalType.setName("Exception"); ACatchClauseDeclIR catchClause = new ACatchClauseDeclIR(); catchClause.setType(externalType); catchClause.setName("e1"); catchClause.setStm(consReturnIntLit(42)); return catchClause; } }