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