simple case (no closures) of class level objects #KT-2398 fixed

This commit is contained in:
Alex Tkachman
2012-09-12 17:35:51 +03:00
parent 3e6c0c0f4e
commit 6c4102bf23
7 changed files with 82 additions and 18 deletions
@@ -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());
}
}