Rework class objects
Class objects have name "Default" by default
Do not produce synthetic class objects
Class objects have new semantics:
class "A" has class object "B" if literal "A" can be used as a value of type "B"
Class objects act like ordinary nested objects
i.e. are accessible from class scope via getClassifier()
Jvm backend: class object fields and class have the name of class object ("Default")
as opposed to special "OBJECT$" and "object"
Serialization: only the name of class object is needed to serialize data
This commit is contained in:
+1
-5
@@ -256,11 +256,7 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport
|
||||
@NotNull
|
||||
private static FqName getClassRelativeName(@NotNull JetClassOrObject decompiledClassOrObject) {
|
||||
Name name = decompiledClassOrObject.getNameAsName();
|
||||
if (name == null) {
|
||||
assert decompiledClassOrObject instanceof JetObjectDeclaration &&
|
||||
((JetObjectDeclaration) decompiledClassOrObject).isClassObject();
|
||||
name = Name.identifier(JvmAbi.CLASS_OBJECT_CLASS_NAME);
|
||||
}
|
||||
assert name != null;
|
||||
JetClassOrObject parent = PsiTreeUtil.getParentOfType(decompiledClassOrObject, JetClassOrObject.class, true);
|
||||
if (parent == null) {
|
||||
assert decompiledClassOrObject.isTopLevel();
|
||||
|
||||
+11
-8
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.psi.JetDelegationSpecifierList
|
||||
import org.jetbrains.kotlin.psi.JetDelegatorToSuperClass
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.name.SpecialNames.getClassObjectName
|
||||
import org.jetbrains.kotlin.psi.JetClassObject
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
|
||||
import org.jetbrains.kotlin.psi.stubs.impl.KotlinModifierListStubImpl
|
||||
@@ -68,6 +67,7 @@ private class ClassClsStubBuilder(
|
||||
supertypeIds
|
||||
}
|
||||
}
|
||||
private val classObjectName = if (classProto.hasClassObjectName()) c.nameResolver.getName(classProto.getClassObjectName()) else null
|
||||
|
||||
private val classOrObjectStub = createClassOrObjectStubAndModifierListStub()
|
||||
|
||||
@@ -112,8 +112,8 @@ private class ClassClsStubBuilder(
|
||||
|
||||
private fun doCreateClassOrObjectStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
|
||||
val isClassObject = classKind == ProtoBuf.Class.Kind.CLASS_OBJECT
|
||||
val fqName = if (!isClassObject) outerContext.memberFqNameProvider.getMemberFqName(classId.getRelativeClassName().shortName()) else null
|
||||
val shortName = fqName?.shortName()?.ref()
|
||||
val fqName = outerContext.memberFqNameProvider.getMemberFqName(classId.getRelativeClassName().shortName())
|
||||
val shortName = fqName.shortName()?.ref()
|
||||
val superTypeRefs = supertypeIds.filter {
|
||||
//TODO: filtering function types should go away
|
||||
!KotlinBuiltIns.isExactFunctionType(it.asSingleFqName()) && !KotlinBuiltIns.isExactExtensionFunctionType(it.asSingleFqName())
|
||||
@@ -132,7 +132,7 @@ private class ClassClsStubBuilder(
|
||||
KotlinClassStubImpl(
|
||||
JetClassElementType.getStubType(classKind == ProtoBuf.Class.Kind.ENUM_ENTRY),
|
||||
parent,
|
||||
fqName?.ref(),
|
||||
fqName.ref(),
|
||||
shortName,
|
||||
superTypeRefs,
|
||||
isTrait = classKind == ProtoBuf.Class.Kind.TRAIT,
|
||||
@@ -181,11 +181,11 @@ private class ClassClsStubBuilder(
|
||||
}
|
||||
|
||||
private fun createClassObjectStub(classBody: KotlinPlaceHolderStubImpl<JetClassBody>) {
|
||||
if (!classProto.hasClassObject() || classKind == ProtoBuf.Class.Kind.OBJECT) {
|
||||
if (classObjectName == null) {
|
||||
return
|
||||
}
|
||||
|
||||
val classObjectId = classId.createNestedClassId(getClassObjectName(classId.getRelativeClassName().shortName()))
|
||||
val classObjectId = classId.createNestedClassId(classObjectName)
|
||||
createNestedClassStub(classBody, classObjectId)
|
||||
}
|
||||
|
||||
@@ -221,8 +221,11 @@ private class ClassClsStubBuilder(
|
||||
|
||||
private fun createInnerAndNestedClasses(classBody: KotlinPlaceHolderStubImpl<JetClassBody>) {
|
||||
classProto.getNestedClassNameList().forEach { id ->
|
||||
val nestedClassId = classId.createNestedClassId(c.nameResolver.getName(id))
|
||||
createNestedClassStub(classBody, nestedClassId)
|
||||
val nestedClassName = c.nameResolver.getName(id)
|
||||
if (nestedClassName != classObjectName) {
|
||||
val nestedClassId = classId.createNestedClassId(nestedClassName)
|
||||
createNestedClassStub(classBody, nestedClassId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.load.kotlin.AbstractBinaryClassAnnotationAndConstant
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
|
||||
|
||||
class ClsStubBuilderComponents(
|
||||
@@ -42,11 +41,11 @@ class ClsStubBuilderComponents(
|
||||
}
|
||||
}
|
||||
|
||||
//TODO_R: remove?
|
||||
class MemberFqNameProvider(val fqName: FqName) {
|
||||
fun getMemberFqName(name: Name): FqName = fqName.child(name)
|
||||
|
||||
fun child(name: Name?): MemberFqNameProvider =
|
||||
if (name == null || SpecialNames.isClassObjectName(name)) this else MemberFqNameProvider(fqName.child(name))
|
||||
fun child(name: Name?): MemberFqNameProvider = if (name == null) this else MemberFqNameProvider(fqName.child(name))
|
||||
}
|
||||
|
||||
trait TypeParameters {
|
||||
|
||||
+1
-2
@@ -97,8 +97,7 @@ fun createStubForPackageName(packageDirectiveStub: KotlinPlaceHolderStubImpl<Jet
|
||||
}
|
||||
|
||||
fun createStubForTypeName(typeClassId: ClassId, parent: StubElement<out PsiElement>): KotlinUserTypeStub {
|
||||
//TODO: should go away with default objects
|
||||
val segments = typeClassId.asSingleFqName().pathSegments().filter { !SpecialNames.isClassObjectName(it) }.toArrayList()
|
||||
val segments = typeClassId.asSingleFqName().pathSegments().toArrayList()
|
||||
assert(segments.isNotEmpty())
|
||||
val iterator = segments.listIterator(segments.size())
|
||||
|
||||
|
||||
+4
-1
@@ -148,7 +148,7 @@ private fun buildDecompiledText(packageFqName: FqName, descriptors: List<Declara
|
||||
var firstPassed = false
|
||||
val subindent = indent + " "
|
||||
val classObject = descriptor.getClassObjectDescriptor()
|
||||
if (classObject != null && !isSyntheticClassObject(classObject)) {
|
||||
if (classObject != null && !descriptor.getKind().isSingleton() && !isSyntheticClassObject(classObject)) {
|
||||
firstPassed = true
|
||||
builder.append(subindent)
|
||||
appendDescriptor(classObject, subindent)
|
||||
@@ -157,6 +157,9 @@ private fun buildDecompiledText(packageFqName: FqName, descriptors: List<Declara
|
||||
if (member.getContainingDeclaration() != descriptor) {
|
||||
continue
|
||||
}
|
||||
if (member == classObject) {
|
||||
continue
|
||||
}
|
||||
if (member is CallableMemberDescriptor
|
||||
&& member.getKind() != CallableMemberDescriptor.Kind.DECLARATION
|
||||
//TODO: not synthesized and component like
|
||||
|
||||
+1
-10
@@ -114,16 +114,7 @@ public class DeprecatedAnnotationVisitor extends AfterAnalysisHighlightingVisito
|
||||
}
|
||||
|
||||
private void checkClassDescriptor(@NotNull JetExpression expression, @NotNull ClassDescriptor target) {
|
||||
// Deprecated for Class, for ClassObject (if reference isn't in UserType or in ModifierList (trait))
|
||||
if (!reportAnnotationIfNeeded(expression, target)) {
|
||||
if (PsiTreeUtil.getParentOfType(expression, JetUserType.class) == null &&
|
||||
PsiTreeUtil.getParentOfType(expression, JetModifierList.class) == null) {
|
||||
ClassDescriptor classObjectDescriptor = target.getClassObjectDescriptor();
|
||||
if (classObjectDescriptor != null) {
|
||||
reportAnnotationIfNeeded(expression, classObjectDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
reportAnnotationIfNeeded(expression, target);
|
||||
}
|
||||
|
||||
private void checkPropertyDescriptor(
|
||||
|
||||
+1
-15
@@ -56,25 +56,11 @@ public class StubIndexServiceImpl implements StubIndexService {
|
||||
@Override
|
||||
public void indexObject(KotlinObjectStub stub, IndexSink sink) {
|
||||
String name = stub.getName();
|
||||
FqName fqName = stub.getFqName();
|
||||
|
||||
if (stub.isClassObject()) {
|
||||
StubElement parentClassStub = stub.getParentStub().getParentStub().getParentStub();
|
||||
assert parentClassStub instanceof KotlinStubWithFqName<?>
|
||||
: "Something but a class/object is a parent to class object stub: " + parentClassStub;
|
||||
|
||||
name = JvmAbi.CLASS_OBJECT_CLASS_NAME;
|
||||
|
||||
FqName parentFqName = ((KotlinStubWithFqName<?>) parentClassStub).getFqName();
|
||||
if (parentFqName != null) {
|
||||
fqName = parentFqName.child(Name.identifier(name));
|
||||
}
|
||||
}
|
||||
|
||||
if (name != null) {
|
||||
sink.occurrence(JetClassShortNameIndex.getInstance().getKey(), name);
|
||||
}
|
||||
|
||||
FqName fqName = stub.getFqName();
|
||||
if (fqName != null) {
|
||||
sink.occurrence(JetFullClassNameIndex.getInstance().getKey(), fqName.asString());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user