JET-61 Support class objects

JET-83 Interpret Java static methods as class objects' members
This commit is contained in:
Andrey Breslav
2011-06-03 19:03:33 +04:00
parent 4884af389f
commit 7e2e46ec71
8 changed files with 443 additions and 425 deletions
@@ -6,6 +6,7 @@ import org.jetbrains.jet.lang.resolve.JetScope;
import org.jetbrains.jet.lang.resolve.SubstitutingScope; import org.jetbrains.jet.lang.resolve.SubstitutingScope;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -16,6 +17,7 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
private TypeConstructor typeConstructor; private TypeConstructor typeConstructor;
private JavaClassMembersScope unsubstitutedMemberScope; private JavaClassMembersScope unsubstitutedMemberScope;
private JetType classObjectType;
private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>"); private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
public JavaClassDescriptor(DeclarationDescriptor containingDeclaration) { public JavaClassDescriptor(DeclarationDescriptor containingDeclaration) {
@@ -30,6 +32,20 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
this.unsubstitutedMemberScope = memberScope; this.unsubstitutedMemberScope = memberScope;
} }
public void setClassObjectMemberScope(JavaClassMembersScope memberScope) {
classObjectType = new JetTypeImpl(
new TypeConstructorImpl(
JavaDescriptorResolver.JAVA_CLASS_OBJECT,
Collections.<Annotation>emptyList(),
true,
"Class object emulation for " + getName(),
Collections.<TypeParameterDescriptor>emptyList(),
Collections.<JetType>emptyList()
),
memberScope
);
}
public void addConstructor(ConstructorDescriptor constructorDescriptor) { public void addConstructor(ConstructorDescriptor constructorDescriptor) {
this.constructors.addFunction(constructorDescriptor); this.constructors.addFunction(constructorDescriptor);
} }
@@ -89,7 +105,7 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
@Override @Override
public JetType getClassObjectType() { public JetType getClassObjectType() {
return null; // TODO : static members as class object members return classObjectType;
} }
@Override @Override
@@ -30,6 +30,19 @@ public class JavaDescriptorResolver {
} }
}; };
/*package*/ static final DeclarationDescriptor JAVA_CLASS_OBJECT = new DeclarationDescriptorImpl(null, Collections.<Annotation>emptyList(), "<java_class_object_emulation>") {
@NotNull
@Override
public DeclarationDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException(); // TODO
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitDeclarationDescriptor(this, data);
}
};
protected final Map<String, ClassDescriptor> classDescriptorCache = new HashMap<String, ClassDescriptor>(); protected final Map<String, ClassDescriptor> classDescriptorCache = new HashMap<String, ClassDescriptor>();
protected final Map<PsiTypeParameter, TypeParameterDescriptor> typeParameterDescriptorCache = Maps.newHashMap(); protected final Map<PsiTypeParameter, TypeParameterDescriptor> typeParameterDescriptorCache = Maps.newHashMap();
protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap(); protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap();
@@ -91,6 +104,7 @@ public class JavaDescriptorResolver {
)); ));
classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor); classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor);
classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false)); classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false));
classDescriptor.setClassObjectMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, true));
// UGLY HACK // UGLY HACK
supertypes.addAll(getSupertypes(psiClass)); supertypes.addAll(getSupertypes(psiClass));
@@ -713,7 +713,7 @@ public class JetTypeInferrer {
result = classObjectType; result = classObjectType;
} }
else { else {
trace.getErrorHandler().genericError(expression.getNode(), "This class does not have a class object"); trace.getErrorHandler().genericError(expression.getNode(), "Classifier " + classifier.getName() + " does not have a class object");
} }
trace.recordReferenceResolution(expression, classifier); trace.recordReferenceResolution(expression, classifier);
return; return;
-10
View File
@@ -171,7 +171,6 @@ JetFile: SimpleClassMembers.jet
CLASS_OBJECT CLASS_OBJECT
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL
OBJECT_DECLARATION OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -186,7 +185,6 @@ JetFile: SimpleClassMembers.jet
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL
OBJECT_DECLARATION OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -201,7 +199,6 @@ JetFile: SimpleClassMembers.jet
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL
OBJECT_DECLARATION OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -225,7 +222,6 @@ JetFile: SimpleClassMembers.jet
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL
OBJECT_DECLARATION OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -261,7 +257,6 @@ JetFile: SimpleClassMembers.jet
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL
OBJECT_DECLARATION OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -535,7 +530,6 @@ JetFile: SimpleClassMembers.jet
CLASS_OBJECT CLASS_OBJECT
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL
OBJECT_DECLARATION OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -550,7 +544,6 @@ JetFile: SimpleClassMembers.jet
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL
OBJECT_DECLARATION OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -565,7 +558,6 @@ JetFile: SimpleClassMembers.jet
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL
OBJECT_DECLARATION OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -589,7 +581,6 @@ JetFile: SimpleClassMembers.jet
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL
OBJECT_DECLARATION OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -625,7 +616,6 @@ JetFile: SimpleClassMembers.jet
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL
OBJECT_DECLARATION OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -134,7 +134,6 @@ JetFile: PolymorphicClassObjects.jet
CLASS_OBJECT CLASS_OBJECT
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL
OBJECT_DECLARATION OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -36,7 +36,6 @@ JetFile: UpdateOperation.jet
CLASS_OBJECT CLASS_OBJECT
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL
OBJECT_DECLARATION OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
@@ -70,7 +70,7 @@ public class ControlStructuresTest extends CodegenTestCase {
} }
public void testCondJumpOnStack() throws Exception { public void testCondJumpOnStack() throws Exception {
loadText("fun foo(a: String): Int = if (Boolean.parseBoolean(a)) 5 else 10"); loadText("fun foo(a: String): Int = if (java.lang.Boolean.parseBoolean(a)) 5 else 10");
final Method main = generateFunction(); final Method main = generateFunction();
assertEquals(5, main.invoke(null, "true")); assertEquals(5, main.invoke(null, "true"));
assertEquals(10, main.invoke(null, "false")); assertEquals(10, main.invoke(null, "false"));
@@ -123,7 +123,7 @@ public class PrimitiveTypesTest extends CodegenTestCase {
} }
public void testDoubleToJava() throws Exception { public void testDoubleToJava() throws Exception {
loadText("fun foo(d: Double): String? = Double.toString(d)"); loadText("fun foo(d: Double): String? = java.lang.Double.toString(d)");
final Method main = generateFunction(); final Method main = generateFunction();
assertEquals("1.0", main.invoke(null, 1.0)); assertEquals("1.0", main.invoke(null, 1.0));
} }