KT-1202 object construction fix
This commit is contained in:
@@ -793,7 +793,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
|
||||
if(closureCodegen.superCall != null) {
|
||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) closureCodegen.superCall).getCalleeExpression().getConstructorReferenceExpression());
|
||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, closureCodegen.superCall.getCalleeExpression().getConstructorReferenceExpression());
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION);
|
||||
Type[] argumentTypes = superCallable.getSignature().getAsmMethod().getArgumentTypes();
|
||||
Collections.addAll(consArgTypes, argumentTypes);
|
||||
|
||||
@@ -385,7 +385,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
JvmMethodSignature constructorMethod;
|
||||
CallableMethod callableMethod;
|
||||
if (constructorDescriptor == null) {
|
||||
|
||||
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false);
|
||||
|
||||
signatureWriter.writeFormalTypeParametersStart();
|
||||
@@ -417,10 +416,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
ObjectOrClosureCodegen closure = context.closure;
|
||||
int firstSuperArgument = -1;
|
||||
if(closure != null) {
|
||||
final LinkedList<JvmMethodParameterSignature> consArgTypes = new LinkedList<JvmMethodParameterSignature>(constructorMethod.getKotlinParameterTypes());
|
||||
final LinkedList<JvmMethodParameterSignature> consArgTypes = new LinkedList<JvmMethodParameterSignature>(constructorMethod.getKotlinParameterTypes());
|
||||
|
||||
int insert = 0;
|
||||
int insert = 0;
|
||||
if(closure != null) {
|
||||
if(closure.captureThis) {
|
||||
if(!CodegenUtil.hasThis0(descriptor))
|
||||
consArgTypes.add(insert, new JvmMethodParameterSignature(Type.getObjectType(context.getThisDescriptor().getName()), "", JvmMethodParameterKind.THIS0));
|
||||
@@ -444,22 +443,27 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
assert closure.captureReceiver != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(myClass instanceof JetObjectDeclaration) {
|
||||
if(superCall instanceof JetDelegatorToSuperCall) {
|
||||
if(myClass instanceof JetObjectDeclaration && ((JetObjectDeclaration) myClass).isObjectLiteral()) {
|
||||
if(superCall instanceof JetDelegatorToSuperCall) {
|
||||
if(closure != null)
|
||||
closure.superCall = (JetDelegatorToSuperCall) superCall;
|
||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION);
|
||||
firstSuperArgument = insert;
|
||||
for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) {
|
||||
consArgTypes.add(insert++, new JvmMethodParameterSignature(t, "", JvmMethodParameterKind.SHARED_VAR));
|
||||
}
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
||||
if(declarationDescriptor instanceof ClassDescriptor) {
|
||||
declarationDescriptor = ((ClassDescriptor)declarationDescriptor).getUnsubstitutedPrimaryConstructor();
|
||||
}
|
||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) declarationDescriptor;
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION);
|
||||
firstSuperArgument = insert;
|
||||
for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) {
|
||||
consArgTypes.add(insert++, new JvmMethodParameterSignature(t, "", JvmMethodParameterKind.SHARED_VAR));
|
||||
}
|
||||
}
|
||||
|
||||
constructorMethod = JvmMethodSignature.simple("<init>", Type.VOID_TYPE, consArgTypes);
|
||||
}
|
||||
|
||||
constructorMethod = JvmMethodSignature.simple("<init>", Type.VOID_TYPE, consArgTypes);
|
||||
|
||||
int flags = ACC_PUBLIC; // TODO
|
||||
final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(), constructorMethod.getGenericsSignature(), null);
|
||||
if (!v.generateCode()) return;
|
||||
@@ -547,7 +551,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "<init>", superCallMethod.getDescriptor());
|
||||
}
|
||||
else {
|
||||
iv.load(0, classType);
|
||||
ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
||||
generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap, firstSuperArgument);
|
||||
}
|
||||
@@ -726,17 +729,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
ConstructorDescriptor constructorDescriptor,
|
||||
ConstructorFrameMap frameMap, int firstSuperArgument) {
|
||||
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
||||
Type type = typeMapper.mapType(classDecl.getDefaultType(), OwnerKind.IMPLEMENTATION);
|
||||
|
||||
iv.load(0, type);
|
||||
iv.load(0, TYPE_OBJECT);
|
||||
|
||||
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||
iv.load(frameMap.getOuterThisIndex(), typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), OwnerKind.IMPLEMENTATION));
|
||||
}
|
||||
|
||||
CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, kind);
|
||||
if(myClass instanceof JetObjectDeclaration && superCall instanceof JetDelegatorToSuperCall) {
|
||||
iv.load(0, TYPE_OBJECT);
|
||||
|
||||
if(myClass instanceof JetObjectDeclaration && superCall instanceof JetDelegatorToSuperCall && ((JetObjectDeclaration) myClass).isObjectLiteral()) {
|
||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION);
|
||||
int nextVar = firstSuperArgument+1;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package interactive;
|
||||
|
||||
class Shape(var height : Double = 1.0, var fillColor : String = "#AAAAAA") {
|
||||
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
var a : Shape? = Shape()
|
||||
a?.height = 1.0
|
||||
return "OK"
|
||||
}
|
||||
@@ -265,4 +265,8 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
public void testKt471() throws Exception {
|
||||
blackBoxFile("regressions/kt471.kt");
|
||||
}
|
||||
|
||||
public void testKt1213() throws Exception {
|
||||
// blackBoxFile("regressions/kt1213.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<file leaf-file-name="Main.kt" pinned="false" current="true" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/src/Main.kt">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="32" column="57" selection-start="881" selection-end="881" vertical-scroll-proportion="1.3675214">
|
||||
<state line="29" column="74" selection-start="845" selection-end="845" vertical-scroll-proportion="1.2393162">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
@@ -100,12 +100,16 @@
|
||||
<sortByType />
|
||||
</navigator>
|
||||
<panes>
|
||||
<pane id="Scope">
|
||||
<subPane subId="Project Files">
|
||||
<pane id="PackagesPane">
|
||||
<subPane>
|
||||
<PATH>
|
||||
<PATH_ELEMENT USER_OBJECT="Root">
|
||||
<option name="myItemId" value="" />
|
||||
<option name="myItemType" value="" />
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="actors" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="actors" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewModuleNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
</subPane>
|
||||
@@ -144,16 +148,12 @@
|
||||
</PATH>
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="PackagesPane">
|
||||
<subPane>
|
||||
<pane id="Scope">
|
||||
<subPane subId="Project Files">
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="actors" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="actors" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewModuleNode" />
|
||||
<PATH_ELEMENT USER_OBJECT="Root">
|
||||
<option name="myItemId" value="" />
|
||||
<option name="myItemType" value="" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
</subPane>
|
||||
@@ -161,17 +161,17 @@
|
||||
</panes>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="project.structure.last.edited" value="Modules" />
|
||||
<property name="GoToFile.includeJavaFiles" value="false" />
|
||||
<property name="project.structure.proportion" value="0.15" />
|
||||
<property name="project.structure.last.edited" value="Modules" />
|
||||
<property name="GoToClass.toSaveIncludeLibraries" value="false" />
|
||||
<property name="recentsLimit" value="5" />
|
||||
<property name="project.structure.proportion" value="0.15" />
|
||||
<property name="MemberChooser.sorted" value="false" />
|
||||
<property name="recentsLimit" value="5" />
|
||||
<property name="MemberChooser.showClasses" value="true" />
|
||||
<property name="project.structure.side.proportion" value="0.2" />
|
||||
<property name="GoToClass.includeLibraries" value="false" />
|
||||
<property name="dynamic.classpath" value="false" />
|
||||
<property name="project.structure.side.proportion" value="0.2" />
|
||||
<property name="MemberChooser.copyJavadoc" value="false" />
|
||||
<property name="dynamic.classpath" value="false" />
|
||||
</component>
|
||||
<component name="RunManager" selected="Kotlin.org.jetbrains.kotlin.examples.actors">
|
||||
<configuration default="false" name="org.jetbrains.kotlin.examples.actors" type="JetRunConfigurationType" factoryName="Kotlin" temporary="true">
|
||||
@@ -228,6 +228,24 @@
|
||||
<option name="Maven.BeforeRunTask" enabled="false" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="Applet" factoryName="Applet">
|
||||
<module name="" />
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="HTML_FILE_NAME" />
|
||||
<option name="HTML_USED" value="false" />
|
||||
<option name="WIDTH" value="400" />
|
||||
<option name="HEIGHT" value="300" />
|
||||
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
|
||||
<option name="VM_PARAMETERS" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<method>
|
||||
<option name="AntTarget" enabled="false" />
|
||||
<option name="BuildArtifacts" enabled="false" />
|
||||
<option name="Make" enabled="true" />
|
||||
<option name="Maven.BeforeRunTask" enabled="false" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="TestNG" factoryName="TestNG">
|
||||
<module name="" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
@@ -260,24 +278,6 @@
|
||||
<option name="Maven.BeforeRunTask" enabled="false" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="Applet" factoryName="Applet">
|
||||
<module name="" />
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="HTML_FILE_NAME" />
|
||||
<option name="HTML_USED" value="false" />
|
||||
<option name="WIDTH" value="400" />
|
||||
<option name="HEIGHT" value="300" />
|
||||
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
|
||||
<option name="VM_PARAMETERS" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<method>
|
||||
<option name="AntTarget" enabled="false" />
|
||||
<option name="BuildArtifacts" enabled="false" />
|
||||
<option name="Make" enabled="true" />
|
||||
<option name="Maven.BeforeRunTask" enabled="false" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration default="true" type="Application" factoryName="Application">
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="VM_PARAMETERS" />
|
||||
@@ -341,7 +341,7 @@
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="0" y="22" width="1440" height="874" extended-state="6" />
|
||||
<editor active="true" />
|
||||
<editor active="false" />
|
||||
<layout>
|
||||
<window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
@@ -357,7 +357,7 @@
|
||||
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.18175288" sideWeight="0.50199205" order="0" side_tool="false" content_ui="combo" />
|
||||
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.10632184" sideWeight="0.50199205" order="0" side_tool="false" content_ui="combo" />
|
||||
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.49800798" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="ResolveWindow" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
|
||||
@@ -426,7 +426,7 @@
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$PROJECT_DIR$/src/Main.kt">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="32" column="57" selection-start="881" selection-end="881" vertical-scroll-proportion="1.3675214">
|
||||
<state line="29" column="74" selection-start="845" selection-end="845" vertical-scroll-proportion="1.2393162">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
package testeval
|
||||
|
||||
import java.util.*
|
||||
import junit.framework.TestCase.*
|
||||
|
||||
trait Expression
|
||||
class Num(val value : Int) : Expression
|
||||
class Sum(val left : Expression, val right : Expression) : Expression
|
||||
class Mult(val left : Expression, val right : Expression) : Expression
|
||||
|
||||
fun eval(e : Expression) : Int {
|
||||
return when (e) {
|
||||
is Num -> e.value
|
||||
is Sum -> eval(e.left) + eval (e.right)
|
||||
is Mult -> eval(e.left) * eval (e.right)
|
||||
else -> throw AssertionError("Unknown expression")
|
||||
}
|
||||
}
|
||||
|
||||
trait ParseResult<out T> {
|
||||
val success : Boolean
|
||||
val value : T
|
||||
}
|
||||
|
||||
class Success<T>(override val value : T) : ParseResult<T> {
|
||||
public override val success : Boolean = true
|
||||
}
|
||||
|
||||
class Failure(val message : String) : ParseResult<Nothing> {
|
||||
override val success = false
|
||||
override val value : Nothing = throw UnsupportedOperationException("Don't call value on a Failure")
|
||||
}
|
||||
|
||||
open class Token(val text : String) {
|
||||
fun toString() = text
|
||||
}
|
||||
object LPAR : Token("(")
|
||||
object RPAR : Token(")")
|
||||
object PLUS : Token("+")
|
||||
object TIMES : Token("*")
|
||||
object EOF : Token("EOF")
|
||||
class Number(text : String) : Token(text)
|
||||
class Error(text : String) : Token("[Error: $text]")
|
||||
|
||||
|
||||
fun tokenize(text : String) : Deque<Token> {
|
||||
val result = LinkedList<Token>()
|
||||
for (c in text) {
|
||||
result add when (c) {
|
||||
'(' -> LPAR
|
||||
')' -> RPAR
|
||||
'+' -> PLUS
|
||||
'*' -> TIMES
|
||||
in '0'..'9' -> Number(c.toString())
|
||||
else -> Error(c.toString())
|
||||
}
|
||||
}
|
||||
result.add(EOF)
|
||||
return result
|
||||
}
|
||||
|
||||
fun parseSum(tokens : Deque<Token>) : ParseResult<Expression> {
|
||||
val left = parseMult(tokens)
|
||||
if (!left.success) return left
|
||||
|
||||
if (tokens.peek() == PLUS) {
|
||||
tokens.pop()
|
||||
val right = parseSum(tokens)
|
||||
if (!right.success) return right
|
||||
return Success(Sum(left.value, right.value))
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
fun parseMult(tokens : Deque<Token>) : ParseResult<Expression> {
|
||||
val left = parseAtomic(tokens)
|
||||
if (!left.success) return left
|
||||
|
||||
if (tokens.peek() == PLUS) {
|
||||
tokens.pop()
|
||||
val right = parseMult(tokens)
|
||||
if (!right.success) return right
|
||||
return Success(Mult(left.value, right.value))
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
fun parseAtomic(tokens : Deque<Token>) : ParseResult<Expression> {
|
||||
val token = tokens.poll()
|
||||
return when (token) {
|
||||
LPAR -> {
|
||||
val result = parseSum(tokens)
|
||||
val rpar = tokens.poll()
|
||||
if (rpar == RPAR)
|
||||
result
|
||||
else
|
||||
Failure("Expecting ')'")
|
||||
}
|
||||
is Number -> Success(Num(Integer.parseInt((token as Token).text).sure()))
|
||||
else -> Failure("Unexpected EOF")
|
||||
}
|
||||
}
|
||||
|
||||
fun parse(text : String) : ParseResult<Expression> = parseSum(tokenize(text))
|
||||
|
||||
class EvalTest : junit.framework.TestCase() {
|
||||
fun testEval() {
|
||||
assertEquals(1, eval(Num(1)))
|
||||
assertEquals(2, eval(Sum(Num(1), Num(1))))
|
||||
assertEquals(3, eval(Mult(Num(3), Num(1))))
|
||||
assertEquals(6, eval(Mult(Num(3), Sum(Num(1), Num(1)))))
|
||||
}
|
||||
|
||||
fun testParse() {
|
||||
assertEquals(1, eval(parse("1").value))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user