simple case (no closures) of class level objects #KT-2398 fixed
This commit is contained in:
@@ -60,9 +60,12 @@ public class ClassCodegen extends GenerationStateAware {
|
||||
|
||||
generate(contextForInners, (JetClass) declaration);
|
||||
}
|
||||
if (declaration instanceof JetClassObject) {
|
||||
else if (declaration instanceof JetClassObject) {
|
||||
generate(contextForInners, ((JetClassObject) declaration).getObjectDeclaration());
|
||||
}
|
||||
else if (declaration instanceof JetObjectDeclaration) {
|
||||
generate(contextForInners, (JetObjectDeclaration) declaration);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) {
|
||||
|
||||
@@ -2925,7 +2925,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
receiver.put(receiver.type, v);
|
||||
|
||||
pushClosureOnStack(bindingContext.get(CLOSURE, classDescriptor), true);
|
||||
final MutableClosure closure = bindingContext.get(CLOSURE, classDescriptor);
|
||||
|
||||
if(receiver.type.getSort() != Type.VOID && (closure == null || closure.getCaptureThis() == null)) {
|
||||
v.pop();
|
||||
}
|
||||
|
||||
pushClosureOnStack(closure, true);
|
||||
invokeMethodWithArguments(method, expression, StackValue.none());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1156,7 +1156,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
@Override
|
||||
protected void generateDeclaration(PropertyCodegen propertyCodegen, JetDeclaration declaration, FunctionCodegen functionCodegen) {
|
||||
if (declaration instanceof JetClassObject) {
|
||||
if (declaration instanceof JetClassObject || declaration instanceof JetObjectDeclaration) {
|
||||
// done earlier in order to have accessors
|
||||
}
|
||||
else if (declaration instanceof JetEnumEntry) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
@@ -137,15 +136,35 @@ public class CodegenBinding {
|
||||
bindingTrace.record(CLASS_FOR_FUNCTION, scriptDescriptor, classDescriptor);
|
||||
}
|
||||
|
||||
private static boolean canHaveOuter(BindingContext bindingContext, ClassDescriptor classDescriptor) {
|
||||
if (DescriptorUtils.isClassObject(classDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
if (classDescriptor.getKind() == ClassKind.ENUM_CLASS || classDescriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||
private static boolean canHaveOuter(BindingContext bindingContext, @NotNull ClassDescriptor classDescriptor) {
|
||||
final ClassKind kind = classDescriptor.getKind();
|
||||
if (isSingleton(bindingContext, classDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return enclosingClassDescriptor(bindingContext, classDescriptor) != null;
|
||||
if (kind == ClassKind.ENUM_CLASS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ClassDescriptor enclosing = enclosingClassDescriptor(bindingContext, classDescriptor);
|
||||
return enclosing != null && !isSingleton(bindingContext, enclosing);
|
||||
}
|
||||
|
||||
public static boolean isSingleton(BindingContext bindingContext, @NotNull ClassDescriptor classDescriptor) {
|
||||
final ClassKind kind = classDescriptor.getKind();
|
||||
if (kind == ClassKind.CLASS_OBJECT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (kind == ClassKind.OBJECT && isObjectDeclaration(bindingContext, classDescriptor)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (kind == ClassKind.ENUM_ENTRY) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void recordClosure(
|
||||
@@ -227,6 +246,14 @@ public class CodegenBinding {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isObjectDeclaration(BindingContext bindingContext, ClassDescriptor declaration) {
|
||||
PsiElement psiElement = descriptorToDeclaration(bindingContext, declaration);
|
||||
if (psiElement instanceof JetObjectDeclaration && !((JetObjectDeclaration) psiElement).isObjectLiteral()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isLocalFun(BindingContext bindingContext, DeclarationDescriptor fd) {
|
||||
PsiElement psiElement = descriptorToDeclaration(bindingContext, fd);
|
||||
if (psiElement instanceof JetNamedFunction && psiElement.getParent() instanceof JetBlockExpression) {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
class C {
|
||||
public object Obj {
|
||||
val o = "O"
|
||||
|
||||
object InnerObj {
|
||||
fun k() = "K"
|
||||
}
|
||||
|
||||
class D {
|
||||
val ko = "KO"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun box() = C().Obj.o + C().Obj.InnerObj.k() + C().Obj.D().ko
|
||||
@@ -25,23 +25,23 @@ 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.CompileCompilerDependenciesTest;
|
||||
import org.jetbrains.jet.ConfigurationKind;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.TestJdkKind;
|
||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.state.GenerationStrategy;
|
||||
import org.jetbrains.jet.lang.BuiltinsScopeExtensionMode;
|
||||
import org.jetbrains.jet.lang.resolve.ScriptNameUtil;
|
||||
import org.jetbrains.jet.utils.ExceptionUtils;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
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.asm4.Type;
|
||||
import org.jetbrains.jet.utils.ExceptionUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -152,8 +152,12 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
}
|
||||
|
||||
protected void blackBoxFile(String filename) {
|
||||
blackBoxFile(filename, "OK");
|
||||
}
|
||||
|
||||
protected void blackBoxFile(String filename, String expected) {
|
||||
loadFile(filename);
|
||||
blackBox();
|
||||
blackBox(expected);
|
||||
}
|
||||
|
||||
protected void blackBoxFileByFullPath(String filename) {
|
||||
@@ -206,6 +210,10 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
}
|
||||
|
||||
protected void blackBox() {
|
||||
blackBox("OK");
|
||||
}
|
||||
|
||||
protected void blackBox(String expected) {
|
||||
GenerationState state = generateClassesInFileGetState();
|
||||
|
||||
GeneratedClassLoader loader = createClassLoader(state.getFactory());
|
||||
@@ -248,7 +256,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
try {
|
||||
Method method = namespaceClass.getMethod("box");
|
||||
r = (String) method.invoke(null);
|
||||
assertEquals("OK", r);
|
||||
assertEquals(expected, r);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
Method method = namespaceClass.getMethod("main",String[].class);
|
||||
|
||||
@@ -99,4 +99,9 @@ public class ObjectGenTest extends CodegenTestCase {
|
||||
public void testFlist() {
|
||||
blackBoxFile("objects/flist.kt");
|
||||
}
|
||||
|
||||
public void testKt2398() {
|
||||
blackBoxFile("regressions/kt2398.kt", "OKKO");
|
||||
System.out.println(generateToText());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user