diff --git a/compiler/testData/codegen/controlStructures/forLoopMemberExtensionAll.kt b/compiler/testData/codegen/controlStructures/forLoopMemberExtensionAll.kt index 2b6265720d2..95b87de7b86 100644 --- a/compiler/testData/codegen/controlStructures/forLoopMemberExtensionAll.kt +++ b/compiler/testData/codegen/controlStructures/forLoopMemberExtensionAll.kt @@ -20,6 +20,7 @@ class X { fun foo(x: Int) {} -fun main(args: Array) { +fun box(): String { X().test() + return "OK" } diff --git a/compiler/testData/codegen/controlStructures/forLoopMemberExtensionHasNext.kt b/compiler/testData/codegen/controlStructures/forLoopMemberExtensionHasNext.kt index b40a4b4920e..c51b317da02 100644 --- a/compiler/testData/codegen/controlStructures/forLoopMemberExtensionHasNext.kt +++ b/compiler/testData/codegen/controlStructures/forLoopMemberExtensionHasNext.kt @@ -20,6 +20,7 @@ class X { fun foo(x: Int) {} -fun main(args: Array) { +fun box(): String { X().test() + return "OK" } diff --git a/compiler/testData/codegen/controlStructures/forLoopMemberExtensionNext.kt b/compiler/testData/codegen/controlStructures/forLoopMemberExtensionNext.kt index 7cc9fd656d2..1987d8f7936 100644 --- a/compiler/testData/codegen/controlStructures/forLoopMemberExtensionNext.kt +++ b/compiler/testData/codegen/controlStructures/forLoopMemberExtensionNext.kt @@ -20,6 +20,7 @@ class X { fun foo(x: Int) {} -fun main(args: Array) { +fun box(): String { X().test() + return "OK" } diff --git a/compiler/testData/codegen/regressions/ea35963.kt b/compiler/testData/codegen/regressions/ea35963.kt index 0d28b39e695..6d58f3f2de4 100644 --- a/compiler/testData/codegen/regressions/ea35963.kt +++ b/compiler/testData/codegen/regressions/ea35963.kt @@ -1,5 +1,6 @@ -fun main(args : Array) { +fun box(): String { if (1 != 0) { 1 } -} \ No newline at end of file + return "OK" +} diff --git a/compiler/testData/codegen/regressions/kt1535.kt b/compiler/testData/codegen/regressions/kt1535.kt index 4e480a07d98..973a475c4f6 100644 --- a/compiler/testData/codegen/regressions/kt1535.kt +++ b/compiler/testData/codegen/regressions/kt1535.kt @@ -9,10 +9,12 @@ class Broken() : jet.Function0() { } } -fun main(args: Array) { +fun box(): String { val works1: ()->Object = Works(); works1() val broken1: ()->String = Broken(); broken1() -} \ No newline at end of file + + return "OK" +} diff --git a/compiler/testData/codegen/regressions/kt1845_1.kt b/compiler/testData/codegen/regressions/kt1845_1.kt index aad8197b1ab..9c898d2bf80 100644 --- a/compiler/testData/codegen/regressions/kt1845_1.kt +++ b/compiler/testData/codegen/regressions/kt1845_1.kt @@ -1,5 +1,6 @@ public var v1: String = "V1" -fun main(args: Array) { - System.out?.println("v1: $v1, v2: $v2") -} \ No newline at end of file +fun box(): String { + val s = "v1: $v1, v2: $v2" + return "OK" +} diff --git a/compiler/testData/codegen/regressions/kt2210.kt b/compiler/testData/codegen/regressions/kt2210.kt index 3e1cd2decab..1706319e1bd 100644 --- a/compiler/testData/codegen/regressions/kt2210.kt +++ b/compiler/testData/codegen/regressions/kt2210.kt @@ -2,6 +2,7 @@ class A(t: Array>) { val a:Array> = t } -fun main(args : Array) { +fun box(): String { A(array()) // <- java.lang.VerifyError: (class: A, method: getA signature: ()[[Ljava/lang/Object;) Wrong return type in function -} \ No newline at end of file + return "OK" +} diff --git a/compiler/testData/codegen/regressions/kt2246.kt b/compiler/testData/codegen/regressions/kt2246.kt index 3f68b9f770a..5fa670d53ce 100644 --- a/compiler/testData/codegen/regressions/kt2246.kt +++ b/compiler/testData/codegen/regressions/kt2246.kt @@ -1,3 +1,4 @@ -fun main(args: Array) { +fun box(): String { kotlin.assert(true) -} \ No newline at end of file + return "OK" +} diff --git a/compiler/testData/codegen/regressions/kt2275.kt b/compiler/testData/codegen/regressions/kt2275.kt index 997ee20552f..4dc1296a0e5 100644 --- a/compiler/testData/codegen/regressions/kt2275.kt +++ b/compiler/testData/codegen/regressions/kt2275.kt @@ -1,6 +1,5 @@ -import java.util.HashMap - -fun main(args: Array) { +fun box(): String { (0.toLong() as Number?)?.toByte() (0 as Int?)?.toDouble() -} \ No newline at end of file + return "OK" +} diff --git a/compiler/testData/codegen/regressions/kt2291.kt b/compiler/testData/codegen/regressions/kt2291.kt index 29da3e1073e..a1afcfe91b6 100644 --- a/compiler/testData/codegen/regressions/kt2291.kt +++ b/compiler/testData/codegen/regressions/kt2291.kt @@ -1,5 +1,6 @@ -fun main(args : Array) { +fun box(): String { 1 in 1.rangeTo(10) 1..10 'h' in 'A'.rangeTo('Z') -} \ No newline at end of file + return "OK" +} diff --git a/compiler/testData/codegen/regressions/kt2416.kt b/compiler/testData/codegen/regressions/kt2416.kt index 81c2fb4c6ac..19b5e5b8773 100644 --- a/compiler/testData/codegen/regressions/kt2416.kt +++ b/compiler/testData/codegen/regressions/kt2416.kt @@ -1,4 +1,4 @@ -fun main(args: Array) { +fun box(): String { 9 in 0..9 val intRange = 0..9 9 in intRange @@ -10,4 +10,6 @@ fun main(args: Array) { 9.toLong() in longRange val shortRange = 0.toShort()..9.toShort() 9.toShort() in shortRange -} \ No newline at end of file + + return "OK" +} diff --git a/compiler/testData/codegen/regressions/kt2509.kt b/compiler/testData/codegen/regressions/kt2509.kt index ae9c2a19808..441580875c3 100644 --- a/compiler/testData/codegen/regressions/kt2509.kt +++ b/compiler/testData/codegen/regressions/kt2509.kt @@ -1,5 +1,6 @@ -fun main(args: Array) { +fun box(): String { A() + return "OK" } class A: B() { @@ -8,4 +9,4 @@ class A: B() { abstract class B { abstract var foo: Array -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/regressions/kt2711.kt b/compiler/testData/codegen/regressions/kt2711.kt index b58fd12aaea..e6cddd8b42f 100644 --- a/compiler/testData/codegen/regressions/kt2711.kt +++ b/compiler/testData/codegen/regressions/kt2711.kt @@ -7,8 +7,9 @@ class C() { } -fun main(args: Array) { +fun box(): String { if (2 in C()..2) { - System.out?.println(2) + 2 == 2 } -} \ No newline at end of file + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/AbstractDataClassCodegenTest.java b/compiler/tests/org/jetbrains/jet/codegen/AbstractDataClassCodegenTest.java index bb4c1c8bccc..593fae236ba 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/AbstractDataClassCodegenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/AbstractDataClassCodegenTest.java @@ -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); } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index 7532c64fe5d..ab89aaeebf3 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -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 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("")) { - 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 nameValue : myFiles.getExpectedValues()) { - String fieldName = nameValue.first; - String expectedValue = nameValue.second; - - if (expectedValue.equals("")) { - 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); - } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestFiles.java b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestFiles.java index d0ce04aa8e3..424e9f368c6 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestFiles.java +++ b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestFiles.java @@ -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 files = new ArrayList(); for (String name : names) { diff --git a/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java index bf1f59f1a58..7b700e704f2 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/jet/codegen/FullJdkCodegenTest.java b/compiler/tests/org/jetbrains/jet/codegen/FullJdkCodegenTest.java index e1767a525df..aa72ba858ea 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/FullJdkCodegenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/FullJdkCodegenTest.java @@ -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() { diff --git a/compiler/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java index f89b59ad45b..f864f9fa960 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java @@ -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 { diff --git a/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java index 85bda3d988b..93fffbd8e02 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java @@ -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 { diff --git a/compiler/tests/org/jetbrains/jet/codegen/ScriptGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ScriptGenTest.java index 72edfba67ed..429b1d76643 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ScriptGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ScriptGenTest.java @@ -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 nameValue : myFiles.getExpectedValues()) { + String fieldName = nameValue.first; + String expectedValue = nameValue.second; + + if (expectedValue.equals("")) { + 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("")) { + 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() {