Initial support for classes in scripts and REPL
This commit is contained in:
@@ -26,8 +26,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetScript;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
@@ -215,7 +214,12 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
|
||||
|
||||
private void genMembers() {
|
||||
for (JetDeclaration declaration : scriptDeclaration.getDeclarations()) {
|
||||
genFunctionOrProperty(declaration);
|
||||
if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) {
|
||||
genFunctionOrProperty(declaration);
|
||||
}
|
||||
else if (declaration instanceof JetClassOrObject) {
|
||||
genClassOrObject((JetClassOrObject) declaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,6 +309,11 @@ public class CodegenBinding {
|
||||
return fqName.isRoot() ? shortName : fqName.asString().replace('.', '/') + '/' + shortName;
|
||||
}
|
||||
|
||||
if (container instanceof ScriptDescriptor) {
|
||||
Type scriptType = asmTypeForScriptDescriptor(bindingContext, (ScriptDescriptor) container);
|
||||
return scriptType.getInternalName() + "$" + name.getIdentifier();
|
||||
}
|
||||
|
||||
assert container instanceof ClassDescriptor : "Unexpected container: " + container + " for " + klass;
|
||||
|
||||
String containerInternalName = getAsmType(bindingContext, (ClassDescriptor) container).getInternalName();
|
||||
|
||||
@@ -77,6 +77,9 @@ public class OverloadResolver {
|
||||
else if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
||||
inPackages.put(getFqName(klass), klass.getConstructors());
|
||||
}
|
||||
else if (containingDeclaration instanceof ScriptDescriptor) {
|
||||
// TODO: check overload conflicts of functions with constructors in scripts
|
||||
}
|
||||
else if (!(containingDeclaration instanceof FunctionDescriptor)) {
|
||||
throw new IllegalStateException("Illegal class container: " + containingDeclaration);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class SimpleClass(val s: String) {
|
||||
fun foo() = s
|
||||
}
|
||||
|
||||
SimpleClass("OK").foo()
|
||||
|
||||
// expected: rv: OK
|
||||
@@ -0,0 +1,6 @@
|
||||
>>> open class A(val result: String) {
|
||||
... fun foo() = result
|
||||
... }
|
||||
>>> class B : A("OK")
|
||||
>>> B().foo()
|
||||
OK
|
||||
@@ -0,0 +1,13 @@
|
||||
>>> class A {
|
||||
... fun foo() = "Old"
|
||||
... }
|
||||
>>> val oldA = A()
|
||||
>>> class A {
|
||||
... fun foo() = "New"
|
||||
... }
|
||||
>>> oldA.foo()
|
||||
Old
|
||||
>>> A().foo()
|
||||
New
|
||||
>>> oldA.javaClass == javaClass<A>()
|
||||
false
|
||||
@@ -0,0 +1,2 @@
|
||||
>>> class A
|
||||
>>> class B {}
|
||||
@@ -0,0 +1,2 @@
|
||||
>>> class A
|
||||
>>> class A
|
||||
@@ -0,0 +1,11 @@
|
||||
>>> enum class E {
|
||||
... FIRST {
|
||||
... override fun foo() = "HELLO"
|
||||
... }
|
||||
... SECOND {
|
||||
... override fun foo() = "WORLD"
|
||||
... }
|
||||
... open fun foo() = "E"
|
||||
... }
|
||||
>>> E.FIRST.foo() + " " + E.SECOND.foo()
|
||||
HELLO WORLD
|
||||
@@ -0,0 +1,5 @@
|
||||
>>> import java.util.Collections
|
||||
>>> Collections.emptyList<Nothing>()
|
||||
[]
|
||||
>>> Collections.singletonList(":|||:")
|
||||
[:|||:]
|
||||
@@ -0,0 +1,6 @@
|
||||
>>> class A { override fun toString() = "A" }
|
||||
>>> val a = A()
|
||||
>>> a
|
||||
A
|
||||
>>> a.toString()
|
||||
A
|
||||
@@ -0,0 +1,8 @@
|
||||
>>> enum class E {
|
||||
... FIRST
|
||||
... SECOND
|
||||
... }
|
||||
>>> E.values().toList()
|
||||
[FIRST, SECOND]
|
||||
>>> E.FIRST.javaClass == E.SECOND.javaClass // check that no artificial classes are generated for simple enum entries
|
||||
true
|
||||
@@ -0,0 +1,6 @@
|
||||
>>> trait A
|
||||
>>> trait B : A {
|
||||
... fun foo() = 45
|
||||
... }
|
||||
>>> javaClass<A>().isAssignableFrom(javaClass<B>())
|
||||
true
|
||||
@@ -0,0 +1,3 @@
|
||||
>>> object Empty
|
||||
>>> "Empty" in Empty.toString()
|
||||
true
|
||||
@@ -0,0 +1,5 @@
|
||||
>>> object Life {
|
||||
... fun meaning() = 42
|
||||
... }
|
||||
>>> Life.meaning()
|
||||
42
|
||||
@@ -81,6 +81,11 @@ public class ScriptCodegenTestGenerated extends AbstractScriptCodegenTest {
|
||||
doTest("compiler/testData/codegen/script/secondLevelVal.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleClass.kts")
|
||||
public void testSimpleClass() throws Exception {
|
||||
doTest("compiler/testData/codegen/script/simpleClass.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("string.kts")
|
||||
public void testString() throws Exception {
|
||||
doTest("compiler/testData/codegen/script/string.kts");
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.jetbrains.jet.repl.AbstractReplInterpreterTest;
|
||||
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/repl")
|
||||
@InnerTestClasses({ReplInterpreterTestGenerated.Classes.class, ReplInterpreterTestGenerated.Objects.class})
|
||||
public class ReplInterpreterTestGenerated extends AbstractReplInterpreterTest {
|
||||
public void testAllFilesPresentInRepl() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/repl"), Pattern.compile("^(.+)\\.repl$"), true);
|
||||
@@ -106,4 +107,82 @@ public class ReplInterpreterTestGenerated extends AbstractReplInterpreterTest {
|
||||
doTest("compiler/testData/repl/twoClosures.repl");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/repl/classes")
|
||||
public static class Classes extends AbstractReplInterpreterTest {
|
||||
public void testAllFilesPresentInClasses() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/repl/classes"), Pattern.compile("^(.+)\\.repl$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("classInheritance.repl")
|
||||
public void testClassInheritance() throws Exception {
|
||||
doTest("compiler/testData/repl/classes/classInheritance.repl");
|
||||
}
|
||||
|
||||
@TestMetadata("classRedeclaration.repl")
|
||||
public void testClassRedeclaration() throws Exception {
|
||||
doTest("compiler/testData/repl/classes/classRedeclaration.repl");
|
||||
}
|
||||
|
||||
@TestMetadata("emptyClass.repl")
|
||||
public void testEmptyClass() throws Exception {
|
||||
doTest("compiler/testData/repl/classes/emptyClass.repl");
|
||||
}
|
||||
|
||||
@TestMetadata("emptyClassRedeclaration.repl")
|
||||
public void testEmptyClassRedeclaration() throws Exception {
|
||||
doTest("compiler/testData/repl/classes/emptyClassRedeclaration.repl");
|
||||
}
|
||||
|
||||
@TestMetadata("enumEntrySubclass.repl")
|
||||
public void testEnumEntrySubclass() throws Exception {
|
||||
doTest("compiler/testData/repl/classes/enumEntrySubclass.repl");
|
||||
}
|
||||
|
||||
@TestMetadata("import.repl")
|
||||
public void testImport() throws Exception {
|
||||
doTest("compiler/testData/repl/classes/import.repl");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleClass.repl")
|
||||
public void testSimpleClass() throws Exception {
|
||||
doTest("compiler/testData/repl/classes/simpleClass.repl");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleEnum.repl")
|
||||
public void testSimpleEnum() throws Exception {
|
||||
doTest("compiler/testData/repl/classes/simpleEnum.repl");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleTrait.repl")
|
||||
public void testSimpleTrait() throws Exception {
|
||||
doTest("compiler/testData/repl/classes/simpleTrait.repl");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/repl/objects")
|
||||
public static class Objects extends AbstractReplInterpreterTest {
|
||||
public void testAllFilesPresentInObjects() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/repl/objects"), Pattern.compile("^(.+)\\.repl$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("emptyObject.repl")
|
||||
public void testEmptyObject() throws Exception {
|
||||
doTest("compiler/testData/repl/objects/emptyObject.repl");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleObjectDeclaration.repl")
|
||||
public void testSimpleObjectDeclaration() throws Exception {
|
||||
doTest("compiler/testData/repl/objects/simpleObjectDeclaration.repl");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite("ReplInterpreterTestGenerated");
|
||||
suite.addTestSuite(ReplInterpreterTestGenerated.class);
|
||||
suite.addTestSuite(Classes.class);
|
||||
suite.addTestSuite(Objects.class);
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -71,7 +70,10 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
|
||||
@Nullable
|
||||
private static ReceiverParameterDescriptor getExpectedThisObject(@NotNull ClassDescriptor descriptor) {
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
return DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration);
|
||||
if (containingDeclaration instanceof ClassDescriptor) {
|
||||
return ((ClassDescriptor) containingDeclaration).getThisAsReceiverParameter();
|
||||
}
|
||||
return NO_RECEIVER_PARAMETER;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user