Package test

Source Code of test.CompilerTests$CompiledClassLoader

package test;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

import backend.ProgramCodeGenerator;
import junit.framework.Assert;
import lexer.Lexer;
import parser.Parser;
import soot.Printer;
import soot.SootClass;
import soot.jimple.JasminClass;
import soot.util.JasminOutputStream;
import ast.List;
import ast.Module;
import ast.Program;

/**
* System tests for the compiler: compiles a given program to Java bytecode, then immediately
* loads it into the running JVM and executes it.
*/
public class CompilerTests {
  // set this flag to true to dump generated Jimple code to standard output
  private static final boolean DEBUG = false;
 
  /**
   * A simple class loader that allows us to directly load compiled classes.
   */
  private static class CompiledClassLoader extends URLClassLoader {
    private final Map<String, byte[]> classes = new HashMap<String, byte[]>();
   
    public CompiledClassLoader() {
      super(new URL[0], CompilerTests.class.getClassLoader());
    }
   
    public void addClass(String name, byte[] code) {
      classes.put(name, code);
    }
   
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
      if(classes.containsKey(name)) {
        byte[] code = classes.get(name);
        return defineClass(name, code, 0, code.length);
      }
      return super.findClass(name);
    }
  }

  /**
   * Test runner class.
   *
   * @param modules_src Array of strings, representing the source code of the program modules
   * @param main_module the name of the main module
   * @param main_function the name of the main function
   * @param parm_types the parameter types of the main function
   * @param args arguments to pass to the main method
   * @param expected expected result
   */
  private void runtest(String[] modules_src, String main_module, String main_function, Class<?>[] parm_types, Object[] args, Object expected) {
    try {
      List<Module> modules = new List<Module>();
      for(String module_src : modules_src) {
        Parser parser = new Parser();
        Module module = (Module)parser.parse(new Lexer(new StringReader(module_src)));
        modules.add(module);
      }
      Program prog = new Program(modules);
     
      prog.namecheck();
      prog.typecheck();
      prog.flowcheck();
      if(prog.hasErrors()) {
        Assert.fail(prog.getErrors().iterator().next().toString());
      }
     
      CompiledClassLoader loader = new CompiledClassLoader();
      try {
        for(SootClass klass : new ProgramCodeGenerator().generate(prog)) {
          if(DEBUG) {
            PrintWriter stdout_pw = new PrintWriter(System.out);
            Printer.v().printTo(klass, stdout_pw);
            stdout_pw.flush();
          }

          String name = klass.getName();
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          PrintWriter pw = new PrintWriter(new JasminOutputStream(baos));
          new JasminClass(klass).print(pw);
          pw.flush();
          loader.addClass(name, baos.toByteArray());
        }

        Class<?> testclass = loader.loadClass(main_module);
        Method method = testclass.getMethod(main_function, parm_types);
        Object actual = method.invoke(null, args);
        if(!method.getReturnType().equals(void.class))
          Assert.assertEquals(expected, actual);
      } finally {
        loader.close();
      }
    } catch(Exception e) {
      e.printStackTrace();
      Assert.fail(e.getMessage());
    } catch(ClassFormatError e) {
      e.printStackTrace();
      Assert.fail(e.getMessage());
    }
  }

  /** Convenience wrapper for runtest with only a single module. Other arguments are the same .*/
  private void runtest(String string, String classname, String methodname, Class<?>[] parmTypes, Object[] args, Object expected) {
    runtest(new String[] { string }, classname, methodname, parmTypes, args, expected);
  }

  @Test public void testAddition() {
    runtest("module Test {" +
        "  public int f() {" +
        "    return 23+19;" +
        "  }" +
        "}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        42);
  }
  @Test public void testSubtraction() {
    runtest("module Test {" +
        "  public int f() {" +
        "    return 23-19;" +
        "  }" +
        "}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        4);
  }
  @Test public void testMultiplication() {
    runtest("module Test {" +
        "  public int f() {" +
        "    return 23*19;" +
        "  }" +
        "}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        437);
  }
  @Test public void testDivision() {
    runtest("module Test {" +
        "  public int f() {" +
        "    return 23/19;" +
        "  }" +
        "}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        1);
  }
  @Test public void testMod() {
    runtest("module Test {" +
        "  public int f() {" +
        "    return 23%19;" +
        "  }" +
        "}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        4);
  }
//  @Test public void testIf() {
//    runtest("module Test {" +
//        "  public int f() {" +
//        "    int x;x = 0;if(x>0){return 1;}else{return 2;}" +
//        "  }" +
//        "}",
//        "Test",
//        "f",
//        new Class<?>[0],
//        new Object[0],
//        4);
//  }
  @Test public void testIf2() {
    runtest("module Test {public int f() {int x;x=0;if(0){x=1;} return x;}}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        0);
  }
  @Test public void testIf() {
    runtest("module Test {public int f() {if(0)return 1;else return 2;}}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        2);
  }
  @Test public void testEpr() {
    runtest("module Test {public void f() {2;}}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        1);
  }
  @Test public void testWhile() {
    runtest("module Test {public int f() {int x; x = 0; while(x<3) x=4; return x;}}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        4);
  }
  @Test public void testWhile2() {
    runtest("module Test {public int f() {int x; x = 0; while(x<43) {x=5; break;} return x;}}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        5);
  }
  @Test public void testDeclare() {
    runtest("module Test {public int f() {int x; x=2;return 1;}}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        1);
  }
  @Test public void testDeclare1() {
    runtest("module Test {public boolean f() {int x; x=2;return 1>2;}}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        false);
  }
  @Test public void testDeclare2() {
    runtest("module Test {public boolean f() {int x; x=2;return 1<2;}}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        true);
  }
  @Test public void testDeclare3() {
    runtest("module Test {public boolean f() {int x; x=2;return 1==2;}}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        false);
  }
  @Test public void testDeclare4() {
    runtest("module Test {public boolean f() {int x; x=2;return 1>=2;}}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        false);
  }
  @Test public void testDeclare5() {
    runtest("module Test {public boolean f() {int x; x=2;return 1<=2;}}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        true);
  }
  @Test public void testPrecedence() {
    runtest("module Test {" +
        "  public int f() {" +
        "    return 2+42/2;" +
        "  }" +
        "}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        23);
  }

     @Test public void testParentheses() {
    runtest("module Test {" +
        "  public int f() {" +
        "    return (2+42)/2;" +
        "  }" +
        "}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        22);
  }

  @Test public void testNegation() {
    runtest("module Test {" +
        "  public int f() {" +
        "    return -42;" +
        "  }" +
        "}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
        -42);
  }
  @Test public void testAarray() {
    runtest("module Test {" +
        "  public int f() {" +
        " int[][] a;"+
        " a = [[0,0],[1,1]];"+
        " a[1][1] = 2;" +
        "    return a[1][1];" +
        "  }" +
        "}",
        "Test",
        "f",
        new Class<?>[0],
        new Object[0],
      2);
  }

}
TOP

Related Classes of test.CompilerTests$CompiledClassLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.