Refactor CodegenTestCase
- prohibit main(Array<String>) in favor of box(): String - move all script-related code to ScriptGenTest - remove unused environment-creating methods - inline trivial methods & other minor stuff
This commit is contained in:
@@ -20,6 +20,7 @@ class X {
|
||||
|
||||
fun foo(x: Int) {}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
fun box(): String {
|
||||
X().test()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ class X {
|
||||
|
||||
fun foo(x: Int) {}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
fun box(): String {
|
||||
X().test()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ class X {
|
||||
|
||||
fun foo(x: Int) {}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
fun box(): String {
|
||||
X().test()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
fun main(args : Array<String>) {
|
||||
fun box(): String {
|
||||
if (1 != 0) {
|
||||
1
|
||||
}
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -9,10 +9,12 @@ class Broken() : jet.Function0<String>() {
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
fun box(): String {
|
||||
val works1: ()->Object = Works();
|
||||
works1()
|
||||
|
||||
val broken1: ()->String = Broken();
|
||||
broken1()
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
public var v1: String = "V1"
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
System.out?.println("v1: $v1, v2: $v2")
|
||||
}
|
||||
fun box(): String {
|
||||
val s = "v1: $v1, v2: $v2"
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ class A<T>(t: Array<Array<T>>) {
|
||||
val a:Array<Array<T>> = t
|
||||
}
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
fun box(): String {
|
||||
A<Int>(array()) // <- java.lang.VerifyError: (class: A, method: getA signature: ()[[Ljava/lang/Object;) Wrong return type in function
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
fun main(args: Array<String>) {
|
||||
fun box(): String {
|
||||
kotlin.assert(true)
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import java.util.HashMap
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
fun box(): String {
|
||||
(0.toLong() as Number?)?.toByte()
|
||||
(0 as Int?)?.toDouble()
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
fun main(args : Array<String>) {
|
||||
fun box(): String {
|
||||
1 in 1.rangeTo(10)
|
||||
1..10
|
||||
'h' in 'A'.rangeTo('Z')
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
fun main(args: Array<String>) {
|
||||
fun box(): String {
|
||||
9 in 0..9
|
||||
val intRange = 0..9
|
||||
9 in intRange
|
||||
@@ -10,4 +10,6 @@ fun main(args: Array<String>) {
|
||||
9.toLong() in longRange
|
||||
val shortRange = 0.toShort()..9.toShort()
|
||||
9.toShort() in shortRange
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
fun main(args: Array<String>) {
|
||||
fun box(): String {
|
||||
A()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
class A: B() {
|
||||
@@ -8,4 +9,4 @@ class A: B() {
|
||||
|
||||
abstract class B {
|
||||
abstract var foo: Array<Int?>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,9 @@ class C() {
|
||||
}
|
||||
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
fun box(): String {
|
||||
if (2 in C()..2) {
|
||||
System.out?.println(2)
|
||||
2 == 2
|
||||
}
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.jet.ConfigurationKind;
|
||||
|
||||
public abstract class AbstractDataClassCodegenTest extends CodegenTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
createEnvironmentWithFullJdk();
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,12 @@ package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.jet.ConfigurationKind;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.TestJdkKind;
|
||||
@@ -35,17 +33,15 @@ import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.state.Progress;
|
||||
import org.jetbrains.jet.config.CompilerConfiguration;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||
import org.jetbrains.jet.lang.resolve.ScriptNameUtil;
|
||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||
import org.jetbrains.jet.utils.ExceptionUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
@@ -61,31 +57,16 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
protected JetCoreEnvironment myEnvironment;
|
||||
protected CodegenTestFiles myFiles;
|
||||
|
||||
protected Object scriptInstance;
|
||||
private GenerationState alreadyGenerated;
|
||||
private GeneratedClassLoader initializedClassLoader;
|
||||
|
||||
protected void createEnvironmentWithMockJdkAndIdeaAnnotations() {
|
||||
if (myEnvironment != null) {
|
||||
throw new IllegalStateException("must not set up myEnvironemnt twice");
|
||||
}
|
||||
myEnvironment = JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(getTestRootDisposable());
|
||||
}
|
||||
|
||||
protected void createEnvironmentWithMockJdkAndIdeaAnnotations(@NotNull ConfigurationKind configurationKind) {
|
||||
if (myEnvironment != null) {
|
||||
throw new IllegalStateException("must not set up myEnvironemnt twice");
|
||||
throw new IllegalStateException("must not set up myEnvironment twice");
|
||||
}
|
||||
myEnvironment = JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(getTestRootDisposable(), configurationKind);
|
||||
}
|
||||
|
||||
protected void createEnvironmentWithFullJdk() {
|
||||
if (myEnvironment != null) {
|
||||
throw new IllegalStateException("must not set up myEnvironemnt twice");
|
||||
}
|
||||
myEnvironment = JetTestUtils.createEnvironmentWithFullJdk(getTestRootDisposable());
|
||||
}
|
||||
|
||||
protected static void assertThrows(Method foo, Class<? extends Throwable> exceptionClass, Object instance, Object... args) throws IllegalAccessException {
|
||||
boolean caught = false;
|
||||
try {
|
||||
@@ -97,16 +78,10 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
assertTrue(caught);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
myFiles = null;
|
||||
myEnvironment = null;
|
||||
scriptInstance = null;
|
||||
alreadyGenerated = null;
|
||||
|
||||
if (initializedClassLoader != null) {
|
||||
@@ -118,17 +93,11 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
}
|
||||
|
||||
protected void loadText(final String text) {
|
||||
myFiles = CodegenTestFiles.create("a.jet", text, myEnvironment.getProject());
|
||||
myFiles = CodegenTestFiles.create("a.kt", text, myEnvironment.getProject());
|
||||
}
|
||||
|
||||
protected String loadFile(final String name) {
|
||||
try {
|
||||
final String content = JetTestUtils.doLoadFile(JetParsingTest.getTestDataDir() + "/codegen/", name);
|
||||
myFiles = CodegenTestFiles.create(name, content, myEnvironment.getProject());
|
||||
return content;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return loadFileByFullPath(JetParsingTest.getTestDataDir() + "/codegen/" + name);
|
||||
}
|
||||
|
||||
protected String loadFileByFullPath(final String fullPath) {
|
||||
@@ -173,101 +142,22 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
blackBox(false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Class<?> loadClassFromType(@NotNull Type type) {
|
||||
try {
|
||||
switch (type.getSort()) {
|
||||
case Type.OBJECT:
|
||||
return Class.forName(type.getClassName());
|
||||
case Type.INT:
|
||||
return int.class;
|
||||
case Type.LONG:
|
||||
return long.class;
|
||||
default:
|
||||
// AFAIK there is no way to create array class from class
|
||||
if (type.getDescriptor().equals("[Ljava/lang/String;")) {
|
||||
return String[].class;
|
||||
}
|
||||
throw new IllegalStateException("not implemented: " + type.getDescriptor());
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw ExceptionUtils.rethrow(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Constructor getConstructor(@NotNull Class<?> clazz, org.jetbrains.asm4.commons.Method method) {
|
||||
if (!method.getName().equals("<init>")) {
|
||||
throw new IllegalArgumentException("not constructor: " + method);
|
||||
}
|
||||
Class[] classes = new Class[method.getArgumentTypes().length];
|
||||
for (int i = 0; i < classes.length; ++i) {
|
||||
classes[i] = loadClassFromType(method.getArgumentTypes()[i]);
|
||||
}
|
||||
try {
|
||||
return clazz.getConstructor(classes);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void blackBox(boolean classPathInTheSameClassLoader) {
|
||||
GenerationState state = generateClassesInFileGetState();
|
||||
ClassFileFactory factory = generateClassesInFile();
|
||||
GeneratedClassLoader loader = createClassLoader(factory, classPathInTheSameClassLoader);
|
||||
|
||||
GeneratedClassLoader loader = createClassLoader(state.getFactory(), classPathInTheSameClassLoader);
|
||||
|
||||
String r;
|
||||
JetFile firstFile = myFiles.getPsiFiles().get(0);
|
||||
String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(firstFile)).getFqName().getFqName();
|
||||
|
||||
try {
|
||||
if (myFiles.isScript()) {
|
||||
String scriptClassName = ScriptNameUtil.classNameForScript(myFiles.getPsiFile());
|
||||
Class<?> scriptClass = loader.loadClass(scriptClassName);
|
||||
Class<?> namespaceClass = loader.loadClass(fqName);
|
||||
Method method = namespaceClass.getMethod("box");
|
||||
|
||||
Constructor constructor = getConstructor(scriptClass, state.getScriptCodegen().getScriptConstructorMethod());
|
||||
scriptInstance = constructor.newInstance(myFiles.getScriptParameterValues().toArray());
|
||||
|
||||
assertFalse("expecting at least one expectation", myFiles.getExpectedValues().isEmpty());
|
||||
|
||||
for (Pair<String, String> nameValue : myFiles.getExpectedValues()) {
|
||||
String fieldName = nameValue.first;
|
||||
String expectedValue = nameValue.second;
|
||||
|
||||
if (expectedValue.equals("<nofield>")) {
|
||||
try {
|
||||
scriptClass.getDeclaredField(fieldName);
|
||||
fail("must have no field " + fieldName);
|
||||
} catch (NoSuchFieldException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Field field = scriptClass.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
Object result = field.get(scriptInstance);
|
||||
String resultString = result != null ? result.toString() : "null";
|
||||
assertEquals("comparing field " + fieldName, expectedValue, resultString);
|
||||
}
|
||||
}
|
||||
else {
|
||||
String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFiles.getPsiFiles().get(0))).getFqName().getFqName();
|
||||
Class<?> namespaceClass = loader.loadClass(fqName);
|
||||
try {
|
||||
Method method = namespaceClass.getMethod("box");
|
||||
r = (String) method.invoke(null);
|
||||
assertEquals("OK", r);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
Method method = namespaceClass.getMethod("main",String[].class);
|
||||
method.invoke(null,new Object[]{new String[0]});
|
||||
}
|
||||
}
|
||||
} catch (Error e) {
|
||||
System.out.println(generateToText());
|
||||
throw e;
|
||||
String r = (String) method.invoke(null);
|
||||
assertEquals("OK", r);
|
||||
} catch (Throwable e) {
|
||||
System.out.println(generateToText());
|
||||
throw new RuntimeException(e);
|
||||
ExceptionUtils.rethrow(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,10 +284,9 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
try {
|
||||
return createClassLoader(state).loadClass(fqName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
fail("No classfile was generated for: " + fqName);
|
||||
return null;
|
||||
}
|
||||
|
||||
fail("No classfile was generated for: " + fqName);
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -407,7 +296,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private GenerationState generateClassesInFileGetState() {
|
||||
protected GenerationState generateClassesInFileGetState() {
|
||||
GenerationState generationState;
|
||||
try {
|
||||
generationState = generateCommon(ClassBuilderFactories.TEST, myEnvironment, myFiles);
|
||||
@@ -474,8 +363,4 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
assertTrue("Difference with current time: " + diff + " (this test is a bad one: it may fail even if the generated code is correct)",
|
||||
diff <= toleratedDifference);
|
||||
}
|
||||
|
||||
protected Class loadImplementationClass(@NotNull ClassFileFactory codegens, final String name) {
|
||||
return loadClass(name, codegens);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,10 +82,6 @@ public class CodegenTestFiles {
|
||||
return psiFiles;
|
||||
}
|
||||
|
||||
public boolean isScript() {
|
||||
return psiFiles.size() == 1 && psiFiles.get(0).isScript();
|
||||
}
|
||||
|
||||
public static CodegenTestFiles create(Project project, String[] names) {
|
||||
ArrayList<JetFile> files = new ArrayList<JetFile>();
|
||||
for (String name : names) {
|
||||
|
||||
@@ -33,13 +33,13 @@ public class EnumGenTest extends CodegenTestCase {
|
||||
|
||||
public void testSuperclassIsEnum() throws NoSuchFieldException, IllegalAccessException {
|
||||
loadFile("enum/simple.kt");
|
||||
Class season = loadImplementationClass(generateClassesInFile(), "Season");
|
||||
Class season = loadClass("Season", generateClassesInFile());
|
||||
assertEquals("java.lang.Enum", season.getSuperclass().getName());
|
||||
}
|
||||
|
||||
public void testEnumClassModifiers() throws NoSuchFieldException, IllegalAccessException {
|
||||
loadFile("enum/simple.kt");
|
||||
Class season = loadImplementationClass(generateClassesInFile(), "Season");
|
||||
Class season = loadClass("Season", generateClassesInFile());
|
||||
int modifiers = season.getModifiers();
|
||||
assertTrue((modifiers & 0x4000) != 0); // ACC_ENUM
|
||||
assertTrue((modifiers & Modifier.FINAL) != 0);
|
||||
@@ -47,7 +47,7 @@ public class EnumGenTest extends CodegenTestCase {
|
||||
|
||||
public void testEnumFieldModifiers() throws NoSuchFieldException, IllegalAccessException {
|
||||
loadFile("enum/simple.kt");
|
||||
Class season = loadImplementationClass(generateClassesInFile(), "Season");
|
||||
Class season = loadClass("Season", generateClassesInFile());
|
||||
Field summer = season.getField("SUMMER");
|
||||
int modifiers = summer.getModifiers();
|
||||
assertTrue((modifiers & 0x4000) != 0); // ACC_ENUM
|
||||
@@ -120,7 +120,7 @@ public class EnumGenTest extends CodegenTestCase {
|
||||
public void testNoClassForSimpleEnum()
|
||||
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
|
||||
loadFile("enum/name.kt");
|
||||
Class cls = loadImplementationClass(generateClassesInFile(), "State");
|
||||
Class cls = loadClass("State", generateClassesInFile());
|
||||
Field field = cls.getField("O");
|
||||
assertEquals("State", field.get(null).getClass().getName());
|
||||
}
|
||||
@@ -128,7 +128,7 @@ public class EnumGenTest extends CodegenTestCase {
|
||||
public void testYesClassForComplexEnum()
|
||||
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
|
||||
loadFile("enum/abstractmethod.kt");
|
||||
Class cls = loadImplementationClass(generateClassesInFile(), "IssueState");
|
||||
Class cls = loadClass("IssueState", generateClassesInFile());
|
||||
Field field = cls.getField("DEFAULT");
|
||||
assertEquals("IssueState", field.get(null).getClass().getName());
|
||||
field = cls.getField("FIXED");
|
||||
|
||||
@@ -16,11 +16,13 @@
|
||||
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
|
||||
public class FullJdkCodegenTest extends CodegenTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
createEnvironmentWithFullJdk();
|
||||
myEnvironment = JetTestUtils.createEnvironmentWithFullJdk(getTestRootDisposable());
|
||||
}
|
||||
|
||||
public void testKt434() {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import jet.IntRange;
|
||||
import org.jetbrains.jet.ConfigurationKind;
|
||||
|
||||
import java.awt.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -28,7 +29,7 @@ public class NamespaceGenTest extends CodegenTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations();
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL);
|
||||
}
|
||||
|
||||
public void testPSVM() throws Exception {
|
||||
|
||||
@@ -35,7 +35,7 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testPrivateVal() throws Exception {
|
||||
loadFile();
|
||||
final Class aClass = loadImplementationClass(generateClassesInFile(), "PrivateVal");
|
||||
final Class aClass = loadClass("PrivateVal", generateClassesInFile());
|
||||
final Field[] fields = aClass.getDeclaredFields();
|
||||
assertEquals(1, fields.length); // prop
|
||||
final Field field = fields[0];
|
||||
@@ -44,7 +44,7 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testPrivateVar() throws Exception {
|
||||
loadFile();
|
||||
final Class aClass = loadImplementationClass(generateClassesInFile(), "PrivateVar");
|
||||
final Class aClass = loadClass("PrivateVar", generateClassesInFile());
|
||||
final Object instance = aClass.newInstance();
|
||||
Method setter = findMethodByName(aClass, "setValueOfX");
|
||||
setter.invoke(instance, 239);
|
||||
@@ -54,7 +54,7 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testPublicVar() throws Exception {
|
||||
loadText("class PublicVar() { public var foo : Int = 0; }");
|
||||
final Class aClass = loadImplementationClass(generateClassesInFile(), "PublicVar");
|
||||
final Class aClass = loadClass("PublicVar", generateClassesInFile());
|
||||
final Object instance = aClass.newInstance();
|
||||
Method setter = findMethodByName(aClass, "setFoo");
|
||||
setter.invoke(instance, 239);
|
||||
@@ -116,7 +116,7 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testAccessorsWithoutBody() throws Exception {
|
||||
loadText("class AccessorsWithoutBody() { protected var foo: Int = 349\n get\n private set\n fun setter() { foo = 610; } } ");
|
||||
final Class aClass = loadImplementationClass(generateClassesInFile(), "AccessorsWithoutBody");
|
||||
final Class aClass = loadClass("AccessorsWithoutBody", generateClassesInFile());
|
||||
final Object instance = aClass.newInstance();
|
||||
final Method getFoo = findMethodByName(aClass, "getFoo");
|
||||
getFoo.setAccessible(true);
|
||||
@@ -139,7 +139,7 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testPropertyReceiverOnStack() throws Exception {
|
||||
loadFile();
|
||||
final Class aClass = loadImplementationClass(generateClassesInFile(), "Evaluator");
|
||||
final Class aClass = loadClass("Evaluator", generateClassesInFile());
|
||||
final Constructor constructor = aClass.getConstructor(StringBuilder.class);
|
||||
StringBuilder sb = new StringBuilder("xyzzy");
|
||||
final Object instance = constructor.newInstance(sb);
|
||||
@@ -212,7 +212,7 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testKt1846() {
|
||||
loadFile("regressions/kt1846.kt");
|
||||
final Class aClass = loadImplementationClass(generateClassesInFile(), "A");
|
||||
final Class aClass = loadClass("A", generateClassesInFile());
|
||||
try {
|
||||
Method v1 = aClass.getMethod("getV1");
|
||||
System.out.println(generateToText());
|
||||
@@ -256,7 +256,7 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testKt2589() {
|
||||
loadFile("regressions/kt2589.kt");
|
||||
final Class aClass = loadImplementationClass(generateClassesInFile(), "Foo");
|
||||
final Class aClass = loadClass("Foo", generateClassesInFile());
|
||||
assertTrue((aClass.getModifiers() & Opcodes.ACC_FINAL) == 0);
|
||||
|
||||
try {
|
||||
@@ -284,7 +284,7 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testKt2677() {
|
||||
loadFile("regressions/kt2677.kt");
|
||||
final Class aClass = loadImplementationClass(generateClassesInFile(), "DerivedWeatherReport");
|
||||
final Class aClass = loadClass("DerivedWeatherReport", generateClassesInFile());
|
||||
final Class bClass = aClass.getSuperclass();
|
||||
|
||||
try {
|
||||
|
||||
@@ -16,23 +16,24 @@
|
||||
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.asm4.Opcodes;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.jet.ConfigurationKind;
|
||||
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.lang.parsing.JetScriptDefinition;
|
||||
import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider;
|
||||
import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter;
|
||||
import org.jetbrains.jet.lang.resolve.ScriptNameUtil;
|
||||
import org.jetbrains.jet.utils.ExceptionUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ScriptGenTest extends CodegenTestCase {
|
||||
protected Object scriptInstance;
|
||||
|
||||
public static final JetScriptDefinition FIB_SCRIPT_DEFINITION =
|
||||
new JetScriptDefinition(".lang.kt", new AnalyzerScriptParameter("num", "jet.Int"));
|
||||
@@ -43,59 +44,146 @@ public class ScriptGenTest extends CodegenTestCase {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
scriptInstance = null;
|
||||
}
|
||||
|
||||
private void blackBoxScript(String filename) {
|
||||
loadFile(filename);
|
||||
|
||||
GenerationState state = generateClassesInFileGetState();
|
||||
|
||||
GeneratedClassLoader loader = createClassLoader(state.getFactory(), false);
|
||||
|
||||
String scriptClassName = ScriptNameUtil.classNameForScript(myFiles.getPsiFile());
|
||||
|
||||
try {
|
||||
Class<?> scriptClass = loader.loadClass(scriptClassName);
|
||||
|
||||
Constructor constructor = getConstructor(scriptClass, state.getScriptCodegen().getScriptConstructorMethod());
|
||||
scriptInstance = constructor.newInstance(myFiles.getScriptParameterValues().toArray());
|
||||
|
||||
assertFalse("expecting at least one expectation", myFiles.getExpectedValues().isEmpty());
|
||||
|
||||
for (Pair<String, String> nameValue : myFiles.getExpectedValues()) {
|
||||
String fieldName = nameValue.first;
|
||||
String expectedValue = nameValue.second;
|
||||
|
||||
if (expectedValue.equals("<nofield>")) {
|
||||
try {
|
||||
scriptClass.getDeclaredField(fieldName);
|
||||
fail("must have no field " + fieldName);
|
||||
} catch (NoSuchFieldException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Field field = scriptClass.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
Object result = field.get(scriptInstance);
|
||||
String resultString = result != null ? result.toString() : "null";
|
||||
assertEquals("comparing field " + fieldName, expectedValue, resultString);
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
System.out.println(generateToText());
|
||||
ExceptionUtils.rethrow(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected Constructor getConstructor(@NotNull Class<?> clazz, org.jetbrains.asm4.commons.Method method) {
|
||||
if (!method.getName().equals("<init>")) {
|
||||
throw new IllegalArgumentException("not constructor: " + method);
|
||||
}
|
||||
Class[] classes = new Class[method.getArgumentTypes().length];
|
||||
for (int i = 0; i < classes.length; ++i) {
|
||||
classes[i] = loadClassFromType(method.getArgumentTypes()[i]);
|
||||
}
|
||||
try {
|
||||
return clazz.getConstructor(classes);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Class<?> loadClassFromType(@NotNull Type type) {
|
||||
try {
|
||||
switch (type.getSort()) {
|
||||
case Type.OBJECT:
|
||||
return Class.forName(type.getClassName());
|
||||
case Type.INT:
|
||||
return int.class;
|
||||
case Type.LONG:
|
||||
return long.class;
|
||||
default:
|
||||
// AFAIK there is no way to create array class from class
|
||||
if (type.getDescriptor().equals("[Ljava/lang/String;")) {
|
||||
return String[].class;
|
||||
}
|
||||
throw new IllegalStateException("not implemented: " + type.getDescriptor());
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw ExceptionUtils.rethrow(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void testHelloWorld() {
|
||||
blackBoxFile("script/helloWorld.ktscript");
|
||||
blackBoxScript("script/helloWorld.ktscript");
|
||||
}
|
||||
|
||||
public void testString() {
|
||||
blackBoxFile("script/string.ktscript");
|
||||
blackBoxScript("script/string.ktscript");
|
||||
}
|
||||
|
||||
public void testTopLevelFunction() throws Exception {
|
||||
blackBoxFile("script/topLevelFunction.ktscript");
|
||||
blackBoxScript("script/topLevelFunction.ktscript");
|
||||
Method method = scriptInstance.getClass().getMethod("factorial", new Class<?>[]{ int.class });
|
||||
Object r = method.invoke(scriptInstance, 4);
|
||||
assertEquals(24, r);
|
||||
}
|
||||
|
||||
public void testTopLevelFunctionClosure() {
|
||||
blackBoxFile("script/topLevelFunctionClosure.ktscript");
|
||||
blackBoxScript("script/topLevelFunctionClosure.ktscript");
|
||||
}
|
||||
|
||||
public void testSecondLevelFunction() {
|
||||
blackBoxFile("script/secondLevelFunction.ktscript");
|
||||
blackBoxScript("script/secondLevelFunction.ktscript");
|
||||
}
|
||||
|
||||
public void testSecondLevelFunctionClosure() {
|
||||
blackBoxFile("script/secondLevelFunctionClosure.ktscript");
|
||||
blackBoxScript("script/secondLevelFunctionClosure.ktscript");
|
||||
}
|
||||
|
||||
public void testSecondLevelVal() {
|
||||
blackBoxFile("script/secondLevelVal.ktscript");
|
||||
blackBoxScript("script/secondLevelVal.ktscript");
|
||||
}
|
||||
|
||||
public void testTopLevelProperty() {
|
||||
blackBoxFile("script/topLevelProperty.ktscript");
|
||||
blackBoxScript("script/topLevelProperty.ktscript");
|
||||
}
|
||||
|
||||
public void testScriptParameter() {
|
||||
blackBoxFile("script/parameter.ktscript");
|
||||
blackBoxScript("script/parameter.ktscript");
|
||||
}
|
||||
|
||||
public void testScriptParameterLong() {
|
||||
blackBoxFile("script/parameterLong.ktscript");
|
||||
blackBoxScript("script/parameterLong.ktscript");
|
||||
}
|
||||
|
||||
public void testScriptParameterArray() {
|
||||
blackBoxFile("script/parameterArray.ktscript");
|
||||
blackBoxScript("script/parameterArray.ktscript");
|
||||
}
|
||||
|
||||
public void testScriptParameterClosure() {
|
||||
blackBoxFile("script/parameterClosure.ktscript");
|
||||
blackBoxScript("script/parameterClosure.ktscript");
|
||||
}
|
||||
|
||||
public void testEmpty() {
|
||||
blackBoxFile("script/empty.ktscript");
|
||||
blackBoxScript("script/empty.ktscript");
|
||||
}
|
||||
|
||||
public void testLanguage() {
|
||||
|
||||
Reference in New Issue
Block a user